diff --git a/src/archs.nix b/src/archs.nix index c8e6e74..c682c32 100644 --- a/src/archs.nix +++ b/src/archs.nix @@ -55,14 +55,6 @@ }; }; - ppc = { - penguinName = "powerpc"; - compatNames = [ "powerpcle" ]; - crossSystem = { - config = "powerpc-linux-musl"; - }; - }; - ppc64 = { penguinName = "powerpc64"; crossSystem = { diff --git a/src/cross-overlays.nix b/src/cross-overlays.nix index c56dd3e..fefbb9c 100644 --- a/src/cross-overlays.nix +++ b/src/cross-overlays.nix @@ -20,10 +20,26 @@ }); }) + # openssl's test suite runs only on the "native" x86_64-musl build (cross + # builds skip it). Its 04-test_bio_dgram datagram-socket test fails in the + # sandboxed builder. We only use openssl as a transitive dependency, so skip + # the checks. + (self: super: { + openssl = super.openssl.overrideAttrs (_: { + doCheck = false; + }); + }) + # GnuTLS docs builds run generated target binaries such as lt-errcodes. + # --disable-doc skips the doc build, so neither the "man" nor "devdoc" + # outputs get populated. Upstream couples these: it only passes + # --disable-doc for MinGW and drops both outputs in the same case. Mirror + # that here, or Nix fails with "failed to produce output path for output + # 'devdoc'" (then 'man'). (self: super: { gnutls = super.gnutls.overrideAttrs (o: { configureFlags = (o.configureFlags or [ ]) ++ [ "--disable-doc" ]; + outputs = builtins.filter (x: x != "man" && x != "devdoc") (o.outputs or [ "out" ]); }); }) diff --git a/src/mk-arch-bundle.nix b/src/mk-arch-bundle.nix index 70b7567..56cd786 100644 --- a/src/mk-arch-bundle.nix +++ b/src/mk-arch-bundle.nix @@ -229,5 +229,15 @@ pkgs.runCommand "penguin-tools-${penguinArch}" ln -sfn "$arch" "$out/igloo_static/dylibs/${compatArch}" '') compatNames} + # Some tools bake their build-time /nix/store prefix into the binary's + # rodata (e.g. CPython's PREFIX in libpython, ltrace's SYSCONFDIR) or into + # leftover text config. These are compile-time fallbacks, overridden at + # runtime, and point at paths that do not exist on the guest anyway. Rewrite + # the store prefix everywhere so the tree carries no /nix/store references. + # "/igloo_nix" is exactly as long as "/nix/store", so the substitution is + # length-preserving and leaves ELF section offsets intact. + find "$out/igloo_static" -type f -print0 \ + | xargs -0r sed -i 's|/nix/store|/igloo_nix|g' + validate_tree '' diff --git a/src/pkgs/gdbserver.nix b/src/pkgs/gdbserver.nix index 94f9bc8..3173e71 100644 --- a/src/pkgs/gdbserver.nix +++ b/src/pkgs/gdbserver.nix @@ -1,6 +1,16 @@ pkgs: +# gdb is pinned to 16.3 rather than tracking nixpkgs' latest: 16.3 is the +# version Alpine/Buildroot ship on musl across our arch set, and it predates +# the gdb-17 GCS (struct user_gcs) and custom-baudrate (termios c_ispeed) code +# that does not compile against musl + modern kernel headers. Stable over new. pkgs.gdbHostCpuOnly.overrideAttrs (prev: { + version = "16.3"; + src = pkgs.fetchurl { + url = "mirror://gnu/gdb/gdb-16.3.tar.xz"; + hash = "sha256-vPzQlVKKmHkXrPn/8/FnIYFpSSbMGNYJyZ0AQsACJMU="; + }; + postPatch = (prev.postPatch or "") + '' @@ -9,5 +19,10 @@ pkgs.gdbHostCpuOnly.overrideAttrs (prev: { --replace '_ABIO32' '1' ''; + # gdbserver's in-process agent (fast tracepoints) is not supported on every + # target and its configure makes that a hard error (e.g. armv7l-musl). We + # don't use the IPA, so disable it everywhere. + configureFlags = (prev.configureFlags or [ ]) ++ [ "--disable-inprocess-agent" ]; + meta.mainProgram = "gdbserver"; }) diff --git a/src/pkgs/ltrace.nix b/src/pkgs/ltrace.nix index 21c10c3..4aecce1 100644 --- a/src/pkgs/ltrace.nix +++ b/src/pkgs/ltrace.nix @@ -4,10 +4,13 @@ let errorImpl = '' #define _GNU_SOURCE #include + #include + #include + #include #define error(status, errnum, ...) \ do { \ fflush(stdout); \ - fprintf(stderr, "%s: ", program_invocation_name); \ + fprintf(stderr, "ltrace: "); \ fprintf(stderr, __VA_ARGS__); \ if (errnum != 0) { \ fprintf(stderr, ": %s", strerror(errnum)); \ @@ -38,6 +41,13 @@ pkgs.ltrace.overrideAttrs (prev: { substituteInPlace sysdeps/linux-gnu/{mips/plt.c,ppc/regs.c} \ --replace '#include ' ${pkgs.lib.escapeShellArg errorImpl} + + # The ppc backend uses the kernel's PT_R0/PT_NIP/PT_LNK ptrace offsets. + # glibc's pulls these in transitively; musl's does not, so + # include the kernel that actually defines them. + substituteInPlace sysdeps/linux-gnu/ppc/ptrace.h \ + --replace '#include ' '#include +#include ' ''; configureFlags = [ "--datadir=/igloo" ]; diff --git a/src/pkgs/python.nix b/src/pkgs/python.nix index 4094e51..87eeefc 100644 --- a/src/pkgs/python.nix +++ b/src/pkgs/python.nix @@ -40,4 +40,15 @@ pkgs.runCommand "cpython-runtime-${version}" if grep -Irl -- ${python} "$out" >/dev/null 2>&1; then grep -IrlZ -- ${python} "$out" | xargs -0r sed -i "s|${python}|$out|g" fi + + # subprocess.py and ctypes' fetch_macholib hardcode the build sysroot's + # shell. On the guest the shell lives at /bin/sh. (Other residual + # build-time /nix/store references in this tree -- sysconfigdata, the + # libpython PREFIX baked into rodata, etc. -- are neutralized generically + # by the bundle's store-path scrub.) + grep -IrlZ -aP '/nix/store/[a-z0-9]{32}-[^/]*/bin/sh' "$out" | xargs -0r \ + sed -i -E 's,/nix/store/[a-z0-9]{32}-[^/]*/bin/sh,/bin/sh,g' + + # pip's EXTERNALLY-MANAGED marker is meaningless on the guest. + rm -f "$out/lib/python${version}/EXTERNALLY-MANAGED" ''