The folks from nim discord's brought me to the answer. It consists of passing flags to the nim-compiler to swap out the compiler nim normally uses for its generated C-code, in order to use musl-gcc
. This can be done by using the --gcc.exe:"musl-gcc"
and --gcc.linkerexe:"musl-gcc"
flags.
Here an example for Linux:
1. install musl to get access to musl-gcc
- download the tar file from the official musl page
- Unpack the tar file somewhere
- Run bash configure in the unpacked directory. WARNING: Make sure that you do NOT install musl with
--prefix
being /usr/local
, as that may adversely affect your system. Use somewhere else where it is unlikely to override files, e.g. /usr/local/musl
. This path will further be referred to as <MUSL_INSTALL_PATH>
- Run
make && make install
in the unpacked directory
- Add
<MUSL_INSTALL_PATH>
to your PATH
environment variable
- Validate whether you set everything up correctly by opening a new terminal and seeing whether you have access to the musl-gcc command
2. Compile with musl
- Create a compile command with
--gcc.exe:"musl-gcc"
to swap out gcc with musl-gcc and --gcc.linkerexe:"musl-gcc"
to swap out the default linker with musl-gcc as well. An example can look like this:
nim c \
--gcc.exe:"musl-gcc" \
--gcc.linkerexe:"musl-gcc" \
--define:release \
--threads:on \
--mm:orc \
--deepcopy:on \
--define:lto \
--outdir:"." \
<PATH_TO_YOUR_MAIN_PROJECT_FILE>.nim
This should generate a binary that is dynamically linked against musl and thus can run within an alpine docker container.