add bootstraped x86_64-linux cross compiled gcc (#8)
Some checks failed
buildbot/nix-eval Build done.

Work in progress cross compiler for x86_64. I've managed to get a full x86_64 gcc using the binaries built from foundation, and am working on implementing their builds into tidepool.

### Bootstrapping steps
0) Start with i686 tools (gcc, binutils, musl, etc)
1) Build binutils targeting x86_64-linux
2) Build a minimal gcc cross compiler using the cross binutils. This minimal cross compiler does not have support for libc, so is pretty much only useful for building musl or glibc.
3) Use the minimal cross compiler to build x86_64-linux glibc or musl
4) Now that we have a cross compiler and x86_64-linux libc, we can build gcc for the target architecture!
5) Profit! We can now build anything x86_64 using our gcc compiler!

Co-authored-by: Jake Hamilton <jake.hamilton@hey.com>
Reviewed-on: #8
Reviewed-by: Jake Hamilton <jake.hamilton@hey.com>
Co-authored-by: Victor Fuentes <vmfuentes64@gmail.com>
Co-committed-by: Victor Fuentes <vmfuentes64@gmail.com>
This commit is contained in:
Victor Fuentes 2024-09-22 02:55:02 +00:00 committed by Jake Hamilton
parent cadfaabc85
commit d7762a5a78
15 changed files with 903 additions and 345 deletions

View file

@ -3,17 +3,18 @@
"lib": { "lib": {
"locked": { "locked": {
"dir": "lib", "dir": "lib",
"dirtyRev": "2be3111b2c0911f40b47fe0a1fb22b5f5188cf59-dirty", "lastModified": 1723737980,
"dirtyShortRev": "2be3111-dirty", "narHash": "sha256-1WnFatW5kSuO2jjt62hvSbH84TSYyO+VmvkJ0d5e/ZY=",
"lastModified": 1719251485, "ref": "master",
"narHash": "sha256-63NvfFVeTDITfNu60rmCUlaZtAeZUnvrIaOLSk9ScC8=", "rev": "cadfaabc853d20f2bc20bad794fcbe520ea48f13",
"revCount": 82,
"type": "git", "type": "git",
"url": "file:../?dir=lib" "url": "file:../"
}, },
"original": { "original": {
"dir": "lib", "dir": "lib",
"type": "git", "type": "git",
"url": "file:../?dir=lib" "url": "file:../"
} }
}, },
"root": { "root": {

View file

@ -8,33 +8,35 @@
}, },
"locked": { "locked": {
"dir": "foundation", "dir": "foundation",
"dirtyRev": "3f9d287065ac685ce500c2cddb35428b2927f5a2-dirty", "lastModified": 1724190751,
"dirtyShortRev": "3f9d287-dirty", "narHash": "sha256-e8sOmeXS9YWuQqjW6gvtS3PIueazkf4S1iiJ/94eXv4=",
"lastModified": 1720514984, "ref": "master",
"narHash": "sha256-AuixwSlYk34Z6+GEc7y4QotF3Hk963zC9I9hAwX5KCE=", "rev": "4b36a5a0133f5481840bdfaf693c971215a7ef1f",
"revCount": 84,
"type": "git", "type": "git",
"url": "file:../?dir=foundation" "url": "file:../"
}, },
"original": { "original": {
"dir": "foundation", "dir": "foundation",
"type": "git", "type": "git",
"url": "file:../?dir=foundation" "url": "file:../"
} }
}, },
"lib": { "lib": {
"locked": { "locked": {
"dir": "lib", "dir": "lib",
"dirtyRev": "3f9d287065ac685ce500c2cddb35428b2927f5a2-dirty", "lastModified": 1724190751,
"dirtyShortRev": "3f9d287-dirty", "narHash": "sha256-e8sOmeXS9YWuQqjW6gvtS3PIueazkf4S1iiJ/94eXv4=",
"lastModified": 1720514984, "ref": "master",
"narHash": "sha256-AuixwSlYk34Z6+GEc7y4QotF3Hk963zC9I9hAwX5KCE=", "rev": "4b36a5a0133f5481840bdfaf693c971215a7ef1f",
"revCount": 84,
"type": "git", "type": "git",
"url": "file:../?dir=lib" "url": "file:../"
}, },
"original": { "original": {
"dir": "lib", "dir": "lib",
"type": "git", "type": "git",
"url": "file:../?dir=lib" "url": "file:../"
} }
}, },
"root": { "root": {

View file

@ -65,7 +65,15 @@ in
PATH = PATH =
let let
bins = lib.paths.bin ( bins = lib.paths.bin (
(lib.packages.dependencies.get dependencies.build.host) (lib.packages.dependencies.get dependencies.build.only)
++ (lib.packages.dependencies.get dependencies.build.build)
++ (lib.packages.dependencies.get dependencies.build.host)
++ (lib.packages.dependencies.get dependencies.build.target)
++ (lib.packages.dependencies.get dependencies.host.only)
++ (lib.packages.dependencies.get dependencies.host.host)
++ (lib.packages.dependencies.get dependencies.host.target)
++ (lib.packages.dependencies.get dependencies.target.only)
++ (lib.packages.dependencies.get dependencies.target.target)
++ [ ++ [
foundation.stage2-bash foundation.stage2-bash
foundation.stage2-coreutils foundation.stage2-coreutils
@ -99,6 +107,7 @@ in
} }
); );
in in
# (builtins.trace "build: ${package.name} -> build=${package.platform.build.triple} host=${package.platform.host.triple} target=${package.platform.target.triple}")
built built
// { // {
inherit (package) meta; inherit (package) meta;

View file

@ -16,27 +16,24 @@ in
aux-a = config.packages.aux.a; aux-a = config.packages.aux.a;
aux-b = config.packages.aux.b; aux-b = config.packages.aux.b;
# foundation-gcc-x86_64 =
# (config.packages.foundation.gcc.versions."13.2.0".extend (args: {
# config = {
# platform = {
# target = lib.modules.overrides.force "x86_64-linux";
# };
# };
# }))
# .config;
foundation-gcc = config.packages.foundation.gcc; foundation-gcc = config.packages.foundation.gcc;
foundation-glibc = config.packages.foundation.glibc;
foundation-binutils = config.packages.foundation.binutils; foundation-binutils = config.packages.foundation.binutils;
foundation-linux-headers = config.packages.foundation.linux-headers; foundation-linux-headers = config.packages.foundation.linux-headers;
# foundation-linux-headers = config.packages.foundation.linux-headers.versions.latest.extend {
# platform.host = lib.modules.overrides.force "x86_64-linux"; cross-foundation-glibc-x86_64-linux = config.packages.cross.x86_64-linux.foundation.glibc;
# }; cross-foundation-binutils-x86_64-linux = config.packages.cross.x86_64-linux.foundation.binutils;
# example-x = config.packages.example.x;
cross-aux-a-x86_64-linux = config.packages.cross.x86_64-linux.aux.a; cross-tool-foundation-gcc-newlib-x86_64-linux = config.packages.cross-tools.x86_64-linux.foundation.gcc-newlib;
cross-foundation-gcc-x86_64-linux = config.packages.cross.x86_64-linux.foundation.gcc; cross-tool-foundation-gcc-x86_64-linux = config.packages.cross-tools.x86_64-linux.foundation.gcc-cross;
cross-foundation-gcc-x86_64-linux = config.packages.cross.x86_64-linux.foundation.gcc-bootstrap;
example-a = config.packages.foundation.gcc.versions.latest.extend {
platform = {
target = lib.modules.override 0 "x86_64-linux";
};
};
}; };
}; };
# exported.packages.i686-linux.cross-foundation-gcc-x86_64-linux = config.packages.cross.x86_64-linux.foundation.gcc.package;
}; };
} }

View file

@ -230,6 +230,34 @@ in
default.value = [ ]; default.value = [ ];
}; };
# extend = lib.options.create {
# description = "Extend the package definition.";
# type = lib.types.function lib.types.raw;
# internal = true;
# writable = false;
# default.value = module:
# let
# normalized =
# if builtins.isList module then
# module
# else if builtins.isFunction module || module ? config then
# [ module ]
# else
# [{
# config = module;
# }];
# result = meta.extend {
# modules =
# normalized ++ [
# {
# config.__modules__ = lib.modules.overrides.force (config.__modules__ ++ normalized);
# }
# ];
# };
# in
# result.config;
# };
extend = lib.options.create { extend = lib.options.create {
description = "Extend the package definition."; description = "Extend the package definition.";
type = lib.types.function lib.types.raw; type = lib.types.function lib.types.raw;
@ -246,13 +274,14 @@ in
[{ [{
config = module; config = module;
}]; }];
result = meta.extend {
modules = modules = config.__modules__ ++ normalized;
normalized ++ [
{ result = lib.modules.run {
config.__modules__ = lib.modules.overrides.force (config.__modules__ ++ normalized); modules = [
} submodule
]; { config.__modules__ = modules; }
] ++ modules;
}; };
in in
result.config; result.config;
@ -261,8 +290,8 @@ in
meta = { meta = {
description = lib.options.create { description = lib.options.create {
description = "The description for the package."; description = "The description for the package.";
type = lib.types.nullish lib.types.string; type = lib.types.string;
default.value = null; default.value = "";
}; };
homepage = lib.options.create { homepage = lib.options.create {

View file

@ -1,4 +1,4 @@
{ lib', config }: { config }:
let let
inherit (config) builders packages; inherit (config) builders packages;
in in

View file

@ -4,7 +4,7 @@ let
doubles = lib.systems.doubles.all; doubles = lib.systems.doubles.all;
packages = builtins.removeAttrs config.packages [ "cross" ]; packages = builtins.removeAttrs config.packages [ "cross" "cross-tools" ];
in in
{ {
includes = [ includes = [
@ -21,6 +21,14 @@ in
freeform = lib.types.packages; freeform = lib.types.packages;
options = { options = {
cross-tools = lib.attrs.generate doubles (
system:
lib.options.create {
description = "The cross-compilation tools for the ${system} target.";
type = lib.types.packages;
default.value = { };
}
);
cross = lib.attrs.generate doubles ( cross = lib.attrs.generate doubles (
system: system:
lib.options.create { lib.options.create {
@ -54,6 +62,36 @@ in
}; };
config = { config = {
packages.cross-tools = lib.attrs.generate doubles (
system:
builtins.mapAttrs
(
namespace:
builtins.mapAttrs (
name: alias:
let
setTarget =
package:
package
// {
__modules__ = package.__modules__ ++ [
{
config.platform = {
target = lib.modules.override 5 system;
};
}
];
};
updated = alias // {
versions = builtins.mapAttrs (version: package: setTarget package) alias.versions;
};
in
updated
)
)
packages
);
packages.cross = lib.attrs.generate doubles ( packages.cross = lib.attrs.generate doubles (
system: system:
builtins.mapAttrs builtins.mapAttrs
@ -62,7 +100,7 @@ in
builtins.mapAttrs ( builtins.mapAttrs (
name: alias: name: alias:
let let
setHost = setPlatform =
package: package:
package package
// { // {
@ -77,7 +115,7 @@ in
}; };
updated = alias // { updated = alias // {
versions = builtins.mapAttrs (version: package: setHost package) alias.versions; versions = builtins.mapAttrs (version: package: setPlatform package) alias.versions;
}; };
in in
updated updated

View file

@ -1,8 +1,8 @@
{ { lib
lib, , lib'
lib', , config
config, , options
options, ,
}: }:
let let
inherit (config) inherit (config)
@ -27,101 +27,149 @@ in
}; };
}; };
config = { config =
meta = { let
platforms = [ "i686-linux" ]; isBuildBootstrapped = config.platform.build.double == "i686-linux";
}; isHostBootstrapped = config.platform.host.double == "i686-linux";
pname = "binutils"; isBootstrapped = isBuildBootstrapped && isHostBootstrapped;
version = "2.41";
builder = builders.basic; isCross =
config.platform.build.double != config.platform.host.double
&& config.platform.host.double == config.platform.target.double;
in
{
meta = {
platforms = [
"i686-linux"
"x86_64-linux"
];
};
deps = { pname = "binutils";
build = { version = "2.41";
host = {
inherit (packages.foundation) gcc; builder = builders.basic;
deps = {
build = {
only = {
gcc = lib.modules.when (!isBootstrapped) (
if isCross then
packages.foundation.gcc-cross.versions.latest.extend
{
platform = lib.modules.override 0 {
inherit (config.platform) build target;
host = config.platform.build;
};
}
else
packages.foundation.gcc.versions.latest
);
glibc = lib.modules.when (isCross) (
packages.foundation.glibc.versions.latest.extend {
platform = lib.modules.override 0 {
inherit (config.platform) host target build;
};
}
);
binutils = lib.modules.when (isCross) (
packages.foundation.binutils.versions.latest.extend {
platform = lib.modules.override 0 {
inherit (config.platform) target build;
host = config.platform.build;
};
}
);
};
}; };
}; };
};
env = { env = {
PATH = lib.paths.bin [ PATH = lib.paths.bin (
# foundation.stage2-gcc lib.lists.when (isBootstrapped) [ foundation.stage2-gcc ]
foundation.stage2-binutils ++ [
foundation.stage2-gnumake foundation.stage2-gcc
foundation.stage2-gnupatch foundation.stage2-binutils
foundation.stage2-gnused foundation.stage2-gnumake
foundation.stage2-gnugrep foundation.stage2-gnupatch
foundation.stage2-gawk foundation.stage2-gnused
foundation.stage2-diffutils foundation.stage2-gnugrep
foundation.stage2-findutils foundation.stage2-gawk
foundation.stage2-gnutar foundation.stage2-diffutils
foundation.stage1-xz foundation.stage2-findutils
]; foundation.stage2-gnutar
}; foundation.stage1-xz
]
);
} // (lib.attrs.when (isCross) {
LDFLAGS_FOR_TARGET = "-B${config.deps.build.only.glibc.package}/lib -L${config.deps.build.only.glibc.package}/lib -I${config.deps.build.only.glibc.package}/include";
});
phases = phases =
let let
patches = [ patches = [
# Make binutils output deterministic by default. # Make binutils output deterministic by default.
./patches/deterministic.patch ./patches/deterministic.patch
]; ];
configureFlags = [ configureFlags =
# "CC=musl-gcc" lib.lists.when (!isCross) [
"LDFLAGS=--static" "LDFLAGS=--static"
"--prefix=${builtins.placeholder "out"}" ]
"--build=${config.platform.build.triple}" ++ [
"--host=${config.platform.host.triple}" "--prefix=${builtins.placeholder "out"}"
"--target=${config.platform.target.triple}" "--build=${config.platform.build.triple}"
"--host=${config.platform.host.triple}"
"--target=${config.platform.target.triple}"
"--with-sysroot=/" "--with-sysroot=/"
"--enable-deterministic-archives" "--enable-deterministic-archives"
# depends on bison # depends on bison
"--disable-gprofng" "--disable-gprofng"
# Turn on --enable-new-dtags by default to make the linker set # Turn on --enable-new-dtags by default to make the linker set
# RUNPATH instead of RPATH on binaries. This is important because # RUNPATH instead of RPATH on binaries. This is important because
# RUNPATH can be overridden using LD_LIBRARY_PATH at runtime. # RUNPATH can be overridden using LD_LIBRARY_PATH at runtime.
"--enable-new-dtags" "--enable-new-dtags"
# By default binutils searches $libdir for libraries. This brings in # By default binutils searches $libdir for libraries. This brings in
# libbfd and libopcodes into a default visibility. Drop default lib # libbfd and libopcodes into a default visibility. Drop default lib
# path to force users to declare their use of these libraries. # path to force users to declare their use of these libraries.
"--with-lib-path=:" "--with-lib-path=:"
"--disable-multilib" "--disable-multilib"
];
in
{
unpack = ''
tar xf ${config.src}
cd binutils-${config.version}
'';
patch = '' ];
${lib.strings.concatMapSep "\n" (file: "patch -Np1 -i ${file}") patches} in
''; {
unpack = ''
tar xf ${config.src}
cd binutils-${config.version}
'';
configure = '' patch = ''
bash ./configure ${builtins.concatStringsSep " " configureFlags} ${lib.strings.concatMapSep "\n" (file: "patch -Np1 -i ${file}") patches}
''; '';
build = '' configure = ''
make -j $NIX_BUILD_CORES bash ./configure ${builtins.concatStringsSep " " configureFlags}
''; '';
install = '' build = ''
make -j $NIX_BUILD_CORES install-strip make -j $NIX_BUILD_CORES
''; '';
install = ''
make -j $NIX_BUILD_CORES install-strip
'';
};
src = builtins.fetchurl {
url = "${mirrors.gnu}/binutils/binutils-${config.version}.tar.xz";
sha256 = "rppXieI0WeWWBuZxRyPy0//DHAMXQZHvDQFb3wYAdFA=";
}; };
src = builtins.fetchurl {
url = "${mirrors.gnu}/binutils/binutils-${config.version}.tar.xz";
sha256 = "rppXieI0WeWWBuZxRyPy0//DHAMXQZHvDQFb3wYAdFA=";
}; };
};
}; };
}; };
}; };

View file

@ -0,0 +1,84 @@
{ config, options }:
let
inherit (config)
lib
packages
;
in
{
config.packages.foundation.gcc-bootstrap = {
versions = {
"latest" = config.packages.foundation.gcc.versions.latest.extend
(
{ config }:
{
config = {
meta = {
platforms = lib.modules.override 0 [
"i686-linux"
];
};
deps = {
build = {
build = {
gcc = lib.modules.override 0 (
packages.foundation.gcc-cross.versions.latest.extend {
platform = lib.modules.override 0 {
build = "i686-linux";
target = config.platform.target;
host = "i686-linux";
};
}
);
binutils = lib.modules.override 0 (
packages.foundation.binutils.versions.latest.extend {
platform = lib.modules.override 0 {
build = "i686-linux";
target = config.platform.target;
host = config.platform.host;
};
}
);
glibc = lib.modules.override 0 (
packages.foundation.glibc.versions.latest.extend {
platform = lib.modules.override 0 {
build = "i686-linux";
target = config.platform.target;
host = config.platform.host;
};
}
);
};
};
};
env = {
LIBRARY_PATH = lib.modules.override 0 "${config.deps.build.build.glibc.package}/lib";
LDFLAGS_FOR_TARGET =
lib.modules.override 0
"-L$(pwd)/${config.platform.target.triple}/libgcc -L${config.deps.build.build.glibc.package}/lib";
};
configureFlags = lib.modules.override 0 [
"--prefix=${builtins.placeholder "out"}"
# Pretend we're native even though we're not
"--build=${config.platform.target.triple}"
"--host=${config.platform.host.triple}"
"--target=${config.platform.target.triple}"
"--with-as=${config.deps.build.build.binutils.package}/bin/as"
"--with-ld=${config.deps.build.build.binutils.package}/bin/ld"
"--enable-languages=c,c++"
"--disable-bootstrap"
"--disable-libsanitizer"
"--disable-multilib"
"--with-native-system-header-dir=${config.deps.build.build.glibc.package}/include"
"--with-gxx-include-dir=${placeholder "out"}/include/c++/${config.version}/"
"--with-build-sysroot=/"
];
};
}
);
};
};
}

View file

@ -0,0 +1,104 @@
{ config, options }:
let
inherit (config)
lib
foundation
packages
;
in
{
config.packages.foundation.gcc-cross = {
versions = {
"latest" = config.packages.foundation.gcc.versions.latest.extend
(
{ config }:
{
config =
let
programPrefix = lib.strings.when
(
config.platform.build.triple != config.platform.target.triple
) "${config.platform.target.triple}-";
in
{
meta = {
platforms = lib.modules.override 0 [
"i686-linux"
];
};
deps = {
build = {
build = {
binutils = (
packages.foundation.binutils.versions.latest.extend {
platform = lib.modules.override 0 config.platform;
}
);
glibc = (
packages.foundation.glibc.versions.latest.extend {
platform = lib.modules.override 0 {
inherit (config.platform) build target;
host = config.platform.target;
};
}
);
linux-headers = (
packages.foundation.linux-headers.versions.latest.extend {
platform.target = lib.modules.override 0 config.platform.target;
}
);
};
};
};
env = {
# LIBRARY_PATH = lib.modules.override 0 "${foundation.stage1-musl}/lib";
CC = lib.modules.override 0 "gcc -Wl,-dynamic-linker -Wl,${foundation.stage1-musl}/lib/libc.so -idirafter ${foundation.stage1-musl}/include";
CXX = lib.modules.override 0 "g++ -Wl,-dynamic-linker -Wl,${foundation.stage1-musl}/lib/libc.so -idirafter ${foundation.stage1-musl}/include";
CFLAGS_FOR_TARGET =
lib.modules.override 0
"-Wl,-dynamic-linker -Wl,${config.deps.build.build.glibc.package}/lib/ld-linux-x86-64.so.2 -B${config.deps.build.build.glibc.package}/lib";
LDFLAGS_FOR_TARGET =
lib.modules.override 0
"-L$(pwd)/${config.platform.target.triple}/libgcc -L${config.deps.build.build.glibc.package}/lib";
};
configureFlags = lib.modules.override 0 [
"--prefix=${builtins.placeholder "out"}"
"--build=${config.platform.build.triple}"
"--host=${config.platform.host.triple}"
"--target=${config.platform.target.triple}"
"--with-as=${config.deps.build.build.binutils.package}/bin/${programPrefix}as"
"--with-ld=${config.deps.build.build.binutils.package}/bin/${programPrefix}ld"
"--enable-languages=c,c++"
"--disable-libsanitizer"
"--disable-lto"
"--disable-multilib"
"--with-headers=${config.deps.build.build.glibc.package}/include"
"--with-build-sysroot=/"
# "--with-sysroot=${config.deps.build.build.glibc.package}"
"--with-native-system-header-dir=${config.deps.build.build.glibc.package}/include"
];
phases.configure = lib.modules.override 0 ''
# Configure
mkdir build
cd build
echo PATH=$PATH
# TODO(vlinkz) Hack to fix missing crti.o and crtn.o. Figure out how to properly find their paths.
mkdir gcc
ln -sv ${config.deps.build.build.glibc.package}/lib/{crti.o,crtn.o} gcc
mkdir -p x86_64-unknown-linux-gnu/libstdc++-v3/src
ln -sv ${config.deps.build.build.glibc.package}/lib/{crti.o,crtn.o} x86_64-unknown-linux-gnu/libstdc++-v3/src
bash ../configure ${builtins.concatStringsSep " " config.configureFlags}
'';
};
}
);
};
};
}

View file

@ -11,12 +11,11 @@ let
; ;
in in
{ {
config.packages.context.options = { includes = [
"foundation:cflags" = lib.options.create { ./newlib.nix
type = lib.types.list.of lib.types.string; ./cross.nix
default.value = [ ]; ./bootstrap.nix
}; ];
};
config.packages.foundation.gcc = { config.packages.foundation.gcc = {
versions = { versions = {
@ -82,135 +81,239 @@ in
description = "Version of isl."; description = "Version of isl.";
}; };
}; };
};
config = { configureFlags = lib.options.create {
meta = { type = lib.types.list.of lib.types.string;
platforms = [ "i686-linux" ]; description = "Flags to pass to the configure script.";
}; };
pname = "gcc"; exports = lib.options.create {
version = "13.2.0"; type = lib.types.attrs.of lib.types.string;
description = "List of exports to add to the environment.";
builder = builders.basic;
env = {
PATH = lib.paths.bin [
foundation.stage2-gcc
foundation.stage2-binutils
foundation.stage2-gnumake
foundation.stage2-gnused
foundation.stage2-gnugrep
foundation.stage2-gawk
foundation.stage2-diffutils
foundation.stage2-findutils
foundation.stage2-gnutar
foundation.stage2-gzip
foundation.stage2-bzip2
foundation.stage1-xz
];
};
phases =
let
host = lib.systems.withBuildInfo config.platform.host;
mbits = if host.system.cpu.family == "x86" then if host.is64bit then "-m64" else "-m32" else "";
in
{
unpack = ''
# Unpack
tar xf ${config.src}
tar xf ${config.gmp.src}
tar xf ${config.mpfr.src}
tar xf ${config.mpc.src}
tar xf ${config.isl.src}
cd gcc-${config.version}
ln -s ../gmp-${config.gmp.version} gmp
ln -s ../mpfr-${config.mpfr.version} mpfr
ln -s ../mpc-${config.mpc.version} mpc
ln -s ../isl-${config.isl.version} isl
'';
patch = ''
# Patch
# force musl even if host triple is gnu
sed -i 's|"os/gnu-linux"|"os/generic"|' libstdc++-v3/configure.host
'';
configure = ''
# Configure
export CC="gcc -Wl,-dynamic-linker -Wl,${foundation.stage1-musl}/lib/libc.so"
export CXX="g++ -Wl,-dynamic-linker -Wl,${foundation.stage1-musl}/lib/libc.so"
export CFLAGS_FOR_TARGET="-Wl,-dynamic-linker -Wl,${foundation.stage1-musl}/lib/libc.so"
export LIBRARY_PATH="${foundation.stage1-musl}/lib"
bash ./configure \
--prefix=$out \
--build=${config.platform.build.triple} \
--host=${config.platform.host.triple} \
--target=${config.platform.target.triple} \
--with-native-system-header-dir=/include \
--with-sysroot=${foundation.stage1-musl} \
--enable-languages=c,c++ \
--disable-bootstrap \
--disable-libsanitizer \
--disable-lto \
--disable-multilib \
--disable-plugin \
CFLAGS=-static \
CXXFLAGS=-static
'';
build = ''
# Build
make -j $NIX_BUILD_CORES
'';
install = ''
# Install
make -j $NIX_BUILD_CORES install-strip
'';
};
src = builtins.fetchurl {
url = "${mirrors.gnu}/gcc/gcc-${config.version}/gcc-${config.version}.tar.xz";
sha256 = "4nXnZEKmBnNBon8Exca4PYYTFEAEwEE1KIY9xrXHQ9o=";
};
gmp = {
version = "6.3.0";
src = builtins.fetchurl {
url = "${mirrors.gnu}/gmp/gmp-${config.gmp.version}.tar.xz";
sha256 = "o8K4AgG4nmhhb0rTC8Zq7kknw85Q4zkpyoGdXENTiJg=";
};
};
mpfr = {
version = "4.2.1";
src = builtins.fetchurl {
url = "${mirrors.gnu}/mpfr/mpfr-${config.mpfr.version}.tar.xz";
sha256 = "J3gHNTpnJpeJlpRa8T5Sgp46vXqaW3+yeTiU4Y8fy7I=";
};
};
mpc = {
version = "1.3.1";
src = builtins.fetchurl {
url = "${mirrors.gnu}/mpc/mpc-${config.mpc.version}.tar.gz";
sha256 = "q2QkkvXPiCt0qgy3MM1BCoHtzb7IlRg86TDnBsHHWbg=";
};
};
isl = {
version = "0.24";
src = builtins.fetchurl {
url = "https://gcc.gnu.org/pub/gcc/infrastructure/isl-${config.isl.version}.tar.bz2";
sha256 = "/PeN2WVsEOuM+fvV9ZoLawE4YgX+GTSzsoegoYmBRcA=";
};
}; };
}; };
config =
let
isBuildBootstrapped = config.platform.build.double == "i686-linux";
isHostBootstrapped = config.platform.host.double == "i686-linux";
isBootstrapped = isBuildBootstrapped && isHostBootstrapped;
crossTool =
(config.platform.target.triple != config.platform.host.triple)
&& (config.platform.host.triple == config.platform.build.triple);
cross =
(config.platform.target.triple != config.platform.host.triple)
&& (config.platform.host.triple == config.platform.target.triple);
programPrefix = lib.strings.when
(
config.platform.build.triple != config.platform.target.triple
) "${config.platform.target.triple}-";
libc = if isBootstrapped then foundation.stage1-musl else config.deps.build.build.glibc.package;
libcLd =
if isBootstrapped then
"${foundation.stage1-musl}/lib/libc.so"
else
"${config.deps.build.build.glibc.package}/lib/ld-linux-x86-64.so.2";
host = lib.systems.withBuildInfo config.platform.host;
target = lib.systems.withBuildInfo config.platform.target;
in
{
meta = {
platforms = [
"i686-linux"
];
};
pname = "gcc-${config.platform.build.double}--${config.platform.host.double}--${config.platform.target.double}";
version = "13.2.0";
builder = builders.basic;
deps = {
build = {
build = lib.modules.when (!isBootstrapped) {
gcc = packages.foundation.gcc-cross.versions.latest;
glibc = packages.foundation.glibc.versions.latest;
linux-headers = packages.foundation.linux-headers.versions.latest;
binutils = packages.foundation.binutils.versions.latest;
};
};
};
env =
{
PATH = lib.modules.when (isBuildBootstrapped) (
lib.paths.bin ([
foundation.stage2-gnumake
foundation.stage2-gnused
foundation.stage2-gnugrep
foundation.stage2-gnupatch
foundation.stage2-gawk
foundation.stage2-diffutils
foundation.stage2-findutils
foundation.stage2-gnutar
foundation.stage2-gzip
foundation.stage2-bzip2
foundation.stage1-xz
] ++ (lib.lists.when (isBootstrapped) [
foundation.stage2-gcc
foundation.stage2-binutils
]))
);
CFLAGS_FOR_TARGET = "-Wl,-dynamic-linker -Wl,${libcLd}";
}
// lib.attrs.when (isBootstrapped) {
CC = "gcc -Wl,-dynamic-linker -Wl,${foundation.stage1-musl}/lib/libc.so";
CXX = "g++ -Wl,-dynamic-linker -Wl,${foundation.stage1-musl}/lib/libc.so";
}
// lib.attrs.when (!cross && !crossTool) {
LIBRARY_PATH = "${libc}/lib";
};
hooks =
let
flags =
if (isBootstrapped && !(cross || crossTool)) then
[
"-Wl,-dynamic-linker"
"-Wl,${foundation.stage1-musl}/lib/libc.so"
]
else
[
"-Wl,-dynamic-linker"
"-Wl,${config.deps.build.build.glibc.package}/lib/ld-linux${lib.strings.when (target.isx86 && target.is64bit) "-x86-64"}.so.2"
"-B${config.deps.build.build.glibc.package}/lib"
# "-idirafter ${config.deps.build.build.glibc.package}/include"
];
in
ctx: {
"aux:gcc:env" = lib.dag.entry.between [ "unpack" ] [ "configure" ] ''
export CC='${config.package}/bin/${programPrefix}gcc ${builtins.concatStringsSep " " flags}'
export CXX='${config.package}/bin/${programPrefix}g++ ${builtins.concatStringsSep " " flags}'
export CC_FOR_TARGET=$CC
export CXX_FOR_TARGET=$CXX
export CC_FOR_BUILD=$CC
export CXX_FOR_BUILD=$CXX
alias gcc='$CC'
alias g++='$CXX'
'';
};
configureFlags =
[
"--prefix=${builtins.placeholder "out"}"
"--build=${config.platform.build.triple}"
"--host=${config.platform.host.triple}"
"--target=${config.platform.target.triple}"
"--enable-languages=c,c++"
"--disable-bootstrap"
"--disable-libsanitizer"
"--disable-multilib"
"--with-build-sysroot=/"
"--with-native-system-header-dir=${libc}/include"
]
++ lib.lists.when (isBootstrapped) [
"--disable-lto"
];
phases =
let
patches = [
# Make binutils output deterministic by default.
./patches/libstdc++-target.patch
];
in
{
unpack = ''
# Unpack
tar xf ${config.src}
tar xf ${config.gmp.src}
tar xf ${config.mpfr.src}
tar xf ${config.mpc.src}
tar xf ${config.isl.src}
cd gcc-${config.version}
ln -s ../gmp-${config.gmp.version} gmp
ln -s ../mpfr-${config.mpfr.version} mpfr
ln -s ../mpc-${config.mpc.version} mpc
ln -s ../isl-${config.isl.version} isl
'';
patch = ''
${lib.strings.concatMapSep "\n" (file: "patch -Np1 -i ${file}") patches}
${lib.strings.when (isBootstrapped && !(crossTool || cross))''
# force musl even if host triple is gnu
sed -i 's|"os/gnu-linux"|"os/generic"|' libstdc++-v3/configure.host
''}
'';
configure = ''
# Configure
mkdir build
cd build
bash ../configure ${builtins.concatStringsSep " " config.configureFlags}
'';
build = ''
# Build
make -j $NIX_BUILD_CORES
'';
install = ''
# Install
${
lib.strings.when (host.is64bit) ''
mkdir -p $out/lib
ln -s lib $out/lib64
''
}
make -j $NIX_BUILD_CORES install
'';
};
src = builtins.fetchurl {
url = "${mirrors.gnu}/gcc/gcc-${config.version}/gcc-${config.version}.tar.xz";
sha256 = "4nXnZEKmBnNBon8Exca4PYYTFEAEwEE1KIY9xrXHQ9o=";
};
gmp = {
version = "6.3.0";
src = builtins.fetchurl {
url = "${mirrors.gnu}/gmp/gmp-${config.gmp.version}.tar.xz";
sha256 = "o8K4AgG4nmhhb0rTC8Zq7kknw85Q4zkpyoGdXENTiJg=";
};
};
mpfr = {
version = "4.2.1";
src = builtins.fetchurl {
url = "${mirrors.gnu}/mpfr/mpfr-${config.mpfr.version}.tar.xz";
sha256 = "J3gHNTpnJpeJlpRa8T5Sgp46vXqaW3+yeTiU4Y8fy7I=";
};
};
mpc = {
version = "1.3.1";
src = builtins.fetchurl {
url = "${mirrors.gnu}/mpc/mpc-${config.mpc.version}.tar.gz";
sha256 = "q2QkkvXPiCt0qgy3MM1BCoHtzb7IlRg86TDnBsHHWbg=";
};
};
isl = {
version = "0.24";
src = builtins.fetchurl {
url = "https://gcc.gnu.org/pub/gcc/infrastructure/isl-${config.isl.version}.tar.bz2";
sha256 = "/PeN2WVsEOuM+fvV9ZoLawE4YgX+GTSzsoegoYmBRcA=";
};
};
};
}; };
}; };
}; };

View file

@ -0,0 +1,71 @@
{ config, options }:
let
inherit (config)
lib
packages
;
in
{
config.packages.foundation.gcc-newlib = {
versions = {
"latest" = config.packages.foundation.gcc.versions.latest.extend (
{ config }:
{
config =
let
programPrefix = lib.strings.when
(
config.platform.build.triple != config.platform.target.triple
) "${config.platform.target.triple}-";
in
{
meta = {
platforms = lib.modules.override 0 [
"i686-linux"
];
};
deps = {
build = {
build = {
binutils = (
packages.foundation.binutils.versions.latest.extend {
platform = lib.modules.override 0 config.platform;
}
);
};
};
};
configureFlags = lib.modules.override 0 [
"--prefix=${builtins.placeholder "out"}"
"--build=${config.platform.build.triple}"
"--host=${config.platform.host.triple}"
"--target=${config.platform.target.triple}"
"--with-as=${config.deps.build.build.binutils.package}/bin/${programPrefix}as"
"--with-ld=${config.deps.build.build.binutils.package}/bin/${programPrefix}ld"
"--enable-languages=c,c++"
"--disable-bootstrap"
"--disable-libsanitizer"
"--disable-lto"
"--disable-multilib"
"--disable-plugin"
"--disable-libssp"
"--disable-libvtv"
"--disable-libstdcxx"
"--disable-libquadmath"
"--disable-threads"
"--disable-decimal-float"
"--disable-shared"
"--disable-libmudflap"
"--disable-libgomp"
"--disable-libatomic"
"--without-headers"
"--with-newlib"
];
};
}
);
};
};
}

View file

@ -0,0 +1,33 @@
# From https://github.com/NixOS/nixpkgs/blob/nixos-24.05/pkgs/development/compilers/gcc/patches/libstdc%2B%2B-target.patch
Patch to make the target libraries 'configure' scripts find the proper CPP.
I noticed that building the mingw32 cross compiler.
Looking at the build script for mingw in archlinux, I think that only nixos
needs this patch. I don't know why.
diff --git a/Makefile.in b/Makefile.in
index 93f66b6..d691917 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -266,6 +266,7 @@ BASE_TARGET_EXPORTS = \
AR="$(AR_FOR_TARGET)"; export AR; \
AS="$(COMPILER_AS_FOR_TARGET)"; export AS; \
CC="$(CC_FOR_TARGET) $(XGCC_FLAGS_FOR_TARGET) $$TFLAGS"; export CC; \
+ CPP="$(CC_FOR_TARGET) $(XGCC_FLAGS_FOR_TARGET) $$TFLAGS -E"; export CC; \
CFLAGS="$(CFLAGS_FOR_TARGET)"; export CFLAGS; \
CONFIG_SHELL="$(SHELL)"; export CONFIG_SHELL; \
CPPFLAGS="$(CPPFLAGS_FOR_TARGET)"; export CPPFLAGS; \
@@ -291,11 +292,13 @@ BASE_TARGET_EXPORTS = \
RAW_CXX_TARGET_EXPORTS = \
$(BASE_TARGET_EXPORTS) \
CXX_FOR_TARGET="$(RAW_CXX_FOR_TARGET)"; export CXX_FOR_TARGET; \
- CXX="$(RAW_CXX_FOR_TARGET) $(XGCC_FLAGS_FOR_TARGET) $$TFLAGS"; export CXX;
+ CXX="$(RAW_CXX_FOR_TARGET) $(XGCC_FLAGS_FOR_TARGET) $$TFLAGS"; export CXX; \
+ CXXCPP="$(RAW_CXX_FOR_TARGET) $(XGCC_FLAGS_FOR_TARGET) $$TFLAGS -E"; export CXX;
NORMAL_TARGET_EXPORTS = \
$(BASE_TARGET_EXPORTS) \
- CXX="$(CXX_FOR_TARGET) $(XGCC_FLAGS_FOR_TARGET) $$TFLAGS"; export CXX;
+ CXX="$(CXX_FOR_TARGET) $(XGCC_FLAGS_FOR_TARGET) $$TFLAGS"; export CXX; \
+ CXXCPP="$(CXX_FOR_TARGET) $(XGCC_FLAGS_FOR_TARGET) $$TFLAGS -E"; export CXX;
# Where to find GMP
HOST_GMPLIBS = @gmplibs@

View file

@ -3,6 +3,7 @@
lib', lib',
config, config,
options, options,
packages,
}: }:
let let
inherit (config) inherit (config)
@ -10,6 +11,7 @@ let
builders builders
# These are the upstream foundational packages exported from the Aux Foundation project. # These are the upstream foundational packages exported from the Aux Foundation project.
packages
foundation foundation
; ;
in in
@ -26,87 +28,124 @@ in
}; };
}; };
config = { config =
meta = { let
platforms = [ "i686-linux" ]; isCross =
}; (config.platform.build.triple != config.platform.host.triple)
&& (config.platform.host.triple == config.platform.target.triple);
pname = "gcc"; binutils =
version = "2.38"; if isCross then
"${
(packages.foundation.binutils.versions.latest.extend {
platform = lib.modules.override 0 {
inherit (config.platform) build target;
host = config.platform.build;
};
}).package
}/${config.platform.target.triple}"
else
foundation.stage2-binutils;
in
{
src = builtins.fetchurl { meta = {
url = "${mirrors.gnu}/libc/glibc-${config.version}.tar.xz"; platforms = [
sha256 = "+4KZiZiyspllRnvBtp0VLpwwfSzzAcnq+0VVt3DvP9I="; "i686-linux"
}; "x86_64-linux"
builder = builders.basic;
env = {
PATH =
let
gcc =
if
config.platform.build.triple == config.platform.host.triple
# If we're on the same system then we can use the existing GCC instance.
then
foundation.stage2-gcc
# Otherwise we are going to need a cross-compiler.
else
(meta.extend (args: {
config = {
platform = {
build = config.platform.build.triple;
host = config.platform.build.triple;
target = lib.modules.override.force config.platform.host.triple;
};
};
})).config.package;
in
lib.paths.bin [
foundation.stage2-gcc
foundation.stage2-binutils
foundation.stage2-gnumake
foundation.stage2-gnused
foundation.stage2-gnugrep
foundation.stage2-gawk
foundation.stage2-diffutils
foundation.stage2-findutils
foundation.stage2-gnutar
foundation.stage2-gzip
foundation.stage2-bzip2
foundation.stage1-xz
]; ];
};
pname = "glibc";
version = "2.38";
src = builtins.fetchurl {
url = "${mirrors.gnu}/libc/glibc-${config.version}.tar.xz";
sha256 = "+4KZiZiyspllRnvBtp0VLpwwfSzzAcnq+0VVt3DvP9I=";
};
builder = builders.basic;
deps = {
build = {
host = {
linux-headers = (
packages.foundation.linux-headers.versions.latest.extend {
platform.target = lib.modules.override 0 config.platform.target;
}
);
};
};
};
env = {
PATH =
let
gcc =
if
isCross
# Otherwise we are going to need a cross-compiler.
then
(packages.foundation.gcc-newlib.versions.latest.extend {
platform = lib.modules.override 0 {
inherit (config.platform) build target;
host = config.platform.build;
};
}).package
# If we're on the same system then we can use the existing GCC instance.
else
foundation.stage2-gcc;
in
lib.paths.bin [
gcc
binutils
foundation.stage2-gnumake
foundation.stage2-gnused
foundation.stage2-gnugrep
foundation.stage2-gawk
foundation.stage2-diffutils
foundation.stage2-findutils
foundation.stage2-gnutar
foundation.stage2-gzip
foundation.stage2-bzip2
foundation.stage1-python
foundation.stage1-bison
foundation.stage1-xz
];
};
phases =
{
unpack = ''
tar xf ${config.src}
cd glibc-${config.version}
'';
configure = ''
mkdir build
cd build
bash ../configure \
--prefix=$out \
--build=${config.platform.build.triple} \
--host=${config.platform.host.triple} \
--with-headers=${config.deps.build.host.linux-headers.package}/include \
--with-binutils=${binutils}/bin
'';
build = ''
# Build
make -j $NIX_BUILD_CORES
'';
install = ''
# Install
make -j $NIX_BUILD_CORES install
ln -sv $(ls -d ${config.deps.build.host.linux-headers.package}/include/* | grep -v scsi\$) $out/include/
'';
};
}; };
phases = {
unpack = ''
tar xf ${config.src}
cd glibc-${config.version}
'';
configure = ''
mkdir build
cd build
# libstdc++.so is built against musl and fails to link
export CXX=false
bash ../configure \
--prefix=$out \
--build=${config.platform.build.triple} \
--host=${config.platform.host.triple} \
--with-headers=${foundation.stage1-linux-headers}/include
'';
build = ''
# Build
make -j $NIX_BUILD_CORES
'';
install = ''
# Install
make -j $NIX_BUILD_CORES install-strip
'';
};
};
}; };
}; };
}; };

View file

@ -1,8 +1,8 @@
{ { lib
lib, , lib'
lib', , config
config, , options
options, ,
}: }:
let let
inherit (config) inherit (config)
@ -28,7 +28,7 @@ in
config = { config = {
meta = { meta = {
platforms = [ "i686-linux" ]; platforms = [ "x86_64-linux" "i686-linux" ];
}; };
pname = "linux-headers"; pname = "linux-headers";
@ -60,7 +60,7 @@ in
''; '';
build = '' build = ''
make -j $NIX_BUILD_CORES CC=musl-gcc HOSTCC=musl-gcc ARCH=${config.platform.host.linux.arch} headers make -j $NIX_BUILD_CORES CC=musl-gcc HOSTCC=musl-gcc ARCH=${config.platform.target.linux.arch} headers
''; '';
install = '' install = ''