diff options
Diffstat (limited to 'pkgs/build-support')
94 files changed, 1399 insertions, 1092 deletions
diff --git a/pkgs/build-support/alternatives/blas/default.nix b/pkgs/build-support/alternatives/blas/default.nix index 5ebbc737e11a..cf880677fddc 100644 --- a/pkgs/build-support/alternatives/blas/default.nix +++ b/pkgs/build-support/alternatives/blas/default.nix @@ -132,7 +132,7 @@ Description: BLAS C implementation Cflags: -I$dev/include Libs: -L$out/lib -lcblas EOF -'' + stdenv.lib.optionalString (blasImplementation == "mkl") '' +'' + lib.optionalString (blasImplementation == "mkl") '' mkdir -p $out/nix-support echo 'export MKL_INTERFACE_LAYER=${lib.optionalString isILP64 "I"}LP64,GNU' > $out/nix-support/setup-hook ln -s $out/lib/libblas${canonicalExtension} $out/lib/libmkl_rt${stdenv.hostPlatform.extensions.sharedLibrary} diff --git a/pkgs/build-support/alternatives/lapack/default.nix b/pkgs/build-support/alternatives/lapack/default.nix index 98b458b778a7..7e74eb96b747 100644 --- a/pkgs/build-support/alternatives/lapack/default.nix +++ b/pkgs/build-support/alternatives/lapack/default.nix @@ -98,7 +98,7 @@ Description: LAPACK C implementation Cflags: -I$dev/include Libs: -L$out/lib -llapacke EOF -'' + stdenv.lib.optionalString (lapackImplementation == "mkl") '' +'' + lib.optionalString (lapackImplementation == "mkl") '' mkdir -p $out/nix-support echo 'export MKL_INTERFACE_LAYER=${lib.optionalString isILP64 "I"}LP64,GNU' > $out/nix-support/setup-hook ln -s $out/lib/liblapack${canonicalExtension} $out/lib/libmkl_rt${stdenv.hostPlatform.extensions.sharedLibrary} diff --git a/pkgs/build-support/appimage/appimage-exec.sh b/pkgs/build-support/appimage/appimage-exec.sh index 82ebdd0bbe4a..4ff6802e6453 100755 --- a/pkgs/build-support/appimage/appimage-exec.sh +++ b/pkgs/build-support/appimage/appimage-exec.sh @@ -1,4 +1,6 @@ #!@shell@ +# shellcheck shell=bash + if [ -n "$DEBUG" ] ; then set -x fi @@ -13,8 +15,10 @@ unpack() { local out="$2" # https://github.com/AppImage/libappimage/blob/ca8d4b53bed5cbc0f3d0398e30806e0d3adeaaab/src/libappimage/utils/MagicBytesChecker.cpp#L45-L63 - local appimageSignature=$(readelf -h "$src" | awk 'NR==2{print $10$11;}') - local appimageType=$(readelf -h "$src" | awk 'NR==2{print $12;}') + local appimageSignature; + appimageSignature="$(LC_ALL=C readelf -h "$src" | awk 'NR==2{print $10$11;}')" + local appimageType; + appimageType="$(LC_ALL=C readelf -h "$src" | awk 'NR==2{print $12;}')" # check AppImage signature if [ "$appimageSignature" != "4149" ]; then @@ -35,7 +39,7 @@ unpack() { # multiarch offset one-liner using same method as AppImage # see https://gist.github.com/probonopd/a490ba3401b5ef7b881d5e603fa20c93 - offset=$(readelf -h "$src" | awk 'NR==13{e_shoff=$5} NR==18{e_shentsize=$5} NR==19{e_shnum=$5} END{print e_shoff+e_shentsize*e_shnum}') + offset=$(LC_ALL=C readelf -h "$src" | awk 'NR==13{e_shoff=$5} NR==18{e_shentsize=$5} NR==19{e_shnum=$5} END{print e_shoff+e_shentsize*e_shnum}') echo "Uncompress $(basename "$src") of type $appimageType @ offset $offset" unsquashfs -q -d "$out" -o "$offset" "$src" chmod go-w "$out" @@ -71,15 +75,15 @@ apprun() { wrap() { - cd "$APPDIR" || exit # quite same in appimageTools export APPIMAGE_SILENT_INSTALL=1 if [ -n "$APPIMAGE_DEBUG_EXEC" ]; then + cd "$APPDIR" || true exec "$APPIMAGE_DEBUG_EXEC" fi - exec ./AppRun "$@" + exec "$APPDIR/AppRun" "$@" } usage() { diff --git a/pkgs/build-support/appimage/default.nix b/pkgs/build-support/appimage/default.nix index e6014e35aef9..1613e9dea24b 100644 --- a/pkgs/build-support/appimage/default.nix +++ b/pkgs/build-support/appimage/default.nix @@ -1,4 +1,5 @@ -{ stdenv +{ lib + , bash , binutils-unwrapped , coreutils @@ -15,7 +16,7 @@ rec { src = ./appimage-exec.sh; isExecutable = true; dir = "bin"; - path = with pkgs; stdenv.lib.makeBinPath [ + path = lib.makeBinPath [ bash binutils-unwrapped coreutils diff --git a/pkgs/build-support/bintools-wrapper/add-flags.sh b/pkgs/build-support/bintools-wrapper/add-flags.sh index e99beb381586..3b94daba65d7 100644 --- a/pkgs/build-support/bintools-wrapper/add-flags.sh +++ b/pkgs/build-support/bintools-wrapper/add-flags.sh @@ -3,6 +3,7 @@ var_templates_list=( NIX_IGNORE_LD_THROUGH_GCC NIX_LDFLAGS NIX_LDFLAGS_BEFORE + NIX_DYNAMIC_LINKER NIX_LDFLAGS_AFTER NIX_LDFLAGS_HARDEN NIX_HARDENING_ENABLE @@ -25,6 +26,10 @@ if [ -e @out@/nix-support/libc-ldflags ]; then NIX_LDFLAGS_@suffixSalt@+=" $(< @out@/nix-support/libc-ldflags)" fi +if [ -z "$NIX_DYNAMIC_LINKER_@suffixSalt@" ] && [ -e @out@/nix-support/ld-set-dynamic-linker ]; then + NIX_DYNAMIC_LINKER_@suffixSalt@="$(< @out@/nix-support/dynamic-linker)" +fi + if [ -e @out@/nix-support/libc-ldflags-before ]; then NIX_LDFLAGS_BEFORE_@suffixSalt@="$(< @out@/nix-support/libc-ldflags-before) $NIX_LDFLAGS_BEFORE_@suffixSalt@" fi diff --git a/pkgs/build-support/bintools-wrapper/default.nix b/pkgs/build-support/bintools-wrapper/default.nix index 15fcc3742932..48a3ebb32dfe 100644 --- a/pkgs/build-support/bintools-wrapper/default.nix +++ b/pkgs/build-support/bintools-wrapper/default.nix @@ -6,6 +6,7 @@ # compiler and the linker just "work". { name ? "" +, lib , stdenvNoCC , bintools ? null, libc ? null, coreutils ? null, shell ? stdenvNoCC.shell, gnugrep ? null , nativeTools, noLibc ? false, nativeLibc, nativePrefix ? "" @@ -15,7 +16,7 @@ , useMacosReexportHack ? false }: -with stdenvNoCC.lib; +with lib; assert nativeTools -> !propagateDoc && nativePrefix != ""; assert !nativeTools -> @@ -31,11 +32,11 @@ let # # TODO(@Ericson2314) Make unconditional, or optional but always true by # default. - targetPrefix = stdenv.lib.optionalString (targetPlatform != hostPlatform) + targetPrefix = lib.optionalString (targetPlatform != hostPlatform) (targetPlatform.config + "-"); - bintoolsVersion = stdenv.lib.getVersion bintools; - bintoolsName = stdenv.lib.removePrefix targetPrefix (stdenv.lib.getName bintools); + bintoolsVersion = lib.getVersion bintools; + bintoolsName = lib.removePrefix targetPrefix (lib.getName bintools); libc_bin = if libc == null then null else getBin libc; libc_dev = if libc == null then null else getDev libc; @@ -63,7 +64,7 @@ let else if targetPlatform.system == "powerpc-linux" then "${libc_lib}/lib/ld.so.1" else if targetPlatform.isMips then "${libc_lib}/lib/ld.so.1" else if targetPlatform.isDarwin then "/usr/lib/dyld" - else if stdenv.lib.hasSuffix "pc-gnu" targetPlatform.config then "ld.so.1" + else if lib.hasSuffix "pc-gnu" targetPlatform.config then "ld.so.1" else null; expand-response-params = @@ -168,7 +169,7 @@ stdenv.mkDerivation { else if targetPlatform.isWindows then "pe" else "elf" + toString targetPlatform.parsed.cpu.bits; endianPrefix = if targetPlatform.isBigEndian then "big" else "little"; - sep = optionalString (!targetPlatform.isMips && !targetPlatform.isPower) "-"; + sep = optionalString (!targetPlatform.isMips && !targetPlatform.isPower && !targetPlatform.isRiscV) "-"; arch = /**/ if targetPlatform.isAarch64 then endianPrefix + "aarch64" else if targetPlatform.isAarch32 then endianPrefix + "arm" @@ -188,9 +189,10 @@ stdenv.mkDerivation { else if targetPlatform.isAlpha then "alpha" else if targetPlatform.isVc4 then "vc4" else if targetPlatform.isOr1k then "or1k" + else if targetPlatform.isRiscV then "lriscv" else throw "unknown emulation for platform: ${targetPlatform.config}"; in if targetPlatform.useLLVM or false then "" - else targetPlatform.platform.bfdEmulation or (fmt + sep + arch); + else targetPlatform.bfdEmulation or (fmt + sep + arch); strictDeps = true; depsTargetTargetPropagated = extraPackages; @@ -237,19 +239,14 @@ stdenv.mkDerivation { if [ -n "''${dynamicLinker-}" ]; then echo $dynamicLinker > $out/nix-support/dynamic-linker - '' + (if targetPlatform.isDarwin then '' - printf "export LD_DYLD_PATH=%q\n" "$dynamicLinker" >> $out/nix-support/setup-hook - '' else '' - if [ -e ${libc_lib}/lib/32/ld-linux.so.2 ]; then - echo ${libc_lib}/lib/32/ld-linux.so.2 > $out/nix-support/dynamic-linker-m32 - fi - '' - # The dynamic linker is passed in `ldflagsBefore' to allow - # explicit overrides of the dynamic linker by callers to ld - # (the *last* value counts, so ours should come first). - + '' - echo -dynamic-linker "$dynamicLinker" >> $out/nix-support/libc-ldflags-before - '') + '' + ${if targetPlatform.isDarwin then '' + printf "export LD_DYLD_PATH=%q\n" "$dynamicLinker" >> $out/nix-support/setup-hook + '' else '' + if [ -e ${libc_lib}/lib/32/ld-linux.so.2 ]; then + echo ${libc_lib}/lib/32/ld-linux.so.2 > $out/nix-support/dynamic-linker-m32 + fi + touch $out/nix-support/ld-set-dynamic-linker + ''} fi '') @@ -331,10 +328,10 @@ stdenv.mkDerivation { let bintools_ = if bintools != null then bintools else {}; in (if bintools_ ? meta then removeAttrs bintools.meta ["priority"] else {}) // { description = - stdenv.lib.attrByPath ["meta" "description"] "System binary utilities" bintools_ + lib.attrByPath ["meta" "description"] "System binary utilities" bintools_ + " (wrapper script)"; priority = 10; } // optionalAttrs useMacosReexportHack { - platforms = stdenv.lib.platforms.darwin; + platforms = lib.platforms.darwin; }; } diff --git a/pkgs/build-support/bintools-wrapper/ld-wrapper.sh b/pkgs/build-support/bintools-wrapper/ld-wrapper.sh index 81b5a90edd5c..9d02f99851a5 100644 --- a/pkgs/build-support/bintools-wrapper/ld-wrapper.sh +++ b/pkgs/build-support/bintools-wrapper/ld-wrapper.sh @@ -20,6 +20,7 @@ if [ -z "${NIX_BINTOOLS_WRAPPER_FLAGS_SET_@suffixSalt@:-}" ]; then source @out@/nix-support/add-flags.sh fi +setDynamicLinker=1 # Optionally filter out paths not refering to the store. expandResponseParams "$@" @@ -47,6 +48,11 @@ if [[ "${NIX_ENFORCE_PURITY:-}" = 1 && -n "${NIX_STORE:-}" # Our ld is not built with sysroot support (Can we fix that?) : else + if [[ "$p" = -static || "$p" = -static-pie ]]; then + # Using a dynamic linker for static binaries can lead to crashes. + # This was observed for rust binaries. + setDynamicLinker=0 + fi rest+=("$p") fi n+=1 @@ -63,6 +69,11 @@ extraBefore=(${hardeningLDFlags[@]+"${hardeningLDFlags[@]}"}) if [ -z "${NIX_LDFLAGS_SET_@suffixSalt@:-}" ]; then extraAfter+=($NIX_LDFLAGS_@suffixSalt@) extraBefore+=($NIX_LDFLAGS_BEFORE_@suffixSalt@) + # By adding dynamic linker to extraBefore we allow the users set their + # own dynamic linker as NIX_LD_FLAGS will override earlier set flags + if [[ "$setDynamicLinker" = 1 && -n "$NIX_DYNAMIC_LINKER_@suffixSalt@" ]]; then + extraBefore+=("-dynamic-linker" "$NIX_DYNAMIC_LINKER_@suffixSalt@") + fi fi extraAfter+=($NIX_LDFLAGS_AFTER_@suffixSalt@) @@ -134,7 +145,7 @@ then done fi -if [ -e "@out@/nix-support/dynamic-linker-m32" ] && (( "$link32" )); then +if [[ "$link32" = "1" && "$setDynamicLinker" = 1 && -e "@out@/nix-support/dynamic-linker-m32" ]]; then # We have an alternate 32-bit linker and we're producing a 32-bit ELF, let's # use it. extraAfter+=( diff --git a/pkgs/build-support/build-bazel-package/default.nix b/pkgs/build-support/build-bazel-package/default.nix index 10a331bcc9e7..3be72bd22c3f 100644 --- a/pkgs/build-support/build-bazel-package/default.nix +++ b/pkgs/build-support/build-bazel-package/default.nix @@ -172,7 +172,9 @@ in stdenv.mkDerivation (fBuildAttrs // { chmod -R +w $bazelOut find $bazelOut -type l | while read symlink; do - ln -sf $(readlink "$symlink" | sed "s,NIX_BUILD_TOP,$NIX_BUILD_TOP,") "$symlink" + if [[ $(readlink "$symlink") == *NIX_BUILD_TOP* ]]; then + ln -sf $(readlink "$symlink" | sed "s,NIX_BUILD_TOP,$NIX_BUILD_TOP,") "$symlink" + fi done '' + fBuildAttrs.preConfigure or ""; diff --git a/pkgs/build-support/build-dotnet-package/default.nix b/pkgs/build-support/build-dotnet-package/default.nix index dae9ed888c75..440b10044f0f 100644 --- a/pkgs/build-support/build-dotnet-package/default.nix +++ b/pkgs/build-support/build-dotnet-package/default.nix @@ -1,4 +1,4 @@ -{ stdenv, lib, makeWrapper, pkgconfig, mono, dotnetbuildhelpers }: +{ stdenv, lib, makeWrapper, pkg-config, mono, dotnetbuildhelpers }: attrsOrig @ { baseName @@ -19,7 +19,7 @@ attrsOrig @ attrs = { name = "${baseName}-${version}"; - nativeBuildInputs = [ pkgconfig ]; + nativeBuildInputs = [ pkg-config ]; buildInputs = [ mono dotnetbuildhelpers diff --git a/pkgs/build-support/build-fhs-userenv-bubblewrap/default.nix b/pkgs/build-support/build-fhs-userenv-bubblewrap/default.nix index 3a3c9e932fdb..9a9e5a9ce10a 100644 --- a/pkgs/build-support/build-fhs-userenv-bubblewrap/default.nix +++ b/pkgs/build-support/build-fhs-userenv-bubblewrap/default.nix @@ -1,20 +1,27 @@ -{ callPackage, runCommandLocal, writeShellScriptBin, stdenv, coreutils, bubblewrap }: - -let buildFHSEnv = callPackage ./env.nix { }; in +{ lib, callPackage, runCommandLocal, writeShellScriptBin, coreutils, bubblewrap }: args @ { - name, - runScript ? "bash", - extraInstallCommands ? "", - meta ? {}, - passthru ? {}, - ... + name +, runScript ? "bash" +, extraInstallCommands ? "" +, meta ? {} +, passthru ? {} +, unshareUser ? true +, unshareIpc ? true +, unsharePid ? true +, unshareNet ? false +, unshareUts ? true +, unshareCgroup ? true +, ... }: with builtins; let + buildFHSEnv = callPackage ./env.nix { }; + env = buildFHSEnv (removeAttrs args [ "runScript" "extraInstallCommands" "meta" "passthru" + "unshareUser" "unshareCgroup" "unshareUts" "unshareNet" "unsharePid" "unshareIpc" ]); chrootenv = callPackage ./chrootenv {}; @@ -92,8 +99,12 @@ let --dev-bind /dev /dev --proc /proc --chdir "$(pwd)" - --unshare-all - --share-net + ${lib.optionalString unshareUser "--unshare-user"} + ${lib.optionalString unshareIpc "--unshare-ipc"} + ${lib.optionalString unsharePid "--unshare-pid"} + ${lib.optionalString unshareNet "--unshare-net"} + ${lib.optionalString unshareUts "--unshare-uts"} + ${lib.optionalString unshareCgroup "--unshare-cgroup"} --die-with-parent --ro-bind /nix /nix ${etcBindFlags} diff --git a/pkgs/build-support/build-fhs-userenv/chrootenv/chrootenv.c b/pkgs/build-support/build-fhs-userenv/chrootenv/chrootenv.c index dcb2e97aa932..a438b80e1829 100644 --- a/pkgs/build-support/build-fhs-userenv/chrootenv/chrootenv.c +++ b/pkgs/build-support/build-fhs-userenv/chrootenv/chrootenv.c @@ -43,6 +43,7 @@ const gchar *create_tmpdir() { void pivot_host(const gchar *guest) { g_autofree gchar *point = g_build_filename(guest, "host", NULL); fail_if(g_mkdir(point, 0755)); + fail_if(mount(0, "/", 0, MS_PRIVATE | MS_REC, 0)); fail_if(pivot_root(guest, point)); } @@ -56,6 +57,7 @@ void bind_mount_item(const gchar *host, const gchar *guest, const gchar *name) { void bind(const gchar *host, const gchar *guest) { mount_tmpfs(guest); + pivot_host(guest); g_autofree gchar *host_dir = g_build_filename("/host", host, NULL); @@ -105,7 +107,11 @@ int main(gint argc, gchar **argv) { uid_t uid = getuid(); gid_t gid = getgid(); - if (unshare(CLONE_NEWNS | CLONE_NEWUSER) < 0) { + int namespaces = CLONE_NEWNS; + if (uid != 0) { + namespaces |= CLONE_NEWUSER; + } + if (unshare(namespaces) < 0) { int unshare_errno = errno; g_message("Requires Linux version >= 3.19 built with CONFIG_USER_NS"); @@ -116,9 +122,11 @@ int main(gint argc, gchar **argv) { fail("unshare", unshare_errno); } - spit("/proc/self/setgroups", "deny"); - spit("/proc/self/uid_map", "%d %d 1", uid, uid); - spit("/proc/self/gid_map", "%d %d 1", gid, gid); + if (uid != 0) { + spit("/proc/self/setgroups", "deny"); + spit("/proc/self/uid_map", "%d %d 1", uid, uid); + spit("/proc/self/gid_map", "%d %d 1", gid, gid); + } // If there is a /host directory, assume this is nested chrootenv and use it as host instead. gboolean nested_host = g_file_test("/host", G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR); diff --git a/pkgs/build-support/build-fhs-userenv/chrootenv/default.nix b/pkgs/build-support/build-fhs-userenv/chrootenv/default.nix index 70a7a43bd398..15d7b3153580 100644 --- a/pkgs/build-support/build-fhs-userenv/chrootenv/default.nix +++ b/pkgs/build-support/build-fhs-userenv/chrootenv/default.nix @@ -1,13 +1,13 @@ -{ stdenv, meson, ninja, pkgconfig, glib }: +{ lib, stdenv, meson, ninja, pkg-config, glib }: stdenv.mkDerivation { name = "chrootenv"; src = ./.; - nativeBuildInputs = [ meson ninja pkgconfig ]; + nativeBuildInputs = [ meson ninja pkg-config ]; buildInputs = [ glib ]; - meta = with stdenv.lib; { + meta = with lib; { description = "Setup mount/user namespace for FHS emulation"; license = licenses.mit; maintainers = with maintainers; [ yegortimoshenko ]; diff --git a/pkgs/build-support/cc-wrapper/cc-wrapper.sh b/pkgs/build-support/cc-wrapper/cc-wrapper.sh index 7e734f57773e..1450218aff27 100644 --- a/pkgs/build-support/cc-wrapper/cc-wrapper.sh +++ b/pkgs/build-support/cc-wrapper/cc-wrapper.sh @@ -28,6 +28,7 @@ cc1=0 [[ "@prog@" = *++ ]] && isCpp=1 || isCpp=0 cppInclude=1 cInclude=1 +setDynamicLinker=1 expandResponseParams "$@" declare -i n=0 @@ -58,6 +59,8 @@ while (( "$n" < "$nParams" )); do cppInclude=0 elif [ "$p" = -nostdinc++ ]; then cppInclude=0 + elif [[ "$p" = -static || "$p" = -static-pie ]]; then + setDynamicLinker=0 elif [[ "$p" != -?* ]]; then # A dash alone signifies standard input; it is not a flag nonFlagArgs=1 @@ -152,6 +155,9 @@ if [ "$dontLink" != 1 ]; then for i in $NIX_LDFLAGS_BEFORE_@suffixSalt@; do extraBefore+=("-Wl,$i") done + if [[ "$setDynamicLinker" = 1 && -n "$NIX_DYNAMIC_LINKER_@suffixSalt@" ]]; then + extraBefore+=("-Wl,-dynamic-linker=$NIX_DYNAMIC_LINKER_@suffixSalt@") + fi for i in $NIX_LDFLAGS_@suffixSalt@; do if [ "${i:0:3}" = -L/ ]; then extraAfter+=("$i") diff --git a/pkgs/build-support/cc-wrapper/default.nix b/pkgs/build-support/cc-wrapper/default.nix index 09cef8b8678d..341e2850437c 100644 --- a/pkgs/build-support/cc-wrapper/default.nix +++ b/pkgs/build-support/cc-wrapper/default.nix @@ -6,6 +6,7 @@ # compiler and the linker just "work". { name ? "" +, lib , stdenvNoCC , cc ? null, libc ? null, bintools, coreutils ? null, shell ? stdenvNoCC.shell , gccForLibs ? null @@ -18,7 +19,7 @@ , libcxx ? null }: -with stdenvNoCC.lib; +with lib; assert nativeTools -> !propagateDoc && nativePrefix != ""; assert !nativeTools -> @@ -34,11 +35,11 @@ let # # TODO(@Ericson2314) Make unconditional, or optional but always true by # default. - targetPrefix = stdenv.lib.optionalString (targetPlatform != hostPlatform) + targetPrefix = lib.optionalString (targetPlatform != hostPlatform) (targetPlatform.config + "-"); - ccVersion = stdenv.lib.getVersion cc; - ccName = stdenv.lib.removePrefix targetPrefix (stdenv.lib.getName cc); + ccVersion = lib.getVersion cc; + ccName = lib.removePrefix targetPrefix (lib.getName cc); libc_bin = if libc == null then null else getBin libc; libc_dev = if libc == null then null else getDev libc; @@ -65,6 +66,7 @@ let && libcxx == null && !(stdenv.targetPlatform.useLLVM or false) && !(stdenv.targetPlatform.useAndroidPrebuilt or false) + && !(stdenv.targetPlatform.isiOS or false) && gccForLibs != null; # older compilers (for example bootstrap's GCC 5) fail with -march=too-modern-cpu @@ -76,10 +78,14 @@ let cannonlake = versionAtLeast ccVersion "8.0"; icelake-client = versionAtLeast ccVersion "8.0"; icelake-server = versionAtLeast ccVersion "8.0"; + cascadelake = versionAtLeast ccVersion "9.0"; + cooperlake = versionAtLeast ccVersion "10.0"; + tigerlake = versionAtLeast ccVersion "10.0"; knm = versionAtLeast ccVersion "8.0"; # AMD znver1 = versionAtLeast ccVersion "6.0"; znver2 = versionAtLeast ccVersion "9.0"; + znver3 = versionAtLeast ccVersion "11.0"; }.${arch} or true else if isClang then { # Intel @@ -242,8 +248,8 @@ stdenv.mkDerivation { setupHooks = [ ../setup-hooks/role.bash - ] ++ stdenv.lib.optional (cc.langC or true) ./setup-hook.sh - ++ stdenv.lib.optional (cc.langFortran or false) ./fortran-hook.sh; + ] ++ lib.optional (cc.langC or true) ./setup-hook.sh + ++ lib.optional (cc.langFortran or false) ./fortran-hook.sh; postFixup = # Ensure flags files exists, as some other programs cat them. (That these @@ -285,6 +291,17 @@ stdenv.mkDerivation { echo "-L${gccForLibs.lib}/${targetPlatform.config}/lib" >> $out/nix-support/cc-ldflags '' + # TODO We would like to connect this to `useGccForLibs`, but we cannot yet + # because `libcxxStdenv` on linux still needs this. Maybe someday we'll + # always set `useLLVM` on Darwin, and maybe also break down `useLLVM` into + # fine-grained use flags (libgcc vs compiler-rt, ld.lld vs legacy, libc++ + # vs libstdc++, etc.) since Darwin isn't `useLLVM` on all counts. (See + # https://clang.llvm.org/docs/Toolchain.html for all the axes one might + # break `useLLVM` into.) + + optionalString (isClang && gccForLibs != null && targetPlatform.isLinux && !(stdenv.targetPlatform.useLLVM or false)) '' + echo "--gcc-toolchain=${gccForLibs}" >> $out/nix-support/cc-cflags + '' + ## ## General libc support ## @@ -337,7 +354,7 @@ stdenv.mkDerivation { + optionalString (libcxx.isLLVM or false) ('' echo "-isystem ${libcxx}/include/c++/v1" >> $out/nix-support/libcxx-cxxflags echo "-stdlib=libc++" >> $out/nix-support/libcxx-ldflags - '' + stdenv.lib.optionalString stdenv.targetPlatform.isLinux '' + '' + lib.optionalString stdenv.targetPlatform.isLinux '' echo "-lc++abi" >> $out/nix-support/libcxx-ldflags '') @@ -397,32 +414,32 @@ stdenv.mkDerivation { # Always add -march based on cpu in triple. Sometimes there is a # discrepency (x86_64 vs. x86-64), so we provide an "arch" arg in # that case. - + optionalString ((targetPlatform ? platform.gcc.arch) && - isGccArchSupported targetPlatform.platform.gcc.arch) '' - echo "-march=${targetPlatform.platform.gcc.arch}" >> $out/nix-support/cc-cflags-before + + optionalString ((targetPlatform ? gcc.arch) && + isGccArchSupported targetPlatform.gcc.arch) '' + echo "-march=${targetPlatform.gcc.arch}" >> $out/nix-support/cc-cflags-before '' # -mcpu is not very useful. You should use mtune and march # instead. It’s provided here for backwards compatibility. - + optionalString (targetPlatform ? platform.gcc.cpu) '' - echo "-mcpu=${targetPlatform.platform.gcc.cpu}" >> $out/nix-support/cc-cflags-before + + optionalString (targetPlatform ? gcc.cpu) '' + echo "-mcpu=${targetPlatform.gcc.cpu}" >> $out/nix-support/cc-cflags-before '' # -mfloat-abi only matters on arm32 but we set it here # unconditionally just in case. If the abi specifically sets hard # vs. soft floats we use it here. - + optionalString (targetPlatform ? platform.gcc.float-abi) '' - echo "-mfloat-abi=${targetPlatform.platform.gcc.float-abi}" >> $out/nix-support/cc-cflags-before + + optionalString (targetPlatform ? gcc.float-abi) '' + echo "-mfloat-abi=${targetPlatform.gcc.float-abi}" >> $out/nix-support/cc-cflags-before '' - + optionalString (targetPlatform ? platform.gcc.fpu) '' - echo "-mfpu=${targetPlatform.platform.gcc.fpu}" >> $out/nix-support/cc-cflags-before + + optionalString (targetPlatform ? gcc.fpu) '' + echo "-mfpu=${targetPlatform.gcc.fpu}" >> $out/nix-support/cc-cflags-before '' - + optionalString (targetPlatform ? platform.gcc.mode) '' - echo "-mmode=${targetPlatform.platform.gcc.mode}" >> $out/nix-support/cc-cflags-before + + optionalString (targetPlatform ? gcc.mode) '' + echo "-mmode=${targetPlatform.gcc.mode}" >> $out/nix-support/cc-cflags-before '' - + optionalString (targetPlatform ? platform.gcc.tune && - isGccArchSupported targetPlatform.platform.gcc.tune) '' - echo "-mtune=${targetPlatform.platform.gcc.tune}" >> $out/nix-support/cc-cflags-before + + optionalString (targetPlatform ? gcc.tune && + isGccArchSupported targetPlatform.gcc.tune) '' + echo "-mtune=${targetPlatform.gcc.tune}" >> $out/nix-support/cc-cflags-before '' # TODO: categorize these and figure out a better place for them @@ -437,7 +454,7 @@ stdenv.mkDerivation { '' + optionalString targetPlatform.isNetBSD '' hardening_unsupported_flags+=" stackprotector fortify" '' + optionalString cc.langAda or false '' - hardening_unsupported_flags+=" stackprotector strictoverflow" + hardening_unsupported_flags+=" format stackprotector strictoverflow" '' + optionalString cc.langD or false '' hardening_unsupported_flags+=" format" '' + optionalString targetPlatform.isWasm '' @@ -476,7 +493,7 @@ stdenv.mkDerivation { let cc_ = if cc != null then cc else {}; in (if cc_ ? meta then removeAttrs cc.meta ["priority"] else {}) // { description = - stdenv.lib.attrByPath ["meta" "description"] "System C compiler" cc_ + lib.attrByPath ["meta" "description"] "System C compiler" cc_ + " (wrapper script)"; priority = 10; }; diff --git a/pkgs/build-support/coq/default.nix b/pkgs/build-support/coq/default.nix new file mode 100644 index 000000000000..7e925e2473e1 --- /dev/null +++ b/pkgs/build-support/coq/default.nix @@ -0,0 +1,92 @@ +{ lib, stdenv, coqPackages, coq, fetchzip }@args: +let lib = import ./extra-lib.nix {inherit (args) lib;}; in +with builtins; with lib; +let + isGitHubDomain = d: match "^github.*" d != null; + isGitLabDomain = d: match "^gitlab.*" d != null; +in +{ pname, + version ? null, + fetcher ? null, + owner ? "coq-community", + domain ? "github.com", + repo ? pname, + defaultVersion ? null, + releaseRev ? (v: v), + displayVersion ? {}, + release ? {}, + extraBuildInputs ? [], + namePrefix ? [], + enableParallelBuilding ? true, + extraInstallFlags ? [], + setCOQBIN ? true, + mlPlugin ? false, + useMelquiondRemake ? null, + dropAttrs ? [], + keepAttrs ? [], + dropDerivationAttrs ? [], + ... +}@args: +let + args-to-remove = foldl (flip remove) ([ + "version" "fetcher" "repo" "owner" "domain" "releaseRev" + "displayVersion" "defaultVersion" "useMelquiondRemake" + "release" "extraBuildInputs" "extraPropagatedBuildInputs" "namePrefix" "meta" + "extraInstallFlags" "setCOQBIN" "mlPlugin" + "dropAttrs" "dropDerivationAttrs" "keepAttrs" ] ++ dropAttrs) keepAttrs; + fetch = import ../coq/meta-fetch/default.nix + { inherit stdenv fetchzip; } ({ + inherit release releaseRev; + location = { inherit domain owner repo; }; + } // optionalAttrs (args?fetcher) {inherit fetcher;}); + fetched = fetch (if !isNull version then version else defaultVersion); + namePrefix = args.namePrefix or [ "coq" ]; + display-pkg = n: sep: v: + let d = displayVersion.${n} or (if sep == "" then ".." else true); in + n + optionalString (v != "" && v != null) (switch d [ + { case = true; out = sep + v; } + { case = "."; out = sep + versions.major v; } + { case = ".."; out = sep + versions.majorMinor v; } + { case = "..."; out = sep + versions.majorMinorPatch v; } + { case = isFunction; out = optionalString (d v != "") (sep + d v); } + { case = isString; out = optionalString (d != "") (sep + d); } + ] "") + optionalString (v == null) "-broken"; + append-version = p: n: p + display-pkg n "" coqPackages.${n}.version + "-"; + prefix-name = foldl append-version "" namePrefix; + var-coqlib-install = (optionalString (versions.isGe "8.7" coq.coq-version) "COQMF_") + "COQLIB"; +in + +stdenv.mkDerivation (removeAttrs ({ + + name = prefix-name + (display-pkg pname "-" fetched.version); + + inherit (fetched) version src; + + buildInputs = [ coq ] ++ optionals mlPlugin coq.ocamlBuildInputs ++ extraBuildInputs; + inherit enableParallelBuilding; + + meta = ({ platforms = coq.meta.platforms; } // + (switch domain [{ + case = pred.union isGitHubDomain isGitLabDomain; + out = { homepage = "https://${domain}/${owner}/${repo}"; }; + }] {}) // + optionalAttrs (fetched.broken or false) { coqFilter = true; broken = true; }) // + (args.meta or {}) ; + +} // +(optionalAttrs setCOQBIN { COQBIN = "${coq}/bin/"; }) // +(optionalAttrs (!args?installPhase && !args?useMelquiondRemake) { + installFlags = + [ "${var-coqlib-install}=$(out)/lib/coq/${coq.coq-version}/" ] ++ + optional (match ".*doc$" (args.installTargets or "") != null) + "DOCDIR=$(out)/share/coq/${coq.coq-version}/" ++ + extraInstallFlags; +}) // +(optionalAttrs (args?useMelquiondRemake) rec { + COQUSERCONTRIB = "$out/lib/coq/${coq.coq-version}/user-contrib"; + preConfigurePhases = "autoconf"; + configureFlags = [ "--libdir=${COQUSERCONTRIB}/${useMelquiondRemake.logpath or ""}" ]; + buildPhase = "./remake -j$NIX_BUILD_CORES"; + installPhase = "./remake install"; +}) // +(removeAttrs args args-to-remove)) dropDerivationAttrs) diff --git a/pkgs/build-support/coq/extra-lib.nix b/pkgs/build-support/coq/extra-lib.nix new file mode 100644 index 000000000000..65b48f511267 --- /dev/null +++ b/pkgs/build-support/coq/extra-lib.nix @@ -0,0 +1,145 @@ +{ lib }: +with builtins; with lib; recursiveUpdate lib (rec { + + versions = + let + truncate = n: v: concatStringsSep "." (take n (splitVersion v)); + opTruncate = op: v0: v: let n = length (splitVersion v0); in + op (truncate n v) (truncate n v0); + in rec { + + /* Get string of the first n parts of a version string. + + Example: + - truncate 2 "1.2.3-stuff" + => "1.2" + + - truncate 4 "1.2.3-stuff" + => "1.2.3.stuff" + */ + + inherit truncate; + + /* Get string of the first three parts (major, minor and patch) + of a version string. + + Example: + majorMinorPatch "1.2.3-stuff" + => "1.2.3" + */ + majorMinorPatch = truncate 3; + + /* Version comparison predicates, + - isGe v0 v <-> v is greater or equal than v0 [*] + - isLe v0 v <-> v is lesser or equal than v0 [*] + - isGt v0 v <-> v is strictly greater than v0 [*] + - isLt v0 v <-> v is strictly lesser than v0 [*] + - isEq v0 v <-> v is equal to v0 [*] + - range low high v <-> v is between low and high [**] + + [*] truncating v to the same number of digits as v0 + [**] truncating v to low for the lower bound and high for the upper bound + + Examples: + - isGe "8.10" "8.10.1" + => true + - isLe "8.10" "8.10.1" + => true + - isGt "8.10" "8.10.1" + => false + - isGt "8.10.0" "8.10.1" + => true + - isEq "8.10" "8.10.1" + => true + - range "8.10" "8.11" "8.11.1" + => true + - range "8.10" "8.11+" "8.11.0" + => false + - range "8.10" "8.11+" "8.11+beta1" + => false + + */ + isGe = opTruncate versionAtLeast; + isGt = opTruncate (flip versionOlder); + isLe = opTruncate (flip versionAtLeast); + isLt = opTruncate versionOlder; + isEq = opTruncate pred.equal; + range = low: high: pred.inter (versions.isGe low) (versions.isLe high); + }; + + /* Returns a list of list, splitting it using a predicate. + This is analoguous to builtins.split sep list, + with a predicate as a separator and a list instead of a string. + + Type: splitList :: (a -> bool) -> [a] -> [[a]] + + Example: + splitList (x: x == "x") [ "y" "x" "z" "t" ] + => [ [ "y" ] "x" [ "z" "t" ] ] + */ + splitList = pred: l: # put in file lists + let loop = (vv: v: l: if l == [] then vv ++ [v] + else let hd = head l; tl = tail l; in + if pred hd then loop (vv ++ [ v hd ]) [] tl else loop vv (v ++ [hd]) tl); + in loop [] [] l; + + pred = { + /* Predicate intersection, union, and complement */ + inter = p: q: x: p x && q x; + union = p: q: x: p x || q x; + compl = p: x: ! p x; + true = p: true; + false = p: false; + + /* predicate "being equal to y" */ + equal = y: x: x == y; + }; + + /* Emulate a "switch - case" construct, + instead of relying on `if then else if ...` */ + /* Usage: + ```nix + switch-if [ + if-clause-1 + .. + if-clause-k + ] default-out + ``` + where a if-clause has the form `{ cond = b; out = r; }` + the first branch such as `b` is true */ + + switch-if = c: d: (findFirst (getAttr "cond") {} c).out or d; + + /* Usage: + ```nix + switch x [ + simple-clause-1 + .. + simple-clause-k + ] default-out + ``` + where a simple-clause has the form `{ case = p; out = r; }` + the first branch such as `p x` is true + or + ```nix + switch [ x1 .. xn ] [ + complex-clause-1 + .. + complex-clause-k + ] default-out + ``` + where a complex-clause is either a simple-clause + or has the form { cases = [ p1 .. pn ]; out = r; } + in which case the first branch such as all `pi x` are true + + if the variables p are not functions, + they are converted to a equal p + if out is missing the default-out is taken */ + + switch = var: clauses: default: with pred; let + compare = f: if isFunction f then f else equal f; + combine = cl: var: + if cl?case then compare cl.case var + else all (equal true) (zipListsWith compare cl.cases var); in + switch-if (map (cl: { cond = combine cl var; inherit (cl) out; }) clauses) default; +}) diff --git a/pkgs/build-support/coq/meta-fetch/default.nix b/pkgs/build-support/coq/meta-fetch/default.nix new file mode 100644 index 000000000000..580d58395ef4 --- /dev/null +++ b/pkgs/build-support/coq/meta-fetch/default.nix @@ -0,0 +1,66 @@ +{ stdenv, fetchzip }@args: +let lib = import ../extra-lib.nix {inherit (args.stdenv) lib;}; in +with builtins; with lib; +let + default-fetcher = {domain ? "github.com", owner ? "", repo, rev, name ? "source", sha256 ? null, ...}@args: + let ext = if args?sha256 then "zip" else "tar.gz"; + fmt = if args?sha256 then "zip" else "tarball"; + pr = match "^#(.*)$" rev; + url = switch-if [ + { cond = isNull pr && !isNull (match "^github.*" domain); + out = "https://${domain}/${owner}/${repo}/archive/${rev}.${ext}"; } + { cond = !isNull pr && !isNull (match "^github.*" domain); + out = "https://api.${domain}/repos/${owner}/${repo}/${fmt}/pull/${head pr}/head"; } + { cond = isNull pr && !isNull (match "^gitlab.*" domain); + out = "https://${domain}/${owner}/${repo}/-/archive/${rev}/${repo}-${rev}.${ext}"; } + { cond = !isNull (match "(www.)?mpi-sws.org" domain); + out = "https://www.mpi-sws.org/~${owner}/${repo}/download/${repo}-${rev}.${ext}";} + ] (throw "meta-fetch: no fetcher found for domain ${domain} on ${rev}"); + fetch = x: if args?sha256 then fetchzip (x // { inherit sha256; }) else fetchTarball x; + in fetch { inherit url ; }; +in +{ + fetcher ? default-fetcher, + location, + release ? {}, + releaseRev ? (v: v), +}: +let isVersion = x: isString x && match "^/.*" x == null && release?${x}; + shortVersion = x: if (isString x && match "^/.*" x == null) + then findFirst (v: versions.majorMinor v == x) null + (sort versionAtLeast (attrNames release)) + else null; + isShortVersion = x: shortVersion x != null; + isPathString = x: isString x && match "^/.*" x != null && pathExists x; in +arg: +switch arg [ + { case = isNull; out = { version = "broken"; src = ""; broken = true; }; } + { case = isPathString; out = { version = "dev"; src = arg; }; } + { case = pred.union isVersion isShortVersion; + out = let v = if isVersion arg then arg else shortVersion arg; in + if !release.${v}?sha256 then throw "meta-fetch: a sha256 must be provided for each release" + else { + version = release.${v}.version or v; + src = release.${v}.src or fetcher (location // { rev = releaseRev v; } // release.${v}); + }; + } + { case = isString; + out = let + splitted = filter isString (split ":" arg); + rev = last splitted; + has-owner = length splitted > 1; + version = "dev"; in { + inherit version; + src = fetcher (location // { inherit rev; } // + (optionalAttrs has-owner { owner = head splitted; })); + }; } + { case = isAttrs; + out = let + { version = arg.version or "dev"; + src = (arg.fetcher or fetcher) (location // (arg.location or {})); + }; } + { case = isPath; + out = { + version = "dev" ; + src = builtins.path {path = arg; name = location.name or "source";}; }; } +] (throw "not a valid source description") diff --git a/pkgs/build-support/docker/default.nix b/pkgs/build-support/docker/default.nix index 4da26ba7cfda..0c9d4f110ada 100644 --- a/pkgs/build-support/docker/default.nix +++ b/pkgs/build-support/docker/default.nix @@ -1,4 +1,5 @@ { + bashInteractive, buildPackages, cacert, callPackage, @@ -24,16 +25,16 @@ storeDir ? builtins.storeDir, substituteAll, symlinkJoin, - utillinux, + util-linux, vmTools, writeReferencesToFile, writeScript, writeText, + writeTextDir, writePython3, system, # Note: This is the cross system we're compiling for }: -# WARNING: this API is unstable and may be subject to backwards-incompatible changes in the future. let mkDbExtraCommand = contents: let @@ -56,21 +57,18 @@ let done; ''; - # Map nixpkgs architecture to Docker notation - # Reference: https://github.com/docker-library/official-images#architectures-other-than-amd64 - getArch = nixSystem: { - aarch64-linux = "arm64v8"; - armv7l-linux = "arm32v7"; - x86_64-linux = "amd64"; - powerpc64le-linux = "ppc64le"; - i686-linux = "i386"; - }.${nixSystem} or "Can't map Nix system ${nixSystem} to Docker architecture notation. Please check that your input and your requested build are correct or update the mapping in Nixpkgs."; + # The OCI Image specification recommends that configurations use values listed + # in the Go Language document for GOARCH. + # Reference: https://github.com/opencontainers/image-spec/blob/master/config.md#properties + # For the mapping from Nixpkgs system parameters to GOARCH, we can reuse the + # mapping from the go package. + defaultArch = go.GOARCH; in rec { examples = callPackage ./examples.nix { - inherit buildImage pullImage shadowSetup buildImageWithNixDb; + inherit buildImage buildLayeredImage fakeNss pullImage shadowSetup buildImageWithNixDb; }; pullImage = let @@ -82,7 +80,7 @@ rec { , imageDigest , sha256 , os ? "linux" - , arch ? getArch system + , arch ? defaultArch # This is used to set name to the pulled image , finalImageName ? imageName @@ -96,7 +94,7 @@ rec { inherit imageDigest; imageName = finalImageName; imageTag = finalImageTag; - impureEnvVars = stdenv.lib.fetchers.proxyImpureEnvVars; + impureEnvVars = lib.fetchers.proxyImpureEnvVars; outputHashMode = "flat"; outputHashAlgo = "sha256"; outputHash = sha256; @@ -111,7 +109,7 @@ rec { ''; # We need to sum layer.tar, not a directory, hence tarsum instead of nix-hash. - # And we cannot untar it, because then we cannot preserve permissions ecc. + # And we cannot untar it, because then we cannot preserve permissions etc. tarsum = runCommand "tarsum" { nativeBuildInputs = [ go ]; } '' @@ -122,7 +120,7 @@ rec { export GOPATH=$(pwd) export GOCACHE="$TMPDIR/go-cache" mkdir -p src/github.com/docker/docker/pkg - ln -sT ${docker.src}/components/engine/pkg/tarsum src/github.com/docker/docker/pkg/tarsum + ln -sT ${docker.moby.src}/pkg/tarsum src/github.com/docker/docker/pkg/tarsum go build mkdir -p $out/bin @@ -204,7 +202,7 @@ rec { }; inherit fromImage fromImageName fromImageTag; - nativeBuildInputs = [ utillinux e2fsprogs jshon rsync jq ]; + nativeBuildInputs = [ util-linux e2fsprogs jshon rsync jq ]; } '' mkdir disk mkfs /dev/${vmTools.hd} @@ -498,7 +496,7 @@ rec { baseJson = let pure = writeText "${baseName}-config.json" (builtins.toJSON { inherit created config; - architecture = getArch system; + architecture = defaultArch; os = "linux"; }); impure = runCommand "${baseName}-config.json" @@ -684,6 +682,33 @@ rec { in result; + # Provide a /etc/passwd and /etc/group that contain root and nobody. + # Useful when packaging binaries that insist on using nss to look up + # username/groups (like nginx). + # /bin/sh is fine to not exist, and provided by another shim. + fakeNss = symlinkJoin { + name = "fake-nss"; + paths = [ + (writeTextDir "etc/passwd" '' + root:x:0:0:root user:/var/empty:/bin/sh + nobody:x:65534:65534:nobody:/var/empty:/bin/sh + '') + (writeTextDir "etc/group" '' + root:x:0: + nobody:x:65534: + '') + (runCommand "var-empty" {} '' + mkdir -p $out/var/empty + '') + ]; + }; + + # This provides /bin/sh, pointing to bashInteractive. + binSh = runCommand "bin-sh" {} '' + mkdir -p $out/bin + ln -s ${bashInteractive}/bin/bash $out/bin/sh + ''; + # Build an image and populate its nix database with the provided # contents. The main purpose is to be able to use nix commands in # the container. @@ -725,7 +750,7 @@ rec { streamScript = writePython3 "stream" {} ./stream_layered_image.py; baseJson = writeText "${name}-base.json" (builtins.toJSON { inherit config; - architecture = getArch system; + architecture = defaultArch; os = "linux"; }); diff --git a/pkgs/build-support/docker/examples.nix b/pkgs/build-support/docker/examples.nix index 3f30f1a2adb4..86375a40baa0 100644 --- a/pkgs/build-support/docker/examples.nix +++ b/pkgs/build-support/docker/examples.nix @@ -7,7 +7,7 @@ # $ nix-build '<nixpkgs>' -A dockerTools.examples.redis # $ docker load < result -{ pkgs, buildImage, pullImage, shadowSetup, buildImageWithNixDb, pkgsCross }: +{ pkgs, buildImage, buildLayeredImage, fakeNss, pullImage, shadowSetup, buildImageWithNixDb, pkgsCross }: rec { # 1. basic example @@ -44,7 +44,7 @@ rec { nginx = let nginxPort = "80"; nginxConf = pkgs.writeText "nginx.conf" '' - user nginx nginx; + user nobody nobody; daemon off; error_log /dev/stdout info; pid /dev/null; @@ -64,10 +64,13 @@ rec { <html><body><h1>Hello from NGINX</h1></body></html> ''; in - buildImage { + buildLayeredImage { name = "nginx-container"; tag = "latest"; - contents = pkgs.nginx; + contents = [ + fakeNss + pkgs.nginx + ]; extraCommands = '' # nginx still tries to read this directory even if error_log @@ -75,12 +78,6 @@ rec { mkdir -p var/log/nginx mkdir -p var/cache/nginx ''; - runAsRoot = '' - #!${pkgs.stdenv.shell} - ${shadowSetup} - groupadd --system nginx - useradd --system --gid nginx nginx - ''; config = { Cmd = [ "nginx" "-c" nginxConf ]; @@ -419,4 +416,15 @@ rec { contents = crossPkgs.hello; }; + # layered image where a store path is itself a symlink + layeredStoreSymlink = + let + target = pkgs.writeTextDir "dir/target" "Content doesn't matter."; + symlink = pkgs.runCommandNoCC "symlink" {} "ln -s ${target} $out"; + in + pkgs.dockerTools.buildLayeredImage { + name = "layeredstoresymlink"; + tag = "latest"; + contents = [ pkgs.bash symlink ]; + } // { passthru = { inherit symlink; }; }; } diff --git a/pkgs/build-support/docker/nix-prefetch-docker b/pkgs/build-support/docker/nix-prefetch-docker index 1b6785189c28..5798ab5984f1 100755 --- a/pkgs/build-support/docker/nix-prefetch-docker +++ b/pkgs/build-support/docker/nix-prefetch-docker @@ -127,7 +127,7 @@ trap "rm -rf \"$tmpPath\"" EXIT tmpFile="$tmpPath/$(get_name $finalImageName $finalImageTag)" if test -z "$QUIET"; then - skopeo --insecure-policy --tmpdir=$TMPDIR --override-os ${os} --override-arch ${arch} copy "$sourceUrl" "docker-archive://$tmpFile:$finalImageName:$finalImageTag" + skopeo --insecure-policy --tmpdir=$TMPDIR --override-os ${os} --override-arch ${arch} copy "$sourceUrl" "docker-archive://$tmpFile:$finalImageName:$finalImageTag" >&2 else skopeo --insecure-policy --tmpdir=$TMPDIR --override-os ${os} --override-arch ${arch} copy "$sourceUrl" "docker-archive://$tmpFile:$finalImageName:$finalImageTag" > /dev/null fi @@ -139,12 +139,12 @@ imageHash=$(nix-hash --flat --type $hashType --base32 "$tmpFile") finalPath=$(nix-store --add-fixed "$hashType" "$tmpFile") if test -z "$QUIET"; then - echo "-> ImageName: $imageName" - echo "-> ImageDigest: $imageDigest" - echo "-> FinalImageName: $finalImageName" - echo "-> FinalImageTag: $finalImageTag" - echo "-> ImagePath: $finalPath" - echo "-> ImageHash: $imageHash" + echo "-> ImageName: $imageName" >&2 + echo "-> ImageDigest: $imageDigest" >&2 + echo "-> FinalImageName: $finalImageName" >&2 + echo "-> FinalImageTag: $finalImageTag" >&2 + echo "-> ImagePath: $finalPath" >&2 + echo "-> ImageHash: $imageHash" >&2 fi if [ "$format" == "nix" ]; then diff --git a/pkgs/build-support/docker/nix-prefetch-docker.nix b/pkgs/build-support/docker/nix-prefetch-docker.nix index 6341eb0154b0..61e917461ed9 100644 --- a/pkgs/build-support/docker/nix-prefetch-docker.nix +++ b/pkgs/build-support/docker/nix-prefetch-docker.nix @@ -1,6 +1,4 @@ -{ stdenv, makeWrapper, nix, skopeo, jq }: - -with stdenv.lib; +{ lib, stdenv, makeWrapper, nix, skopeo, jq }: stdenv.mkDerivation { name = "nix-prefetch-docker"; @@ -12,13 +10,13 @@ stdenv.mkDerivation { installPhase = '' install -vD ${./nix-prefetch-docker} $out/bin/$name; wrapProgram $out/bin/$name \ - --prefix PATH : ${makeBinPath [ nix skopeo jq ]} \ + --prefix PATH : ${lib.makeBinPath [ nix skopeo jq ]} \ --set HOME /homeless-shelter ''; preferLocalBuild = true; - meta = { + meta = with lib; { description = "Script used to obtain source hashes for dockerTools.pullImage"; maintainers = with maintainers; [ offline ]; platforms = platforms.unix; diff --git a/pkgs/build-support/docker/stream_layered_image.py b/pkgs/build-support/docker/stream_layered_image.py index cbae0f723f92..e35bd0b0e8c0 100644 --- a/pkgs/build-support/docker/stream_layered_image.py +++ b/pkgs/build-support/docker/stream_layered_image.py @@ -83,7 +83,11 @@ def archive_paths_to(obj, paths, mtime): for path in paths: path = pathlib.Path(path) - files = itertools.chain([path], path.rglob("*")) + if path.is_symlink(): + files = [path] + else: + files = itertools.chain([path], path.rglob("*")) + for filename in sorted(files): ti = append_root(tar.gettarinfo(filename)) diff --git a/pkgs/build-support/dotnetbuildhelpers/default.nix b/pkgs/build-support/dotnetbuildhelpers/default.nix index 809619ed55d9..4348832ac04c 100644 --- a/pkgs/build-support/dotnetbuildhelpers/default.nix +++ b/pkgs/build-support/dotnetbuildhelpers/default.nix @@ -1,4 +1,4 @@ -{ runCommand, mono, pkgconfig }: +{ runCommand, mono, pkg-config }: runCommand "dotnetbuildhelpers" { preferLocalBuild = true; } @@ -12,7 +12,7 @@ cp -v "$script" "$target"/"$scriptName" chmod 755 "$target"/"$scriptName" patchShebangs "$target"/"$scriptName" - substituteInPlace "$target"/"$scriptName" --replace pkg-config ${pkgconfig}/bin/${pkgconfig.targetPrefix}pkg-config + substituteInPlace "$target"/"$scriptName" --replace pkg-config ${pkg-config}/bin/${pkg-config.targetPrefix}pkg-config substituteInPlace "$target"/"$scriptName" --replace monodis ${mono}/bin/monodis done '' diff --git a/pkgs/build-support/dotnetenv/build-solution.nix b/pkgs/build-support/dotnetenv/build-solution.nix index 57af1fe9bd49..b3372b942177 100644 --- a/pkgs/build-support/dotnetenv/build-solution.nix +++ b/pkgs/build-support/dotnetenv/build-solution.nix @@ -1,4 +1,4 @@ -{stdenv, dotnetfx}: +{ lib, stdenv, dotnetfx }: { name , src , baseDir ? "." @@ -24,7 +24,7 @@ stdenv.mkDerivation { ''; preBuild = '' - ${stdenv.lib.optionalString modifyPublicMain '' + ${lib.optionalString modifyPublicMain '' sed -i -e "s|static void Main|public static void Main|" ${mainClassFile} ''} ${preBuild} diff --git a/pkgs/build-support/dotnetenv/default.nix b/pkgs/build-support/dotnetenv/default.nix index c7145504eb7b..3015db42b07b 100644 --- a/pkgs/build-support/dotnetenv/default.nix +++ b/pkgs/build-support/dotnetenv/default.nix @@ -1,9 +1,9 @@ -{stdenv, dotnetfx}: +{ lib, stdenv, dotnetfx }: let dotnetenv = { buildSolution = import ./build-solution.nix { - inherit stdenv; + inherit lib stdenv; dotnetfx = dotnetfx.pkg; }; diff --git a/pkgs/build-support/emacs/elpa.nix b/pkgs/build-support/emacs/elpa.nix index e6f6c23e449f..214aed9c3f9c 100644 --- a/pkgs/build-support/emacs/elpa.nix +++ b/pkgs/build-support/emacs/elpa.nix @@ -7,9 +7,18 @@ with lib; { pname , version , src +, meta ? {} , ... }@args: +let + + defaultMeta = { + homepage = args.src.meta.homepage or "https://elpa.gnu.org/packages/${pname}.html"; + }; + +in + import ./generic.nix { inherit lib stdenv emacs texinfo; } ({ phases = "installPhase fixupPhase distPhase"; @@ -23,6 +32,8 @@ import ./generic.nix { inherit lib stdenv emacs texinfo; } ({ runHook postInstall ''; + + meta = defaultMeta // meta; } // removeAttrs args [ "files" "fileSpecs" diff --git a/pkgs/build-support/emacs/generic.nix b/pkgs/build-support/emacs/generic.nix index 956787ad59e4..588699517baf 100644 --- a/pkgs/build-support/emacs/generic.nix +++ b/pkgs/build-support/emacs/generic.nix @@ -60,10 +60,13 @@ stdenv.mkDerivation ({ LIBRARY_PATH = "${lib.getLib stdenv.cc.libc}/lib"; + addEmacsNativeLoadPath = true; + postInstall = '' - find $out/share/emacs -type f -name '*.el' -print0 | xargs -0 -n 1 -I {} -P $NIX_BUILD_CORES sh -c "emacs --batch -f batch-native-compile {} || true" + find $out/share/emacs -type f -name '*.el' -print0 \ + | xargs -0 -n 1 -I {} -P $NIX_BUILD_CORES sh -c \ + "emacs --batch --eval=\"(add-to-list 'comp-eln-load-path \\\"$out/share/emacs/native-lisp/\\\")\" -f batch-native-compile {} || true" ''; - } // removeAttrs args [ "buildInputs" "packageRequires" diff --git a/pkgs/build-support/emacs/melpa.nix b/pkgs/build-support/emacs/melpa.nix index e2ec84c75e66..d6fe3085837e 100644 --- a/pkgs/build-support/emacs/melpa.nix +++ b/pkgs/build-support/emacs/melpa.nix @@ -23,7 +23,7 @@ with lib; let defaultMeta = { - homepage = args.src.meta.homepage or "http://melpa.org/#/${pname}"; + homepage = args.src.meta.homepage or "https://melpa.org/#/${pname}"; }; in diff --git a/pkgs/build-support/emacs/setup-hook.sh b/pkgs/build-support/emacs/setup-hook.sh index 83e995631b3e..f6f2331b8e02 100644 --- a/pkgs/build-support/emacs/setup-hook.sh +++ b/pkgs/build-support/emacs/setup-hook.sh @@ -7,9 +7,20 @@ addToEmacsLoadPath() { fi } +addToEmacsNativeLoadPath() { + local nativeDir="$1" + if [[ -d $nativeDir && ${EMACSNATIVELOADPATH-} != *"$nativeDir":* ]]; then + export EMACSNATIVELOADPATH="$nativeDir:${EMACSNATIVELOADPATH-}" + fi +} + addEmacsVars () { addToEmacsLoadPath "$1/share/emacs/site-lisp" + if [ -n "${addEmacsNativeLoadPath:-}" ]; then + addToEmacsNativeLoadPath "$1/share/emacs/native-lisp" + fi + # Add sub paths to the Emacs load path if it is a directory # containing .el files. This is necessary to build some packages, # e.g., using trivialBuild. diff --git a/pkgs/build-support/emacs/trivial.nix b/pkgs/build-support/emacs/trivial.nix index 396c971b2f01..9a36b44a270d 100644 --- a/pkgs/build-support/emacs/trivial.nix +++ b/pkgs/build-support/emacs/trivial.nix @@ -1,6 +1,6 @@ # trivial builder for Emacs packages -{ lib, stdenv, texinfo, ... }@envargs: +{ lib, texinfo, ... }@envargs: with lib; diff --git a/pkgs/build-support/emacs/wrapper.nix b/pkgs/build-support/emacs/wrapper.nix index 1f2fbd8068e7..f34835eaf096 100644 --- a/pkgs/build-support/emacs/wrapper.nix +++ b/pkgs/build-support/emacs/wrapper.nix @@ -2,11 +2,11 @@ # Usage -`emacsWithPackages` takes a single argument: a function from a package +`emacs.pkgs.withPackages` takes a single argument: a function from a package set to a list of packages (the packages that will be available in Emacs). For example, ``` -emacsWithPackages (epkgs: [ epkgs.evil epkgs.magit ]) +emacs.pkgs.withPackages (epkgs: [ epkgs.evil epkgs.magit ]) ``` All the packages in the list should come from the provided package set. It is possible to add any package to the list, but the provided @@ -15,26 +15,34 @@ the correct version of Emacs. # Overriding -`emacsWithPackages` inherits the package set which contains it, so the +`emacs.pkgs.withPackages` inherits the package set which contains it, so the correct way to override the provided package set is to override the -set which contains `emacsWithPackages`. For example, to override -`emacsPackages.emacsWithPackages`, +set which contains `emacs.pkgs.withPackages`. For example, to override +`emacs.pkgs.emacs.pkgs.withPackages`, ``` let customEmacsPackages = - emacsPackages.overrideScope' (self: super: { + emacs.pkgs.overrideScope' (self: super: { # use a custom version of emacs emacs = ...; # use the unstable MELPA version of magit magit = self.melpaPackages.magit; }); -in customEmacsPackages.emacsWithPackages (epkgs: [ epkgs.evil epkgs.magit ]) +in customEmacsPackages.emacs.pkgs.withPackages (epkgs: [ epkgs.evil epkgs.magit ]) ``` */ { lib, lndir, makeWrapper, runCommand }: self: -with lib; let inherit (self) emacs; in +with lib; + +let + + inherit (self) emacs; + + nativeComp = emacs.nativeComp or false; + +in packagesFun: # packages explicitly requested by the user @@ -95,6 +103,9 @@ runCommand } mkdir -p $out/bin mkdir -p $out/share/emacs/site-lisp + ${optionalString nativeComp '' + mkdir -p $out/share/emacs/native-lisp + ''} local requires for pkg in $explicitRequires; do @@ -116,6 +127,9 @@ runCommand linkEmacsPackage() { linkPath "$1" "bin" "bin" linkPath "$1" "share/emacs/site-lisp" "share/emacs/site-lisp" + ${optionalString nativeComp '' + linkPath "$1" "share/emacs/native-lisp" "share/emacs/native-lisp" + ''} } # Iterate over the array of inputs (avoiding nix's own interpolation) @@ -138,12 +152,21 @@ runCommand (load-file "$emacs/share/emacs/site-lisp/site-start.el") (add-to-list 'load-path "$out/share/emacs/site-lisp") (add-to-list 'exec-path "$out/bin") + ${optionalString nativeComp '' + (add-to-list 'comp-eln-load-path "$out/share/emacs/native-lisp/") + ''} EOF # Link subdirs.el from the emacs distribution ln -s $emacs/share/emacs/site-lisp/subdirs.el -T $subdirs # Byte-compiling improves start-up time only slightly, but costs nothing. $emacs/bin/emacs --batch -f batch-byte-compile "$siteStart" "$subdirs" + + ${optionalString nativeComp '' + $emacs/bin/emacs --batch \ + --eval "(add-to-list 'comp-eln-load-path \"$out/share/emacs/native-lisp/\")" \ + -f batch-native-compile "$siteStart" "$subdirs" + ''} ''; inherit (emacs) meta; @@ -155,8 +178,13 @@ runCommand for prog in $emacs/bin/*; do # */ local progname=$(basename "$prog") rm -f "$out/bin/$progname" - makeWrapper "$prog" "$out/bin/$progname" \ - --suffix EMACSLOADPATH ":" "$deps/share/emacs/site-lisp:" + + substitute ${./wrapper.sh} $out/bin/$progname \ + --subst-var-by bash ${emacs.stdenv.shell} \ + --subst-var-by wrapperSiteLisp "$deps/share/emacs/site-lisp" \ + --subst-var-by wrapperSiteLispNative "$deps/share/emacs/native-lisp:" \ + --subst-var prog + chmod +x $out/bin/$progname done # Wrap MacOS app @@ -168,8 +196,13 @@ runCommand $emacs/Applications/Emacs.app/Contents/PkgInfo \ $emacs/Applications/Emacs.app/Contents/Resources \ $out/Applications/Emacs.app/Contents - makeWrapper $emacs/Applications/Emacs.app/Contents/MacOS/Emacs $out/Applications/Emacs.app/Contents/MacOS/Emacs \ - --suffix EMACSLOADPATH ":" "$deps/share/emacs/site-lisp:" + + + substitute ${./wrapper.sh} $out/Applications/Emacs.app/Contents/MacOS/Emacs \ + --subst-var-by bash ${emacs.stdenv.shell} \ + --subst-var-by wrapperSiteLisp "$deps/share/emacs/site-lisp" \ + --subst-var-by prog "$emacs/Applications/Emacs.app/Contents/MacOS/Emacs" + chmod +x $out/Applications/Emacs.app/Contents/MacOS/Emacs fi mkdir -p $out/share diff --git a/pkgs/build-support/emacs/wrapper.sh b/pkgs/build-support/emacs/wrapper.sh new file mode 100644 index 000000000000..e8eecb8c8696 --- /dev/null +++ b/pkgs/build-support/emacs/wrapper.sh @@ -0,0 +1,47 @@ +#!@bash@ + +IFS=: + +newLoadPath=() +newNativeLoadPath=() +added= + +if [[ -n $EMACSLOADPATH ]] +then + while read -rd: entry + do + if [[ -z $entry && -z $added ]] + then + newLoadPath+=(@wrapperSiteLisp@) + added=1 + fi + newLoadPath+=("$entry") + done <<< "$EMACSLOADPATH:" +else + newLoadPath+=(@wrapperSiteLisp@) + newLoadPath+=("") +fi + +if [[ -n $EMACSNATIVELOADPATH ]] +then + while read -rd: entry + do + if [[ -z $entry && -z $added ]] + then + newNativeLoadPath+=(@wrapperSiteLispNative@) + added=1 + fi + newNativeLoadPath+=("$entry") + done <<< "$EMACSNATIVELOADPATH:" +else + newNativeLoadPath+=(@wrapperSiteLispNative@) + newNativeLoadPath+=("") +fi + +export EMACSLOADPATH="${newLoadPath[*]}" +export emacsWithPackages_siteLisp=@wrapperSiteLisp@ + +export EMACSNATIVELOADPATH="${newNativeLoadPath[*]}" +export emacsWithPackages_siteLispNative=@wrapperSiteLispNative@ + +exec @prog@ "$@" diff --git a/pkgs/build-support/fetchbzr/default.nix b/pkgs/build-support/fetchbzr/default.nix index 2cf169de7a52..b7db9e9274da 100644 --- a/pkgs/build-support/fetchbzr/default.nix +++ b/pkgs/build-support/fetchbzr/default.nix @@ -10,6 +10,6 @@ stdenvNoCC.mkDerivation { outputHashAlgo = "sha256"; outputHashMode = "recursive"; outputHash = sha256; - + inherit url rev; } diff --git a/pkgs/build-support/fetchdocker/fetchDockerConfig.nix b/pkgs/build-support/fetchdocker/fetchDockerConfig.nix index 9fd813bfa575..e8b2403d8f33 100644 --- a/pkgs/build-support/fetchdocker/fetchDockerConfig.nix +++ b/pkgs/build-support/fetchdocker/fetchDockerConfig.nix @@ -1,4 +1,4 @@ -pkgargs@{ stdenv, lib, haskellPackages, writeText, gawk }: +pkgargs@{ lib, haskellPackages, writeText, gawk }: let generic-fetcher = import ./generic-fetcher.nix pkgargs; diff --git a/pkgs/build-support/fetchdocker/fetchDockerLayer.nix b/pkgs/build-support/fetchdocker/fetchDockerLayer.nix index 869ba637429c..0fbbc078efc3 100644 --- a/pkgs/build-support/fetchdocker/fetchDockerLayer.nix +++ b/pkgs/build-support/fetchdocker/fetchDockerLayer.nix @@ -1,4 +1,4 @@ -pkgargs@{ stdenv, lib, haskellPackages, writeText, gawk }: +pkgargs@{ lib, haskellPackages, writeText, gawk }: let generic-fetcher = import ./generic-fetcher.nix pkgargs; diff --git a/pkgs/build-support/fetchfirefoxaddon/default.nix b/pkgs/build-support/fetchfirefoxaddon/default.nix new file mode 100644 index 000000000000..9efe9197d687 --- /dev/null +++ b/pkgs/build-support/fetchfirefoxaddon/default.nix @@ -0,0 +1,41 @@ +{stdenv, lib, coreutils, unzip, jq, zip, fetchurl,writeScript, ...}: + +{ + name +, url +, md5 ? "" +, sha1 ? "" +, sha256 ? "" +, sha512 ? "" +, fixedExtid ? null +, hash ? "" +}: + +stdenv.mkDerivation rec { + + inherit name; + extid = if fixedExtid == null then "nixos@${name}" else fixedExtid; + passthru = { + exitd=extid; + }; + + builder = writeScript "xpibuilder" '' + source $stdenv/setup + + header "firefox addon $name into $out" + + UUID="${extid}" + mkdir -p "$out/$UUID" + unzip -q ${src} -d "$out/$UUID" + NEW_MANIFEST=$(jq '. + {"applications": { "gecko": { "id": "${extid}" }}, "browser_specific_settings":{"gecko":{"id": "${extid}"}}}' "$out/$UUID/manifest.json") + echo "$NEW_MANIFEST" > "$out/$UUID/manifest.json" + cd "$out/$UUID" + zip -r -q -FS "$out/$UUID.xpi" * + rm -r "$out/$UUID" + ''; + src = fetchurl { + url = url; + inherit md5 sha1 sha256 sha512 hash; + }; + nativeBuildInputs = [ coreutils unzip zip jq ]; +} diff --git a/pkgs/build-support/fetchfossil/default.nix b/pkgs/build-support/fetchfossil/default.nix index 27933b47178a..3a4876bc5de3 100644 --- a/pkgs/build-support/fetchfossil/default.nix +++ b/pkgs/build-support/fetchfossil/default.nix @@ -1,11 +1,11 @@ -{stdenv, fossil}: +{stdenv, fossil, cacert}: {name ? null, url, rev, sha256}: stdenv.mkDerivation { name = "fossil-archive" + (if name != null then "-${name}" else ""); builder = ./builder.sh; - nativeBuildInputs = [fossil]; + nativeBuildInputs = [fossil cacert]; # Envvar docs are hard to find. A link for the future: # https://www.fossil-scm.org/index.html/doc/trunk/www/env-opts.md diff --git a/pkgs/build-support/fetchgit/builder.sh b/pkgs/build-support/fetchgit/builder.sh index 6ae46469738a..0047a335c76c 100644 --- a/pkgs/build-support/fetchgit/builder.sh +++ b/pkgs/build-support/fetchgit/builder.sh @@ -8,6 +8,7 @@ header "exporting $url (rev $rev) into $out" $SHELL $fetcher --builder --url "$url" --out "$out" --rev "$rev" \ ${leaveDotGit:+--leave-dotGit} \ + ${fetchLFS:+--fetch-lfs} \ ${deepClone:+--deepClone} \ ${fetchSubmodules:+--fetch-submodules} \ ${branchName:+--branch-name "$branchName"} diff --git a/pkgs/build-support/fetchgit/default.nix b/pkgs/build-support/fetchgit/default.nix index 0405951a9e40..5f5ded128de5 100644 --- a/pkgs/build-support/fetchgit/default.nix +++ b/pkgs/build-support/fetchgit/default.nix @@ -1,4 +1,4 @@ -{stdenvNoCC, git, cacert}: let +{stdenvNoCC, git, git-lfs, cacert}: let urlToName = url: rev: let inherit (stdenvNoCC.lib) removeSuffix splitString last; base = last (splitString ":" (baseNameOf (removeSuffix "/" url))); @@ -20,6 +20,7 @@ in # successfully. This can do things like check or transform the file. postFetch ? "" , preferLocalBuild ? true +, fetchLFS ? false }: /* NOTE: @@ -53,13 +54,15 @@ stdenvNoCC.mkDerivation { inherit name; builder = ./builder.sh; fetcher = ./nix-prefetch-git; # This must be a string to ensure it's called with bash. - nativeBuildInputs = [git]; + + nativeBuildInputs = [ git ] + ++ stdenvNoCC.lib.optionals fetchLFS [ git-lfs ]; outputHashAlgo = "sha256"; outputHashMode = "recursive"; outputHash = sha256; - inherit url rev leaveDotGit fetchSubmodules deepClone branchName postFetch; + inherit url rev leaveDotGit fetchLFS fetchSubmodules deepClone branchName postFetch; GIT_SSL_CAINFO = "${cacert}/etc/ssl/certs/ca-bundle.crt"; diff --git a/pkgs/build-support/fetchgit/nix-prefetch-git b/pkgs/build-support/fetchgit/nix-prefetch-git index 43f7c5acd5ad..3cb115c5e6e6 100755 --- a/pkgs/build-support/fetchgit/nix-prefetch-git +++ b/pkgs/build-support/fetchgit/nix-prefetch-git @@ -9,6 +9,7 @@ hashType=$NIX_HASH_ALGO deepClone=$NIX_PREFETCH_GIT_DEEP_CLONE leaveDotGit=$NIX_PREFETCH_GIT_LEAVE_DOT_GIT fetchSubmodules= +fetchLFS= builder= branchName=$NIX_PREFETCH_GIT_BRANCH_NAME @@ -72,6 +73,7 @@ for arg; do --quiet) QUIET=true;; --no-deepClone) deepClone=;; --leave-dotGit) leaveDotGit=true;; + --fetch-lfs) fetchLFS=true;; --fetch-submodules) fetchSubmodules=true;; --builder) builder=true;; -h|--help) usage; exit;; @@ -283,6 +285,11 @@ clone_user_rev() { local url="$2" local rev="${3:-HEAD}" + if [ -n "$fetchLFS" ]; then + HOME=$TMPDIR + git lfs install + fi + # Perform the checkout. case "$rev" in HEAD|refs/*) diff --git a/pkgs/build-support/fetchmavenartifact/default.nix b/pkgs/build-support/fetchmavenartifact/default.nix index 583a9ea396cf..4274b4b52bfa 100644 --- a/pkgs/build-support/fetchmavenartifact/default.nix +++ b/pkgs/build-support/fetchmavenartifact/default.nix @@ -1,12 +1,12 @@ # Adaptation of the MIT-licensed work on `sbt2nix` done by Charles O'Farrell -{ fetchurl, stdenv }: +{ lib, fetchurl, stdenv }: let defaultRepos = [ - "http://repo1.maven.org/maven2" - "http://oss.sonatype.org/content/repositories/releases" - "http://oss.sonatype.org/content/repositories/public" - "http://repo.typesafe.com/typesafe/releases" + "https://repo1.maven.org/maven2" + "https://oss.sonatype.org/content/repositories/releases" + "https://oss.sonatype.org/content/repositories/public" + "https://repo.typesafe.com/typesafe/releases" ]; in @@ -17,6 +17,8 @@ args@ artifactId , # Example: "4.3.6" version +, # Example: "jdk11" + classifier ? null , # List of maven repositories from where to fetch the artifact. # Example: [ http://oss.sonatype.org/content/repositories/public ]. repos ? defaultRepos @@ -34,21 +36,20 @@ assert (url == "") || (urls == []); # if repos is empty, then url or urls must be specified. assert (repos != []) || (url != "") || (urls != []); - let name_ = - with stdenv.lib; concatStrings [ - (replaceChars ["."] ["_"] groupId) "_" - (replaceChars ["."] ["_"] artifactId) "-" + lib.concatStrings [ + (lib.replaceChars ["."] ["_"] groupId) "_" + (lib.replaceChars ["."] ["_"] artifactId) "-" version ]; mkJarUrl = repoUrl: - with stdenv.lib; concatStringsSep "/" [ - (removeSuffix "/" repoUrl) - (replaceChars ["."] ["/"] groupId) + lib.concatStringsSep "/" [ + (lib.removeSuffix "/" repoUrl) + (lib.replaceChars ["."] ["/"] groupId) artifactId version - "${artifactId}-${version}.jar" + "${artifactId}-${version}${lib.optionalString (!isNull classifier) "-${classifier}"}.jar" ]; urls_ = if url != "" then [url] @@ -56,7 +57,7 @@ let else map mkJarUrl repos; jar = fetchurl ( - builtins.removeAttrs args ["groupId" "artifactId" "version" "repos" "url" ] + builtins.removeAttrs args ["groupId" "artifactId" "version" "classifier" "repos" "url" ] // { urls = urls_; name = "${name_}.jar"; } ); in diff --git a/pkgs/build-support/fetchmtn/default.nix b/pkgs/build-support/fetchmtn/default.nix index 7ce67453d698..b5da0f80a31f 100644 --- a/pkgs/build-support/fetchmtn/default.nix +++ b/pkgs/build-support/fetchmtn/default.nix @@ -4,7 +4,7 @@ # each is an url for sync # selector is mtn selector, like h:org.example.branch -# +# {name ? "mtn-checkout", dbs ? [], sha256 , selector ? "h:" + branch, branch}: diff --git a/pkgs/build-support/fetchurl/mirrors.nix b/pkgs/build-support/fetchurl/mirrors.nix index 0eba8816b638..b61cd9a0d902 100644 --- a/pkgs/build-support/fetchurl/mirrors.nix +++ b/pkgs/build-support/fetchurl/mirrors.nix @@ -9,10 +9,10 @@ # "sourceforge", "gnu", etc. luarocks = [ - "https://luarocks.org" + "https://luarocks.org/" "https://raw.githubusercontent.com/rocks-moonscript-org/moonrocks-mirror/master/" - "http://luafr.org/moonrocks" - "http://luarocks.logiceditor.com/rocks" + "http://luafr.org/moonrocks/" + "http://luarocks.logiceditor.com/rocks/" ]; # SourceForge. diff --git a/pkgs/build-support/fetchzip/default.nix b/pkgs/build-support/fetchzip/default.nix index c61df8ceb001..a1744b48deb9 100644 --- a/pkgs/build-support/fetchzip/default.nix +++ b/pkgs/build-support/fetchzip/default.nix @@ -44,8 +44,20 @@ mv "$unpackDir/$fn" "$out" '' else '' mv "$unpackDir" "$out" - '') #*/ - + extraPostFetch; + '') + + extraPostFetch + # Remove write permissions for files unpacked with write bits set + # Fixes https://github.com/NixOS/nixpkgs/issues/38649 + # + # However, we should (for the moment) retain write permission on the directory + # itself, to avoid tickling https://github.com/NixOS/nix/issues/4295 in + # single-user Nix installations. This is because in sandbox mode we'll try to + # move the path, and if we don't have write permissions on the directory, + # then we can't update the ".." entry. + + '' + chmod -R a-w "$out" + chmod u+w "$out" + ''; } // removeAttrs args [ "stripRoot" "extraPostFetch" ])).overrideAttrs (x: { # Hackety-hack: we actually need unzip hooks, too nativeBuildInputs = x.nativeBuildInputs ++ [ unzip ]; diff --git a/pkgs/build-support/icon-conv-tools/default.nix b/pkgs/build-support/icon-conv-tools/default.nix index 0ea18d8768ac..79d3838e6884 100644 --- a/pkgs/build-support/icon-conv-tools/default.nix +++ b/pkgs/build-support/icon-conv-tools/default.nix @@ -1,4 +1,4 @@ -{ stdenv, icoutils }: +{ lib, stdenv, icoutils }: stdenv.mkDerivation { name = "icon-conv-tools-0.0.0"; @@ -23,9 +23,9 @@ stdenv.mkDerivation { dontPatchELF = true; dontStrip = true; - meta = { + meta = with lib; { description = "Tools for icon conversion specific to nix package manager"; - maintainers = with stdenv.lib.maintainers; [ jraygauthier ]; - platforms = with stdenv.lib.platforms; linux; + maintainers = with maintainers; [ jraygauthier ]; + platforms = platforms.linux; }; } diff --git a/pkgs/build-support/kernel/initrd-compressor-meta.nix b/pkgs/build-support/kernel/initrd-compressor-meta.nix new file mode 100644 index 000000000000..443e599a239e --- /dev/null +++ b/pkgs/build-support/kernel/initrd-compressor-meta.nix @@ -0,0 +1,53 @@ +rec { + cat = { + executable = pkgs: "cat"; + ubootName = "none"; + extension = ".cpio"; + }; + gzip = { + executable = pkgs: "${pkgs.gzip}/bin/gzip"; + defaultArgs = ["-9n"]; + ubootName = "gzip"; + extension = ".gz"; + }; + bzip2 = { + executable = pkgs: "${pkgs.bzip2}/bin/bzip2"; + ubootName = "bzip2"; + extension = ".bz2"; + }; + xz = { + executable = pkgs: "${pkgs.xz}/bin/xz"; + defaultArgs = ["--check=crc32" "--lzma2=dict=512KiB"]; + extension = ".xz"; + }; + lzma = { + executable = pkgs: "${pkgs.xz}/bin/lzma"; + defaultArgs = ["--check=crc32" "--lzma1=dict=512KiB"]; + ubootName = "lzma"; + extension = ".lzma"; + }; + lz4 = { + executable = pkgs: "${pkgs.lz4}/bin/lz4"; + defaultArgs = ["-l"]; + ubootName = "lz4"; + extension = ".lz4"; + }; + lzop = { + executable = pkgs: "${pkgs.lzop}/bin/lzop"; + ubootName = "lzo"; + extension = ".lzo"; + }; + zstd = { + executable = pkgs: "${pkgs.zstd}/bin/zstd"; + defaultArgs = ["-10"]; + ubootName = "zstd"; + extension = ".zst"; + }; + pigz = gzip // { + executable = pkgs: "${pkgs.pigz}/bin/pigz"; + }; + pixz = xz // { + executable = pkgs: "${pkgs.pixz}/bin/pixz"; + defaultArgs = []; + }; +} diff --git a/pkgs/build-support/kernel/make-initrd.nix b/pkgs/build-support/kernel/make-initrd.nix index ed5dbdaee171..9af40d33242d 100644 --- a/pkgs/build-support/kernel/make-initrd.nix +++ b/pkgs/build-support/kernel/make-initrd.nix @@ -1,22 +1,74 @@ -# Create an initial ramdisk containing the closure of the specified -# file system objects. An initial ramdisk is used during the initial +# Create an initramfs containing the closure of the specified +# file system objects. An initramfs is used during the initial # stages of booting a Linux system. It is loaded by the boot loader # along with the kernel image. It's supposed to contain everything # (such as kernel modules) necessary to allow us to mount the root # file system. Once the root file system is mounted, the `real' boot # script can be called. # -# An initrd is really just a gzipped cpio archive. -# -# Symlinks are created for each top-level file system object. E.g., -# `contents = {object = ...; symlink = /init;}' is a typical -# argument. - -{ stdenvNoCC, perl, cpio, contents, ubootTools +# An initramfs is a cpio archive, and may be compressed with a number +# of algorithms. +let + # Some metadata on various compression programs, relevant to naming + # the initramfs file and, if applicable, generating a u-boot image + # from it. + compressors = import ./initrd-compressor-meta.nix; + # Get the basename of the actual compression program from the whole + # compression command, for the purpose of guessing the u-boot + # compression type and filename extension. + compressorName = fullCommand: builtins.elemAt (builtins.match "([^ ]*/)?([^ ]+).*" fullCommand) 1; +in +{ stdenvNoCC, perl, cpio, ubootTools, lib, pkgsBuildHost +# Name of the derivation (not of the resulting file!) , name ? "initrd" -, compressor ? "gzip -9n" + +# Program used to compress the cpio archive; use "cat" for no compression. +# This can also be a function which takes a package set and returns the path to the compressor, +# such as `pkgs: "${pkgs.lzop}/bin/lzop"`. +, compressor ? "gzip" +, _compressorFunction ? + if lib.isFunction compressor then compressor + else if ! builtins.hasContext compressor && builtins.hasAttr compressor compressors then compressors.${compressor}.executable + else _: compressor +, _compressorExecutable ? _compressorFunction pkgsBuildHost +, _compressorName ? compressorName _compressorExecutable +, _compressorMeta ? compressors.${_compressorName} or {} + +# List of arguments to pass to the compressor program, or null to use its defaults +, compressorArgs ? null +, _compressorArgsReal ? if compressorArgs == null then _compressorMeta.defaultArgs or [] else compressorArgs + +# Filename extension to use for the compressed initramfs. This is +# included for clarity, but $out/initrd will always be a symlink to +# the final image. +# If this isn't guessed, you may want to complete the metadata above and send a PR :) +, extension ? _compressorMeta.extension or + (throw "Unrecognised compressor ${_compressorName}, please specify filename extension") + +# List of { object = path_or_derivation; symlink = "/path"; } +# The paths are copied into the initramfs in their nix store path +# form, then linked at the root according to `symlink`. +, contents + +# List of uncompressed cpio files to prepend to the initramfs. This +# can be used to add files in specified paths without them becoming +# symlinks to store paths. , prepend ? [] -, lib + +# Whether to wrap the initramfs in a u-boot image. +, makeUInitrd ? stdenvNoCC.hostPlatform.linux-kernel.target == "uImage" + +# If generating a u-boot image, the architecture to use. The default +# guess may not align with u-boot's nomenclature correctly, so it can +# be overridden. +# See https://gitlab.denx.de/u-boot/u-boot/-/blob/9bfb567e5f1bfe7de8eb41f8c6d00f49d2b9a426/common/image.c#L81-106 for a list. +, uInitrdArch ? stdenvNoCC.hostPlatform.linuxArch + +# The name of the compression, as recognised by u-boot. +# See https://gitlab.denx.de/u-boot/u-boot/-/blob/9bfb567e5f1bfe7de8eb41f8c6d00f49d2b9a426/common/image.c#L195-204 for a list. +# If this isn't guessed, you may want to complete the metadata above and send a PR :) +, uInitrdCompression ? _compressorMeta.ubootName or + (throw "Unrecognised compressor ${_compressorName}, please specify uInitrdCompression") }: let # !!! Move this into a public lib function, it is probably useful for others @@ -24,15 +76,26 @@ let lib.concatStringsSep "-" (filter (x: !(isList x)) (split "[^a-zA-Z0-9_=.?-]+" x)); in stdenvNoCC.mkDerivation rec { - inherit name; + inherit name makeUInitrd extension uInitrdArch prepend; - builder = ./make-initrd.sh; + ${if makeUInitrd then "uinitrdCompression" else null} = uInitrdCompression; - makeUInitrd = stdenvNoCC.hostPlatform.platform.kernelTarget == "uImage"; + builder = ./make-initrd.sh; nativeBuildInputs = [ perl cpio ] ++ stdenvNoCC.lib.optional makeUInitrd ubootTools; + compress = "${_compressorExecutable} ${lib.escapeShellArgs _compressorArgsReal}"; + + # Pass the function through, for reuse in append-initrd-secrets. The + # function is used instead of the string, in order to support + # cross-compilation (append-initrd-secrets running on a different + # architecture than what the main initramfs is built on). + passthru = { + compressorExecutableFunction = _compressorFunction; + compressorArgs = _compressorArgsReal; + }; + # !!! should use XML. objects = map (x: x.object) contents; symlinks = map (x: x.symlink) contents; @@ -47,6 +110,4 @@ in stdenvNoCC.mkDerivation rec { contents (lib.range 0 (lib.length contents - 1)); pathsFromGraph = ./paths-from-graph.pl; - - inherit compressor prepend; } diff --git a/pkgs/build-support/kernel/make-initrd.sh b/pkgs/build-support/kernel/make-initrd.sh index 0aeaedeb3724..c0619ef14ae0 100644 --- a/pkgs/build-support/kernel/make-initrd.sh +++ b/pkgs/build-support/kernel/make-initrd.sh @@ -39,10 +39,13 @@ mkdir -p $out for PREP in $prepend; do cat $PREP >> $out/initrd done -(cd root && find * -print0 | xargs -0r touch -h -d '@1') -(cd root && find * -print0 | sort -z | cpio -o -H newc -R +0:+0 --reproducible --null | $compressor >> $out/initrd) +(cd root && find * .[^.*] -exec touch -h -d '@1' '{}' +) +(cd root && find * .[^.*] -print0 | sort -z | cpio -o -H newc -R +0:+0 --reproducible --null | eval -- $compress >> "$out/initrd") if [ -n "$makeUInitrd" ]; then - mv $out/initrd $out/initrd.gz - mkimage -A arm -O linux -T ramdisk -C gzip -d $out/initrd.gz $out/initrd + mkimage -A $uInitrdArch -O linux -T ramdisk -C "$uInitrdCompression" -d $out/initrd"$extension" $out/initrd.img + # Compatibility symlink + ln -s "initrd.img" "$out/initrd" +else + ln -s "initrd" "$out/initrd$extension" fi diff --git a/pkgs/build-support/kernel/modules-closure.sh b/pkgs/build-support/kernel/modules-closure.sh index 3f895d9cfed9..3b3a38ea1d33 100644 --- a/pkgs/build-support/kernel/modules-closure.sh +++ b/pkgs/build-support/kernel/modules-closure.sh @@ -81,7 +81,8 @@ for module in $(cat closure); do for i in $(modinfo -b $kernel --set-version "$version" -F firmware $module | grep -v '^name:'); do mkdir -p "$out/lib/firmware/$(dirname "$i")" echo "firmware for $module: $i" - cp "$firmware/lib/firmware/$i" "$out/lib/firmware/$i" 2>/dev/null || if test -z "$allowMissing"; then exit 1; fi + cp "$firmware/lib/firmware/$i" "$out/lib/firmware/$i" 2>/dev/null \ + || echo "WARNING: missing firmware $i for module $module" done done diff --git a/pkgs/build-support/libredirect/default.nix b/pkgs/build-support/libredirect/default.nix index 6e54e2a696c5..70da5bf5b5fb 100644 --- a/pkgs/build-support/libredirect/default.nix +++ b/pkgs/build-support/libredirect/default.nix @@ -46,8 +46,8 @@ stdenv.mkDerivation { ) ''; - meta = { - platforms = stdenv.lib.platforms.unix; + meta = with lib; { + platforms = platforms.unix; description = "An LD_PRELOAD library to intercept and rewrite the paths in glibc calls"; longDescription = '' libredirect is an LD_PRELOAD library to intercept and rewrite the paths in diff --git a/pkgs/build-support/make-desktopitem/default.nix b/pkgs/build-support/make-desktopitem/default.nix index 8e51dc1b8480..329286bd3628 100644 --- a/pkgs/build-support/make-desktopitem/default.nix +++ b/pkgs/build-support/make-desktopitem/default.nix @@ -12,16 +12,16 @@ , mimeType ? null , categories ? null , startupNotify ? null -, extraDesktopEntries ? {} # Extra key-value pairs to add to the [Desktop Entry] section. This may override other values +, extraDesktopEntries ? { } # Extra key-value pairs to add to the [Desktop Entry] section. This may override other values , extraEntries ? "" # Extra configuration. Will be appended to the end of the file and may thus contain extra sections , fileValidation ? true # whether to validate resulting desktop file. }: - let # like builtins.toString, but null -> null instead of null -> "" - nullableToString = value: if value == null then null - else if builtins.isBool value then lib.boolToString value - else builtins.toString value; + nullableToString = value: + if value == null then null + else if builtins.isBool value then lib.boolToString value + else builtins.toString value; # The [Desktop entry] section of the desktop file, as attribute set. mainSection = { @@ -39,16 +39,19 @@ let # Map all entries to a list of lines desktopFileStrings = - ["[Desktop Entry]"] + [ "[Desktop Entry]" ] ++ builtins.filter (v: v != null) (lib.mapAttrsToList (name: value: if value != null then "${name}=${value}" else null) mainSection ) - ++ (if extraEntries == "" then [] else ["${extraEntries}"]); + ++ (if extraEntries == "" then [ ] else [ "${extraEntries}" ]); in -runCommandLocal "${name}.desktop" {} +runCommandLocal "${name}.desktop" +{ + nativeBuildInputs = [ desktop-file-utils ]; +} ('' mkdir -p "$out/share/applications" cat > "$out/share/applications/${name}.desktop" <<EOF @@ -56,5 +59,5 @@ runCommandLocal "${name}.desktop" {} EOF '' + lib.optionalString fileValidation '' echo "Running desktop-file validation" - ${desktop-file-utils}/bin/desktop-file-validate "$out/share/applications/${name}.desktop" + desktop-file-validate "$out/share/applications/${name}.desktop" '') diff --git a/pkgs/build-support/nix-gitignore/default.nix b/pkgs/build-support/nix-gitignore/default.nix index 28ee6bad5540..5d7b945bf1b1 100644 --- a/pkgs/build-support/nix-gitignore/default.nix +++ b/pkgs/build-support/nix-gitignore/default.nix @@ -148,10 +148,10 @@ in rec { ''); withGitignoreFile = patterns: root: - lib.toList patterns ++ [(root + "/.gitignore")]; + lib.toList patterns ++ [ ".git" ] ++ [(root + "/.gitignore")]; withRecursiveGitignoreFile = patterns: root: - lib.toList patterns ++ [(compileRecursiveGitignore root)]; + lib.toList patterns ++ [ ".git" ] ++ [(compileRecursiveGitignore root)]; # filterSource derivatives diff --git a/pkgs/build-support/ocaml/default.nix b/pkgs/build-support/ocaml/default.nix index 3957b955a2c6..88ed3dfc2c2f 100644 --- a/pkgs/build-support/ocaml/default.nix +++ b/pkgs/build-support/ocaml/default.nix @@ -1,4 +1,4 @@ -{ stdenv, writeText, ocaml, findlib, ocamlbuild, camlp4 }: +{ lib, stdenv, writeText, ocaml, findlib, ocamlbuild, camlp4 }: { name, version, buildInputs ? [], createFindlibDestdir ? true, @@ -14,7 +14,7 @@ let }; in assert minimumSupportedOcamlVersion != null -> - stdenv.lib.versionOlder minimumSupportedOcamlVersion ocaml.version; + lib.versionOlder minimumSupportedOcamlVersion ocaml.version; stdenv.mkDerivation (args // { name = "ocaml-${name}-${version}"; diff --git a/pkgs/build-support/ocaml/dune.nix b/pkgs/build-support/ocaml/dune.nix index b134effab8ac..f9f59b21510f 100644 --- a/pkgs/build-support/ocaml/dune.nix +++ b/pkgs/build-support/ocaml/dune.nix @@ -1,11 +1,11 @@ -{ stdenv, ocaml, findlib, dune, dune_2, opaline }: +{ lib, stdenv, ocaml, findlib, dune, dune_2 }: { pname, version, buildInputs ? [], enableParallelBuilding ? true, ... }@args: let Dune = if args.useDune2 or false then dune_2 else dune; in if args ? minimumOCamlVersion && - ! stdenv.lib.versionAtLeast ocaml.version args.minimumOCamlVersion + ! lib.versionAtLeast ocaml.version args.minimumOCamlVersion then throw "${pname}-${version} is not available for OCaml ${ocaml.version}" else @@ -25,7 +25,7 @@ stdenv.mkDerivation ({ ''; installPhase = '' runHook preInstall - ${opaline}/bin/opaline -prefix $out -libdir $OCAMLFIND_DESTDIR + dune install --prefix $out --libdir $OCAMLFIND_DESTDIR ${pname} runHook postInstall ''; diff --git a/pkgs/build-support/ocaml/oasis.nix b/pkgs/build-support/ocaml/oasis.nix index c1d1d699765b..ee231a6e258c 100644 --- a/pkgs/build-support/ocaml/oasis.nix +++ b/pkgs/build-support/ocaml/oasis.nix @@ -1,4 +1,4 @@ -{ stdenv, ocaml_oasis, ocaml, findlib, ocamlbuild }: +{ lib, stdenv, ocaml_oasis, ocaml, findlib, ocamlbuild }: { pname, version, buildInputs ? [], meta ? { platforms = ocaml.meta.platforms or []; }, minimumOCamlVersion ? null, @@ -8,7 +8,7 @@ }@args: if args ? minimumOCamlVersion && - ! stdenv.lib.versionAtLeast ocaml.version args.minimumOCamlVersion + ! lib.versionAtLeast ocaml.version args.minimumOCamlVersion then throw "${pname}-${version} is not available for OCaml ${ocaml.version}" else diff --git a/pkgs/build-support/pkg-config-wrapper/default.nix b/pkgs/build-support/pkg-config-wrapper/default.nix index e01df107dd17..bbc49d6728c9 100644 --- a/pkgs/build-support/pkg-config-wrapper/default.nix +++ b/pkgs/build-support/pkg-config-wrapper/default.nix @@ -2,6 +2,7 @@ # PKG_CONFIG_PATH_FOR_BUILD work properly. { stdenvNoCC +, lib , buildPackages , pkg-config , baseBinName ? "pkg-config" @@ -9,7 +10,7 @@ , extraPackages ? [], extraBuildCommands ? "" }: -with stdenvNoCC.lib; +with lib; let stdenv = stdenvNoCC; @@ -19,7 +20,7 @@ let # # TODO(@Ericson2314) Make unconditional, or optional but always true by # default. - targetPrefix = stdenv.lib.optionalString (targetPlatform != hostPlatform) + targetPrefix = lib.optionalString (targetPlatform != hostPlatform) (targetPlatform.config + "-"); # See description in cc-wrapper. @@ -119,7 +120,7 @@ stdenv.mkDerivation { let pkg-config_ = if pkg-config != null then pkg-config else {}; in (if pkg-config_ ? meta then removeAttrs pkg-config.meta ["priority"] else {}) // { description = - stdenv.lib.attrByPath ["meta" "description"] "pkg-config" pkg-config_ + lib.attrByPath ["meta" "description"] "pkg-config" pkg-config_ + " (wrapper script)"; priority = 10; }; diff --git a/pkgs/build-support/plugins.nix b/pkgs/build-support/plugins.nix index bf8a982a88f9..31b478c6c0de 100644 --- a/pkgs/build-support/plugins.nix +++ b/pkgs/build-support/plugins.nix @@ -1,4 +1,4 @@ -{ stdenv }: +{ lib }: # helper functions for packaging programs with plugin systems { @@ -13,7 +13,7 @@ diffPlugins = expectedPlugins: foundPluginsFilePath: '' # sort both lists first plugins_expected=$(mktemp) - (${stdenv.lib.concatMapStrings (s: "echo \"${s}\";") expectedPlugins}) \ + (${lib.concatMapStrings (s: "echo \"${s}\";") expectedPlugins}) \ | sort -u > "$plugins_expected" plugins_found=$(mktemp) sort -u "${foundPluginsFilePath}" > "$plugins_found" diff --git a/pkgs/build-support/release/ant-build.nix b/pkgs/build-support/release/ant-build.nix index 2d24d5bd7041..996f4f45d07b 100644 --- a/pkgs/build-support/release/ant-build.nix +++ b/pkgs/build-support/release/ant-build.nix @@ -1,5 +1,6 @@ { src , pkgs +, lib , stdenv ? pkgs.stdenv , name , antTargets ? [] @@ -16,8 +17,7 @@ , ... } @ args: let - antFlags = "-f ${buildfile} " + stdenv.lib.concatMapStrings ({name, value}: "-D${name}=${value} " ) antProperties ; - lib = stdenv.lib; + antFlags = "-f ${buildfile} " + lib.concatMapStrings ({name, value}: "-D${name}=${value} " ) antProperties ; in stdenv.mkDerivation ( @@ -31,7 +31,7 @@ stdenv.mkDerivation ( prePhases = ["antSetupPhase"]; - antSetupPhase = with stdenv.lib; '' + antSetupPhase = with lib; '' if test "$hydraAntLogger" != "" ; then export ANT_ARGS="-logger org.hydra.ant.HydraLogger -lib `ls $hydraAntLogger/share/java/*.jar | head -1`" fi @@ -46,7 +46,7 @@ stdenv.mkDerivation ( mkdir -p $out/share/java ${ if jars == [] then '' find . -name "*.jar" | xargs -I{} cp -v {} $out/share/java - '' else stdenv.lib.concatMapStrings (j: '' + '' else lib.concatMapStrings (j: '' cp -v ${j} $out/share/java '') jars } @@ -65,7 +65,7 @@ stdenv.mkDerivation ( in '' header "Generating jar wrappers" - '' + (stdenv.lib.concatMapStrings (w: '' + '' + (lib.concatMapStrings (w: '' mkdir -p $out/bin cat >> $out/bin/${w.name} <<EOF @@ -85,7 +85,7 @@ stdenv.mkDerivation ( header "Building default ant target" ant ${antFlags} closeNest - '' else stdenv.lib.concatMapStrings (t: '' + '' else lib.concatMapStrings (t: '' header "Building '${t}' target" ant ${antFlags} ${t} closeNest @@ -103,12 +103,12 @@ stdenv.mkDerivation ( ''; } - // removeAttrs args ["antProperties" "buildInputs" "pkgs" "jarWrappers"] // + // removeAttrs args ["antProperties" "buildInputs" "pkgs" "lib" "jarWrappers"] // { name = name + (if src ? version then "-" + src.version else ""); - buildInputs = [ant jre zip unzip] ++ stdenv.lib.optional (args ? buildInputs) args.buildInputs ; + buildInputs = [ant jre zip unzip] ++ lib.optional (args ? buildInputs) args.buildInputs ; postHook = '' mkdir -p $out/nix-support diff --git a/pkgs/build-support/release/debian-build.nix b/pkgs/build-support/release/debian-build.nix index dfa896a86a60..2544d5c740c2 100644 --- a/pkgs/build-support/release/debian-build.nix +++ b/pkgs/build-support/release/debian-build.nix @@ -2,8 +2,9 @@ # that contains a Debian-like (i.e. dpkg-based) OS. { name ? "debian-build" +, lib , diskImage -, src, stdenv, vmTools, checkinstall +, src, lib, stdenv, vmTools, checkinstall , fsTranslation ? false , # Features provided by this package. debProvides ? [] @@ -11,8 +12,6 @@ debRequires ? [] , ... } @ args: -with stdenv.lib; - vmTools.runInLinuxImage (stdenv.mkDerivation ( { @@ -59,8 +58,8 @@ vmTools.runInLinuxImage (stdenv.mkDerivation ( export PAGER=cat ${checkinstall}/sbin/checkinstall --nodoc -y -D \ --fstrans=${if fsTranslation then "yes" else "no"} \ - --requires="${concatStringsSep "," debRequires}" \ - --provides="${concatStringsSep "," debProvides}" \ + --requires="${lib.concatStringsSep "," debRequires}" \ + --provides="${lib.concatStringsSep "," debProvides}" \ ${if (src ? version) then "--pkgversion=$(echo ${src.version} | tr _ -)" else "--pkgversion=0.0.0"} \ ''${debMaintainer:+--maintainer="'$debMaintainer'"} \ diff --git a/pkgs/build-support/release/default.nix b/pkgs/build-support/release/default.nix index 6aaa0338f0cc..83f755b2bece 100644 --- a/pkgs/build-support/release/default.nix +++ b/pkgs/build-support/release/default.nix @@ -1,4 +1,4 @@ -{ pkgs }: +{ lib, pkgs }: with pkgs; @@ -15,7 +15,7 @@ rec { } // args); antBuild = args: import ./ant-build.nix ( - { inherit pkgs; + { inherit lib pkgs; } // args); mvnBuild = args: import ./maven-build.nix ( @@ -23,7 +23,7 @@ rec { } // args); nixBuild = args: import ./nix-build.nix ( - { inherit stdenv; + { inherit lib stdenv; } // args); coverageAnalysis = args: nixBuild ( @@ -46,7 +46,7 @@ rec { } // args); debBuild = args: import ./debian-build.nix ( - { inherit stdenv vmTools checkinstall; + { inherit lib stdenv vmTools checkinstall; } // args); aggregate = @@ -94,7 +94,7 @@ rec { phases = [ "unpackPhase" "patchPhase" "installPhase" ]; - patchPhase = stdenv.lib.optionalString isNixOS '' + patchPhase = lib.optionalString isNixOS '' touch .update-on-nixos-rebuild ''; diff --git a/pkgs/build-support/release/nix-build.nix b/pkgs/build-support/release/nix-build.nix index feda54de46fe..97df52eaced2 100644 --- a/pkgs/build-support/release/nix-build.nix +++ b/pkgs/build-support/release/nix-build.nix @@ -12,7 +12,7 @@ , doCoverityAnalysis ? false , lcovFilter ? [] , lcovExtraTraceFiles ? [] -, src, stdenv +, src, lib, stdenv , name ? if doCoverageAnalysis then "nix-coverage" else "nix-build" , failureHook ? null , prePhases ? [] @@ -69,7 +69,7 @@ stdenv.mkDerivation ( fi ''; - failureHook = (stdenv.lib.optionalString (failureHook != null) failureHook) + + failureHook = (lib.optionalString (failureHook != null) failureHook) + '' if test -n "$succeedOnFailure"; then if test -n "$keepBuildDirectory"; then @@ -136,10 +136,10 @@ stdenv.mkDerivation ( buildInputs = buildInputs ++ - (stdenv.lib.optional doCoverageAnalysis args.makeGCOVReport) ++ - (stdenv.lib.optional doClangAnalysis args.clang-analyzer) ++ - (stdenv.lib.optional doCoverityAnalysis args.cov-build) ++ - (stdenv.lib.optional doCoverityAnalysis args.xz); + (lib.optional doCoverageAnalysis args.makeGCOVReport) ++ + (lib.optional doClangAnalysis args.clang-analyzer) ++ + (lib.optional doCoverityAnalysis args.cov-build) ++ + (lib.optional doCoverityAnalysis args.xz); lcovFilter = ["/nix/store/*"] ++ lcovFilter; diff --git a/pkgs/build-support/rust/build-rust-crate/build-crate.nix b/pkgs/build-support/rust/build-rust-crate/build-crate.nix index 142109cef49f..84d1b2300f14 100644 --- a/pkgs/build-support/rust/build-rust-crate/build-crate.nix +++ b/pkgs/build-support/rust/build-rust-crate/build-crate.nix @@ -15,7 +15,7 @@ ++ [(mkRustcDepArgs dependencies crateRenames)] ++ [(mkRustcFeatureArgs crateFeatures)] ++ extraRustcOpts - ++ lib.optional (stdenv.hostPlatform != stdenv.buildPlatform) "--target ${rust.toRustTarget stdenv.hostPlatform} -C linker=${stdenv.hostPlatform.config}-gcc" + ++ lib.optional (stdenv.hostPlatform != stdenv.buildPlatform) "--target ${rust.toRustTargetSpec stdenv.hostPlatform} -C linker=${stdenv.hostPlatform.config}-gcc" # since rustc 1.42 the "proc_macro" crate is part of the default crate prelude # https://github.com/rust-lang/cargo/commit/4d64eb99a4#diff-7f98585dbf9d30aa100c8318e2c77e79R1021-R1022 ++ lib.optional (lib.elem "proc-macro" crateType) "--extern proc_macro" diff --git a/pkgs/build-support/rust/build-rust-crate/configure-crate.nix b/pkgs/build-support/rust/build-rust-crate/configure-crate.nix index 18587f7047c4..d1010ac1adb3 100644 --- a/pkgs/build-support/rust/build-rust-crate/configure-crate.nix +++ b/pkgs/build-support/rust/build-rust-crate/configure-crate.nix @@ -135,8 +135,8 @@ in '' export CARGO_MANIFEST_DIR=$(pwd) export DEBUG="${toString (!release)}" export OPT_LEVEL="${toString optLevel}" - export TARGET="${rust.toRustTarget stdenv.hostPlatform}" - export HOST="${rust.toRustTarget stdenv.buildPlatform}" + export TARGET="${rust.toRustTargetSpec stdenv.hostPlatform}" + export HOST="${rust.toRustTargetSpec stdenv.buildPlatform}" export PROFILE=${if release then "release" else "debug"} export OUT_DIR=$(pwd)/target/build/${crateName}.out export CARGO_PKG_VERSION_MAJOR=${lib.elemAt version 0} @@ -144,7 +144,7 @@ in '' export CARGO_PKG_VERSION_PATCH=${lib.elemAt version 2} export CARGO_PKG_VERSION_PRE="${versionPre}" export CARGO_PKG_HOMEPAGE="${crateHomepage}" - export NUM_JOBS=1 + export NUM_JOBS=$NIX_BUILD_CORES export RUSTC="rustc" export RUSTDOC="rustdoc" diff --git a/pkgs/build-support/rust/build-rust-crate/default.nix b/pkgs/build-support/rust/build-rust-crate/default.nix index 9d98e0851780..e605c9550e53 100644 --- a/pkgs/build-support/rust/build-rust-crate/default.nix +++ b/pkgs/build-support/rust/build-rust-crate/default.nix @@ -54,6 +54,10 @@ let }; installCrate = import ./install-crate.nix { inherit stdenv; }; + + # Allow access to the rust attribute set from inside buildRustCrate, which + # has a parameter that shadows the name. + rustAttrs = rust; in /* The overridable pkgs.buildRustCrate function. @@ -250,7 +254,7 @@ stdenv.mkDerivation (rec { depsMetadata = lib.foldl' (str: dep: str + dep.metadata) "" (dependencies ++ buildDependencies); hashedMetadata = builtins.hashString "sha256" (crateName + "-" + crateVersion + "___" + toString (mkRustcFeatureArgs crateFeatures) + - "___" + depsMetadata); + "___" + depsMetadata + "___" + rustAttrs.toRustTarget stdenv.hostPlatform); in lib.substring 0 10 hashedMetadata; build = crate.build or ""; diff --git a/pkgs/build-support/rust/build-rust-crate/test/default.nix b/pkgs/build-support/rust/build-rust-crate/test/default.nix index f6cd54c4ee3e..65c8880b134d 100644 --- a/pkgs/build-support/rust/build-rust-crate/test/default.nix +++ b/pkgs/build-support/rust/build-rust-crate/test/default.nix @@ -146,12 +146,18 @@ let }; in runCommand "assert-outputs-${name}" { - } '' + } ('' local actualFiles=$(mktemp) cd "${crateOutput}" - find . -type f | sort >$actualFiles - diff -q ${expectedFilesFile} $actualFiles >/dev/null || { + find . -type f \ + | sort \ + '' + # sed out the hash because it differs per platform + + '' + | sed -E -e 's/-[0-9a-fA-F]{10}\.rlib/-HASH.rlib/g' \ + > "$actualFiles" + diff -q ${expectedFilesFile} "$actualFiles" > /dev/null || { echo -e "\033[0;1;31mERROR: Difference in expected output files in ${crateOutput} \033[0m" >&2 echo === Got: sed -e 's/^/ /' $actualFiles @@ -164,7 +170,7 @@ let exit 1 } touch $out - '' + '') ; in rec { @@ -594,7 +600,7 @@ let }; expectedFiles = [ "./nix-support/propagated-build-inputs" - "./lib/libtest_lib-042a1fdbef.rlib" + "./lib/libtest_lib-HASH.rlib" "./lib/link" ]; }; @@ -611,7 +617,7 @@ let }; expectedFiles = [ "./nix-support/propagated-build-inputs" - "./lib/libtest_lib-042a1fdbef.rlib" + "./lib/libtest_lib-HASH.rlib" "./lib/link" ]; }; diff --git a/pkgs/build-support/rust/default-crate-overrides.nix b/pkgs/build-support/rust/default-crate-overrides.nix index d0e69ad698a8..3d2dc3733c22 100644 --- a/pkgs/build-support/rust/default-crate-overrides.nix +++ b/pkgs/build-support/rust/default-crate-overrides.nix @@ -1,6 +1,7 @@ -{ stdenv, pkgconfig, curl, darwin, libiconv, libgit2, libssh2, +{ lib, stdenv, pkg-config, curl, darwin, libiconv, libgit2, libssh2, openssl, sqlite, zlib, dbus, dbus-glib, gdk-pixbuf, cairo, python3, - libsodium, postgresql, gmp, foundationdb, ... }: + libsodium, postgresql, gmp, foundationdb, capnproto, nettle, clang, + llvmPackages, ... }: let inherit (darwin.apple_sdk.frameworks) CoreFoundation Security; @@ -10,26 +11,30 @@ in buildInputs = [ cairo ]; }; + capnp-rpc = attrs: { + nativeBuildInputs = [ capnproto ]; + }; + cargo = attrs: { buildInputs = [ openssl zlib curl ] - ++ stdenv.lib.optionals stdenv.isDarwin [ CoreFoundation Security libiconv ]; + ++ lib.optionals stdenv.isDarwin [ CoreFoundation Security libiconv ]; }; libz-sys = attrs: { - nativeBuildInputs = [ pkgconfig ]; + nativeBuildInputs = [ pkg-config ]; buildInputs = [ zlib ]; extraLinkFlags = ["-L${zlib.out}/lib"]; }; curl-sys = attrs: { - nativeBuildInputs = [ pkgconfig ]; + nativeBuildInputs = [ pkg-config ]; buildInputs = [ zlib curl ]; propagatedBuildInputs = [ curl zlib ]; extraLinkFlags = ["-L${zlib.out}/lib"]; }; dbus = attrs: { - nativeBuildInputs = [ pkgconfig ]; + nativeBuildInputs = [ pkg-config ]; buildInputs = [ dbus ]; }; @@ -65,36 +70,42 @@ in libgit2-sys = attrs: { LIBGIT2_SYS_USE_PKG_CONFIG = true; - nativeBuildInputs = [ pkgconfig ]; + nativeBuildInputs = [ pkg-config ]; buildInputs = [ openssl zlib libgit2 ]; }; libsqlite3-sys = attrs: { - nativeBuildInputs = [ pkgconfig ]; + nativeBuildInputs = [ pkg-config ]; buildInputs = [ sqlite ]; }; libssh2-sys = attrs: { - nativeBuildInputs = [ pkgconfig ]; + nativeBuildInputs = [ pkg-config ]; buildInputs = [ openssl zlib libssh2 ]; }; libdbus-sys = attrs: { - nativeBuildInputs = [ pkgconfig ]; + nativeBuildInputs = [ pkg-config ]; buildInputs = [ dbus ]; }; + nettle-sys = attrs: { + nativeBuildInputs = [ pkg-config ]; + buildInputs = [ nettle clang ]; + LIBCLANG_PATH = "${llvmPackages.libclang}/lib"; + }; + openssl = attrs: { buildInputs = [ openssl ]; }; openssl-sys = attrs: { - nativeBuildInputs = [ pkgconfig ]; + nativeBuildInputs = [ pkg-config ]; buildInputs = [ openssl ]; }; pq-sys = attr: { - nativeBuildInputs = [ pkgconfig ]; + nativeBuildInputs = [ pkg-config ]; buildInputs = [ postgresql ]; }; @@ -107,12 +118,42 @@ in propagatedBuildInputs = [ Security ]; }; + sequoia-openpgp = attrs: { + buildInputs = [ gmp ]; + }; + + sequoia-openpgp-ffi = attrs: { + buildInputs = [ gmp ]; + }; + + sequoia-ipc = attrs: { + buildInputs = [ gmp ]; + }; + + sequoia-guide = attrs: { + buildInputs = [ gmp ]; + }; + + sequoia-store = attrs: { + nativeBuildInputs = [ capnproto ]; + buildInputs = [ sqlite gmp ]; + }; + + sequoia-sq = attrs: { + buildInputs = [ sqlite gmp ]; + }; + + sequoia-tool = attrs: { + nativeBuildInputs = [ capnproto ]; + buildInputs = [ sqlite gmp ]; + }; + serde_derive = attrs: { - buildInputs = stdenv.lib.optional stdenv.isDarwin Security; + buildInputs = lib.optional stdenv.isDarwin Security; }; thrussh-libsodium = attrs: { - nativeBuildInputs = [ pkgconfig ]; + nativeBuildInputs = [ pkg-config ]; buildInputs = [ libsodium ]; }; diff --git a/pkgs/build-support/rust/default.nix b/pkgs/build-support/rust/default.nix index f6177ce198da..dc86a7dc581f 100644 --- a/pkgs/build-support/rust/default.nix +++ b/pkgs/build-support/rust/default.nix @@ -1,9 +1,14 @@ { stdenv +, lib , buildPackages , cacert , cargo , diffutils , fetchCargoTarball +, runCommandNoCC +, rustPlatform +, callPackage +, remarshal , git , rust , rustc @@ -11,7 +16,13 @@ }: { name ? "${args.pname}-${args.version}" -, cargoSha256 ? "unset" + + # SRI hash +, cargoHash ? "" + + # Legacy hash +, cargoSha256 ? "" + , src ? null , srcs ? null , unpackPhase ? null @@ -26,12 +37,15 @@ , cargoBuildFlags ? [] , buildType ? "release" , meta ? {} -, target ? null +, target ? rust.toRustTargetSpec stdenv.hostPlatform , cargoVendorDir ? null , checkType ? buildType , depsExtraArgs ? {} , cargoParallelTestThreads ? true +# Toggles whether a custom sysroot is created when the target is a .json file. +, __internal_dontAddSysroot ? false + # Needed to `pushd`/`popd` into a subdir of a tarball if this subdir # contains a Cargo.toml, but isn't part of a workspace (which is e.g. the # case for `rustfmt`/etc from the `rust-sources). @@ -39,7 +53,7 @@ , buildAndTestSubdir ? null , ... } @ args: -assert cargoVendorDir == null -> cargoSha256 != "unset"; +assert cargoVendorDir == null -> !(cargoSha256 == "" && cargoHash == ""); assert buildType == "release" || buildType == "debug"; let @@ -47,6 +61,7 @@ let cargoDeps = if cargoVendorDir == null then fetchCargoTarball ({ inherit name src srcs sourceRoot unpackPhase cargoUpdateHook; + hash = cargoHash; patches = cargoPatches; sha256 = cargoSha256; } // depsExtraArgs) @@ -54,7 +69,7 @@ let # If we have a cargoSha256 fixed-output derivation, validate it at build time # against the src fixed-output derivation to check consistency. - validateCargoDeps = cargoSha256 != "unset"; + validateCargoDeps = !(cargoHash == "" && cargoSha256 == ""); # Some cargo builds include build hooks that modify their own vendor # dependencies. This copies the vendor directory into the build tree and makes @@ -69,13 +84,26 @@ let cargoDepsCopy="$sourceRoot/${cargoVendorDir}" ''; - rustTarget = if target == null then rust.toRustTarget stdenv.hostPlatform else target; + targetIsJSON = lib.hasSuffix ".json" target; + useSysroot = targetIsJSON && !__internal_dontAddSysroot; + + # see https://github.com/rust-lang/cargo/blob/964a16a28e234a3d397b2a7031d4ab4a428b1391/src/cargo/core/compiler/compile_kind.rs#L151-L168 + # the "${}" is needed to transform the path into a /nix/store path before baseNameOf + shortTarget = if targetIsJSON then + (lib.removeSuffix ".json" (builtins.baseNameOf "${target}")) + else target; + + sysroot = (callPackage ./sysroot {}) { + inherit target shortTarget; + RUSTFLAGS = args.RUSTFLAGS or ""; + originalCargoToml = src + /Cargo.toml; # profile info is later extracted + }; ccForBuild="${buildPackages.stdenv.cc}/bin/${buildPackages.stdenv.cc.targetPrefix}cc"; cxxForBuild="${buildPackages.stdenv.cc}/bin/${buildPackages.stdenv.cc.targetPrefix}c++"; ccForHost="${stdenv.cc}/bin/${stdenv.cc.targetPrefix}cc"; cxxForHost="${stdenv.cc}/bin/${stdenv.cc.targetPrefix}c++"; - releaseDir = "target/${rustTarget}/${buildType}"; + releaseDir = "target/${shortTarget}/${buildType}"; tmpDir = "${releaseDir}-tmp"; # Specify the stdenv's `diff` by abspath to ensure that the user's build @@ -85,13 +113,19 @@ let in -stdenv.mkDerivation ((removeAttrs args ["depsExtraArgs"]) // { +# Tests don't currently work for `no_std`, and all custom sysroots are currently built without `std`. +# See https://os.phil-opp.com/testing/ for more information. +assert useSysroot -> !(args.doCheck or true); + +stdenv.mkDerivation ((removeAttrs args ["depsExtraArgs"]) // lib.optionalAttrs useSysroot { + RUSTFLAGS = "--sysroot ${sysroot} " + (args.RUSTFLAGS or ""); +} // { inherit cargoDeps; patchRegistryDeps = ./patch-registry-deps; nativeBuildInputs = nativeBuildInputs ++ [ cacert git cargo rustc ]; - buildInputs = buildInputs ++ stdenv.lib.optional stdenv.hostPlatform.isMinGW windows.pthreads; + buildInputs = buildInputs ++ lib.optional stdenv.hostPlatform.isMinGW windows.pthreads; patches = cargoPatches ++ patches; @@ -114,11 +148,11 @@ stdenv.mkDerivation ((removeAttrs args ["depsExtraArgs"]) // { cat >> .cargo/config <<'EOF' [target."${rust.toRustTarget stdenv.buildPlatform}"] "linker" = "${ccForBuild}" - ${stdenv.lib.optionalString (stdenv.buildPlatform.config != stdenv.hostPlatform.config) '' - [target."${rustTarget}"] + ${lib.optionalString (stdenv.buildPlatform.config != stdenv.hostPlatform.config) '' + [target."${shortTarget}"] "linker" = "${ccForHost}" ${# https://github.com/rust-lang/rust/issues/46651#issuecomment-433611633 - stdenv.lib.optionalString (stdenv.hostPlatform.isMusl && stdenv.hostPlatform.isAarch64) '' + lib.optionalString (stdenv.hostPlatform.isMusl && stdenv.hostPlatform.isAarch64) '' "rustflags" = [ "-C", "target-feature=+crt-static", "-C", "link-arg=-lgcc" ] ''} ''} @@ -130,7 +164,7 @@ stdenv.mkDerivation ((removeAttrs args ["depsExtraArgs"]) // { # After unpacking and applying patches, check that the Cargo.lock matches our # src package. Note that we do this after the patchPhase, because the # patchPhase may create the Cargo.lock if upstream has not shipped one. - postPatch = (args.postPatch or "") + stdenv.lib.optionalString validateCargoDeps '' + postPatch = (args.postPatch or "") + lib.optionalString validateCargoDeps '' cargoDepsLockfile=$NIX_BUILD_TOP/$cargoDepsCopy/Cargo.lock srcLockfile=$NIX_BUILD_TOP/$sourceRoot/Cargo.lock @@ -173,7 +207,7 @@ stdenv.mkDerivation ((removeAttrs args ["depsExtraArgs"]) // { ''; buildPhase = with builtins; args.buildPhase or '' - ${stdenv.lib.optionalString (buildAndTestSubdir != null) "pushd ${buildAndTestSubdir}"} + ${lib.optionalString (buildAndTestSubdir != null) "pushd ${buildAndTestSubdir}"} runHook preBuild ( @@ -184,14 +218,14 @@ stdenv.mkDerivation ((removeAttrs args ["depsExtraArgs"]) // { "CC_${rust.toRustTarget stdenv.hostPlatform}"="${ccForHost}" \ "CXX_${rust.toRustTarget stdenv.hostPlatform}"="${cxxForHost}" \ cargo build -j $NIX_BUILD_CORES \ - ${stdenv.lib.optionalString (buildType == "release") "--release"} \ - --target ${rustTarget} \ + ${lib.optionalString (buildType == "release") "--release"} \ + --target ${target} \ --frozen ${concatStringsSep " " cargoBuildFlags} ) runHook postBuild - ${stdenv.lib.optionalString (buildAndTestSubdir != null) "popd"} + ${lib.optionalString (buildAndTestSubdir != null) "popd"} # This needs to be done after postBuild: packages like `cargo` do a pushd/popd in # the pre/postBuild-hooks that need to be taken into account before gathering @@ -205,15 +239,15 @@ stdenv.mkDerivation ((removeAttrs args ["depsExtraArgs"]) // { ''; checkPhase = args.checkPhase or (let - argstr = "${stdenv.lib.optionalString (checkType == "release") "--release"} --target ${rustTarget} --frozen"; + argstr = "${lib.optionalString (checkType == "release") "--release"} --target ${target} --frozen"; threads = if cargoParallelTestThreads then "$NIX_BUILD_CORES" else "1"; in '' - ${stdenv.lib.optionalString (buildAndTestSubdir != null) "pushd ${buildAndTestSubdir}"} + ${lib.optionalString (buildAndTestSubdir != null) "pushd ${buildAndTestSubdir}"} runHook preCheck echo "Running cargo test ${argstr} -- ''${checkFlags} ''${checkFlagsArray+''${checkFlagsArray[@]}}" cargo test -j $NIX_BUILD_CORES ${argstr} -- --test-threads=${threads} ''${checkFlags} ''${checkFlagsArray+"''${checkFlagsArray[@]}"} runHook postCheck - ${stdenv.lib.optionalString (buildAndTestSubdir != null) "popd"} + ${lib.optionalString (buildAndTestSubdir != null) "popd"} ''); doCheck = args.doCheck or true; diff --git a/pkgs/build-support/rust/fetchCargoTarball.nix b/pkgs/build-support/rust/fetchCargoTarball.nix index dff5d99da9eb..c30e88d99b83 100644 --- a/pkgs/build-support/rust/fetchCargoTarball.nix +++ b/pkgs/build-support/rust/fetchCargoTarball.nix @@ -1,4 +1,4 @@ -{ stdenv, cacert, git, cargo, python3 }: +{ lib, stdenv, cacert, git, cargo, python3 }: let cargo-vendor-normalise = stdenv.mkDerivation { name = "cargo-vendor-normalise"; src = ./cargo-vendor-normalise.py; @@ -22,11 +22,17 @@ in , srcs ? [] , patches ? [] , sourceRoot -, sha256 +, hash ? "" +, sha256 ? "" , cargoUpdateHook ? "" , ... } @ args: -stdenv.mkDerivation ({ + +let hash_ = + if hash != "" then { outputHashAlgo = null; outputHash = hash; } + else if sha256 != "" then { outputHashAlgo = "sha256"; outputHash = sha256; } + else throw "fetchCargoTarball requires a hash for ${name}"; +in stdenv.mkDerivation ({ name = "${name}-vendor.tar.gz"; nativeBuildInputs = [ cacert git cargo-vendor-normalise cargo ]; @@ -40,7 +46,7 @@ stdenv.mkDerivation ({ echo echo "ERROR: The Cargo.lock file doesn't exist" echo - echo "Cargo.lock is needed to make sure that cargoSha256 doesn't change" + echo "Cargo.lock is needed to make sure that cargoHash/cargoSha256 doesn't change" echo "when the registry is updated." echo @@ -72,10 +78,9 @@ stdenv.mkDerivation ({ -czf $out $name ''; - outputHashAlgo = "sha256"; - outputHash = sha256; + inherit (hash_) outputHashAlgo outputHash; - impureEnvVars = stdenv.lib.fetchers.proxyImpureEnvVars; + impureEnvVars = lib.fetchers.proxyImpureEnvVars; } // (builtins.removeAttrs args [ "name" "sha256" "cargoUpdateHook" ])) diff --git a/pkgs/build-support/rust/sysroot/Cargo.lock b/pkgs/build-support/rust/sysroot/Cargo.lock new file mode 100644 index 000000000000..61fcef61744e --- /dev/null +++ b/pkgs/build-support/rust/sysroot/Cargo.lock @@ -0,0 +1,29 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "alloc" +version = "0.0.0" +dependencies = [ + "compiler_builtins", + "core", +] + +[[package]] +name = "compiler_builtins" +version = "0.1.36" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7cd0782e0a7da7598164153173e5a5d4d9b1da094473c98dce0ff91406112369" +dependencies = [ + "rustc-std-workspace-core", +] + +[[package]] +name = "core" +version = "0.0.0" + +[[package]] +name = "rustc-std-workspace-core" +version = "1.99.0" +dependencies = [ + "core", +] diff --git a/pkgs/build-support/rust/sysroot/cargo.py b/pkgs/build-support/rust/sysroot/cargo.py new file mode 100644 index 000000000000..09f6fba6d1c8 --- /dev/null +++ b/pkgs/build-support/rust/sysroot/cargo.py @@ -0,0 +1,45 @@ +import os +import toml + +rust_src = os.environ['RUSTC_SRC'] +orig_cargo = os.environ['ORIG_CARGO'] if 'ORIG_CARGO' in os.environ else None + +base = { + 'package': { + 'name': 'alloc', + 'version': '0.0.0', + 'authors': ['The Rust Project Developers'], + 'edition': '2018', + }, + 'dependencies': { + 'compiler_builtins': { + 'version': '0.1.0', + 'features': ['rustc-dep-of-std', 'mem'], + }, + 'core': { + 'path': os.path.join(rust_src, 'libcore'), + }, + }, + 'lib': { + 'name': 'alloc', + 'path': os.path.join(rust_src, 'liballoc/lib.rs'), + }, + 'patch': { + 'crates-io': { + 'rustc-std-workspace-core': { + 'path': os.path.join(rust_src, 'tools/rustc-std-workspace-core'), + }, + }, + }, +} + +if orig_cargo is not None: + with open(orig_cargo, 'r') as f: + src = toml.loads(f.read()) + if 'profile' in src: + base['profile'] = src['profile'] + +out = toml.dumps(base) + +with open('Cargo.toml', 'x') as f: + f.write(out) diff --git a/pkgs/build-support/rust/sysroot/default.nix b/pkgs/build-support/rust/sysroot/default.nix new file mode 100644 index 000000000000..4db7cf0dc392 --- /dev/null +++ b/pkgs/build-support/rust/sysroot/default.nix @@ -0,0 +1,41 @@ +{ stdenv, rust, rustPlatform, buildPackages }: + +{ shortTarget, originalCargoToml, target, RUSTFLAGS }: + +let + cargoSrc = stdenv.mkDerivation { + name = "cargo-src"; + preferLocalBuild = true; + phases = [ "installPhase" ]; + installPhase = '' + RUSTC_SRC=${rustPlatform.rustcSrc.override { minimalContent = false; }} ORIG_CARGO=${originalCargoToml} \ + ${buildPackages.python3.withPackages (ps: with ps; [ toml ])}/bin/python3 ${./cargo.py} + mkdir -p $out + cp Cargo.toml $out/Cargo.toml + cp ${./Cargo.lock} $out/Cargo.lock + ''; + }; +in rustPlatform.buildRustPackage { + inherit target RUSTFLAGS; + + name = "custom-sysroot"; + src = cargoSrc; + + RUSTC_BOOTSTRAP = 1; + __internal_dontAddSysroot = true; + cargoSha256 = "0y6dqfhsgk00y3fv5bnjzk0s7i30nwqc1rp0xlrk83hkh80x81mw"; + + doCheck = false; + + installPhase = '' + export LIBS_DIR=$out/lib/rustlib/${shortTarget}/lib + mkdir -p $LIBS_DIR + for f in target/${shortTarget}/release/deps/*.{rlib,rmeta}; do + cp $f $LIBS_DIR + done + + export RUST_SYSROOT=$(rustc --print=sysroot) + host=${rust.toRustTarget stdenv.buildPlatform} + cp -r $RUST_SYSROOT/lib/rustlib/$host $out + ''; +} diff --git a/pkgs/build-support/rust/sysroot/update-lockfile.sh b/pkgs/build-support/rust/sysroot/update-lockfile.sh new file mode 100755 index 000000000000..83d29832384f --- /dev/null +++ b/pkgs/build-support/rust/sysroot/update-lockfile.sh @@ -0,0 +1,21 @@ +#!/usr/bin/env nix-shell +#!nix-shell -i bash -p python3 python3.pkgs.toml cargo + +set -e + +HERE=$(dirname "${BASH_SOURCE[0]}") +NIXPKGS_ROOT="$HERE/../../../.." + +# https://unix.stackexchange.com/a/84980/390173 +tempdir=$(mktemp -d 2>/dev/null || mktemp -d -t 'update-lockfile') + +cd "$tempdir" +nix-build -E "with import (/. + \"${NIXPKGS_ROOT}\") {}; pkgs.rustPlatform.rustcSrc.override { minimalContent = false; }" +RUSTC_SRC="$(pwd)/result" python3 "$HERE/cargo.py" +RUSTC_BOOTSTRAP=1 cargo build || echo "Build failure is expected. All that's needed is the lockfile." + +cp Cargo.lock "$HERE" + +rm -rf "$tempdir" + + diff --git a/pkgs/build-support/setup-hooks/auto-patchelf.sh b/pkgs/build-support/setup-hooks/auto-patchelf.sh index 4f7c0c14304c..511371931de8 100644 --- a/pkgs/build-support/setup-hooks/auto-patchelf.sh +++ b/pkgs/build-support/setup-hooks/auto-patchelf.sh @@ -1,9 +1,20 @@ +#!/usr/bin/env bash + declare -a autoPatchelfLibs +declare -Ag autoPatchelfFailedDeps gatherLibraries() { autoPatchelfLibs+=("$1/lib") } +# wrapper around patchelf to raise proper error messages +# containing the tried file name and command +runPatchelf() { + patchelf "$@" || (echo "Command failed: patchelf $*" && exit 1) +} + +# shellcheck disable=SC2154 +# (targetOffset is referenced but not assigned.) addEnvHooks "$targetOffset" gatherLibraries isExecutable() { @@ -23,14 +34,19 @@ isExecutable() { # We cache dependencies so that we don't need to search through all of them on # every consecutive call to findDependency. -declare -a cachedDependencies +declare -Ag autoPatchelfCachedDepsAssoc +declare -ag autoPatchelfCachedDeps + addToDepCache() { - local existing - for existing in "${cachedDependencies[@]}"; do - if [ "$existing" = "$1" ]; then return; fi - done - cachedDependencies+=("$1") + if [[ ${autoPatchelfCachedDepsAssoc[$1]+f} ]]; then return; fi + + # store deps in an assoc. array for efficient lookups + # otherwise findDependency would have quadratic complexity + autoPatchelfCachedDepsAssoc["$1"]="" + + # also store deps in normal array to maintain their order + autoPatchelfCachedDeps+=("$1") } declare -gi depCacheInitialised=0 @@ -43,9 +59,8 @@ getDepsFromSo() { populateCacheWithRecursiveDeps() { local so found foundso - for so in "${cachedDependencies[@]}"; do + for so in "${autoPatchelfCachedDeps[@]}"; do for found in $(getDepsFromSo "$so"); do - local libdir="${found%/*}" local base="${found##*/}" local soname="${base%.so*}" for foundso in "${found%/*}/$soname".so*; do @@ -76,7 +91,7 @@ findDependency() { depCacheInitialised=1 fi - for dep in "${cachedDependencies[@]}"; do + for dep in "${autoPatchelfCachedDeps[@]}"; do if [ "$filename" = "${dep##*/}" ]; then if [ "$(getSoArch "$dep")" = "$arch" ]; then foundDependency="$dep" @@ -101,9 +116,12 @@ findDependency() { autoPatchelfFile() { local dep rpath="" toPatch="$1" - local interpreter="$(< "$NIX_CC/nix-support/dynamic-linker")" + local interpreter + interpreter="$(< "$NIX_CC/nix-support/dynamic-linker")" if isExecutable "$toPatch"; then - patchelf --set-interpreter "$interpreter" "$toPatch" + runPatchelf --set-interpreter "$interpreter" "$toPatch" + # shellcheck disable=SC2154 + # (runtimeDependencies is referenced but not assigned.) if [ -n "$runtimeDependencies" ]; then for dep in $runtimeDependencies; do rpath="$rpath${rpath:+:}$dep/lib" @@ -115,17 +133,19 @@ autoPatchelfFile() { # We're going to find all dependencies based on ldd output, so we need to # clear the RPATH first. - patchelf --remove-rpath "$toPatch" + runPatchelf --remove-rpath "$toPatch" - local missing="$( + # If the file is not a dynamic executable, ldd/sed will fail, + # in which case we return, since there is nothing left to do. + local missing + missing="$( ldd "$toPatch" 2> /dev/null | \ sed -n -e 's/^[\t ]*\([^ ]\+\) => not found.*/\1/p' - )" + )" || return 0 # This ensures that we get the output of all missing dependencies instead # of failing at the first one, because it's more useful when working on a # new package where you don't yet know its dependencies. - local -i depNotFound=0 for dep in $missing; do echo -n " $dep -> " >&2 @@ -134,18 +154,13 @@ autoPatchelfFile() { echo "found: $foundDependency" >&2 else echo "not found!" >&2 - depNotFound=1 + autoPatchelfFailedDeps["$dep"]="$toPatch" fi done - # This makes sure the builder fails if we didn't find a dependency, because - # the stdenv setup script is run with set -e. The actual error is emitted - # earlier in the previous loop. - [ $depNotFound -eq 0 -o -n "$autoPatchelfIgnoreMissingDeps" ] - if [ -n "$rpath" ]; then echo "setting RPATH to: $rpath" >&2 - patchelf --set-rpath "$rpath" "$toPatch" + runPatchelf --set-rpath "$rpath" "$toPatch" fi } @@ -168,10 +183,10 @@ addAutoPatchelfSearchPath() { esac done - cachedDependencies+=( - $(find "$@" "${findOpts[@]}" \! -type d \ - \( -name '*.so' -o -name '*.so.*' \)) - ) + while IFS= read -r -d '' file; do + addToDepCache "$file" + done < <(find "$@" "${findOpts[@]}" \! -type d \ + \( -name '*.so' -o -name '*.so.*' \) -print0) } autoPatchelf() { @@ -197,14 +212,9 @@ autoPatchelf() { echo "automatically fixing dependencies for ELF files" >&2 # Add all shared objects of the current output path to the start of - # cachedDependencies so that it's choosen first in findDependency. + # autoPatchelfCachedDeps so that it's chosen first in findDependency. addAutoPatchelfSearchPath ${norecurse:+--no-recurse} -- "$@" - # Here we actually have a subshell, which also means that - # $cachedDependencies is final at this point, so whenever we want to run - # findDependency outside of this, the dependency cache needs to be rebuilt - # from scratch, so keep this in mind if you want to run findDependency - # outside of this function. while IFS= read -r -d $'\0' file; do isELF "$file" || continue segmentHeaders="$(LANG=C $READELF -l "$file")" @@ -215,8 +225,26 @@ autoPatchelf() { # Skip if the executable is statically linked. [ -n "$(echo "$segmentHeaders" | grep "^ *INTERP\\>")" ] || continue fi + # Jump file if patchelf is unable to parse it + # Some programs contain binary blobs for testing, + # which are identified as ELF but fail to be parsed by patchelf + patchelf "$file" || continue autoPatchelfFile "$file" done < <(find "$@" ${norecurse:+-maxdepth 1} -type f -print0) + + # fail if any dependencies were not found and + # autoPatchelfIgnoreMissingDeps is not set + local depsMissing=0 + for failedDep in "${!autoPatchelfFailedDeps[@]}"; do + echo "autoPatchelfHook could not satisfy dependency $failedDep wanted by ${autoPatchelfFailedDeps[$failedDep]}" + depsMissing=1 + done + # shellcheck disable=SC2154 + # (autoPatchelfIgnoreMissingDeps is referenced but not assigned.) + if [[ $depsMissing == 1 && -z "$autoPatchelfIgnoreMissingDeps" ]]; then + echo "Add the missing dependencies to the build inputs or set autoPatchelfIgnoreMissingDeps=true" + exit 1 + fi } # XXX: This should ultimately use fixupOutputHooks but we currently don't have diff --git a/pkgs/build-support/setup-hooks/compress-man-pages.sh b/pkgs/build-support/setup-hooks/compress-man-pages.sh index 82e48cd8aa77..f5af76e8168f 100644 --- a/pkgs/build-support/setup-hooks/compress-man-pages.sh +++ b/pkgs/build-support/setup-hooks/compress-man-pages.sh @@ -21,6 +21,7 @@ compressManPages() { # Point symlinks to compressed manpages. find "$dir"/share/man/ -type l -a '!' -regex '.*\.\(bz2\|gz\)$' -print0 \ + | sort -z \ | while IFS= read -r -d $'\0' f do local target diff --git a/pkgs/build-support/setup-hooks/copy-desktop-items.sh b/pkgs/build-support/setup-hooks/copy-desktop-items.sh new file mode 100644 index 000000000000..f96a10f33d5c --- /dev/null +++ b/pkgs/build-support/setup-hooks/copy-desktop-items.sh @@ -0,0 +1,42 @@ +# shellcheck shell=bash + +# Setup hook that installs specified desktop items. +# +# Example usage in a derivation: +# +# { …, makeDesktopItem, copyDesktopItems, … }: +# +# let desktopItem = makeDesktopItem { … }; in +# stdenv.mkDerivation { +# … +# nativeBuildInputs = [ copyDesktopItems ]; +# +# desktopItems = [ desktopItem ]; +# … +# } +# +# This hook will copy files which are either given by full path +# or all '*.desktop' files placed inside the 'share/applications' +# folder of each `desktopItems` argument. + +postInstallHooks+=(copyDesktopItems) + +copyDesktopItems() { + if [ "${dontCopyDesktopItems-}" = 1 ]; then return; fi + + if [ -z "$desktopItems" ]; then + return + fi + + for desktopItem in $desktopItems; do + if [[ -f "$desktopItem" ]]; then + echo "Copying '$f' into '$out/share/applications'" + install -D -m 444 -t "$out"/share/applications "$f" + else + for f in "$desktopItem"/share/applications/*.desktop; do + echo "Copying '$f' into '$out/share/applications'" + install -D -m 444 -t "$out"/share/applications "$f" + done + fi + done +} diff --git a/pkgs/build-support/setup-hooks/reproducible-builds.sh b/pkgs/build-support/setup-hooks/reproducible-builds.sh new file mode 100644 index 000000000000..5b01c213fe4a --- /dev/null +++ b/pkgs/build-support/setup-hooks/reproducible-builds.sh @@ -0,0 +1,9 @@ +# Use the last part of the out path as hash input for the build. +# This should ensure that it is deterministic across rebuilds of the same +# derivation and not easily collide with other builds. +# We also truncate the hash so that it cannot cause reference cycles. +export NIX_CFLAGS_COMPILE+=" -frandom-seed=$( + outbase="${out##*/}" + randomseed="${outbase:0:10}" + echo $randomseed +)" diff --git a/pkgs/build-support/setup-hooks/strip.sh b/pkgs/build-support/setup-hooks/strip.sh index f5fa9378fd7e..c31a50eba57b 100644 --- a/pkgs/build-support/setup-hooks/strip.sh +++ b/pkgs/build-support/setup-hooks/strip.sh @@ -51,7 +51,7 @@ stripDirs() { if [ -n "${dirs}" ]; then header "stripping (with command $cmd and flags $stripFlags) in$dirs" - find $dirs -type f -print0 | xargs -0 ${xargsFlags:--r} $cmd $commonStripFlags $stripFlags 2>/dev/null || true + find $dirs -type f -exec $cmd $commonStripFlags $stripFlags '{}' \; 2>/dev/null stopNest fi } diff --git a/pkgs/build-support/setup-hooks/wrap-gapps-hook/default.nix b/pkgs/build-support/setup-hooks/wrap-gapps-hook/default.nix index 5a87893d9726..d0ea088bf71e 100644 --- a/pkgs/build-support/setup-hooks/wrap-gapps-hook/default.nix +++ b/pkgs/build-support/setup-hooks/wrap-gapps-hook/default.nix @@ -3,6 +3,7 @@ , makeSetupHook , makeWrapper , gobject-introspection +, isGraphical ? true , gtk3 , librsvg , dconf @@ -21,7 +22,7 @@ makeSetupHook { # Unfortunately, it also requires the user to have dconf # D-Bus service enabled globally (e.g. through a NixOS module). dconf.lib - ] ++ [ + ] ++ lib.optionals isGraphical [ # TODO: remove this, packages should depend on GTK explicitly. gtk3 @@ -30,6 +31,7 @@ makeSetupHook { # graphics in GTK (e.g. cross for closing window in window title bar) # so it is pretty much required for applications using GTK. librsvg + ] ++ [ # We use the wrapProgram function. makeWrapper diff --git a/pkgs/build-support/singularity-tools/default.nix b/pkgs/build-support/singularity-tools/default.nix index d937ec626682..318f5b430fef 100644 --- a/pkgs/build-support/singularity-tools/default.nix +++ b/pkgs/build-support/singularity-tools/default.nix @@ -1,4 +1,5 @@ { runCommand +, lib , stdenv , storeDir ? builtins.storeDir , writeScript @@ -7,7 +8,7 @@ , bash , vmTools , gawk -, utillinux +, util-linux , runtimeShell , e2fsprogs }: @@ -47,7 +48,7 @@ rec { runScriptFile = shellScript "run-script.sh" runScript; result = vmTools.runInLinuxVM ( runCommand "singularity-image-${name}.img" { - buildInputs = [ singularity e2fsprogs utillinux gawk ]; + buildInputs = [ singularity e2fsprogs util-linux gawk ]; layerClosure = writeReferencesToFile layer; preVM = vmTools.createEmptyImage { size = diskSize; @@ -64,7 +65,7 @@ rec { mkdir proc sys dev # Run root script - ${stdenv.lib.optionalString (runAsRoot != null) '' + ${lib.optionalString (runAsRoot != null) '' mkdir -p ./${storeDir} mount --rbind ${storeDir} ./${storeDir} unshare -imnpuf --mount-proc chroot ./ ${runAsRootFile} diff --git a/pkgs/build-support/skaware/build-skaware-package.nix b/pkgs/build-support/skaware/build-skaware-package.nix index e6e2e35789bc..7a5db942b2cb 100644 --- a/pkgs/build-support/skaware/build-skaware-package.nix +++ b/pkgs/build-support/skaware/build-skaware-package.nix @@ -1,6 +1,5 @@ -{ stdenv, cleanPackaging, fetchurl }: -let lib = stdenv.lib; -in { +{ lib, stdenv, cleanPackaging, fetchurl }: +{ # : string pname # : string @@ -98,7 +97,7 @@ in stdenv.mkDerivation { meta = { homepage = "https://skarnet.org/software/${pname}/"; inherit description platforms; - license = stdenv.lib.licenses.isc; + license = lib.licenses.isc; maintainers = with lib.maintainers; [ pmahoney Profpatsch ] ++ maintainers; }; diff --git a/pkgs/build-support/skaware/clean-packaging.nix b/pkgs/build-support/skaware/clean-packaging.nix index 762fe25c0acf..d51cbec8aeb2 100644 --- a/pkgs/build-support/skaware/clean-packaging.nix +++ b/pkgs/build-support/skaware/clean-packaging.nix @@ -3,12 +3,12 @@ # files were either discarded or moved to outputs. # This ensures nothing is forgotten and new files # are correctly handled on update. -{ stdenv, file, writeScript }: +{ lib, stdenv, file, writeScript }: let - globWith = stdenv.lib.concatMapStringsSep "\n"; + globWith = lib.concatMapStringsSep "\n"; rmNoise = noiseGlobs: globWith (f: - ''rm -rf ${f}'') noiseGlobs; + "rm -rf ${f}") noiseGlobs; mvDoc = docGlobs: globWith (f: ''mv ${f} "$DOCDIR" 2>/dev/null || true'') docGlobs; diff --git a/pkgs/build-support/substitute-files/substitute-all-files.nix b/pkgs/build-support/substitute-files/substitute-all-files.nix index 66feb695c418..682e976dcfe5 100644 --- a/pkgs/build-support/substitute-files/substitute-all-files.nix +++ b/pkgs/build-support/substitute-files/substitute-all-files.nix @@ -1,10 +1,10 @@ -{ stdenv }: +{ lib, stdenv }: args: stdenv.mkDerivation ({ name = if args ? name then args.name else baseNameOf (toString args.src); - builder = with stdenv.lib; builtins.toFile "builder.sh" '' + builder = builtins.toFile "builder.sh" '' source $stdenv/setup set -o pipefail @@ -13,7 +13,7 @@ stdenv.mkDerivation ({ args= pushd "$src" - echo -ne "${concatStringsSep "\\0" args.files}" | xargs -0 -n1 -I {} -- find {} -type f -print0 | while read -d "" line; do + echo -ne "${lib.concatStringsSep "\\0" args.files}" | xargs -0 -n1 -I {} -- find {} -type f -print0 | while read -d "" line; do mkdir -p "$out/$(dirname "$line")" substituteAll "$line" "$out/$line" done diff --git a/pkgs/build-support/templaterpm/default.nix b/pkgs/build-support/templaterpm/default.nix index 30465c740e53..ffe5b0b45816 100644 --- a/pkgs/build-support/templaterpm/default.nix +++ b/pkgs/build-support/templaterpm/default.nix @@ -1,4 +1,4 @@ -{stdenv, makeWrapper, python, toposort, rpm}: +{lib, stdenv, makeWrapper, python, toposort, rpm}: stdenv.mkDerivation { pname = "nix-template-rpm"; @@ -15,10 +15,10 @@ stdenv.mkDerivation { --set PYTHONPATH "${rpm}/lib/${python.libPrefix}/site-packages":"${toposort}/lib/${python.libPrefix}/site-packages" ''; - meta = with stdenv.lib; { + meta = with lib; { description = "Create templates of nix expressions from RPM .spec files"; maintainers = with maintainers; [ tstrobel ]; - platforms = with stdenv.lib.platforms; unix; + platforms = platforms.unix; hydraPlatforms = []; }; } diff --git a/pkgs/build-support/vm/deb/deb-closure.pl b/pkgs/build-support/vm/deb/deb-closure.pl index bed397d6f07e..fe23025df1d8 100644 --- a/pkgs/build-support/vm/deb/deb-closure.pl +++ b/pkgs/build-support/vm/deb/deb-closure.pl @@ -50,7 +50,7 @@ sub getDeps { # virtual dependencies. my %provides; -foreach my $cdata (values %packages) { +foreach my $cdata (sort {$a->{Package} cmp $b->{Package}} (values %packages)) { if (defined $cdata->{Provides}) { my @provides = getDeps(Dpkg::Deps::deps_parse($cdata->{Provides})); foreach my $name (@provides) { diff --git a/pkgs/build-support/vm/default.nix b/pkgs/build-support/vm/default.nix index 909cdc6da044..759245aed1ae 100644 --- a/pkgs/build-support/vm/default.nix +++ b/pkgs/build-support/vm/default.nix @@ -1,6 +1,7 @@ -{ pkgs +{ lib +, pkgs , kernel ? pkgs.linux -, img ? pkgs.stdenv.hostPlatform.platform.kernelTarget +, img ? pkgs.stdenv.hostPlatform.linux-kernel.target , storeDir ? builtins.storeDir , rootModules ? [ "virtio_pci" "virtio_mmio" "virtio_blk" "virtio_balloon" "virtio_rng" "ext4" "unix" "9p" "9pnet_virtio" "crc32c_generic" ] @@ -151,7 +152,7 @@ rec { # Set the system time from the hardware clock. Works around an # apparent KVM > 1.5.2 bug. - ${pkgs.utillinux}/bin/hwclock -s + ${pkgs.util-linux}/bin/hwclock -s export NIX_STORE=${storeDir} export NIX_BUILD_TOP=/tmp @@ -270,7 +271,7 @@ rec { defaultCreateRootFS = '' mkdir /mnt ${e2fsprogs}/bin/mkfs.ext4 /dev/${hd} - ${utillinux}/bin/mount -t ext4 /dev/${hd} /mnt + ${util-linux}/bin/mount -t ext4 /dev/${hd} /mnt if test -e /mnt/.debug; then exec ${bash}/bin/sh @@ -317,7 +318,7 @@ rec { with pkgs; runInLinuxVM ( stdenv.mkDerivation { name = "extract-file"; - buildInputs = [ utillinux ]; + buildInputs = [ util-linux ]; buildCommand = '' ln -s ${kernel}/lib /lib ${kmod}/bin/modprobe loop @@ -342,7 +343,7 @@ rec { with pkgs; runInLinuxVM ( stdenv.mkDerivation { name = "extract-file-mtd"; - buildInputs = [ utillinux mtdutils ]; + buildInputs = [ util-linux mtdutils ]; buildCommand = '' ln -s ${kernel}/lib /lib ${kmod}/bin/modprobe mtd @@ -417,7 +418,7 @@ rec { # Make the Nix store available in /mnt, because that's where the RPMs live. mkdir -p /mnt${storeDir} - ${utillinux}/bin/mount -o bind ${storeDir} /mnt${storeDir} + ${util-linux}/bin/mount -o bind ${storeDir} /mnt${storeDir} # Newer distributions like Fedora 18 require /lib etc. to be # symlinked to /usr. @@ -427,7 +428,7 @@ rec { ln -s /usr/sbin /mnt/sbin ln -s /usr/lib /mnt/lib ln -s /usr/lib64 /mnt/lib64 - ${utillinux}/bin/mount -t proc none /mnt/proc + ${util-linux}/bin/mount -t proc none /mnt/proc ''} echo "unpacking RPMs..." @@ -445,7 +446,7 @@ rec { PATH=/usr/bin:/bin:/usr/sbin:/sbin $chroot /mnt \ rpm --initdb - ${utillinux}/bin/mount -o bind /tmp /mnt/tmp + ${util-linux}/bin/mount -o bind /tmp /mnt/tmp echo "installing RPMs..." PATH=/usr/bin:/bin:/usr/sbin:/sbin $chroot /mnt \ @@ -456,8 +457,8 @@ rec { rm /mnt/.debug - ${utillinux}/bin/umount /mnt${storeDir} /mnt/tmp ${lib.optionalString unifiedSystemDir "/mnt/proc"} - ${utillinux}/bin/umount /mnt + ${util-linux}/bin/umount /mnt${storeDir} /mnt/tmp ${lib.optionalString unifiedSystemDir "/mnt/proc"} + ${util-linux}/bin/umount /mnt ''; passthru = { inherit fullName; }; @@ -572,7 +573,7 @@ rec { buildCommand = '' ${createRootFS} - PATH=$PATH:${stdenv.lib.makeBinPath [ dpkg dpkg glibc lzma ]} + PATH=$PATH:${lib.makeBinPath [ dpkg dpkg glibc lzma ]} # Unpack the .debs. We do this to prevent pre-install scripts # (which have lots of circular dependencies) from barfing. @@ -587,9 +588,9 @@ rec { # Make the Nix store available in /mnt, because that's where the .debs live. mkdir -p /mnt/inst${storeDir} - ${utillinux}/bin/mount -o bind ${storeDir} /mnt/inst${storeDir} - ${utillinux}/bin/mount -o bind /proc /mnt/proc - ${utillinux}/bin/mount -o bind /dev /mnt/dev + ${util-linux}/bin/mount -o bind ${storeDir} /mnt/inst${storeDir} + ${util-linux}/bin/mount -o bind /proc /mnt/proc + ${util-linux}/bin/mount -o bind /dev /mnt/dev # Misc. files/directories assumed by various packages. echo "initialising Dpkg DB..." @@ -635,10 +636,10 @@ rec { rm /mnt/.debug - ${utillinux}/bin/umount /mnt/inst${storeDir} - ${utillinux}/bin/umount /mnt/proc - ${utillinux}/bin/umount /mnt/dev - ${utillinux}/bin/umount /mnt + ${util-linux}/bin/umount /mnt/inst${storeDir} + ${util-linux}/bin/umount /mnt/proc + ${util-linux}/bin/umount /mnt/dev + ${util-linux}/bin/umount /mnt ''; passthru = { inherit fullName; }; @@ -1196,4 +1197,4 @@ rec { `debDistros' sets. */ diskImages = lib.mapAttrs (name: f: f {}) diskImageFuns; -} // import ./windows pkgs +} diff --git a/pkgs/build-support/vm/windows/bootstrap.nix b/pkgs/build-support/vm/windows/bootstrap.nix deleted file mode 100644 index 3b06d8f47490..000000000000 --- a/pkgs/build-support/vm/windows/bootstrap.nix +++ /dev/null @@ -1,83 +0,0 @@ -{ stdenv, fetchurl, vmTools, writeScript, writeText, runCommand, makeInitrd -, python, perl, coreutils, dosfstools, gzip, mtools, netcat-gnu, openssh, qemu -, samba, socat, vde2, cdrkit, pathsFromGraph, gnugrep -}: - -{ isoFile, productKey, arch ? null }: - -with stdenv.lib; - -let - controller = import ./controller { - inherit stdenv writeScript vmTools makeInitrd; - inherit samba vde2 openssh socat netcat-gnu coreutils gzip gnugrep; - }; - - mkCygwinImage = import ./cygwin-iso { - inherit stdenv fetchurl runCommand python perl cdrkit pathsFromGraph; - arch = let - defaultArch = if stdenv.is64bit then "x86_64" else "i686"; - in if arch == null then defaultArch else arch; - }; - - installer = import ./install { - inherit controller mkCygwinImage; - inherit stdenv runCommand openssh qemu writeText dosfstools mtools; - }; -in rec { - installedVM = installer { - inherit isoFile productKey; - }; - - runInVM = img: attrs: controller (attrs // { - inherit (installedVM) sshKey; - qemuArgs = attrs.qemuArgs or [] ++ [ - "-boot order=c" - "-drive file=${img},index=0,media=disk" - ]; - }); - - runAndSuspend = let - drives = { - s = { - source = "nixstore"; - target = "/nix/store"; - }; - x = { - source = "xchg"; - target = "/tmp/xchg"; - }; - }; - - genDriveCmds = letter: { source, target }: [ - "net use ${letter}: '\\\\192.168.0.2\\${source}' /persistent:yes" - "mkdir -p '${target}'" - "mount -o bind '/cygdrive/${letter}' '${target}'" - "echo '/cygdrive/${letter} ${target} none bind 0 0' >> /etc/fstab" - ]; - in runInVM "winvm.img" { - command = concatStringsSep " && " ([ - "net config server /autodisconnect:-1" - ] ++ concatLists (mapAttrsToList genDriveCmds drives)); - suspendTo = "state.gz"; - }; - - suspendedVM = stdenv.mkDerivation { - name = "cygwin-suspended-vm"; - buildCommand = '' - ${qemu}/bin/qemu-img create \ - -b "${installedVM}/disk.img" \ - -f qcow2 winvm.img - ${runAndSuspend} - mkdir -p "$out" - cp winvm.img "$out/disk.img" - cp state.gz "$out/state.gz" - ''; - }; - - resumeAndRun = command: runInVM "${suspendedVM}/disk.img" { - resumeFrom = "${suspendedVM}/state.gz"; - qemuArgs = singleton "-snapshot"; - inherit command; - }; -} diff --git a/pkgs/build-support/vm/windows/controller/default.nix b/pkgs/build-support/vm/windows/controller/default.nix deleted file mode 100644 index 9d13983a2833..000000000000 --- a/pkgs/build-support/vm/windows/controller/default.nix +++ /dev/null @@ -1,263 +0,0 @@ -{ stdenv, writeScript, vmTools, makeInitrd -, samba, vde2, openssh, socat, netcat-gnu, coreutils, gnugrep, gzip -, runtimeShell -}: - -{ sshKey -, qemuArgs ? [] -, command ? "sync" -, suspendTo ? null -, resumeFrom ? null -, installMode ? false -}: - -with stdenv.lib; - -let - preInitScript = writeScript "preinit.sh" '' - #!${vmTools.initrdUtils}/bin/ash -e - export PATH=${vmTools.initrdUtils}/bin - mount -t proc none /proc - mount -t sysfs none /sys - for arg in $(cat /proc/cmdline); do - if [ "x''${arg#command=}" != "x$arg" ]; then - command="''${arg#command=}" - fi - done - - for i in $(cat ${modulesClosure}/insmod-list); do - insmod $i - done - - mkdir -p /dev /fs - - mount -t tmpfs none /dev - mknod /dev/null c 1 3 - mknod /dev/zero c 1 5 - mknod /dev/random c 1 8 - mknod /dev/urandom c 1 9 - mknod /dev/tty c 5 0 - - ifconfig lo up - ifconfig eth0 up 192.168.0.2 - - mount -t tmpfs none /fs - mkdir -p /fs/nix/store /fs/xchg /fs/dev /fs/sys /fs/proc /fs/etc /fs/tmp - - mount -o bind /dev /fs/dev - mount -t sysfs none /fs/sys - mount -t proc none /fs/proc - - mount -t 9p \ - -o trans=virtio,version=9p2000.L,cache=loose \ - store /fs/nix/store - - mount -t 9p \ - -o trans=virtio,version=9p2000.L \ - xchg /fs/xchg - - echo root:x:0:0::/root:/bin/false > /fs/etc/passwd - - set +e - chroot /fs $command $out - echo $? > /fs/xchg/in-vm-exit - - poweroff -f - ''; - - initrd = makeInitrd { - contents = singleton { - object = preInitScript; - symlink = "/init"; - }; - }; - - loopForever = "while :; do ${coreutils}/bin/sleep 1; done"; - - initScript = writeScript "init.sh" ('' - #!${runtimeShell} - ${coreutils}/bin/cp -L "${sshKey}" /ssh.key - ${coreutils}/bin/chmod 600 /ssh.key - '' + (if installMode then '' - echo -n "Waiting for Windows installation to finish..." - while ! ${netcat-gnu}/bin/netcat -z 192.168.0.1 22; do - echo -n . - # Print a dot every 10 seconds only to shorten line length. - ${coreutils}/bin/sleep 10 - done - ${coreutils}/bin/touch /xchg/waiting_done - echo " success." - # Loop forever, because this VM is going to be killed. - ${loopForever} - '' else '' - ${coreutils}/bin/mkdir -p /etc/samba /etc/samba/private \ - /var/lib/samba /var/log /var/run - ${coreutils}/bin/cat > /etc/samba/smb.conf <<CONFIG - [global] - security = user - map to guest = Bad User - guest account = root - workgroup = cygwin - netbios name = controller - server string = %h - log level = 1 - max log size = 1000 - log file = /var/log/samba.log - - [nixstore] - path = /nix/store - writable = yes - guest ok = yes - - [xchg] - path = /xchg - writable = yes - guest ok = yes - CONFIG - - ${samba}/sbin/nmbd -D - ${samba}/sbin/smbd -D - - echo -n "Waiting for Windows VM to become available..." - while ! ${netcat-gnu}/bin/netcat -z 192.168.0.1 22; do - echo -n . - ${coreutils}/bin/sleep 1 - done - ${coreutils}/bin/touch /xchg/waiting_done - echo " success." - - ${openssh}/bin/ssh \ - -o UserKnownHostsFile=/dev/null \ - -o StrictHostKeyChecking=no \ - -i /ssh.key \ - -l Administrator \ - 192.168.0.1 -- ${lib.escapeShellArg command} - '') + optionalString (suspendTo != null) '' - ${coreutils}/bin/touch /xchg/suspend_now - ${loopForever} - ''); - - kernelAppend = concatStringsSep " " [ - "panic=1" - "loglevel=4" - "console=tty1" - "console=ttyS0" - "command=${initScript}" - ]; - - controllerQemuArgs = concatStringsSep " " (maybeKvm64 ++ [ - "-pidfile $CTRLVM_PIDFILE" - "-nographic" - "-no-reboot" - "-virtfs local,path=/nix/store,security_model=none,mount_tag=store" - "-virtfs local,path=$XCHG_DIR,security_model=none,mount_tag=xchg" - "-kernel ${modulesClosure.kernel}/bzImage" - "-initrd ${initrd}/initrd" - "-append \"${kernelAppend}\"" - "-net nic,vlan=0,macaddr=52:54:00:12:01:02,model=virtio" - "-net vde,vlan=0,sock=$QEMU_VDE_SOCKET" - ]); - - maybeKvm64 = optional (stdenv.hostPlatform.system == "x86_64-linux") "-cpu kvm64"; - - cygwinQemuArgs = concatStringsSep " " (maybeKvm64 ++ [ - "-monitor unix:$MONITOR_SOCKET,server,nowait" - "-pidfile $WINVM_PIDFILE" - "-nographic" - "-net nic,vlan=0,macaddr=52:54:00:12:01:01" - "-net vde,vlan=0,sock=$QEMU_VDE_SOCKET" - "-rtc base=2010-01-01,clock=vm" - ] ++ qemuArgs ++ optionals (resumeFrom != null) [ - "-incoming 'exec: ${gzip}/bin/gzip -c -d \"${resumeFrom}\"'" - ]); - - modulesClosure = overrideDerivation vmTools.modulesClosure (o: { - rootModules = o.rootModules ++ singleton "virtio_net"; - }); - - preVM = '' - (set; declare -p) > saved-env - XCHG_DIR="$(${coreutils}/bin/mktemp -d nix-vm.XXXXXXXXXX --tmpdir)" - ${coreutils}/bin/mv saved-env "$XCHG_DIR/" - - eval "$preVM" - - QEMU_VDE_SOCKET="$(pwd)/vde.ctl" - MONITOR_SOCKET="$(pwd)/monitor" - WINVM_PIDFILE="$(pwd)/winvm.pid" - CTRLVM_PIDFILE="$(pwd)/ctrlvm.pid" - ${vde2}/bin/vde_switch -s "$QEMU_VDE_SOCKET" --dirmode 0700 & - echo 'alive?' | ${socat}/bin/socat - \ - UNIX-CONNECT:$QEMU_VDE_SOCKET/ctl,retry=20 - ''; - - vmExec = '' - ${vmTools.qemuProg} ${controllerQemuArgs} & - ${vmTools.qemuProg} ${cygwinQemuArgs} & - echo -n "Waiting for VMs to start up..." - timeout=60 - while ! test -e "$WINVM_PIDFILE" -a -e "$CTRLVM_PIDFILE"; do - timeout=$(($timeout - 1)) - echo -n . - if test $timeout -le 0; then - echo " timed out." - exit 1 - fi - ${coreutils}/bin/sleep 1 - done - echo " done." - ''; - - checkDropOut = '' - if ! test -e "$XCHG_DIR/waiting_done" && - ! kill -0 $(< "$WINVM_PIDFILE"); then - echo "Windows VM has dropped out early, bailing out!" >&2 - exit 1 - fi - ''; - - toMonitor = "${socat}/bin/socat - UNIX-CONNECT:$MONITOR_SOCKET"; - - postVM = if suspendTo != null then '' - while ! test -e "$XCHG_DIR/suspend_now"; do - ${checkDropOut} - ${coreutils}/bin/sleep 1 - done - ${toMonitor} <<CMD - stop - migrate_set_speed 4095m - migrate "exec:${gzip}/bin/gzip -c > '${suspendTo}'" - CMD - echo -n "Waiting for memory dump to finish..." - while ! echo info migrate | ${toMonitor} | \ - ${gnugrep}/bin/grep -qi '^migration *status: *complete'; do - ${coreutils}/bin/sleep 1 - echo -n . - done - echo " done." - echo quit | ${toMonitor} - wait $(< "$WINVM_PIDFILE") - eval "$postVM" - exit 0 - '' else if installMode then '' - wait $(< "$WINVM_PIDFILE") - eval "$postVM" - exit 0 - '' else '' - while kill -0 $(< "$CTRLVM_PIDFILE"); do - ${checkDropOut} - done - if ! test -e "$XCHG_DIR/in-vm-exit"; then - echo "Virtual machine didn't produce an exit code." - exit 1 - fi - eval "$postVM" - exit $(< "$XCHG_DIR/in-vm-exit") - ''; - -in writeScript "run-cygwin-vm.sh" '' - #!${stdenv.shell} -e - ${preVM} - ${vmExec} - ${postVM} -'' diff --git a/pkgs/build-support/vm/windows/cygwin-iso/default.nix b/pkgs/build-support/vm/windows/cygwin-iso/default.nix deleted file mode 100644 index 76cd41a75bc7..000000000000 --- a/pkgs/build-support/vm/windows/cygwin-iso/default.nix +++ /dev/null @@ -1,56 +0,0 @@ -{ stdenv, fetchurl, runCommand, python, perl, xorriso, pathsFromGraph -, arch ? "x86_64" -}: - -{ packages ? [] -, mirror ? "http://ftp.gwdg.de/pub/linux/sources.redhat.com/cygwin" -, extraContents ? [] -}: - -let - cygPkgList = if arch == "x86_64" then fetchurl { - url = "${mirror}/x86_64/setup.ini"; - sha256 = "0arrxvxbl85l82iy648snx5cl952w791p45p0dfg1xpiaf96cbkj"; - } else fetchurl { - url = "${mirror}/x86/setup.ini"; - sha256 = "1fayx34868vd5h2nah7chiw65sl3i9qzrwvs7lrlv2h8k412vb69"; - }; - - cygwinCross = (import ../../../../.. { - localSystem = stdenv.hostPlatform; - crossSystem = { - libc = "msvcrt"; - platform = {}; - inherit arch; - config = "${arch}-w64-mingw32"; - }; - }).windows.cygwinSetup; - - makeCygwinClosure = { packages, packageList }: let - expr = import (runCommand "cygwin.nix" { buildInputs = [ python ]; } '' - python ${./mkclosure.py} "${packages}" ${toString packageList} > "$out" - ''); - gen = { url, hash }: { - source = fetchurl { - url = "${mirror}/${url}"; - sha512 = hash; - }; - target = url; - }; - in map gen expr; - -in import ../../../../../nixos/lib/make-iso9660-image.nix { - inherit stdenv perl xorriso pathsFromGraph; - syslinux = null; - contents = [ - { source = "${cygwinCross}/bin/setup.exe"; - target = "setup.exe"; - } - { source = cygPkgList; - target = "setup.ini"; - } - ] ++ makeCygwinClosure { - packages = cygPkgList; - packageList = packages; - } ++ extraContents; -} diff --git a/pkgs/build-support/vm/windows/cygwin-iso/mkclosure.py b/pkgs/build-support/vm/windows/cygwin-iso/mkclosure.py deleted file mode 100644 index 4c0d67c43bac..000000000000 --- a/pkgs/build-support/vm/windows/cygwin-iso/mkclosure.py +++ /dev/null @@ -1,78 +0,0 @@ -# Ugliest Python code I've ever written. -- aszlig -import sys - -def get_plist(path): - in_pack = False - in_str = False - current_key = None - buf = "" - packages = {} - package_name = None - package_attrs = {} - with open(path, 'r') as setup: - for line in setup: - if in_str and line.rstrip().endswith('"'): - package_attrs[current_key] = buf + line.rstrip()[:-1] - in_str = False - continue - elif in_str: - buf += line - continue - - if line.startswith('@'): - in_pack = True - package_name = line[1:].strip() - package_attrs = {} - elif in_pack and ':' in line: - key, value = line.split(':', 1) - if value.lstrip().startswith('"'): - if value.lstrip()[1:].rstrip().endswith('"'): - value = value.strip().strip('"') - else: - in_str = True - current_key = key.strip().lower() - buf = value.lstrip()[1:] - continue - package_attrs[key.strip().lower()] = value.strip() - elif in_pack: - in_pack = False - packages[package_name] = package_attrs - return packages - -def main(): - packages = get_plist(sys.argv[1]) - to_include = set() - - def traverse(package): - to_include.add(package) - attrs = packages.get(package, {}) - deps = attrs.get('requires', '').split() - for new_dep in set(deps) - to_include: - traverse(new_dep) - - map(traverse, sys.argv[2:]) - - sys.stdout.write('[\n') - for package, attrs in packages.iteritems(): - if package not in to_include: - cats = [c.lower() for c in attrs.get('category', '').split()] - if 'base' not in cats: - continue - - install_line = attrs.get('install') - if install_line is None: - continue - - url, size, hash = install_line.split(' ', 2) - - pack = [ - ' {', - ' url = "{0}";'.format(url), - ' hash = "{0}";'.format(hash), - ' }', - ]; - sys.stdout.write('\n'.join(pack) + '\n') - sys.stdout.write(']\n') - -if __name__ == '__main__': - main() diff --git a/pkgs/build-support/vm/windows/default.nix b/pkgs/build-support/vm/windows/default.nix deleted file mode 100644 index 309241c36dee..000000000000 --- a/pkgs/build-support/vm/windows/default.nix +++ /dev/null @@ -1,44 +0,0 @@ -#note: the hardcoded /bin/sh is required for the VM's cygwin shell -pkgs: - -let - bootstrapper = import ./bootstrap.nix { - inherit (pkgs) stdenv vmTools writeScript writeText runCommand makeInitrd; - inherit (pkgs) coreutils dosfstools gzip mtools netcat-gnu openssh qemu samba; - inherit (pkgs) socat vde2 fetchurl python perl cdrkit pathsFromGraph; - inherit (pkgs) gnugrep; - }; - - builder = '' - source /tmp/xchg/saved-env 2> /dev/null || true - export NIX_STORE=/nix/store - export NIX_BUILD_TOP=/tmp - export TMPDIR=/tmp - export PATH=/empty - cd "$NIX_BUILD_TOP" - exec $origBuilder $origArgs - ''; - -in { - runInWindowsVM = drv: pkgs.lib.overrideDerivation drv (attrs: let - bootstrap = bootstrapper attrs.windowsImage; - in { - requiredSystemFeatures = [ "kvm" ]; - builder = pkgs.stdenv.shell; - args = ["-e" (bootstrap.resumeAndRun builder)]; - windowsImage = bootstrap.suspendedVM; - origArgs = attrs.args; - origBuilder = if attrs.builder == attrs.stdenv.shell - then "/bin/sh" - else attrs.builder; - - postHook = '' - PATH=/usr/bin:/bin:/usr/sbin:/sbin - SHELL=/bin/sh - eval "$origPostHook" - ''; - - origPostHook = attrs.postHook or ""; - fixupPhase = ":"; - }); -} diff --git a/pkgs/build-support/vm/windows/install/default.nix b/pkgs/build-support/vm/windows/install/default.nix deleted file mode 100644 index fe8e8f61de02..000000000000 --- a/pkgs/build-support/vm/windows/install/default.nix +++ /dev/null @@ -1,74 +0,0 @@ -{ stdenv, runCommand, openssh, qemu, controller, mkCygwinImage -, writeText, dosfstools, mtools -}: - -{ isoFile -, productKey -}: - -let - bootstrapAfterLogin = runCommand "bootstrap.sh" {} '' - cat > "$out" <<EOF - mkdir -p ~/.ssh - cat > ~/.ssh/authorized_keys <<PUBKEY - $(cat "${cygwinSshKey}/key.pub") - PUBKEY - ssh-host-config -y -c 'binmode ntsec' -w dummy - cygrunsrv -S sshd - shutdown -s 5 - EOF - ''; - - cygwinSshKey = stdenv.mkDerivation { - name = "snakeoil-ssh-cygwin"; - buildCommand = '' - mkdir -p "$out" - ${openssh}/bin/ssh-keygen -t ecdsa -f "$out/key" -N "" - ''; - }; - - sshKey = "${cygwinSshKey}/key"; - - packages = [ "openssh" "shutdown" ]; - - floppyCreator = import ./unattended-image.nix { - inherit stdenv writeText dosfstools mtools; - }; - - instfloppy = floppyCreator { - cygwinPackages = packages; - inherit productKey; - }; - - cygiso = mkCygwinImage { - inherit packages; - extraContents = stdenv.lib.singleton { - source = bootstrapAfterLogin; - target = "bootstrap.sh"; - }; - }; - - installController = controller { - inherit sshKey; - installMode = true; - qemuArgs = [ - "-boot order=c,once=d" - "-drive file=${instfloppy},readonly,index=0,if=floppy" - "-drive file=winvm.img,index=0,media=disk" - "-drive file=${isoFile},index=1,media=cdrom" - "-drive file=${cygiso}/iso/cd.iso,index=2,media=cdrom" - ]; - }; - -in stdenv.mkDerivation { - name = "cygwin-base-vm"; - buildCommand = '' - ${qemu}/bin/qemu-img create -f qcow2 winvm.img 2G - ${installController} - mkdir -p "$out" - cp winvm.img "$out/disk.img" - ''; - passthru = { - inherit sshKey; - }; -} diff --git a/pkgs/build-support/vm/windows/install/unattended-image.nix b/pkgs/build-support/vm/windows/install/unattended-image.nix deleted file mode 100644 index 5b1ff84cf44d..000000000000 --- a/pkgs/build-support/vm/windows/install/unattended-image.nix +++ /dev/null @@ -1,123 +0,0 @@ -{ stdenv, writeText, dosfstools, mtools }: - -{ productKey -, shExecAfterwards ? "E:\\bootstrap.sh" -, cygwinRoot ? "C:\\cygwin" -, cygwinSetup ? "E:\\setup.exe" -, cygwinRepository ? "E:\\" -, cygwinPackages ? [ "openssh" ] -}: - -let - afterSetup = [ - cygwinSetup - "-L -n -q" - "-l ${cygwinRepository}" - "-R ${cygwinRoot}" - "-C base" - ] ++ map (p: "-P ${p}") cygwinPackages; - - winXpUnattended = writeText "winnt.sif" '' - [Data] - AutoPartition = 1 - AutomaticUpdates = 0 - MsDosInitiated = 0 - UnattendedInstall = Yes - - [Unattended] - DUDisable = Yes - DriverSigningPolicy = Ignore - Hibernation = No - OemPreinstall = No - OemSkipEula = Yes - Repartition = Yes - TargetPath = \WINDOWS - UnattendMode = FullUnattended - UnattendSwitch = Yes - WaitForReboot = No - - [GuiUnattended] - AdminPassword = "nopasswd" - AutoLogon = Yes - AutoLogonCount = 1 - OEMSkipRegional = 1 - OemSkipWelcome = 1 - ServerWelcome = No - TimeZone = 85 - - [UserData] - ComputerName = "cygwin" - FullName = "cygwin" - OrgName = "" - ProductKey = "${productKey}" - - [Networking] - InstallDefaultComponents = Yes - - [Identification] - JoinWorkgroup = cygwin - - [NetAdapters] - PrimaryAdapter = params.PrimaryAdapter - - [params.PrimaryAdapter] - InfID = * - - [params.MS_MSClient] - - [NetProtocols] - MS_TCPIP = params.MS_TCPIP - - [params.MS_TCPIP] - AdapterSections=params.MS_TCPIP.PrimaryAdapter - - [params.MS_TCPIP.PrimaryAdapter] - DHCP = No - IPAddress = 192.168.0.1 - SpecificTo = PrimaryAdapter - SubnetMask = 255.255.255.0 - WINS = No - - ; Turn off all components - [Components] - ${stdenv.lib.concatMapStrings (comp: "${comp} = Off\n") [ - "AccessOpt" "Appsrv_console" "Aspnet" "BitsServerExtensionsISAPI" - "BitsServerExtensionsManager" "Calc" "Certsrv" "Certsrv_client" - "Certsrv_server" "Charmap" "Chat" "Clipbook" "Cluster" "Complusnetwork" - "Deskpaper" "Dialer" "Dtcnetwork" "Fax" "Fp_extensions" "Fp_vdir_deploy" - "Freecell" "Hearts" "Hypertrm" "IEAccess" "IEHardenAdmin" "IEHardenUser" - "Iis_asp" "Iis_common" "Iis_ftp" "Iis_inetmgr" "Iis_internetdataconnector" - "Iis_nntp" "Iis_serversideincludes" "Iis_smtp" "Iis_webdav" "Iis_www" - "Indexsrv_system" "Inetprint" "Licenseserver" "Media_clips" "Media_utopia" - "Minesweeper" "Mousepoint" "Msmq_ADIntegrated" "Msmq_Core" - "Msmq_HTTPSupport" "Msmq_LocalStorage" "Msmq_MQDSService" - "Msmq_RoutingSupport" "Msmq_TriggersService" "Msnexplr" "Mswordpad" - "Netcis" "Netoc" "OEAccess" "Objectpkg" "Paint" "Pinball" "Pop3Admin" - "Pop3Service" "Pop3Srv" "Rec" "Reminst" "Rootautoupdate" "Rstorage" "SCW" - "Sakit_web" "Solitaire" "Spider" "TSWebClient" "Templates" - "TerminalServer" "UDDIAdmin" "UDDIDatabase" "UDDIWeb" "Vol" "WMAccess" - "WMPOCM" "WbemMSI" "Wms" "Wms_admin_asp" "Wms_admin_mmc" "Wms_isapi" - "Wms_server" "Zonegames" - ]} - - [WindowsFirewall] - Profiles = WindowsFirewall.TurnOffFirewall - - [WindowsFirewall.TurnOffFirewall] - Mode = 0 - - [SetupParams] - UserExecute = "${stdenv.lib.concatStringsSep " " afterSetup}" - - [GuiRunOnce] - Command0 = "${cygwinRoot}\bin\bash -l ${shExecAfterwards}" - ''; - -in stdenv.mkDerivation { - name = "unattended-floppy.img"; - buildCommand = '' - dd if=/dev/zero of="$out" count=1440 bs=1024 - ${dosfstools}/sbin/mkfs.msdos "$out" - ${mtools}/bin/mcopy -i "$out" "${winXpUnattended}" ::winnt.sif - ''; -} diff --git a/pkgs/build-support/writers/default.nix b/pkgs/build-support/writers/default.nix index 9c709921d210..f853f37fec63 100644 --- a/pkgs/build-support/writers/default.nix +++ b/pkgs/build-support/writers/default.nix @@ -63,7 +63,7 @@ rec { # # Examples: # writeSimpleC = makeBinWriter { compileScript = name: "gcc -o $out $contentPath"; } - makeBinWriter = { compileScript }: nameOrPath: content: + makeBinWriter = { compileScript, strip ? true }: nameOrPath: content: assert lib.or (types.path.check nameOrPath) (builtins.match "([0-9A-Za-z._])[0-9A-Za-z._-]*" nameOrPath != null); assert lib.or (types.path.check content) (types.str.check content); let @@ -76,6 +76,8 @@ rec { contentPath = content; }) '' ${compileScript} + ${lib.optionalString strip + "${pkgs.binutils-unwrapped}/bin/strip --strip-unneeded $out"} ${optionalString (types.path.check nameOrPath) '' mv $out tmp mkdir -p $out/$(dirname "${nameOrPath}") @@ -109,7 +111,10 @@ rec { # return 0; # } # '' - writeC = name: { libraries ? [] }: + writeC = name: { + libraries ? [], + strip ? true + }: makeBinWriter { compileScript = '' PATH=${makeBinPath [ @@ -117,7 +122,7 @@ rec { pkgs.coreutils pkgs.findutils pkgs.gcc - pkgs.pkgconfig + pkgs.pkg-config ]} export PKG_CONFIG_PATH=${concatMapStringsSep ":" (pkg: "${pkg}/lib/pkgconfig") libraries} gcc \ @@ -131,8 +136,8 @@ rec { -Wall \ -x c \ "$contentPath" - strip --strip-unneeded "$out" ''; + inherit strip; } name; # writeCBin takes the same arguments as writeC but outputs a directory (like writeScriptBin) @@ -165,21 +170,38 @@ rec { writeHaskell = name: { libraries ? [], ghc ? pkgs.ghc, - ghcArgs ? [] + ghcArgs ? [], + strip ? true }: makeBinWriter { compileScript = '' cp $contentPath tmp.hs ${ghc.withPackages (_: libraries )}/bin/ghc ${lib.escapeShellArgs ghcArgs} tmp.hs mv tmp $out - ${pkgs.binutils-unwrapped}/bin/strip --strip-unneeded "$out" ''; + inherit strip; } name; # writeHaskellBin takes the same arguments as writeHaskell but outputs a directory (like writeScriptBin) writeHaskellBin = name: writeHaskell "/bin/${name}"; + writeRust = name: { + rustc ? pkgs.rustc, + rustcArgs ? [], + strip ? true + }: + makeBinWriter { + compileScript = '' + cp "$contentPath" tmp.rs + PATH=${makeBinPath [pkgs.gcc]} ${lib.getBin rustc}/bin/rustc ${lib.escapeShellArgs rustcArgs} -o "$out" tmp.rs + ''; + inherit strip; + } name; + + writeRustBin = name: + writeRust "/bin/${name}"; + # writeJS takes a name an attributeset with libraries and some JavaScript sourcecode and # returns an executable # diff --git a/pkgs/build-support/writers/test.nix b/pkgs/build-support/writers/test.nix index d284bda43d05..7b7a698376a1 100644 --- a/pkgs/build-support/writers/test.nix +++ b/pkgs/build-support/writers/test.nix @@ -31,6 +31,12 @@ let test '~' = '~' && echo 'success' ''; + rust = writeRustBin "test_writers" {} '' + fn main(){ + println!("success") + } + ''; + haskell = writeHaskellBin "test_writers" { libraries = [ haskellPackages.acme-default ]; } '' import Data.Default @@ -190,7 +196,7 @@ let in runCommand "test-writers" { passthru = { inherit writeTest bin simple; }; - meta.platforms = stdenv.lib.platforms.all; + meta.platforms = lib.platforms.all; } '' ${lib.concatMapStringsSep "\n" (test: writeTest "success" "${test}/bin/test_writers") (lib.attrValues bin)} ${lib.concatMapStringsSep "\n" (test: writeTest "success" test) (lib.attrValues simple)} |