From 560078707cdc28b05882638513beaacd23a8df95 Mon Sep 17 00:00:00 2001 From: Jake Hamilton Date: Thu, 6 Jun 2024 17:13:22 -0700 Subject: [PATCH] feat: add tinycc --- foundation/src/stages/stage1/default.nix | 17 ++ .../src/stages/stage1/ln-boot/default.nix | 64 ++++++ foundation/src/stages/stage1/ln-boot/main.c | 16 ++ foundation/src/stages/stage1/mes/default.nix | 1 + foundation/src/stages/stage1/mes/libc.nix | 95 +++++++++ foundation/src/stages/stage1/mes/libs.nix | 6 +- foundation/src/stages/stage1/tinycc/boot.nix | 194 ++++++++++++++++++ .../src/stages/stage1/tinycc/default.nix | 55 +++++ .../src/stages/stage1/tinycc/helpers.nix | 176 ++++++++++++++++ foundation/src/stages/stage1/tinycc/mes.nix | 142 +++++++++++++ 10 files changed, 765 insertions(+), 1 deletion(-) create mode 100644 foundation/src/stages/stage1/ln-boot/default.nix create mode 100644 foundation/src/stages/stage1/ln-boot/main.c create mode 100644 foundation/src/stages/stage1/mes/libc.nix create mode 100644 foundation/src/stages/stage1/tinycc/boot.nix create mode 100644 foundation/src/stages/stage1/tinycc/default.nix create mode 100644 foundation/src/stages/stage1/tinycc/helpers.nix create mode 100644 foundation/src/stages/stage1/tinycc/mes.nix diff --git a/foundation/src/stages/stage1/default.nix b/foundation/src/stages/stage1/default.nix index c25a027..101b21e 100644 --- a/foundation/src/stages/stage1/default.nix +++ b/foundation/src/stages/stage1/default.nix @@ -9,6 +9,8 @@ in { includes = [ ./nyacc ./mes + ./ln-boot + ./tinycc ]; config = { @@ -17,6 +19,12 @@ in { stage1-nyacc = stage1.nyacc.package; stage1-mes = stage1.mes.compiler.package; stage1-mes-libs = stage1.mes.libs.package; + stage1-ln-boot = stage1.ln-boot.package; + stage1-mes-libc = stage1.mes.libc.package; + stage1-tinycc-boot = stage1.tinycc.boot.compiler.package; + stage1-tinycc-boot-libs = stage1.tinycc.boot.libs.package; + stage1-tinycc-mes = stage1.tinycc.mes.compiler.package; + stage1-tinycc-mes-libs = stage1.tinycc.mes.libs.package; }; extras = { @@ -27,6 +35,15 @@ in { prefix = stage1.mes.libs.prefix; }; }; + tinycc = { + boot = { + src = stage1.tinycc.boot.src; + tarball = builtins.fetchurl { + url = "https://gitlab.com/janneke/tinycc/-/archive/${stage1.tinycc.boot.revision}/tinycc-${stage1.tinycc.boot.revision}.tar.gz"; + sha256 = "1a0cw9a62qc76qqn5sjmp3xrbbvsz2dxrw21lrnx9q0s74mwaxbq"; + }; + }; + }; }; }; }; diff --git a/foundation/src/stages/stage1/ln-boot/default.nix b/foundation/src/stages/stage1/ln-boot/default.nix new file mode 100644 index 0000000..172159a --- /dev/null +++ b/foundation/src/stages/stage1/ln-boot/default.nix @@ -0,0 +1,64 @@ +{ + lib, + config, +}: let + cfg = config.aux.foundation.stages.stage1.ln-boot; + + builders = config.aux.foundation.builders; + + stage0 = config.aux.foundation.stages.stage0; + stage1 = config.aux.foundation.stages.stage1; +in { + options.aux.foundation.stages.stage1.ln-boot = { + package = lib.options.create { + type = lib.types.package; + description = "The package to use for ln-boot."; + }; + + meta = { + description = lib.options.create { + type = lib.types.string; + description = "Description for the package."; + default.value = "A basic program to create symlinks."; + }; + + homepage = lib.options.create { + type = lib.types.string; + description = "Homepage for the package."; + default.value = "https://github.com/auxolotl/labs"; + }; + + license = lib.options.create { + # TODO: Add a proper type for licenses. + type = lib.types.attrs.any; + description = "License for the package."; + default.value = lib.licenses.mit; + }; + + platforms = lib.options.create { + type = lib.types.list.of lib.types.string; + description = "Platforms the package supports."; + default.value = ["x86_64-linux" "aarch64-linux" "i686-linux"]; + }; + }; + }; + + config = { + aux.foundation.stages.stage1.ln-boot = { + package = builders.kaem.build { + name = "ln-boot"; + + meta = cfg.meta; + + script = '' + mkdir -p ''${out}/bin + ${stage1.mes.compiler.package}/bin/mes --no-auto-compile -e main ${stage1.mes.libs.src.bin}/bin/mescc.scm -- \ + -L ${stage1.mes.libs.package}/lib \ + -lc+tcc \ + -o ''${out}/bin/ln \ + ${./main.c} + ''; + }; + }; + }; +} diff --git a/foundation/src/stages/stage1/ln-boot/main.c b/foundation/src/stages/stage1/ln-boot/main.c new file mode 100644 index 0000000..2e16f39 --- /dev/null +++ b/foundation/src/stages/stage1/ln-boot/main.c @@ -0,0 +1,16 @@ +#include +#include +#include +#include + +int main(int argc, char **argv) { + if (argc != 4 || strcmp(argv[1], "-s")) { + fputs("Usage: ", stdout); + fputs(argv[0], stdout); + fputs(" -s TARGET LINK_NAME\n", stdout); + exit(EXIT_FAILURE); + } + + symlink(argv[2], argv[3]); + exit(EXIT_SUCCESS); +} diff --git a/foundation/src/stages/stage1/mes/default.nix b/foundation/src/stages/stage1/mes/default.nix index ccc9f87..91b9cfc 100644 --- a/foundation/src/stages/stage1/mes/default.nix +++ b/foundation/src/stages/stage1/mes/default.nix @@ -10,6 +10,7 @@ in { includes = [ ./compiler.nix ./libs.nix + ./libc.nix ]; options.aux.foundation.stages.stage1.mes = { diff --git a/foundation/src/stages/stage1/mes/libc.nix b/foundation/src/stages/stage1/mes/libc.nix new file mode 100644 index 0000000..cfe9191 --- /dev/null +++ b/foundation/src/stages/stage1/mes/libc.nix @@ -0,0 +1,95 @@ +{ + lib, + config, +}: let + cfg = config.aux.foundation.stages.stage1.mes.libc; + + builders = config.aux.foundation.builders; + + stage1 = config.aux.foundation.stages.stage1; +in { + options.aux.foundation.stages.stage1.mes.libc = { + package = lib.options.create { + type = lib.types.package; + description = "The package to use for mes-libc."; + }; + + meta = { + description = lib.options.create { + type = lib.types.string; + description = "Description for the package."; + default.value = "The Mes C Library"; + }; + + homepage = lib.options.create { + type = lib.types.string; + description = "Homepage for the package."; + default.value = "https://gnu.org/software/mes"; + }; + + license = lib.options.create { + # TODO: Add a proper type for licenses. + type = lib.types.attrs.any; + description = "License for the package."; + default.value = lib.licenses.gpl3Plus; + }; + + platforms = lib.options.create { + type = lib.types.list.of lib.types.string; + description = "Platforms the package supports."; + default.value = ["x86_64-linux" "aarch64-linux" "i686-linux"]; + }; + }; + }; + + config = { + aux.foundation.stages.stage1.mes.libc = { + package = let + sources = import ./sources.nix; + + libtcc1 = sources.x86.linux.gcc.libtcc1; + + first = lib.lists.take 100 sources.x86.linux.gcc.libc_gnu; + last = lib.lists.drop 100 sources.x86.linux.gcc.libc_gnu; + in + builders.kaem.build { + name = "mes-libc-${stage1.mes.version}"; + + meta = cfg.meta; + + deps.build.host = [ + stage1.ln-boot.package + ]; + + script = '' + cd ${stage1.mes.libs.prefix} + + # mescc compiled libc.a + mkdir -p ''${out}/lib/x86-mes + + # libc.c + catm ''${TMPDIR}/first.c ${builtins.concatStringsSep " " first} + catm ''${out}/lib/libc.c ''${TMPDIR}/first.c ${builtins.concatStringsSep " " last} + + # crt{1,n,i}.c + cp lib/linux/x86-mes-gcc/crt1.c ''${out}/lib + cp lib/linux/x86-mes-gcc/crtn.c ''${out}/lib + cp lib/linux/x86-mes-gcc/crti.c ''${out}/lib + + # libtcc1.c + catm ''${out}/lib/libtcc1.c ${builtins.concatStringsSep " " libtcc1} + + # getopt.c + cp lib/posix/getopt.c ''${out}/lib/libgetopt.c + + # Install headers + ln -s ${stage1.mes.libs.prefix}/include ''${out}/include + ''; + + extras = { + CFLAGS = "-DHAVE_CONFIG_H=1 -I${cfg.package}/include -I${cfg.package}/include/linux/x86"; + }; + }; + }; + }; +} diff --git a/foundation/src/stages/stage1/mes/libs.nix b/foundation/src/stages/stage1/mes/libs.nix index c170213..a980c76 100644 --- a/foundation/src/stages/stage1/mes/libs.nix +++ b/foundation/src/stages/stage1/mes/libs.nix @@ -199,7 +199,11 @@ in { libc-mini = createLib "libc-mini" sources.x86.linux.mescc.libc_mini; libmescc = createLib "libmescc" sources.x86.linux.mescc.libmescc; libc = createLib "libc" sources.x86.linux.mescc.libc; - libc_tcc = createLib "libc+tcc" sources.x86.linux.mescc.libc_tcc; + libc_tcc = createLib "libc+tcc" (sources.x86.linux.mescc.libc_tcc + ++ [ + # We need `symlink` support for `ln-boot` to work. + "lib/linux/symlink.c" + ]); in builders.kaem.build { name = "mes-m2-libs-${stage1.mes.version}"; diff --git a/foundation/src/stages/stage1/tinycc/boot.nix b/foundation/src/stages/stage1/tinycc/boot.nix new file mode 100644 index 0000000..02d4da4 --- /dev/null +++ b/foundation/src/stages/stage1/tinycc/boot.nix @@ -0,0 +1,194 @@ +args @ { + lib, + config, +}: let + cfg = config.aux.foundation.stages.stage1.tinycc.boot; + + builders = config.aux.foundation.builders; + + stage1 = config.aux.foundation.stages.stage1; + + pname = "tinycc-boot"; + + helpers = lib.fp.withDynamicArgs (import ./helpers.nix) args; +in { + options.aux.foundation.stages.stage1.tinycc.boot = { + compiler = { + package = lib.options.create { + type = lib.types.package; + description = "The package to use for the tinycc-boot compiler."; + }; + }; + + libs = { + package = lib.options.create { + type = lib.types.package; + description = "The package to use for the tinycc-boot libs."; + }; + }; + + meta = { + description = lib.options.create { + type = lib.types.string; + description = "Description for the package."; + default.value = "Tiny C Compiler's bootstrappable fork."; + }; + + homepage = lib.options.create { + type = lib.types.string; + description = "Homepage for the package."; + default.value = "https://repo.or.cz/w/tinycc.git"; + }; + + license = lib.options.create { + # TODO: Add a proper type for licenses. + type = lib.types.attrs.any; + description = "License for the package."; + default.value = lib.licenses.lgpl21Only; + }; + + platforms = lib.options.create { + type = lib.types.list.of lib.types.string; + description = "Platforms the package supports."; + default.value = ["x86_64-linux" "i686-linux"]; + }; + }; + + src = lib.options.create { + type = lib.types.string; + description = "Source for the package."; + }; + + revision = lib.options.create { + type = lib.types.string; + description = "Revision of the package."; + }; + }; + + config = { + aux.foundation.stages.stage1.tinycc.boot = let + tinycc-boot = let + tinycc-mes-bootstrappable = helpers.createBoot { + pname = "tinycc-mes-bootstrappable"; + version = stage1.tinycc.version; + src = cfg.src; + }; + + tinycc-boot0 = helpers.createTinyccMes { + pname = "tinycc-boot0"; + version = stage1.tinycc.version; + src = cfg.src; + args = [ + "-D HAVE_LONG_LONG_STUB=1" + "-D HAVE_SETJMP=1" + ]; + lib.args = [ + "-D HAVE_LONG_LONG_STUB=1" + ]; + boot = tinycc-mes-bootstrappable; + meta = cfg.meta; + }; + + tinycc-boot1 = helpers.createTinyccMes { + pname = "tinycc-boot1"; + version = stage1.tinycc.version; + src = cfg.src; + args = [ + "-D HAVE_BITFIELD=1" + "-D HAVE_LONG_LONG=1" + "-D HAVE_SETJMP=1" + ]; + lib.args = [ + "-D HAVE_LONG_LONG=1" + ]; + boot = tinycc-boot0; + meta = cfg.meta; + }; + + tinycc-boot2 = helpers.createTinyccMes { + pname = "tinycc-boot2"; + version = stage1.tinycc.version; + src = cfg.src; + args = [ + "-D HAVE_BITFIELD=1" + "-D HAVE_FLOAT_STUB=1" + "-D HAVE_LONG_LONG=1" + "-D HAVE_SETJMP=1" + ]; + lib.args = [ + "-D HAVE_FLOAT_STUB=1" + "-D HAVE_LONG_LONG=1" + ]; + boot = tinycc-boot1; + meta = cfg.meta; + }; + + tinycc-boot3 = helpers.createTinyccMes { + pname = "tinycc-boot3"; + version = stage1.tinycc.version; + src = cfg.src; + args = [ + "-D HAVE_BITFIELD=1" + "-D HAVE_FLOAT=1" + "-D HAVE_LONG_LONG=1" + "-D HAVE_SETJMP=1" + ]; + lib.args = [ + "-D HAVE_FLOAT=1" + "-D HAVE_LONG_LONG=1" + ]; + boot = tinycc-boot2; + meta = cfg.meta; + }; + in + helpers.createTinyccMes { + pname = "tinycc-boot"; + version = stage1.tinycc.version; + src = cfg.src; + args = [ + "-D HAVE_BITFIELD=1" + "-D HAVE_FLOAT=1" + "-D HAVE_LONG_LONG=1" + "-D HAVE_SETJMP=1" + ]; + lib.args = [ + "-D HAVE_FLOAT=1" + "-D HAVE_LONG_LONG=1" + ]; + boot = tinycc-boot3; + meta = cfg.meta; + }; + in { + revision = "80114c4da6b17fbaabb399cc29f427e368309bc8"; + + libs.package = tinycc-boot.libs; + compiler.package = tinycc-boot.compiler; + + src = let + tarball = builtins.fetchurl { + url = "https://gitlab.com/janneke/tinycc/-/archive/${cfg.revision}/tinycc-${cfg.revision}.tar.gz"; + sha256 = "1a0cw9a62qc76qqn5sjmp3xrbbvsz2dxrw21lrnx9q0s74mwaxbq"; + }; + + patched = builders.kaem.build { + name = "${pname}-src"; + + meta = stage1.tinycc.meta; + + script = '' + ungz --file ${tarball} --output tinycc.tar + mkdir -p ''${out} + cd ''${out} + untar --file ''${NIX_BUILD_TOP}/tinycc.tar + + # Patch + cd tinycc-${cfg.revision} + + # Static link by default + replace --file libtcc.c --output libtcc.c --match-on "s->ms_extensions = 1;" --replace-with "s->ms_extensions = 1; s->static_link = 1;" + ''; + }; + in "${patched}/tinycc-${cfg.revision}"; + }; + }; +} diff --git a/foundation/src/stages/stage1/tinycc/default.nix b/foundation/src/stages/stage1/tinycc/default.nix new file mode 100644 index 0000000..3a41a6c --- /dev/null +++ b/foundation/src/stages/stage1/tinycc/default.nix @@ -0,0 +1,55 @@ +{ + lib, + config, +}: let + cfg = config.aux.foundation.stages.stage1.tinycc; + + builders = config.aux.foundation.builders; + + stage1 = config.aux.foundation.stages.stage1; +in { + includes = [ + ./boot.nix + ./mes.nix + ]; + + options.aux.foundation.stages.stage1.tinycc = { + meta = { + description = lib.options.create { + type = lib.types.string; + description = "Description for the package."; + default.value = "Small, fast, embeddable C compiler and interpreter"; + }; + + homepage = lib.options.create { + type = lib.types.string; + description = "Homepage for the package."; + default.value = "https://repo.or.cz/w/tinycc.git"; + }; + + license = lib.options.create { + # TODO: Add a proper type for licenses. + type = lib.types.attrs.any; + description = "License for the package."; + default.value = lib.licenses.lgpl21Only; + }; + + platforms = lib.options.create { + type = lib.types.list.of lib.types.string; + description = "Platforms the package supports."; + default.value = ["x86_64-linux" "i686-linux"]; + }; + }; + + version = lib.options.create { + type = lib.types.string; + description = "Version of the package."; + }; + }; + + config = { + aux.foundation.stages.stage1.tinycc = { + version = "unstable-2023-04-20"; + }; + }; +} diff --git a/foundation/src/stages/stage1/tinycc/helpers.nix b/foundation/src/stages/stage1/tinycc/helpers.nix new file mode 100644 index 0000000..c2450ce --- /dev/null +++ b/foundation/src/stages/stage1/tinycc/helpers.nix @@ -0,0 +1,176 @@ +{ + lib, + config, +}: let + cfg = config.aux.foundation.stages.stage1.tinycc.boot; + + builders = config.aux.foundation.builders; + + stage1 = config.aux.foundation.stages.stage1; + cflags = stage1.mes.libc.package.extras.CFLAGS; + + createBoot = { + pname, + version, + src, + }: let + compiler = builders.kaem.build { + name = "${pname}-${version}"; + + script = '' + catm config.h + ${stage1.mes.compiler.package}/bin/mes --no-auto-compile -e main ${stage1.mes.libs.src.bin}/bin/mescc.scm -- \ + -S \ + -o tcc.s \ + -I . \ + -D BOOTSTRAP=1 \ + -I ${src} \ + -D TCC_TARGET_I386=1 \ + -D inline= \ + -D CONFIG_TCCDIR=\"\" \ + -D CONFIG_SYSROOT=\"\" \ + -D CONFIG_TCC_CRTPREFIX=\"{B}\" \ + -D CONFIG_TCC_ELFINTERP=\"/mes/loader\" \ + -D CONFIG_TCC_LIBPATHS=\"{B}\" \ + -D CONFIG_TCC_SYSINCLUDEPATHS=\"${stage1.mes.libc.package}/include\" \ + -D TCC_LIBGCC=\"${stage1.mes.libc.package}/lib/x86-mes/libc.a\" \ + -D CONFIG_TCC_LIBTCC1_MES=0 \ + -D CONFIG_TCCBOOT=1 \ + -D CONFIG_TCC_STATIC=1 \ + -D CONFIG_USE_LIBGCC=1 \ + -D TCC_MES_LIBC=1 \ + -D TCC_VERSION=\"${version}\" \ + -D ONE_SOURCE=1 \ + ${src}/tcc.c + mkdir -p ''${out}/bin + ${stage1.mes.compiler.package}/bin/mes --no-auto-compile -e main ${stage1.mes.libs.src.bin}/bin/mescc.scm -- \ + -L ${stage1.mes.libs.package}/lib \ + -l c+tcc \ + -o ''${out}/bin/tcc \ + tcc.s + ''; + }; + + libs = createLibc { + inherit pname version; + src = stage1.mes.libc.package; + args = cflags; + tinycc = compiler; + }; + in {inherit compiler libs;}; + + createTinyccMes = { + pname, + version, + src, + args, + boot, + lib ? {}, + meta, + }: let + compiler = builders.kaem.build { + name = "${pname}-${version}"; + + inherit meta; + + # + script = '' + catm config.h + mkdir -p ''${out}/bin + ${boot.compiler}/bin/tcc \ + -B ${boot.libs}/lib \ + -g \ + -v \ + -o ''${out}/bin/tcc \ + -D BOOTSTRAP=1 \ + ${builtins.concatStringsSep " " args} \ + -I . \ + -I ${src} \ + -D TCC_TARGET_I386=1 \ + -D CONFIG_TCCDIR=\"\" \ + -D CONFIG_SYSROOT=\"\" \ + -D CONFIG_TCC_CRTPREFIX=\"{B}\" \ + -D CONFIG_TCC_ELFINTERP=\"\" \ + -D CONFIG_TCC_LIBPATHS=\"{B}\" \ + -D CONFIG_TCC_SYSINCLUDEPATHS=\"${stage1.mes.libc.package}/include\" \ + -D TCC_LIBGCC=\"libc.a\" \ + -D TCC_LIBTCC1=\"libtcc1.a\" \ + -D CONFIG_TCCBOOT=1 \ + -D CONFIG_TCC_STATIC=1 \ + -D CONFIG_USE_LIBGCC=1 \ + -D TCC_MES_LIBC=1 \ + -D TCC_VERSION=\"${version}\" \ + -D ONE_SOURCE=1 \ + ${src}/tcc.c + ''; + }; + + libs = createLibc { + inherit pname version src; + + args = + builtins.concatStringsSep + " " + ( + ["-c" "-D" "TCC_TARGET_I386=1"] + ++ (lib.args or []) + ); + + tinycc = compiler; + }; + in { + inherit compiler libs boot; + }; + + createLibc = { + pname, + version, + src, + args, + tinycc, + }: let + createLibrary = name: args: source: + builders.kaem.build { + name = "${name}.a"; + + script = '' + ${tinycc}/bin/tcc ${args} -c -o ${name}.o ${source} + ${tinycc}/bin/tcc -ar cr ''${out} ${name}.o + ''; + }; + + crt = builders.kaem.build { + name = "crt"; + + script = '' + mkdir -p ''${out}/lib + ${tinycc}/bin/tcc ${cflags} -c -o ''${out}/lib/crt1.o ${stage1.mes.libc.package}/lib/crt1.c + ${tinycc}/bin/tcc ${cflags} -c -o ''${out}/lib/crtn.o ${stage1.mes.libc.package}/lib/crtn.c + ${tinycc}/bin/tcc ${cflags} -c -o ''${out}/lib/crti.o ${stage1.mes.libc.package}/lib/crti.c + ''; + }; + + libtcc1 = createLibrary "libtcc1" args "${src}/lib/libtcc1.c"; + libc = createLibrary "libc" cflags "${stage1.mes.libc.package}/lib/libc.c"; + libgetopt = createLibrary "libgetopt" cflags "${stage1.mes.libc.package}/lib/libgetopt.c"; + in + builders.kaem.build { + name = "${pname}-libs-${version}"; + + script = '' + mkdir -p ''${out}/lib + cp ${crt}/lib/crt1.o ''${out}/lib + cp ${crt}/lib/crtn.o ''${out}/lib + cp ${crt}/lib/crti.o ''${out}/lib + cp ${libtcc1} ''${out}/lib/libtcc1.a + cp ${libc} ''${out}/lib/libc.a + cp ${libgetopt} ''${out}/lib/libgetopt.a + ''; + }; +in { + inherit + createBoot + createTinyccMes + createLibc + ; +} diff --git a/foundation/src/stages/stage1/tinycc/mes.nix b/foundation/src/stages/stage1/tinycc/mes.nix new file mode 100644 index 0000000..1aae609 --- /dev/null +++ b/foundation/src/stages/stage1/tinycc/mes.nix @@ -0,0 +1,142 @@ +args @ { + lib, + config, +}: let + cfg = config.aux.foundation.stages.stage1.tinycc.mes; + + builders = config.aux.foundation.builders; + + stage1 = config.aux.foundation.stages.stage1; + + pname = "tinycc-boot"; + + helpers = lib.fp.withDynamicArgs (import ./helpers.nix) args; +in { + options.aux.foundation.stages.stage1.tinycc.mes = { + compiler = { + package = lib.options.create { + type = lib.types.package; + description = "The package to use for the tinycc-mes compiler."; + }; + }; + + libs = { + package = lib.options.create { + type = lib.types.package; + description = "The package to use for the tinycc-mes libs."; + }; + }; + + src = lib.options.create { + type = lib.types.string; + description = "Source for the package."; + }; + + revision = lib.options.create { + type = lib.types.string; + description = "Revision of the package."; + }; + }; + + config = { + aux.foundation.stages.stage1.tinycc.mes = let + tinycc-mes = let + tccdefs = builders.kaem.build { + name = "tccdefs-${stage1.tinycc.version}"; + + script = '' + mkdir ''${out} + ${stage1.tinycc.boot.compiler.package}/bin/tcc \ + -B ${stage1.tinycc.boot.libs.package}/lib \ + -DC2STR \ + -o c2str \ + ${cfg.src}/conftest.c + ./c2str ${cfg.src}/include/tccdefs.h ''${out}/tccdefs_.h + ''; + }; + + tinycc-mes-boot = helpers.createTinyccMes { + pname = "tinycc-mes-boot"; + version = stage1.tinycc.version; + src = cfg.src; + args = [ + "-D HAVE_BITFIELD=1" + "-D HAVE_FLOAT=1" + "-D HAVE_LONG_LONG=1" + "-D HAVE_SETJMP=1" + "-D CONFIG_TCC_PREDEFS=1" + "-I ${tccdefs}" + "-D CONFIG_TCC_SEMLOCK=0" + ]; + lib.args = [ + "-D HAVE_FLOAT=1" + "-D HAVE_LONG_LONG=1" + "-D CONFIG_TCC_PREDEFS=1" + "-I ${tccdefs}" + "-D CONFIG_TCC_SEMLOCK=0" + ]; + boot = { + libs = stage1.tinycc.boot.libs.package; + compiler = stage1.tinycc.boot.compiler.package; + }; + meta = stage1.tinycc.meta; + }; + in + helpers.createTinyccMes { + pname = "tinycc-mes"; + version = stage1.tinycc.version; + src = cfg.src; + args = [ + "-std=c99" + "-D HAVE_BITFIELD=1" + "-D HAVE_FLOAT=1" + "-D HAVE_LONG_LONG=1" + "-D HAVE_SETJMP=1" + "-D CONFIG_TCC_PREDEFS=1" + "-I ${tccdefs}" + "-D CONFIG_TCC_SEMLOCK=0" + ]; + lib.args = [ + "-D HAVE_FLOAT=1" + "-D HAVE_LONG_LONG=1" + "-D CONFIG_TCC_PREDEFS=1" + "-I ${tccdefs}" + "-D CONFIG_TCC_SEMLOCK=0" + ]; + boot = tinycc-mes-boot; + meta = stage1.tinycc.meta; + }; + in { + revision = "86f3d8e33105435946383aee52487b5ddf918140"; + + libs.package = tinycc-mes.libs; + compiler.package = tinycc-mes.compiler; + + src = let + tarball = builtins.fetchurl { + url = "https://repo.or.cz/tinycc.git/snapshot/${cfg.revision}.tar.gz"; + sha256 = "11idrvbwfgj1d03crv994mpbbbyg63j1k64lw1gjy7mkiifw2xap"; + }; + + patched = builders.kaem.build { + name = "${pname}-src"; + + meta = stage1.tinycc.meta; + + script = '' + ungz --file ${tarball} --output tinycc.tar + mkdir -p ''${out} + cd ''${out} + untar --file ''${NIX_BUILD_TOP}/tinycc.tar + + # Patch + cd tinycc-${builtins.substring 0 7 cfg.revision} + + # Static link by default + replace --file libtcc.c --output libtcc.c --match-on "s->ms_extensions = 1;" --replace-with "s->ms_extensions = 1; s->static_link = 1;" + ''; + }; + in "${patched}/tinycc-${builtins.substring 0 7 cfg.revision}"; + }; + }; +}