diff options
Diffstat (limited to 'pkgs/build-support')
21 files changed, 348 insertions, 345 deletions
diff --git a/pkgs/build-support/bintools-wrapper/default.nix b/pkgs/build-support/bintools-wrapper/default.nix index 0dcae204824d..bb0e6b82aa5d 100644 --- a/pkgs/build-support/bintools-wrapper/default.nix +++ b/pkgs/build-support/bintools-wrapper/default.nix @@ -164,7 +164,21 @@ stdenv.mkDerivation { set +u ''; - propagatedBuildInputs = extraPackages; + emulation = let + fmt = + /**/ if targetPlatform.isDarwin then "mach-o" + else if targetPlatform.isWindows then "pe" + else "elf" + toString targetPlatform.parsed.cpu.bits; + endianPrefix = if targetPlatform.isBigEndian then "big" else "little"; + arch = + /**/ if targetPlatform.isAarch64 then endianPrefix + "aarch64" + else if targetPlatform.isArm then endianPrefix + "arm" + else if targetPlatform.isx86_64 then "x86-64" + else if targetPlatform.isi686 then "i386" + else throw "unknown emulation for platform: " + targetPlatform.config; + in targetPlatform.platform.bfdEmulation or (fmt + "-" + arch); + + depsTargetTargetPropagated = extraPackages; setupHook = ./setup-hook.sh; diff --git a/pkgs/build-support/bintools-wrapper/ld-wrapper.sh b/pkgs/build-support/bintools-wrapper/ld-wrapper.sh index 136621d27af5..991ed0fe263c 100644 --- a/pkgs/build-support/bintools-wrapper/ld-wrapper.sh +++ b/pkgs/build-support/bintools-wrapper/ld-wrapper.sh @@ -67,6 +67,11 @@ fi extraAfter+=($NIX_@infixSalt@_LDFLAGS_AFTER) +# Specify the target emulation if nothing is passed in ("-m" overrides this +# environment variable). Ensures we never blindly fallback on targeting the host +# platform. +: ${LDEMULATION:=@emulation@} + # Three tasks: # # 1. Find all -L... switches for rpath diff --git a/pkgs/build-support/bintools-wrapper/setup-hook.sh b/pkgs/build-support/bintools-wrapper/setup-hook.sh index 43f79ec59200..48a00b0b9b07 100644 --- a/pkgs/build-support/bintools-wrapper/setup-hook.sh +++ b/pkgs/build-support/bintools-wrapper/setup-hook.sh @@ -2,12 +2,20 @@ # # See comments in cc-wrapper's setup hook. This works exactly the same way. +set -u + +# Skip setup hook if we're neither a build-time dep, nor, temporarily, doing a +# native compile. +# +# TODO(@Ericson2314): No native exception +[[ -z ${crossConfig-} ]] || (( "$hostOffset" < 0 )) || return 0 + bintoolsWrapper_addLDVars () { - case $depOffset in + case $depHostOffset in -1) local role='BUILD_' ;; 0) local role='' ;; 1) local role='TARGET_' ;; - *) echo "bintools-wrapper: Error: Cannot be used with $depOffset-offset deps, " >2; + *) echo "bintools-wrapper: Error: Cannot be used with $depHostOffset-offset deps" >2; return 1 ;; esac @@ -20,17 +28,29 @@ bintoolsWrapper_addLDVars () { fi } -if [ -n "${crossConfig:-}" ]; then - export NIX_BINTOOLS_WRAPPER_@infixSalt@_TARGET_BUILD=1 - role_pre='BUILD_' - role_post='_FOR_BUILD' -else - export NIX_BINTOOLS_WRAPPER_@infixSalt@_TARGET_HOST=1 - role_pre="" - role_post='' -fi +case $targetOffset in + -1) + export NIX_BINTOOLS_WRAPPER_@infixSalt@_TARGET_BUILD=1 + role_pre='BUILD_' + role_post='_FOR_BUILD' + ;; + 0) + export NIX_BINTOOLS_WRAPPER_@infixSalt@_TARGET_HOST=1 + role_pre='' + role_post='' + ;; + 1) + export NIX_BINTOOLS_WRAPPER_@infixSalt@_TARGET_TARGET=1 + role_pre='TARGET_' + role_post='_FOR_TARGET' + ;; + *) + echo "cc-wrapper: used as improper sort of dependency" >2; + return 1 + ;; +esac -envHooks+=(bintoolsWrapper_addLDVars) +addEnvHooks "$targetOffset" bintoolsWrapper_addLDVars # shellcheck disable=SC2157 if [ -n "@bintools_bin@" ]; then @@ -65,3 +85,4 @@ done # No local scope in sourced file unset -v role_pre role_post cmd upper_case +set +u diff --git a/pkgs/build-support/build-fhs-userenv/chrootenv.c b/pkgs/build-support/build-fhs-userenv/chrootenv.c deleted file mode 100644 index d3b49db0e42d..000000000000 --- a/pkgs/build-support/build-fhs-userenv/chrootenv.c +++ /dev/null @@ -1,242 +0,0 @@ -#define _GNU_SOURCE - -#include <errno.h> -#include <error.h> - -#define errorf(status, fmt, ...) \ - error_at_line(status, errno, __FILE__, __LINE__, fmt, ##__VA_ARGS__) - -#include <dirent.h> -#include <ftw.h> -#include <sched.h> -#include <stdarg.h> -#include <stdbool.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <sysexits.h> -#include <unistd.h> - -#include <sys/mount.h> -#include <sys/stat.h> -#include <sys/wait.h> - -#define LEN(x) (sizeof(x) / sizeof(*x)) - -// TODO: fill together with @abbradar when he gets better -const char *environ_blacklist[] = {}; - -void environ_blacklist_filter() { - for (size_t i = 0; i < LEN(environ_blacklist); i++) { - if (unsetenv(environ_blacklist[i]) < 0) - errorf(EX_OSERR, "unsetenv(%s)", environ_blacklist[i]); - } -} - -void bind(const char *from, const char *to) { - if (mkdir(to, 0755) < 0) - errorf(EX_IOERR, "mkdir(%s)", to); - - if (mount(from, to, "bind", MS_BIND | MS_REC, NULL) < 0) - errorf(EX_OSERR, "mount(%s, %s)", from, to); -} - -const char *bind_blacklist[] = {".", "..", "bin", "etc", "host", "usr"}; - -bool str_contains(const char *needle, const char **haystack, size_t len) { - for (size_t i = 0; i < len; i++) { - if (!strcmp(needle, haystack[i])) - return true; - } - - return false; -} - -bool is_dir(const char *path) { - struct stat buf; - - if (stat(path, &buf) < 0) - errorf(EX_IOERR, "stat(%s)", path); - - return S_ISDIR(buf.st_mode); -} - -void bind_to_cwd(const char *prefix) { - DIR *prefix_dir = opendir(prefix); - - if (prefix_dir == NULL) - errorf(EX_IOERR, "opendir(%s)", prefix); - - struct dirent *prefix_dirent; - - while (prefix_dirent = readdir(prefix_dir)) { - if (str_contains(prefix_dirent->d_name, bind_blacklist, - LEN(bind_blacklist))) - continue; - - char *prefix_dirent_path; - - if (asprintf(&prefix_dirent_path, "%s%s", prefix, prefix_dirent->d_name) < - 0) - errorf(EX_IOERR, "asprintf"); - - if (is_dir(prefix_dirent_path)) { - bind(prefix_dirent_path, prefix_dirent->d_name); - } else { - char *host_target; - - if (asprintf(&host_target, "host/%s", prefix_dirent->d_name) < 0) - errorf(EX_IOERR, "asprintf"); - - if (symlink(host_target, prefix_dirent->d_name) < 0) - errorf(EX_IOERR, "symlink(%s, %s)", host_target, prefix_dirent->d_name); - - free(host_target); - } - - free(prefix_dirent_path); - } - - bind(prefix, "host"); - - if (closedir(prefix_dir) < 0) - errorf(EX_IOERR, "closedir(%s)", prefix); -} - -void spitf(const char *path, char *fmt, ...) { - va_list args; - va_start(args, fmt); - - FILE *f = fopen(path, "w"); - - if (f == NULL) - errorf(EX_IOERR, "spitf(%s): fopen", path); - - if (vfprintf(f, fmt, args) < 0) - errorf(EX_IOERR, "spitf(%s): vfprintf", path); - - if (fclose(f) < 0) - errorf(EX_IOERR, "spitf(%s): fclose", path); -} - -int nftw_remove(const char *path, const struct stat *sb, int type, - struct FTW *ftw) { - return remove(path); -} - -char *root; - -void root_cleanup() { - if (nftw(root, nftw_remove, getdtablesize(), - FTW_DEPTH | FTW_MOUNT | FTW_PHYS) < 0) - errorf(EX_IOERR, "nftw(%s)", root); - - free(root); -} - -#define REQUIREMENTS \ - "Requires Linux version >= 3.19 built with CONFIG_USER_NS option.\n" - -int main(int argc, char *argv[]) { - const char *self = *argv++; - - if (argc < 2) { - fprintf(stderr, "Usage: %s command [arguments...]\n" REQUIREMENTS, self); - exit(EX_USAGE); - } - - if (getenv("NIX_CHROOTENV") != NULL) { - fputs("Can't create chrootenv inside chrootenv!\n", stderr); - exit(EX_USAGE); - } - - if (setenv("NIX_CHROOTENV", "1", false) < 0) - errorf(EX_OSERR, "setenv(NIX_CHROOTENV, 1)"); - - const char *temp = getenv("TMPDIR"); - - if (temp == NULL) - temp = "/tmp"; - - if (asprintf(&root, "%s/chrootenvXXXXXX", temp) < 0) - errorf(EX_IOERR, "asprintf"); - - root = mkdtemp(root); - - if (root == NULL) - errorf(EX_IOERR, "mkdtemp(%s)", root); - - atexit(root_cleanup); - - // Don't make root private so that privilege drops inside chroot are possible: - if (chmod(root, 0755) < 0) - errorf(EX_IOERR, "chmod(%s, 0755)", root); - - pid_t cpid = fork(); - - if (cpid < 0) - errorf(EX_OSERR, "fork"); - - if (cpid == 0) { - uid_t uid = getuid(); - gid_t gid = getgid(); - - // If we are root, no need to create new user namespace. - if (uid == 0) { - if (unshare(CLONE_NEWNS) < 0) { - fputs(REQUIREMENTS, stderr); - errorf(EX_OSERR, "unshare"); - } - // Mark all mounted filesystems as slave so changes - // don't propagate to the parent mount namespace. - if (mount(NULL, "/", NULL, MS_REC | MS_SLAVE, NULL) < 0) - errorf(EX_OSERR, "mount"); - } else { - // Create new mount and user namespaces. CLONE_NEWUSER - // requires a program to be non-threaded. - if (unshare(CLONE_NEWNS | CLONE_NEWUSER) < 0) { - fputs(access("/proc/sys/kernel/unprivileged_userns_clone", F_OK) - ? REQUIREMENTS - : "Run: sudo sysctl -w kernel.unprivileged_userns_clone=1\n", - stderr); - errorf(EX_OSERR, "unshare"); - } - - // Map users and groups to the parent namespace. - // setgroups is only available since Linux 3.19: - spitf("/proc/self/setgroups", "deny"); - - spitf("/proc/self/uid_map", "%d %d 1", uid, uid); - spitf("/proc/self/gid_map", "%d %d 1", gid, gid); - } - - if (chdir(root) < 0) - errorf(EX_IOERR, "chdir(%s)", root); - - bind_to_cwd("/"); - - if (chroot(root) < 0) - errorf(EX_OSERR, "chroot(%s)", root); - - if (chdir("/") < 0) - errorf(EX_IOERR, "chdir(/)"); - - environ_blacklist_filter(); - - if (execvp(*argv, argv) < 0) - errorf(EX_OSERR, "execvp(%s)", *argv); - } - - int status; - - if (waitpid(cpid, &status, 0) < 0) - errorf(EX_OSERR, "waitpid(%d)", cpid); - - if (WIFEXITED(status)) { - return WEXITSTATUS(status); - } else if (WIFSIGNALED(status)) { - kill(getpid(), WTERMSIG(status)); - } - - return EX_OSERR; -} diff --git a/pkgs/build-support/build-fhs-userenv/chrootenv/chrootenv.c b/pkgs/build-support/build-fhs-userenv/chrootenv/chrootenv.c new file mode 100644 index 000000000000..c03a1710f451 --- /dev/null +++ b/pkgs/build-support/build-fhs-userenv/chrootenv/chrootenv.c @@ -0,0 +1,139 @@ +#define _GNU_SOURCE + +#include <glib.h> +#include <glib/gstdio.h> + +#include <errno.h> +#include <sched.h> +#include <unistd.h> + +#define fail(s, err) g_error("%s: %s: %s", __func__, s, g_strerror(err)) +#define fail_if(expr) \ + if (expr) \ + fail(#expr, errno); + +#include <ftw.h> + +#include <sys/mount.h> +#include <sys/stat.h> +#include <sys/types.h> +#include <sys/wait.h> + +const gchar *bind_blacklist[] = {"bin", "etc", "host", "usr", NULL}; + +void bind_mount(const gchar *source, const gchar *target) { + fail_if(g_mkdir(target, 0755)); + fail_if(mount(source, target, "bind", MS_BIND | MS_REC, NULL)); +} + +void bind_mount_host(const gchar *host, const gchar *guest) { + g_autofree gchar *point = g_build_filename(guest, "host", NULL); + bind_mount(host, point); +} + +void bind_mount_item(const gchar *host, const gchar *guest, const gchar *name) { + g_autofree gchar *source = g_build_filename(host, name, NULL); + g_autofree gchar *target = g_build_filename(guest, name, NULL); + + if (G_LIKELY(g_file_test(source, G_FILE_TEST_IS_DIR))) + bind_mount(source, target); +} + +void bind(const gchar *host, const gchar *guest) { + g_autoptr(GError) err = NULL; + g_autoptr(GDir) dir = g_dir_open(host, 0, &err); + + if (err != NULL) + fail("g_dir_open", errno); + + const gchar *item; + + while (item = g_dir_read_name(dir)) + if (!g_strv_contains(bind_blacklist, item)) + bind_mount_item(host, guest, item); + + bind_mount_host(host, guest); +} + +void spit(const char *path, char *fmt, ...) { + va_list args; + va_start(args, fmt); + + FILE *f = g_fopen(path, "w"); + + if (f == NULL) + fail("g_fopen", errno); + + g_vfprintf(f, fmt, args); + fclose(f); +} + +int nftw_remove(const char *path, const struct stat *sb, int type, + struct FTW *ftw) { + return remove(path); +} + +int main(gint argc, gchar **argv) { + const gchar *self = *argv++; + + if (argc < 2) { + g_message("%s command [arguments...]", self); + return 1; + } + + if (g_getenv("NIX_CHROOTENV")) + g_warning("chrootenv doesn't stack!"); + else + g_setenv("NIX_CHROOTENV", "", TRUE); + + g_autofree gchar *prefix = + g_build_filename(g_get_tmp_dir(), "chrootenvXXXXXX", NULL); + + fail_if(!g_mkdtemp_full(prefix, 0755)); + + pid_t cpid = fork(); + + if (cpid < 0) + fail("fork", errno); + + else if (cpid == 0) { + uid_t uid = getuid(); + gid_t gid = getgid(); + + if (unshare(CLONE_NEWNS | CLONE_NEWUSER) < 0) { + int unshare_errno = errno; + + g_message("Requires Linux version >= 3.19 built with CONFIG_USER_NS"); + if (g_file_test("/proc/sys/kernel/unprivileged_userns_clone", + G_FILE_TEST_EXISTS)) + g_message("Run: sudo sysctl -w kernel.unprivileged_userns_clone=1"); + + 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); + + bind("/", prefix); + + fail_if(chroot(prefix)); + fail_if(execvp(*argv, argv)); + } + + else { + int status; + + fail_if(waitpid(cpid, &status, 0) != cpid); + fail_if(nftw(prefix, nftw_remove, getdtablesize(), + FTW_DEPTH | FTW_MOUNT | FTW_PHYS)); + + if (WIFEXITED(status)) + return WEXITSTATUS(status); + + else if (WIFSIGNALED(status)) + kill(getpid(), WTERMSIG(status)); + + return 1; + } +} diff --git a/pkgs/build-support/build-fhs-userenv/chrootenv/default.nix b/pkgs/build-support/build-fhs-userenv/chrootenv/default.nix new file mode 100644 index 000000000000..375c30e1e463 --- /dev/null +++ b/pkgs/build-support/build-fhs-userenv/chrootenv/default.nix @@ -0,0 +1,19 @@ +{ stdenv, pkgconfig, glib }: + +stdenv.mkDerivation { + name = "chrootenv"; + + nativeBuildInputs = [ pkgconfig ]; + buildInputs = [ glib ]; + + buildCommand = '' + cc ${./chrootenv.c} $(pkg-config --cflags --libs glib-2.0) -o $out + ''; + + meta = with stdenv.lib; { + description = "Setup mount/user namespace for FHS emulation"; + license = licenses.free; + maintainers = with maintainers; [ yegortimoshenko ]; + platforms = platforms.linux; + }; +} diff --git a/pkgs/build-support/build-fhs-userenv/default.nix b/pkgs/build-support/build-fhs-userenv/default.nix index 5f3ec4dc8eaf..219530a67bd8 100644 --- a/pkgs/build-support/build-fhs-userenv/default.nix +++ b/pkgs/build-support/build-fhs-userenv/default.nix @@ -1,4 +1,4 @@ -{ callPackage, runCommand, lib, writeScript, stdenv, coreutils, ruby }: +{ callPackage, runCommand, lib, writeScript, stdenv, coreutils }: let buildFHSEnv = callPackage ./env.nix { }; in @@ -7,14 +7,7 @@ args@{ name, runScript ? "bash", extraInstallCommands ? "", meta ? {}, passthru let env = buildFHSEnv (removeAttrs args [ "runScript" "extraInstallCommands" "meta" "passthru" ]); - chrootenv = stdenv.mkDerivation { - name = "chrootenv"; - - unpackPhase = "cp ${./chrootenv.c} chrootenv.c"; - installPhase = "cp chrootenv $out"; - - makeFlags = [ "chrootenv" ]; - }; + chrootenv = callPackage ./chrootenv {}; init = run: writeScript "${name}-init" '' #! ${stdenv.shell} diff --git a/pkgs/build-support/build-pecl.nix b/pkgs/build-support/build-pecl.nix index ce948739c320..738dbb56708d 100644 --- a/pkgs/build-support/build-pecl.nix +++ b/pkgs/build-support/build-pecl.nix @@ -22,6 +22,4 @@ stdenv.mkDerivation (args // { makeFlags = [ "EXTENSION_DIR=$(out)/lib/php/extensions" ] ++ makeFlags; autoreconfPhase = "phpize"; - - preConfigure = "touch unix.h"; }) diff --git a/pkgs/build-support/cc-wrapper/default.nix b/pkgs/build-support/cc-wrapper/default.nix index 218e9f6b957f..8de2366ff5f5 100644 --- a/pkgs/build-support/cc-wrapper/default.nix +++ b/pkgs/build-support/cc-wrapper/default.nix @@ -201,7 +201,8 @@ stdenv.mkDerivation { ln -s $ccPath/${targetPrefix}ghdl $out/bin/${targetPrefix}ghdl ''; - propagatedBuildInputs = [ bintools ] ++ extraPackages; + propagatedBuildInputs = [ bintools ]; + depsTargetTargetPropagated = extraPackages; setupHook = ./setup-hook.sh; @@ -292,7 +293,7 @@ stdenv.mkDerivation { ## Hardening support ## - export hardening_unsupported_flags="" + export hardening_unsupported_flags="${builtins.concatStringsSep " " (cc.hardeningUnsupportedFlags or [])}" '' + optionalString hostPlatform.isCygwin '' diff --git a/pkgs/build-support/cc-wrapper/setup-hook.sh b/pkgs/build-support/cc-wrapper/setup-hook.sh index a922193ad2e7..29a7306b9b7e 100644 --- a/pkgs/build-support/cc-wrapper/setup-hook.sh +++ b/pkgs/build-support/cc-wrapper/setup-hook.sh @@ -54,19 +54,26 @@ # For more details, read the individual files where the mechanisms used to # accomplish this will be individually documented. +set -u + +# Skip setup hook if we're neither a build-time dep, nor, temporarily, doing a +# native compile. +# +# TODO(@Ericson2314): No native exception +[[ -z ${crossConfig-} ]] || (( "$hostOffset" < 0 )) || return 0 # It's fine that any other cc-wrapper will redefine this. Bash functions close # over no state, and there's no @-substitutions within, so any redefined # function is guaranteed to be exactly the same. ccWrapper_addCVars () { - # The `depOffset` describes how the platforms of the dependencies are slid - # relative to the depending package. It is brought into scope of the - # environment hook defined as the role of the dependency being applied. - case $depOffset in + # The `depHostOffset` describes how the host platform of the dependencies + # are slid relative to the depending package. It is brought into scope of + # the environment hook defined as the role of the dependency being applied. + case $depHostOffset in -1) local role='BUILD_' ;; 0) local role='' ;; 1) local role='TARGET_' ;; - *) echo "cc-wrapper: Error: Cannot be used with $depOffset-offset deps, " >2; + *) echo "cc-wrapper: Error: Cannot be used with $depHostOffset-offset deps" >2; return 1 ;; esac @@ -87,20 +94,31 @@ ccWrapper_addCVars () { # # We also need to worry about what role is being added on *this* invocation of # setup-hook, which `role` tracks. -if [ -n "${crossConfig:-}" ]; then - export NIX_CC_WRAPPER_@infixSalt@_TARGET_BUILD=1 - role_pre='BUILD_' - role_post='_FOR_BUILD' -else - export NIX_CC_WRAPPER_@infixSalt@_TARGET_HOST=1 - role_pre='' - role_post='' -fi +case $targetOffset in + -1) + export NIX_CC_WRAPPER_@infixSalt@_TARGET_BUILD=1 + role_pre='BUILD_' + role_post='_FOR_BUILD' + ;; + 0) + export NIX_CC_WRAPPER_@infixSalt@_TARGET_HOST=1 + role_pre='' + role_post='' + ;; + 1) + export NIX_CC_WRAPPER_@infixSalt@_TARGET_TARGET=1 + role_pre='TARGET_' + role_post='_FOR_TARGET' + ;; + *) + echo "cc-wrapper: used as improper sort of dependency" >2; + return 1 + ;; +esac -# Eventually the exact sort of env-hook we create will depend on the role. This -# is because based on what relative platform we are targeting, we use different -# dependencies. -envHooks+=(ccWrapper_addCVars) +# We use the `targetOffset` to choose the right env hook to accumulate the right +# sort of deps (those with that offset). +addEnvHooks "$targetOffset" ccWrapper_addCVars # Note 1: these come *after* $out in the PATH (see setup.sh). # Note 2: phase separation makes this look useless to shellcheck. @@ -131,3 +149,4 @@ export CXX${role_post}=@named_cxx@ # No local scope in sourced file unset -v role_pre role_post +set +u diff --git a/pkgs/build-support/docker/examples.nix b/pkgs/build-support/docker/examples.nix index b9a334971744..691d4bb74dbf 100644 --- a/pkgs/build-support/docker/examples.nix +++ b/pkgs/build-support/docker/examples.nix @@ -102,7 +102,7 @@ rec { ]; }; - # 5. nix example to play with the container nix store + # 6. nix example to play with the container nix store # docker run -it --rm nix nix-store -qR $(nix-build '<nixpkgs>' -A nix) nix = buildImageWithNixDb { name = "nix"; diff --git a/pkgs/build-support/emacs/setup-hook.sh b/pkgs/build-support/emacs/setup-hook.sh index defef45b55f5..e1db3e828fd7 100644 --- a/pkgs/build-support/emacs/setup-hook.sh +++ b/pkgs/build-support/emacs/setup-hook.sh @@ -4,4 +4,8 @@ addEmacsVars () { fi } -envHooks+=(addEmacsVars) +# If this is for a wrapper derivation, emacs and the dependencies are all +# run-time dependencies. If this is for precompiling packages into bytecode, +# emacs is a compile-time dependency of the package. +addEnvHooks "$targetOffset" addEmacsVars +addEnvHooks "$targetOffset" addEmacsVars diff --git a/pkgs/build-support/emacs/wrapper.nix b/pkgs/build-support/emacs/wrapper.nix index bd733f1b9baf..27633c912b23 100644 --- a/pkgs/build-support/emacs/wrapper.nix +++ b/pkgs/build-support/emacs/wrapper.nix @@ -55,12 +55,46 @@ stdenv.mkDerivation { deps = runCommand "emacs-packages-deps" { inherit explicitRequires lndir emacs; } '' + findInputsOld() { + local pkg="$1"; shift + local var="$1"; shift + local propagatedBuildInputsFiles=("$@") + + # TODO(@Ericson2314): Restore using associative array once Darwin + # nix-shell doesn't use impure bash. This should replace the O(n) + # case with an O(1) hash map lookup, assuming bash is implemented + # well :D. + local varSlice="$var[*]" + # ''${..-} to hack around old bash empty array problem + case "''${!varSlice-}" in + *" $pkg "*) return 0 ;; + esac + unset -v varSlice + + eval "$var"'+=("$pkg")' + + if ! [ -e "$pkg" ]; then + echo "build input $pkg does not exist" >&2 + exit 1 + fi + + local file + for file in "''${propagatedBuildInputsFiles[@]}"; do + file="$pkg/nix-support/$file" + [[ -f "$file" ]] || continue + + local pkgNext + for pkgNext in $(< "$file"); do + findInputsOld "$pkgNext" "$var" "''${propagatedBuildInputsFiles[@]}" + done + done + } mkdir -p $out/bin mkdir -p $out/share/emacs/site-lisp local requires for pkg in $explicitRequires; do - findInputs $pkg requires propagated-user-env-packages + findInputsOld $pkg requires propagated-user-env-packages done # requires now holds all requested packages and their transitive dependencies diff --git a/pkgs/build-support/gcc-wrapper-old/default.nix b/pkgs/build-support/gcc-wrapper-old/default.nix index ae17989d932b..2c2b2c0e1d5c 100644 --- a/pkgs/build-support/gcc-wrapper-old/default.nix +++ b/pkgs/build-support/gcc-wrapper-old/default.nix @@ -8,7 +8,7 @@ { name ? "", stdenv, lib, nativeTools, nativeLibc, nativePrefix ? "" , gcc ? null, libc ? null, binutils ? null, coreutils ? null, shell ? stdenv.shell , zlib ? null -, hostPlatform, targetPlatform +, hostPlatform, targetPlatform, targetPackages }: assert nativeTools -> nativePrefix != ""; @@ -58,18 +58,6 @@ stdenv.mkDerivation { zlib = if gcc != null && gcc ? langVhdl then zlib else null; shell = shell + shell.shellPath or ""; - crossAttrs = { - # - # This is not the best way to do this. I think the reference should be - # the style in the gcc-cross-wrapper, but to keep a stable stdenv now I - # do this sufficient if/else. - dynamicLinker = - (if hostPlatform.arch == "arm" then "ld-linux.so.3" else - if hostPlatform.arch == "mips" then "ld.so.1" else - if stdenv.lib.hasSuffix "pc-gnu" hostPlatform.config then "ld.so.1" else - abort "don't know the name of the dynamic linker for this platform"); - }; - preferLocalBuild = true; meta = @@ -83,17 +71,6 @@ stdenv.mkDerivation { # The dynamic linker has different names on different platforms. dynamicLinker = if !nativeLibc then - (if targetPlatform.system == "i686-linux" then "ld-linux.so.2" else - if targetPlatform.system == "x86_64-linux" then "ld-linux-x86-64.so.2" else - # ARM with a wildcard, which can be "" or "-armhf". - if targetPlatform.isArm then "ld-linux*.so.3" else - if targetPlatform.system == "aarch64-linux" then "ld-linux-aarch64.so.1" else - if targetPlatform.system == "powerpc-linux" then "ld.so.1" else - if targetPlatform.system == "mips64el-linux" then "ld.so.1" else - if targetPlatform.system == "x86_64-darwin" then "/usr/lib/dyld" else - if stdenv.lib.hasSuffix "pc-gnu" targetPlatform.config then "ld.so.1" else - builtins.trace - "Don't know the name of the dynamic linker for platform ${targetPlatform.config}, so guessing instead." - null) + targetPackages.stdenv.cc.bintools.dynamicLinker else ""; } diff --git a/pkgs/build-support/gcc-wrapper-old/setup-hook.sh b/pkgs/build-support/gcc-wrapper-old/setup-hook.sh index d8bdf858ae58..ad3ffeffbbbc 100644 --- a/pkgs/build-support/gcc-wrapper-old/setup-hook.sh +++ b/pkgs/build-support/gcc-wrapper-old/setup-hook.sh @@ -1,4 +1,4 @@ -addCVars () { +gccWrapperOld_addCVars () { if test -d $1/include; then export NIX_CFLAGS_COMPILE="$NIX_CFLAGS_COMPILE -isystem $1/include" fi @@ -12,7 +12,7 @@ addCVars () { fi } -envHooks=(${envHooks[@]} addCVars) +envBuildBuildHooks+=(gccWrapperOld_addCVars) # Note: these come *after* $out in the PATH (see setup.sh). diff --git a/pkgs/build-support/rust/carnix.nix b/pkgs/build-support/rust/carnix.nix index 80c0903369af..adb7139758cd 100644 --- a/pkgs/build-support/rust/carnix.nix +++ b/pkgs/build-support/rust/carnix.nix @@ -70,11 +70,11 @@ let kernel = buildPlatform.parsed.kernel.name; sha256 = "0p4b3nr0s5nda2qmm7xdhnvh4lkqk3xd8l9ffmwbvqw137vx7mj1"; inherit dependencies buildDependencies features; }; - carnix_0_5_0_ = { dependencies?[], buildDependencies?[], features?[] }: buildRustCrate { + carnix_0_5_2_ = { dependencies?[], buildDependencies?[], features?[] }: buildRustCrate { crateName = "carnix"; - version = "0.5.0"; + version = "0.5.2"; authors = [ "pe@pijul.org <pe@pijul.org>" ]; - sha256 = "0mrprfa9l6q351ci77zr305jk5wdii8gamaphd2iars4xwn26lj4"; + sha256 = "1znj345jziksxxkq7ap3i8p3fp3x4794qggac35d0banj7ml3fv8"; inherit dependencies buildDependencies features; }; cc_1_0_3_ = { dependencies?[], buildDependencies?[], features?[] }: buildRustCrate { @@ -521,22 +521,22 @@ rec { features = mkFeatures bitflags_1_0_1_features; }; bitflags_1_0_1_features."example_generated".self_default = hasDefault bitflags_1_0_1_features; - carnix_0_5_0 = carnix_0_5_0_ rec { + carnix_0_5_2 = carnix_0_5_2_ rec { dependencies = [ clap_2_28_0 env_logger_0_4_3 error_chain_0_11_0 itertools_0_7_3 log_0_3_8 nom_3_2_1 regex_0_2_2 rusqlite_0_13_0 serde_1_0_21 serde_derive_1_0_21 serde_json_1_0_6 tempdir_0_3_5 toml_0_4_5 ]; }; - clap_2_28_0_features."default".from_carnix_0_5_0__default = true; - env_logger_0_4_3_features."default".from_carnix_0_5_0__default = true; - error_chain_0_11_0_features."default".from_carnix_0_5_0__default = true; - itertools_0_7_3_features."default".from_carnix_0_5_0__default = true; - log_0_3_8_features."default".from_carnix_0_5_0__default = true; - nom_3_2_1_features."default".from_carnix_0_5_0__default = true; - regex_0_2_2_features."default".from_carnix_0_5_0__default = true; - rusqlite_0_13_0_features."default".from_carnix_0_5_0__default = true; - serde_1_0_21_features."default".from_carnix_0_5_0__default = true; - serde_derive_1_0_21_features."default".from_carnix_0_5_0__default = true; - serde_json_1_0_6_features."default".from_carnix_0_5_0__default = true; - tempdir_0_3_5_features."default".from_carnix_0_5_0__default = true; - toml_0_4_5_features."default".from_carnix_0_5_0__default = true; + clap_2_28_0_features."default".from_carnix_0_5_2__default = true; + env_logger_0_4_3_features."default".from_carnix_0_5_2__default = true; + error_chain_0_11_0_features."default".from_carnix_0_5_2__default = true; + itertools_0_7_3_features."default".from_carnix_0_5_2__default = true; + log_0_3_8_features."default".from_carnix_0_5_2__default = true; + nom_3_2_1_features."default".from_carnix_0_5_2__default = true; + regex_0_2_2_features."default".from_carnix_0_5_2__default = true; + rusqlite_0_13_0_features."default".from_carnix_0_5_2__default = true; + serde_1_0_21_features."default".from_carnix_0_5_2__default = true; + serde_derive_1_0_21_features."default".from_carnix_0_5_2__default = true; + serde_json_1_0_6_features."default".from_carnix_0_5_2__default = true; + tempdir_0_3_5_features."default".from_carnix_0_5_2__default = true; + toml_0_4_5_features."default".from_carnix_0_5_2__default = true; cc_1_0_3 = cc_1_0_3_ rec { dependencies = []; features = mkFeatures cc_1_0_3_features; diff --git a/pkgs/build-support/setup-hooks/find-xml-catalogs.sh b/pkgs/build-support/setup-hooks/find-xml-catalogs.sh index b742d5a8ffd9..85364a61f612 100644 --- a/pkgs/build-support/setup-hooks/find-xml-catalogs.sh +++ b/pkgs/build-support/setup-hooks/find-xml-catalogs.sh @@ -18,5 +18,5 @@ if [ -z "$libxmlHookDone" ]; then # xmllint and xsltproc from looking in /etc/xml/catalog. export XML_CATALOG_FILES if [ -z "$XML_CATALOG_FILES" ]; then XML_CATALOG_FILES=" "; fi - envHooks+=(addXMLCatalogs) + addEnvHooks "$hostOffset" addXMLCatalogs fi diff --git a/pkgs/build-support/setup-hooks/set-java-classpath.sh b/pkgs/build-support/setup-hooks/set-java-classpath.sh index 047da91bc97c..5d3548dc2e88 100644 --- a/pkgs/build-support/setup-hooks/set-java-classpath.sh +++ b/pkgs/build-support/setup-hooks/set-java-classpath.sh @@ -10,4 +10,4 @@ addPkgToClassPath () { done } -envHooks+=(addPkgToClassPath) +addEnvHooks "$targetOffset" addPkgToClassPath diff --git a/pkgs/build-support/setup-hooks/setup-debug-info-dirs.sh b/pkgs/build-support/setup-hooks/setup-debug-info-dirs.sh index 2fd2a2d6da6f..96bf48cf123a 100644 --- a/pkgs/build-support/setup-hooks/setup-debug-info-dirs.sh +++ b/pkgs/build-support/setup-hooks/setup-debug-info-dirs.sh @@ -2,4 +2,4 @@ setupDebugInfoDirs () { addToSearchPath NIX_DEBUG_INFO_DIRS $1/lib/debug } -envHooks+=(setupDebugInfoDirs) +addEnvHooks "$targetOffset" setupDebugInfoDirs diff --git a/pkgs/build-support/setup-hooks/strip.sh b/pkgs/build-support/setup-hooks/strip.sh index a33968ca18de..fc4c7bfbaf95 100644 --- a/pkgs/build-support/setup-hooks/strip.sh +++ b/pkgs/build-support/setup-hooks/strip.sh @@ -3,24 +3,45 @@ fixupOutputHooks+=(_doStrip) _doStrip() { - if [ -z "$dontStrip" ]; then + # We don't bother to strip build platform code because it shouldn't make it + # to $out anyways---if it does, that's a bigger problem that a lack of + # stripping will help catch. + local -ra flags=(dontStripHost dontStripTarget) + local -ra stripCmds=(STRIP TARGET_STRIP) + + # Optimization + if [[ "$STRIP" == "$TARGET_STRIP" ]]; then + dontStripTarget+=1 + fi + + local i + for i in ${!stripCmds[@]}; do + local -n flag="${flags[$i]}" + local -n stripCmd="${stripCmds[$i]}" + + # `dontStrip` disables them all + if [[ "$dontStrip" || "$flag" ]] || ! type -f "$stripCmd" 2>/dev/null + then continue; fi + stripDebugList=${stripDebugList:-lib lib32 lib64 libexec bin sbin} if [ -n "$stripDebugList" ]; then - stripDirs "$stripDebugList" "${stripDebugFlags:--S}" + stripDirs "$stripCmd" "$stripDebugList" "${stripDebugFlags:--S}" fi stripAllList=${stripAllList:-} if [ -n "$stripAllList" ]; then - stripDirs "$stripAllList" "${stripAllFlags:--s}" + stripDirs "$stripCmd" "$stripAllList" "${stripAllFlags:--s}" fi - fi + done } stripDirs() { - local dirs="$1" - local stripFlags="$2" + local cmd="$1" + local dirs="$2" + local stripFlags="$3" local dirsNew= + local d for d in ${dirs}; do if [ -d "$prefix/$d" ]; then dirsNew="${dirsNew} $prefix/$d " @@ -29,8 +50,8 @@ stripDirs() { dirs=${dirsNew} if [ -n "${dirs}" ]; then - header "stripping (with flags $stripFlags) in$dirs" - find $dirs -type f -print0 | xargs -0 ${xargsFlags:--r} $STRIP $commonStripFlags $stripFlags 2>/dev/null || true + 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 stopNest fi } diff --git a/pkgs/build-support/setup-hooks/wrap-gapps-hook.sh b/pkgs/build-support/setup-hooks/wrap-gapps-hook.sh index 79b8d5b73fa1..25ac12996cc1 100644 --- a/pkgs/build-support/setup-hooks/wrap-gapps-hook.sh +++ b/pkgs/build-support/setup-hooks/wrap-gapps-hook.sh @@ -6,7 +6,7 @@ find_gio_modules() { fi } -envHooks+=(find_gio_modules) +addEnvHooks "$targetOffset" find_gio_modules # Note: $gappsWrapperArgs still gets defined even if $dontWrapGApps is set. wrapGAppsHook() { |