You can reproduce the build environment with nix-shell -p gcc11. Now simply change src to your local sources.
If you expect a lot of recompilations during your changes, you might prefer to apply the patches from nixpkgs to your source, launch the appropriate nix shell and then build as you would do on other systems.
Another option would be using e.g. Debian in a Container for the hack&test cycles and once you seem satisfied you can easily rebuild gcc and your test code with nix.
I agree building vanilla gcc is not trivial on NixOS. And doing upstream development using nixpkgs derivations is even harder. I suggest a simple hack: use buildFHSEnv to get development environment. Something like the following:
# shell.nix:
{ pkgs ? import <nixpkgs> {} }:
let e =
pkgs.buildFHSEnv {
name = "gcc-git-build-env";
targetPkgs = ps: with ps; [
# library depends
gmp gmp.dev
isl
libffi libffi.dev
libmpc
libxcrypt
mpfr mpfr.dev
xz xz.dev
zlib zlib.dev
# git checkout need flex as they are not complete release tarballs
m4
bison
flex
texinfo
# test harness
dejagnu
autogen
# valgrind annotations
valgrind valgrind.dev
# toolchain itself
gcc
stdenv.cc
stdenv.cc.libc stdenv.cc.libc_dev
];
};
in e.env
The full session would look like that:
$ nix-shell
# fetch
$$ git clone --depth 1 https://gcc.gnu.org/git/gcc.git
# build / install
$$ mkdir gcc-build
$$ cd gcc-build
$$ ../gcc/configure --disable-multilib --prefix=$PWD/../gcc-installed
$$ make -j $(nproc)
$$ make install
# test basics
$$ printf '#include <iostream>\nint main() { std::cout << "Hello!" << std::endl ; }' > a.cc
$$ ../gcc-installed/bin/g++ a.cc -o a -static-libstdc++
$$ ./a
Hello!
# run testsuite
$$ make check
...
=== gcc Summary ===
# of expected passes 191743
# of unexpected failures 107
Hello! I tried to reproduce your method with flakes, and have the following flake:
{
description = "A very basic flake";
outputs = { nixpkgs, self }: {
devShells.riscv64-linux.default = (nixpkgs.legacyPackages.riscv64-linux.buildFHSEnv {
name = "gcc-git-build-env";
targetPkgs = ps: with ps; [
# library depends
gmp gmp.dev
isl
libffi libffi.dev
libmpc
libxcrypt
mpfr mpfr.dev
xz xz.dev
zlib zlib.dev
# git checkout need flex as they are not complete release tarballs
m4
bison
flex
texinfo
# test harness
dejagnu
autogen
# toolchain itself
gcc
stdenv.cc
stdenv.cc.libc stdenv.cc.libc_dev
];
}).env;
};
}
However, when I try to build GCC in nix develop with this flake, I get an error from ld that it can’t find -lmpfr, -lmpc and so on. I can compile program with them, though, configure passes succesfully. In shell files are also present on their intended places. How can I debug this?
That’s on riscv64-linux host, right? Your flake looks reasonable it works for me if I replace riscv64-linux with x86_64-linux. I suspect it has to do with the lib/lib64 symlinks and linker search paths. Should not be too hard to fix.
Try adding -Wl,--verbose to the build command you see failing and check why -lmpc is not searched in usual /lib/libmpc.so locations.
I’ll try to reproduce it as is on riscv64-linux using qemu-user and look closer. But it will take quite a bit to build the environment without the binary cache.
DId not succeed reproducing the failure on riscv64-linux (grep test fails in qemu-user), but I did on i686-linux. I think x86_64-linux works by accident because multilib layout always injects -L /usr/lib path while i686 just relies on linker defaults. For some reason NIX_LDFLAGS does not get read by the ld wrapper.
I’ll try to figure out why and come up with a workaround.
UPD: it’s just an incorrectly applied patch, after more careful examination and fix of patched flake variable did show up. Running the build to check if problem is fixed.
UPD2: it looks like problem is fixed, compilations using mpc pass successfully. Hope this would be the only problem.
Ah, all my fault. profile should have been added within ({ ... }).env block, not the outside. Too much hand-editing on my side. Updated the patch above.
Just for the record, with a few modifications is it possible to build basically any GCC from its vanilla sources on NixOS. We recently ran into this issue with our bootstrappable builds toolchain project, which supports bootstrapping toolchains from only a minimal system, like NixOS.
Assuming you have the following paths (or similar):
We were able to successfully build GCC 4.7.4, GCC 10.2.0, and GCC 13.2.0 with this:
# patch the dynamic linker path
for hdr in gcc/config/*/*.h; do
sed -i 's|"/lib.*/ld-linux.*so.2"|"'$MY_LINKER'"|g' "$hdr"
done
export LIBRARY_PATH="$MY_LIBDIR"
./configure --with-sysroot=/ --with-naive-system-header-dir="$MY_HDRDIR" # ... other configure args
make && make install