feat: tinycc-musl

This commit is contained in:
Jake Hamilton 2024-06-06 23:14:11 -07:00
parent 8e27d6d87e
commit 3a6d4526a6
Signed by: jakehamilton
GPG key ID: 9762169A1B35EA68
9 changed files with 233 additions and 8 deletions

View file

@ -11,7 +11,7 @@ in {
./nyacc
./mes
./ln-boot
./tinycc
./tinycc # With the exception of `tinycc-musl` which uses Bash.
./gnupatch
./gnumake
./coreutils
@ -47,6 +47,8 @@ in {
stage1-gnutar-boot = stage1.gnutar.boot.package;
stage1-gzip = stage1.gzip.package;
stage1-musl-boot = stage1.musl.boot.package;
stage1-tinycc-musl = stage1.tinycc.musl.compiler.package;
stage1-tinycc-musl-libs = stage1.tinycc.musl.libs.package;
};
extras = {

View file

@ -120,7 +120,7 @@ in {
# Configure
bash ./configure \
--prefix=$out \
--build=${(builtins.trace platform.build) platform.build} \
--build=${platform.build} \
--host=${platform.host} \
--disable-shared \
CC=tcc

View file

@ -11,6 +11,7 @@ in {
includes = [
./boot.nix
./mes.nix
./musl.nix
];
options.aux.foundation.stages.stage1.tinycc = {

View file

@ -8,7 +8,7 @@ args @ {
stage1 = config.aux.foundation.stages.stage1;
pname = "tinycc-boot";
pname = "tinycc-mes";
helpers = lib.fp.withDynamicArgs (import ./helpers.nix) args;
in {
@ -56,7 +56,7 @@ in {
};
tinycc-mes-boot = helpers.createTinyccMes {
pname = "tinycc-mes-boot";
pname = "${pname}-boot";
version = stage1.tinycc.version;
src = cfg.src;
args = [
@ -83,7 +83,7 @@ in {
};
in
helpers.createTinyccMes {
pname = "tinycc-mes";
inherit pname;
version = stage1.tinycc.version;
src = cfg.src;
args = [

View file

@ -0,0 +1,177 @@
args @ {
lib,
config,
}: let
cfg = config.aux.foundation.stages.stage1.tinycc.musl;
builders = config.aux.foundation.builders;
stage1 = config.aux.foundation.stages.stage1;
pname = "tinycc-musl";
helpers = lib.fp.withDynamicArgs (import ./helpers.nix) args;
in {
options.aux.foundation.stages.stage1.tinycc.musl = {
compiler = {
package = lib.options.create {
type = lib.types.package;
description = "The package to use for the tinycc-musl compiler.";
};
};
libs = {
package = lib.options.create {
type = lib.types.package;
description = "The package to use for the tinycc-musl 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.musl = let
patches = [
./patches/ignore-duplicate-symbols.patch
./patches/ignore-static-inside-array.patch
./patches/static-link.patch
];
tinycc-musl = builders.bash.boot.build {
name = "${pname}-${stage1.tinycc.version}";
meta = stage1.tinycc.meta;
deps.build.host = [
stage1.tinycc.boot.compiler.package
stage1.gnupatch.package
stage1.gnutar.boot.package
stage1.gzip.package
];
script = ''
# Unpack
tar xzf ${cfg.src}
cd tinycc-${builtins.substring 0 7 cfg.revision}
# Patch
${lib.strings.concatMapSep "\n" (file: "patch -Np0 -i ${file}") patches}
# Configure
touch config.h
# Build
# We first have to recompile using tcc-0.9.26 as tcc-0.9.27 is not self-hosting,
# but when linked with musl it is.
ln -s ${stage1.musl.boot.package}/lib/libtcc1.a ./libtcc1.a
tcc \
-B ${stage1.tinycc.boot.libs.package}/lib \
-DC2STR \
-o c2str \
conftest.c
./c2str include/tccdefs.h tccdefs_.h
tcc -v \
-static \
-o tcc-musl \
-D TCC_TARGET_I386=1 \
-D CONFIG_TCCDIR=\"\" \
-D CONFIG_TCC_CRTPREFIX=\"{B}\" \
-D CONFIG_TCC_ELFINTERP=\"/musl/loader\" \
-D CONFIG_TCC_LIBPATHS=\"{B}\" \
-D CONFIG_TCC_SYSINCLUDEPATHS=\"${stage1.musl.boot.package}/include\" \
-D TCC_LIBGCC=\"libc.a\" \
-D TCC_LIBTCC1=\"libtcc1.a\" \
-D CONFIG_TCC_STATIC=1 \
-D CONFIG_USE_LIBGCC=1 \
-D TCC_VERSION=\"0.9.27\" \
-D ONE_SOURCE=1 \
-D TCC_MUSL=1 \
-D CONFIG_TCC_PREDEFS=1 \
-D CONFIG_TCC_SEMLOCK=0 \
-B . \
-B ${stage1.tinycc.boot.libs.package}/lib \
tcc.c
# libtcc1.a
rm -f libtcc1.a
tcc -c -D HAVE_CONFIG_H=1 lib/libtcc1.c
tcc -ar cr libtcc1.a libtcc1.o
# Rebuild tcc-musl with itself
./tcc-musl \
-v \
-static \
-o tcc-musl \
-D TCC_TARGET_I386=1 \
-D CONFIG_TCCDIR=\"\" \
-D CONFIG_TCC_CRTPREFIX=\"{B}\" \
-D CONFIG_TCC_ELFINTERP=\"/musl/loader\" \
-D CONFIG_TCC_LIBPATHS=\"{B}\" \
-D CONFIG_TCC_SYSINCLUDEPATHS=\"${stage1.musl.boot.package}/include\" \
-D TCC_LIBGCC=\"libc.a\" \
-D TCC_LIBTCC1=\"libtcc1.a\" \
-D CONFIG_TCC_STATIC=1 \
-D CONFIG_USE_LIBGCC=1 \
-D TCC_VERSION=\"0.9.27\" \
-D ONE_SOURCE=1 \
-D TCC_MUSL=1 \
-D CONFIG_TCC_PREDEFS=1 \
-D CONFIG_TCC_SEMLOCK=0 \
-B . \
-B ${stage1.musl.boot.package}/lib \
tcc.c
# libtcc1.a
rm -f libtcc1.a
./tcc-musl -c -D HAVE_CONFIG_H=1 lib/libtcc1.c
./tcc-musl -c -D HAVE_CONFIG_H=1 lib/alloca.S
./tcc-musl -ar cr libtcc1.a libtcc1.o alloca.o
# Install
install -D tcc-musl $out/bin/tcc
install -Dm444 libtcc1.a $out/lib/libtcc1.a
'';
};
in {
revision = "fd6d2180c5c801bb0b4c5dde27d61503059fc97d";
src = builtins.fetchurl {
url = "https://repo.or.cz/tinycc.git/snapshot/${cfg.revision}.tar.gz";
sha256 = "R81SNbEmh4s9FNQxCWZwUiMCYRkkwOHAdRf0aMnnRiA=";
};
compiler.package = builders.bash.boot.build {
name = "${pname}-${stage1.tinycc.version}-compiler";
meta = stage1.tinycc.meta;
script = ''
install -D ${tinycc-musl}/bin/tcc $out/bin/tcc
'';
};
libs.package = builders.bash.boot.build {
name = "${pname}-${stage1.tinycc.version}-libs";
meta = stage1.tinycc.meta;
script = ''
mkdir $out
cp -r ${stage1.musl.boot.package}/* $out
chmod +w $out/lib/libtcc1.a
cp ${tinycc-musl}/lib/libtcc1.a $out/lib/libtcc1.a
'';
};
};
};
}

View file

@ -0,0 +1,14 @@
--- tccelf.c
+++ tccelf.c
@@ -710,8 +710,9 @@ ST_FUNC int set_elf_sym(Section *s, addr_t value, unsigned long size,
#if 0
printf("new_bind=%x new_shndx=%x new_vis=%x old_bind=%x old_shndx=%x old_vis=%x\n",
sym_bind, shndx, new_vis, esym_bind, esym->st_shndx, esym_vis);
-#endif
tcc_error_noabort("'%s' defined twice", name);
+#endif
+ goto do_patch;
}
} else {
esym->st_other = other;

View file

@ -0,0 +1,22 @@
--- tccgen.c
+++ tccgen.c
@@ -4941,7 +4941,7 @@ static int post_type(CType *type, AttributeDef *ad, int storage, int td)
next();
n = -1;
t1 = 0;
- if (td & TYPE_PARAM) while (1) {
+ while (1) {
/* XXX The optional type-quals and static should only be accepted
in parameter decls. The '*' as well, and then even only
in prototypes (not function defs). */
@@ -4972,7 +4972,8 @@ static int post_type(CType *type, AttributeDef *ad, int storage, int td)
}
break;
- } else if (tok != ']') {
+ }
+ if (tok != ']') {
if (!local_stack || (storage & VT_STATIC))
vpushi(expr_const());
else {

View file

@ -0,0 +1,11 @@
--- libtcc.c
+++ libtcc.c
@@ -793,6 +793,7 @@ LIBTCCAPI TCCState *tcc_new(void)
s->gnu_ext = 1;
s->tcc_ext = 1;
+ s->static_link = 1;
s->nocommon = 1;
s->dollars_in_identifiers = 1; /*on by default like in gcc/clang*/
s->cversion = 199901; /* default unless -std=c11 is supplied */

View file

@ -29,9 +29,7 @@ in {
expected = "64";
actual = lib.numbers.into.hex 100;
in
(builtins.trace actual)
actual
== expected;
actual == expected;
};
};