minilibc686 is a minimalistic, size-optimized C runtime library (libc) targeting Linux i386 and i686, for building statically linked ELF-32 executable programs. minilibc686 is batteries-included: it contains all necessary tools (e.g. the compiler driver minicc, C preprocessor, C compiler, assembler, linker) for building size-optimized Linux i386 programs. All of the libc code of minilibc686 is written in NASM assembly language, and it is manually optimized for size (rather than speed). Feature tradeoffs were made to achieve small code sizes, so minilibc686 deviates from standard C in many aspects. In case some functionality is missing from minilibc686, with the minicc compiler fronted it's convenient to use some other supported libcs (diet libc, uClibc and EGLIBC), which are precompiled, and minicc automatically downloads each of them the first time it is needed.
Try it on Linux i386 or Linux amd64 (without the leading $
):
$ git clone --depth 1 https://github.com/pts/minilibc686
$ cd minilibc686
$ export PATH="$PWD/pathbin:$PATH" # Add minicc to $PATH.
$ minicc -mprintf-mini -mno-envp -mconst-seg -o demo demo_c_hello.c
$ ./demo
Hello, World!
$ ls -ld demo
-rwxrwxr-x 1 pts pts 1008 Jul 5 23:28 demo
$ printf '#include <unistd.h>\nint main() { write(1, "Hello, World!\\n", 14); return 0; }\n' >demo_write.c
$ minicc -fomit-frame-pointer -o demo_write demo_write.c
$ ./demo_write
Hello, World!
-rwxrwxr-x 1 pts pts 163 Jun 21 19:12 demo_write
The first time you run minicc, it builds the static libraries
libc/minilibc/libc.i386.a
and libc/minilibc/libc.i686.a
, using the
bundled NASM (tools/nasm-0.98.39
) assembler. That's why you get hundrdeds
of command log lines upon your first compile.
What sizes are achievable:
test/demo_c_hello_snprintf.c
provides the same functionality, but the
program size depends on the C compiler. It's always 679 bytes when
demo_hello_linux_printf.nasm is compiled with NASM.demo_c_hello.c
provides the same functionality, but the
program size depends on the C compiler. The executable size usually
depends on the compiler version used, but to make the results reproducible,
an assembly implementation of main(...) is also included in demo_c_hello.c
above. For the original 1008-byte executable, GCC 7.5.0 was used to compile
main(...).hello-world size comparison of different libcs:
minicc --gcc
) is
1008 bytes, already strippedminicc --diet
) is
5820 bytes after strippingowcc -blinux -Os -fno-stack-check
) is
12934 bytes after strippingminicc --uclibc
) is
14440 bytes, already strippedzig cc -target i386-linux-musl -Os
) is
15548 bytes after strippingminicc --eglibc
) is
582714 bytes after strippinggcc -m32 -s -Os -static
) is
594716 bytes after strippinggcc -m32 -s -Os -static
) is
663424 bytes after strippingHow is this possible?
isatty(0)
at startup time if the program
doesn't use stdin). (Smart linking is not implemented fully, but it
already provides size savings for the libc functions for which it is
implemented.)"Hello, World!\n"
string (not NUL-terminated)minicc -fomit-frame-pointer -W -Wall -Werror -o demo_write demo_write.c
"Hello, World!\n"
string (NUL-terminated, termination not needed)minicc --gcc -W -Wall -Werror test/demo_c_hello_snprintf.c
"(null)"
string (NUL-terminated) in mini___M_vfsprintf(...)minicc --gcc -W -Wall -Werror demo_c_hello.c
"(null)"
string (NUL-terminated) in mini___M_vfsprintf(...)The following components are included in minilibc686:
elf0.inc.nasm: A NASM library for creating ELF-32 executables written in NASM assembly language, entirely using NASM. (A C compiler or linker is not necessary.) The library takes care of adding headers and alignment. See demo_hello_linux_nolibc.nasm and demo_hello_linux_printf.nasm as example users of elf0.inc.nasm.
src/*.nasm: libc functions written in NASM assembly language. They can be indiviually copy-pasted to ther projects.
include/.h and include/sys/.h: C #include files for the users of minilibc686.
build.sh: Shell script to build the minilibc686 (files libmini386.a, libmini686.a etc.) from NASM sources.
soptcc.pl: Perl script to run many C compilers with many settings on the same source file, choose the shortest output, and generate NASM source code. This is useful for adding a new function to the libc. The first implementation of the function can be created by a C compiler (using soptcc.pl), and then manually optimized later
tools/miniutcc: A self-contained, combined driver, C preprocessor, C compiler, ELF-32 linker and libc in a single Linux i386 statically linked executable. The C compiler and linker is TinyCC 0.9.26, and the libc is uClibc 0.9.30.1 (released on 2009-03-02). The C #include files are not provided, but the minilibc686 #include files can be used (they have the proper #ifdef()s). To build a program, run `minicc --utcc -o prog prog.c'.
tools/pts-pcc: A self-contained, combined driver, C preprocessor and C compiler based on PCC (Portable C Compiler) 1.1.0 (released on 2014-12-10). In 2009 it was able to build a working OpenBSD kernel. It supports most of C99. Flags and extensions resemble GCC, because it was built as a replacement for GCC in BSDs (in which it didn't succeed, Clang did in some way). minicc uses it to generate assembly .s output, then minicc calls GNU as(1) to generate object .o output, and then minicc runs the linker (either GNU ld(1) or the TinyCC linker). PCC has a long and amazing history, see blow.
tools/wcc386: OpenWatcom C compiler (released on 2023-03-04). It's
convenient to use it with minicc (see below). It is also the default C
compiler for minicc: to build a program, run minicc -o prog prog.c
.
tools/omf2elf (with C source included): A tool to convert an i386 OMF .obj object file to an i386 ELF relocatable .o object file. This is useful, because the OpenWatcom C compiler creates the former, and the linkers (TinyCC, GNU ld(1) and GNU gold(1)) understand the latter, not the former. The minicc compiler frontend automatically runs this tool when using the OpenWatcom C compiler.
minicc: A C compiler frontend to build small, statically linked ELF-32
executables. Running minicc is the recommended way to build your programs
using minilibc686. By default, these executables link against minilibc686,
but with the usual -nostdlib
flag, you can add your own libc. It can use
GCC and Clang compilers installed onto the system, and it runs the
compiler and the linker with many size-optimization flags, and it removes
most unnecessary stuff from the final executable. In addition to these
compilers, it can use the bundled TinyCC compiler (tools/miniutcc
) (use
the --tcc
flag).
libc/dietlibc-0.34.sfx.7z: Self-extracting archive containing diet libc
0.34 (released on 2018-09-24) (.h and .a files) targeting Linux i386,
compiled for -march=i386
and -march=i686
. Use it with minicc --diet
.
diet libc provides more functionality and compatibility than minilibc686,
but it has more overhead (i.e. the program becomes a few KiB larger).
libc/uclibc-0.9.30.1.sfx.7z: Self-extracting archive containing uClibc
0.9.30.1 (released on 2009-03-02) (.h and .a files) targeting Linux i386,
compiled for -march=i686
. Use it with minicc --uclibc
.
uClibc provides more functionality and compatibility than minilibc686, but
it has more overhead (i.e. the program becomes a few KiB larger, even
larger than diet libc).
libc/eglibc-2.19.sfx.7z:
Self-extracting archive containing EGLIBC
2.19 (released on 2014-09-29) (.h and .a files) targeting Linux i386,
compiled for -march=i686
. Use it with minicc --eglibc
.
EGLIBC is glibc for embedded systems. It has full functionality, but
for a hello-world it's quite bloated (>550 KiB).
tools/nasm-0.98.39: NASM (Netwide Assembler) executables to build .o files from the .nasm files. It is invoked by build.sh.
tools/ndisasm-0.98.39: Simple flat binary disassembler coming with NASM. It is invoked by build.sh to compare the output of various runs of tools/nasm-0.98.39.
tools/tiny_libmaker: A tool to build static library (.a) files from ELF relocatable (object .o) files. Like GNU ar(1), but much smaller. C source is also included.
tools/elfnostack, tools/elfofix, tools/elfxfix: Helper programs for manipulating ELF executable and relocatable files. build.sh and minicc invoke them automatically when needed. C source is also included.
test.sh: Shell script to build parts of minilibc686 and run some unit tests. Please note that there is no full test coverage, and the testing infrastructure (i.e. bunch of hacky shell scripts) is primitive (so far).
test/*.test: Unit tests run by test.sh.
e2e_test.sh: Shell script to build the entire minilibc686 (./build.sh'), run all the unit tests (
./test.sh`), and run some end-to-end tests with
linkining against minilibc686 using minicc.
fyi/*.c: C reference implementations of some libc functions. Some of the
algorithmically interesting ones are fyi/qsort_fast.nasm
and
fyi/qsort.nasm
.
Please note that minilibc686 is more like an experimental technological demo
rather than a feature-complete and battle-tested libc, and it is not ready
for production use, it's especially not ready for easy porting of random
prewritten software. (If you need something like that, use musl with zig cc
with various targets.) It's also not well-documented. However, if you
start writing simple, new command-line tools for Linux, you may want to give
it a try.
Other projects with tiny libc functions:
Other tiny libc projects targeting Windows:
-DCONFIG_PIC
). This is similar to
gcc -fpic
, but better. The precompiled code doesn't have any data
dependencies (i.e. it's self-contained), and it can be copied to any
address in memory and executed there. Thus it's modular on the binary level.-O0
vs -O999999999
).-mno-80387 -mno-fp-ret-in-387
will have to be used to compile C code, and soft-float
functions such as __muldf3
must be added to the libc. Please note that
-mno-fp-ret-in-387
breaks the cdecl ABI, because with that doubles are
returned in EDX:EAX rather than ST(0), the latter requiring an FPU.)Design limitations:
FILE *
files opened by fopen(3) (not including stdin,
stdout and stderr) is limited at compile time. The default limit is 2. To
increase it, specify -mfiles=...
. The number of files opened by
open(2) is not limited by minilibc.O_LARGEFILE
set), the
lseek64(3) function is provided.-fno-rtti -fno-excepions
, and also without any
STL.)An end-to-end demo for building a printf-hello-world program in NASM
assembly with minilibc686, targeting Linux i386 32-bit ELF (actually i686
processors), is provided in test_demo_hello_linux.sh. For the build you need
a Linux host system and NASM. NASM also does the linking with -f bin
and
the provided elf0.inc.nasm.
An end-to-end demo for building a printf-hello-world C program with minilibc686, targeting Linux i386 32-bit ELF (actually i686 processors), is provided in test_demo_c_hello_linux.sh. For the build you need a Linux i386 or amd64 host system. The build script uses the bundled NASM 0.98.39 assembler and the bundled TinyCC compiler, and it also autodetects GCC, and if available, builds with GCC as well. Please note that using the minicc compiler frontend is preferred (to the shell script test_demo_c_hello_linux.sh) is recommended, see the command line above.
Please note that minilibc686 is currently not ready as a general libc
replacement for Linux, mostly because most of the functions haven't been
written yet. If you need more functions, try minicc --diet
or minicc --uclibc
.
The minicc compiler frontend is a batteries-included Linux command-line
tool to build small, statically linked Linux i386 programs from C source. It
is part of the minilibc686 distribution (just run it as minicc
from the
minilib686 directory). It is bundled with several C compilers, linkers and
libcs. Use it like this: ./minlibc -o prog prog.c
. Try it:
Try minicc on Linux i386 or Linux amd64 (without the leading $
):
$ minicc -o demo demo_c_hello.c
$ ./demo
Hello, World!
If you get command not found or similar for minicc
, then you have to set
up your $PATH first. Run this in the minilibc686 directory containing
minicc.sh
:
$ export PATH="$PWD/pathbin:$PATH" # Add minicc to $PATH.
minicc drop-in replacement for gcc
, clang
, owcc
(OpenWatcom C
compiler) or tcc
to build small, statically linked ELF-32 executables for
Linux i386. Running minicc is the recommended way to build your programs
using minilibc686. By default, these executables link against minilibc686,
but with command-line flags (e.g. the usual -nostdlib
and -nostdinc
),
you can specify any libc. It runs the compiler and the linker with many
size-optimization flags, and it removes most unnecessary stuff from the
final executable. minicc accepts the command-line flags in GCC syntax (and
from that it generates OpenWatcom wcc386 syntax and others as needed).
Here is how to pick the compiler:
--watcom
.tools/miniutcc
), specify
--tcc
.tools/pts-pcc
), specify --pcc
.--gcc=4.1
.. --gcc=4.9
. minicc will download (using wget or curl)
the prepared executable from GitHub upon first use. It will also download
the prepared GNU as(1) 2.22 assembler executable. Example donwload
locations: tools/gcc-4.8.5
and tools/as-2.22
. To prevent automatic
downloads, specify --no-download
.--gcc
for minicc. Use --gcc=...
to
run it with a specific GCC command, e.g. --gcc=gcc-4.8
. (Please note
that --gcc=4.8
would use the prepared GCC, not the system GCC.)--gcc=clang
. You can also specify
a specific Clang command, e.g. --gcc=clang-6.0
.--gcc=wcc386
. You can also specify a pathname to the compiler. Only
the wcc386 executable file will be used from the OpenWatcom
distribution.Here is how to pick the linker:
tools/ld
)
for non-TinyCC compiles, and TinyCC itself for TinyCC compiles.--minild
.--gccld
.
This will likely be GNU ld(1) or GNU gold(1) within GNU Binutils installed
along with GCC.tools/miniutcc
),
specify --tccld
.--tccld=...
,
specifying the TinyCC command.Here is how to pick the libc:
-march=i686
).-march=i386
.
This will also make the specified C source files be compiled for i386.--uclibc
.--diet
.--diet -march=i386
.
This will also make the specified C source files be compiled for i386.--eglibc
.
minicc will download (using wget or curl)
the prepared archive
eglibc-2.19.sfx.7z
from GitHub, and it will extract it upon first use.#ifdef
lines have been added to the
libc .h files shipping with minicc. Compilation works and is warningless
within the libc headers with or without -ansi
(same as -std=c89
) and
-std=c99
. Compilation works and is warningles with or without
-pedantic
.--uclibc
instead of this.)
To use the bundled uClibc 0.9.30.1 (built for -march=i686
) with the
bundled TinyCC compiler in restricted mode, specify --utcc
. Instead of
the full uClibc .h files, the minilibc686 .h files will be used. By doing
so, a subset of uClibc will be avaialble.--uclibc
instead of this.)
To use the bundled uClibc 0.9.30.1 (built for -march=i686
) with the GCC
or Clang compiler and the linker of the bundled TinyCC compiler, specify
--utcc --gcc=... --tccld
.Here is how to make the executable program file even smaller:
-msmart
, enabled by default). minilibc686,
especially with smart linking enabled, does very hard work to unused
functions and features out of the generated executable. For example, if
you don't use errno
, it won't be created or populated, so the syscall
wrapper code becomes shorter.--tcc
) as your C compiler, it doesn't optimize code.
See below for using GCC, Clang or the default OpenWatcom C compiler.--tccld
, it's also the default with
--tcc
), it generates larger programs than needed.-mno-envp
. It doesn't matter if you mention this variable
in the function declaration.-mno-argv
. It doesn't matter if you mention this variable
in the function declaration.-mno-argc
. It doesn't matter if you mention this variable
in the function declaration. If you use the OpenWatcom C compiler, and
you write int main(void) { ... }
, then minicc detects this, and
enables -mno-argc
for you..text
section)
becomes writable, specify -Wl,-N
. This will save 0x20 bytes or a few
more. Please note that writable code is a security concern, it can make it
easier for attachers to exploit vulnerabilities in your program.-fomit-frame-pointer
and -fno-omit-frame-pointer
, and pick
the smaller.-march=i386
and -march=i686
, and pick the smaller.--gcc
and without it (i.e. OpenWatcom C compiler). Try
different versionf of GCC. Versions 4.x tend to generate shorter code than
newer versions. Clang tends to generate a bit longer code than GCC.__watcall
) of the vanilla OpenWatcom C
complier often produces shorter code than the minilibc686 calling
convention (GCC-flavored __cdecl
). However, when used by minicc,
the minilibc686 calling convention is activated by default for the
OpenWatcom C compiler is well. You may want to decorate some of your C
functions with __watcall
instead, e.g.
int __watcall mul3(int x) { return 3 * x; }
.
For GCC (and TinyCC), you may want to try another similar calling
convention:
__attribute__((regparm(3))) int mul3(int x) { return 3 * x; }
.Here is how to disable some default minicc functionality:
-O...
flag, e.g. -O0
for
the GCC default. Please note that by specifying -Os
, you will get worse
size optimization than the default minicc.-g...
flag, e.g. -g0
for the
GCC default. If you specify -g0 -s
, the executable will be stripped just
like gcc -s
, rather than full stripping done by minicc.-Wno-no
(or any
-W...
flag which is not a -Wno-...
fag) for the GCC default.-nostdlib -nostdinc
, and
specify any libc (with -I...
for the #include directory and ....a
for
the static library).If you program doesn't compile or doesn't work with minilibc686:
minicc --diet
for diet libc instead of minilibc686.minicc --uclibc
for uClibc instead of minilibc686.minicc --eglibc
for EGLIBC (huge, bloated) instead of minilibc686.--tcc
, --tccld
and --utcc
to prevent using the TinyCC compiler
and linker.--gcc
(system GCC) instead of the default OpenWatcom C compiler.-msmart
and -mno-smart
.How to run minicc:
There are many ways to run minicc. For each of them the first step is cloning the Git repository:
$ git clone --depth 1 https://github.com/pts/minilibc686
$ cd minilibc686
The convenient way is setting up the $PATH
, and then running it as
minicc
. Example path setup command, to be run in the minilibc686
directory containing minicc.sh
:
$ export PATH="$PWD/pathbin:$PATH" # Add minicc to $PATH.
If you don't want to change your $PATH
, you can run shbin/minicc
from
the Git working directory, or from anywhere else, specifying the correct
(relative or absolute) pathname.
Alternatively, you can run sh minicc.sh
, but that uses the system shell
(/bin/sh
) and the readlink(1) command (and then quickly hands it over to
the bundled BusyBox). This makes it slower, and it makes the reproducibility
weaker, because shells have subtle differences.
minilibc686 has some unit tess. Run all of them by running ./test.sh
.
The tests are in the */*.test
files, which are shell scripts run by
./test.sh
after creating some variables and functions.
Typically each test script file compiles the *.nasm
file under test with
some test code written in C (*.c
), runs it, and analyzes the result.
The test framework supports reproducible tests by automatically removing all
environment variables (including $PATH
) and then setting some of them to
known good values; and also it runs each test file in a separte, empty
directory, to prevent accidental data sharing between tests.
Just like with building (./build.sh
), the minilibc686 repository contains
all build tools (e.g. NASM assembler, TinyCC C compiler and linker,
tiny_libmaker static library creator) used by the tests, so running the
tests doesn't need tools (e.g. system GCC) installed to the system. As soon
as you have downloaded the repository to your Linux i386 or amd64 system,
you can run ./test.sh
without having to install anything.
owcc -mabi=cdecl
or
`wcc386 -ecc'.gcc -mpreferred-stack-boundary=2
and clang
-mstack-alignment=4`../build.sh
), rebuilds the entire minilibc686 library
(e.g. minilibc386.a and minilibc686.a) from *.nasm sources.PATH
to shlib
only (and directly invokes tools from tools when needed)./bin/sh
in the very beginning of the build), because all
build tools are included in the repository.Assembly source files src/*.nasm
are under the MIT license. Everything
else is under GPL v2 (GNU General Public License, Version 2).
Various C source files in the tools directory of the minilibc686 source tree.
pts-tiny-7z-sfx, a .7z (self-)extractor.
mininasm, a NASM-compatible mini assembler for 16-bit x86 targets.
A port of PNGOUT (PNG compressor with very small output fies). The actual libc NASM sources are embedded into the pngouta.nasm file.
mw386as, a port of the Mark Williams 80386 assembler to Linux i386.
Development history:
See also PCC on Wikipedia and the official PCC history page.
Dennis Ritchie invented the C language by extending the B languge, starting in 1971 (see C history notest by Dennis Ritchie for details), and he wrote wrote the first C compiler for the PDP-11, starting in 1972. In retrospect, we call this the DMR compiler. Some versions of the original source code (in C and PDP-11 assembly) has been preserved (see the [description]((https://www.bell-labs.com/usr/dmr/www/primevalC.html) and the code on GitHub, and later people succeeded running it in an emulator, and it was able to compile itself.
The first known portable C complier was written in 1973 by Alan Snyder at Bell Labs. PCC doesn't share code with this. portable (in both cases) means retargetable, i.e. only a small part of the compiler has to be rewritten or extended to add support for another target architecture. In contrast, the DMR compiler ran on and targeted PDP-11 only, and it contained many architecture-specific optimizations baked in deeply.
PCC was written by Stephen C. Johnson at Bell Labs in the mid 1970s, released in 1978 (other sources say 1979). He wrote multiple articles about it in the 1970s.
Anders Magnusson and Peter A Jonsson added C99 support between 2007 and 2008-01-27, rewriting most of the compiler along the way. They also added support for new architectures, e.g. amd64. It was also their goal to write a compiler that can replace GCC as a default compiler in NetBSD and OpenBSD. To make such a transition easier, they added command-line flags and language extensions exactly the same way as GCC did them. Thus, depending on the code and the build scripts, PCC can be used as a drop-in replacement for GCC.
The latest PCC, 1.1.0 was released on 2014-12-10. That's 36 years after it was born. In the meantime (between 2008 and 2014) Magnusson and Jonsson started adding a C++ compiler as well.
A quick size comparison in 2014: the cc1 tool of GCC 4.8, running on and targeting Linux i386, statically linked, uncompressed is ~12.25 MiB, and PCC 1.1.0 is ~0.273 MiB, GCC being ~44.87 times larger. This indicates the difference in the amount of creative input and engineering effort these compilers received. GCC is a much larger project, with more contributors.
Use history:
At Bell Labs, the DMR compiler was used between 1972 and 1978.
PCC debuted in Unix Version 7 in 1979-01 and replaced the DMR compiler in both System V and the BSD 4.x releases until 4.4.
GCC replaced PCC in BSD 4.4 (4.4BSD), released beteen 1993-06 and 1994-03.
PCC was added to NetBSD pkgsrc and OpenBSD source tree in 2007-09, and later also to the NetBSD source tree. (GCC was stll the default compiler, and some BSD developers were looking at Clang.)
On 2009-12-29, PCC built a working OpenBSD kernel image.
PCC was removed from OpenBSD source tree in 2012. At that time there was no realistic chance for it to replace GCC.
Since 2012, Clang has replaced GCCs for some targets in some BSDs.
See download links on the release page.
All files are statically linked Linux i386 32-bit ELF executable programs
built for i686 = P6 processors, stripped and then compressed with UPX (upx --best --no-lzma
).
Individual GCC release dates and notes:
Please note that no other files (such as the cc1plus C++ compiler, the
gcc frontend tool, the ld linker, .h files, libc static library .a
files, libc shared library .so files) are provided here. To compile C
programs with these compilers, use minicc at
https://github.com/pts/minilibc686/; example command: minicc --gcc=4.8 -o prog prog.c
. minicc will download these executables from here for you.
__attribute__((aligned(8)))
for global variables of the type double
or long double. -malign-double
and -mno-align-double
doesn't seem to
affect it. In structs, the alignment is 4. PCC, TinyCC and OpenWatcom
align double and long double to 4, even for global variables.nop
so that that different
functions won't end up at the same address..rodata.str1.1
.-Os
) when
compared to GCC (4.8 and 7.5.0).float _Complex
values EAX (real) and EAX (imaginary). GCC >=
4.7 generates suboptimal code: mov eax, [...]
+ mov edx, ...
. GCC 4.6
still generates mov eax, ...
+ mov edx, ...
. Example source:
`float _Complex ffc(void) { return 5 + 6i; }nop
(0x90), o16 nop
(0x66, 0x90) and lea esi, [esi]
(0x8d, 0x76, 0x00).This section is mostly an FYI, it doesn't affter minilibc686 users directly.
GNU gold(1) 2.22 is mostly correct.
-z execstack
or -z noexecstack
was
specified, or if any of the .o files contain a declaration -- but .o
files generated by GNU as(1) compiled from .s generated by GCC do
contain it.-N
, it can merge all sections (rwx).
$ minicc -o mininasm mininasm.c && ls -ld mininasm
-rwxrwxr-x 1 pts pts 23033 Jun 20 12:53 mininasm
$ minicc --tccld -o mininasm mininasm.c && ls -ld mininasm
-rwxrwxr-x 1 pts pts 23072 Jun 20 12:53 mininasm
FYI mark stack as nonexecutable in GNU as:
.section .note.GNU-stack,"",@progbits
tools/miniutcc -nostdlib
):
common
to one of the .nasm files.tcc_common_lib_bug.sh
for TCC failing to link in symbol
mini___M_init_isatty even though it's referenced as extern and common.... defined twice
error, but it doesn't fail.NASM=nasm build.sh
.src/*.nasm
, especially related to __OUTPUT_FORMAT__, bin
.long double' for OpenWatcom. With OpenWatcom,
long double' is the same as `double'.-fno-ident
to PCC.-falign-functions=1
to PCC.unify_str_literal
).--diet
, see
test/test_float_conv.c
.END