Clone of https://github.com/NixOS/nixpkgs.git (to stress-test knotserver)
at devShellTools-shell 364 lines 13 kB view raw
1let 2 genericBuild = 3 { 4 lib, 5 stdenv, 6 fetchFromGitHub, 7 autoreconfHook269, 8 util-linux, 9 nukeReferences, 10 coreutils, 11 linuxPackages, 12 perl, 13 udevCheckHook, 14 configFile ? "all", 15 16 # Userspace dependencies 17 zlib, 18 libuuid, 19 python3, 20 attr, 21 openssl, 22 libtirpc, 23 nfs-utils, 24 gawk, 25 gnugrep, 26 gnused, 27 systemd, 28 smartmontools, 29 enableMail ? false, 30 sysstat, 31 pkg-config, 32 curl, 33 pam, 34 nix-update-script, 35 36 # Kernel dependencies 37 kernel ? null, 38 kernelModuleMakeFlags ? [ ], 39 enablePython ? true, 40 ... 41 }@outerArgs: 42 43 assert (configFile == "kernel") -> (kernel != null); 44 { 45 version, 46 hash, 47 kernelModuleAttribute, 48 extraLongDescription ? "", 49 extraPatches ? [ ], 50 rev ? "zfs-${version}", 51 kernelMinSupportedMajorMinor, 52 kernelMaxSupportedMajorMinor, 53 enableUnsupportedExperimentalKernel ? false, # allows building against unsupported Kernel versions 54 maintainers ? (with lib.maintainers; [ amarshall ]), 55 tests, 56 }@innerArgs: 57 58 let 59 inherit (lib) 60 any 61 optionalString 62 optionals 63 optional 64 makeBinPath 65 ; 66 67 smartmon = smartmontools.override { inherit enableMail; }; 68 69 buildKernel = any (n: n == configFile) [ 70 "kernel" 71 "all" 72 ]; 73 buildUser = any (n: n == configFile) [ 74 "user" 75 "all" 76 ]; 77 kernelIsCompatible = 78 kernel: 79 let 80 nextMajorMinor = 81 ver: 82 "${lib.versions.major ver}.${ 83 lib.pipe ver [ 84 lib.versions.minor 85 lib.toInt 86 (x: x + 1) 87 toString 88 ] 89 }"; 90 in 91 (lib.versionAtLeast kernel.version kernelMinSupportedMajorMinor) 92 && (lib.versionOlder kernel.version (nextMajorMinor kernelMaxSupportedMajorMinor)); 93 94 # XXX: You always want to build kernel modules with the same stdenv as the 95 # kernel was built with. However, since zfs can also be built for userspace we 96 # need to correctly pick between the provided/default stdenv, and the one used 97 # by the kernel. 98 # If you don't do this your ZFS builds will fail on any non-standard (e.g. 99 # clang-built) kernels. 100 stdenv' = if kernel == null then stdenv else kernel.stdenv; 101 in 102 103 stdenv'.mkDerivation { 104 name = "zfs-${configFile}-${version}${optionalString buildKernel "-${kernel.version}"}"; 105 pname = "zfs"; 106 inherit version; 107 108 src = fetchFromGitHub { 109 owner = "openzfs"; 110 repo = "zfs"; 111 inherit rev hash; 112 }; 113 114 patches = extraPatches; 115 116 postPatch = 117 optionalString buildKernel '' 118 patchShebangs scripts 119 # The arrays must remain the same length, so we repeat a flag that is 120 # already part of the command and therefore has no effect. 121 substituteInPlace ./module/os/linux/zfs/zfs_ctldir.c \ 122 --replace-fail '"/usr/bin/env", "umount"' '"${util-linux}/bin/umount", "-n"' \ 123 --replace-fail '"/usr/bin/env", "mount"' '"${util-linux}/bin/mount", "-n"' 124 '' 125 + optionalString buildUser '' 126 substituteInPlace ./lib/libshare/os/linux/nfs.c --replace-fail "/usr/sbin/exportfs" "${ 127 # We don't *need* python support, but we set it like this to minimize closure size: 128 # If it's disabled by default, no need to enable it, even if we have python enabled 129 # And if it's enabled by default, only change that if we explicitly disable python to remove python from the closure 130 nfs-utils.override (old: { 131 enablePython = old.enablePython or true && enablePython; 132 }) 133 }/bin/exportfs" 134 substituteInPlace ./lib/libshare/smb.h --replace-fail "/usr/bin/net" "/run/current-system/sw/bin/net" 135 # Disable dynamic loading of libcurl 136 substituteInPlace ./config/user-libfetch.m4 --replace-fail "curl-config --built-shared" "true" 137 substituteInPlace ./config/user-systemd.m4 --replace-fail "/usr/lib/modules-load.d" "$out/etc/modules-load.d" 138 substituteInPlace ./config/zfs-build.m4 --replace-fail "\$sysconfdir/init.d" "$out/etc/init.d" \ 139 --replace-fail "/etc/default" "$out/etc/default" 140 substituteInPlace ./contrib/initramfs/Makefile.am \ 141 --replace-fail "/usr/share/initramfs-tools" "$out/usr/share/initramfs-tools" 142 143 substituteInPlace ./udev/vdev_id \ 144 --replace-fail "PATH=/bin:/sbin:/usr/bin:/usr/sbin" \ 145 "PATH=${ 146 makeBinPath [ 147 coreutils 148 gawk 149 gnused 150 gnugrep 151 systemd 152 ] 153 }" 154 155 substituteInPlace ./config/zfs-build.m4 \ 156 --replace-fail "bashcompletiondir=/etc/bash_completion.d" \ 157 "bashcompletiondir=$out/share/bash-completion/completions" 158 159 substituteInPlace ./cmd/arc_summary --replace-fail "/sbin/modinfo" "modinfo" 160 '' 161 + '' 162 echo 'Supported Kernel versions:' 163 grep '^Linux-' META 164 echo 'Checking kernelMinSupportedMajorMinor is correct...' 165 grep --quiet '^Linux-Minimum: *${lib.escapeRegex kernelMinSupportedMajorMinor}$' META 166 echo 'Checking kernelMaxSupportedMajorMinor is correct...' 167 grep --quiet '^Linux-Maximum: *${lib.escapeRegex kernelMaxSupportedMajorMinor}$' META 168 ''; 169 170 nativeBuildInputs = [ 171 autoreconfHook269 172 nukeReferences 173 ] 174 ++ optionals buildKernel (kernel.moduleBuildDependencies ++ [ perl ]) 175 ++ optionals buildUser [ 176 pkg-config 177 udevCheckHook 178 ]; 179 buildInputs = 180 optionals buildUser [ 181 zlib 182 libuuid 183 attr 184 libtirpc 185 pam 186 ] 187 ++ optional buildUser openssl 188 ++ optional buildUser curl 189 ++ optional (buildUser && enablePython) python3; 190 191 # for zdb to get the rpath to libgcc_s, needed for pthread_cancel to work 192 NIX_CFLAGS_LINK = "-lgcc_s"; 193 194 hardeningDisable = [ 195 "fortify" 196 "stackprotector" 197 "pic" 198 ]; 199 200 configureFlags = [ 201 "--with-config=${configFile}" 202 "--with-tirpc=1" 203 (lib.withFeatureAs (buildUser && enablePython) "python" python3.interpreter) 204 ] 205 ++ optional enableUnsupportedExperimentalKernel "--enable-linux-experimental" 206 ++ optionals buildUser [ 207 "--with-dracutdir=$(out)/lib/dracut" 208 "--with-udevdir=$(out)/lib/udev" 209 "--with-systemdunitdir=$(out)/etc/systemd/system" 210 "--with-systemdpresetdir=$(out)/etc/systemd/system-preset" 211 "--with-systemdgeneratordir=$(out)/lib/systemd/system-generator" 212 "--with-mounthelperdir=$(out)/bin" 213 "--libexecdir=$(out)/libexec" 214 "--sysconfdir=/etc" 215 "--localstatedir=/var" 216 "--enable-systemd" 217 "--enable-pam" 218 ] 219 ++ optionals buildKernel ( 220 [ 221 "--with-linux=${kernel.dev}/lib/modules/${kernel.modDirVersion}/source" 222 "--with-linux-obj=${kernel.dev}/lib/modules/${kernel.modDirVersion}/build" 223 ] 224 ++ kernelModuleMakeFlags 225 ); 226 227 makeFlags = optionals buildKernel kernelModuleMakeFlags; 228 229 enableParallelBuilding = true; 230 231 doInstallCheck = true; 232 233 installFlags = [ 234 "sysconfdir=\${out}/etc" 235 "DEFAULT_INITCONF_DIR=\${out}/default" 236 "INSTALL_MOD_PATH=\${out}" 237 ]; 238 239 preConfigure = '' 240 # The kernel module builds some tests during the configurePhase, this envvar controls their parallelism 241 export TEST_JOBS=$NIX_BUILD_CORES 242 if [ -z "$enableParallelBuilding" ]; then 243 export TEST_JOBS=1 244 fi 245 ''; 246 247 # Enabling BTF causes zfs to be build with debug symbols. 248 # Since zfs compress kernel modules on installation, our strip hooks skip stripping them. 249 # Hence we strip modules prior to compression. 250 postBuild = optionalString buildKernel '' 251 find . -name "*.ko" -print0 | xargs -0 -P$NIX_BUILD_CORES ${stdenv.cc.targetPrefix}strip --strip-debug 252 ''; 253 254 postInstall = 255 optionalString buildKernel '' 256 # Add reference that cannot be detected due to compressed kernel module 257 mkdir -p "$out/nix-support" 258 echo "${util-linux}" >> "$out/nix-support/extra-refs" 259 '' 260 + optionalString buildUser '' 261 # Remove provided services as they are buggy 262 rm $out/etc/systemd/system/zfs-import-*.service 263 264 for i in $out/etc/systemd/system/*; do 265 if [ -L $i ]; then 266 continue 267 fi 268 sed -i '/zfs-import-scan.service/d' $i 269 substituteInPlace $i --replace-warn "zfs-import-cache.service" "zfs-import.target" 270 done 271 272 # Remove tests because they add a runtime dependency on gcc 273 rm -rf $out/share/zfs/zfs-tests 274 ''; 275 276 postFixup = 277 let 278 path = "PATH=${ 279 makeBinPath [ 280 coreutils 281 gawk 282 gnused 283 gnugrep 284 util-linux 285 smartmon 286 sysstat 287 ] 288 }:$PATH"; 289 in 290 '' 291 for i in $out/libexec/zfs/zpool.d/*; do 292 sed -i '2i${path}' $i 293 done 294 ''; 295 296 outputs = [ "out" ] ++ optionals buildUser [ "dev" ]; 297 298 passthru = { 299 inherit kernel; 300 inherit enableMail kernelModuleAttribute; 301 latestCompatibleLinuxPackages = lib.warn "zfs.latestCompatibleLinuxPackages is deprecated and is now pointing at the default kernel. If using the stable LTS kernel (default `linuxPackages` is not possible then you must explicitly pin a specific kernel release. For example, `boot.kernelPackages = pkgs.linuxPackages_6_6`. Please be aware that non-LTS kernels are likely to go EOL before ZFS supports the latest supported non-LTS release, requiring manual intervention." linuxPackages; 302 303 # The corresponding userspace tools to this instantiation 304 # of the ZFS package set. 305 userspaceTools = genericBuild ( 306 outerArgs 307 // { 308 configFile = "user"; 309 } 310 ) innerArgs; 311 312 inherit tests; 313 } 314 // lib.optionalAttrs (kernelModuleAttribute != "zfs_unstable") { 315 updateScript = nix-update-script { 316 extraArgs = [ 317 "--version-regex=^zfs-(${lib.versions.major version}\\.${lib.versions.minor version}\\.[0-9]+)" 318 "--override-filename=pkgs/os-specific/linux/zfs/${lib.versions.major version}_${lib.versions.minor version}.nix" 319 ]; 320 }; 321 }; 322 323 meta = { 324 description = "ZFS Filesystem Linux" + (if buildUser then " Userspace Tools" else " Kernel Module"); 325 longDescription = '' 326 ZFS is a filesystem that combines a logical volume manager with a 327 Copy-On-Write filesystem with data integrity detection and repair, 328 snapshotting, cloning, block devices, deduplication, and more. 329 330 ${ 331 if buildUser then "This is the userspace tools package." else "This is the kernel module package." 332 } 333 '' 334 + extraLongDescription; 335 homepage = "https://github.com/openzfs/zfs"; 336 changelog = "https://github.com/openzfs/zfs/releases/tag/zfs-${version}"; 337 license = lib.licenses.cddl; 338 339 # The case-block for TARGET_CPU has branches for only some CPU families, 340 # which prevents ZFS from building on any other platform. Since the NixOS 341 # `boot.zfs.enabled` property is `readOnly`, excluding platforms where ZFS 342 # does not build is the only way to produce a NixOS installer on such 343 # platforms. 344 # https://github.com/openzfs/zfs/blob/6723d1110f6daf93be93db74d5ea9f6b64c9bce5/config/always-arch.m4#L12 345 platforms = 346 with lib.systems.inspect.patterns; 347 map (p: p // isLinux) ( 348 [ 349 isx86_32 350 isx86_64 351 isPower 352 isAarch64 353 isSparc 354 ] 355 ++ isArmv7 356 ); 357 358 inherit maintainers; 359 mainProgram = "zfs"; 360 broken = buildKernel && !((kernelIsCompatible kernel) || enableUnsupportedExperimentalKernel); 361 }; 362 }; 363in 364genericBuild