I work with Arch Linux and Nim works great on it. Now I want to build a binary to test on a Windows device, so I wanted to cross-compile it.
I followed the instructions on https://nim-lang.org/docs/nimc.html#crossminuscompilation-for-windows
When I build my program, I get errors at [Link]
$ nim c -d:mingw --path:/home/dirk/libs/nim main.nim
Hint: [Link]
/usr/lib/gcc/x86_64-w64-mingw32/13.1.0/../../../../x86_64-w64-mingw32/bin/ld: unrecognized option '-z'
/usr/lib/gcc/x86_64-w64-mingw32/13.1.0/../../../../x86_64-w64-mingw32/bin/ld: use the --help option for usage information
collect2: error: ld returned 1 exit status
Error: execution of an external program failed: '/usr/bin/x86_64-w64-mingw32-gcc -o /home/dirk/projects/nim-opengl/main.exe /home/dirk/.cache/nim/main_d/@m..@s..@slibs@sstb@sstb_image.cpp.o /home/dirk/.cache/nim/main_d/@m..@s..@slibs@sstb@sstb_truetype.cpp.o /home/dirk/.cache/nim/main_d/@m..@s..@s..@s..@susr@slib@snim@[email protected] /home/dirk/.cache/nim/main_d/@m..@s..@s..@s..@susr@slib@snim@sstd@[email protected] /home/dirk/.cache/nim/main_d/@m..@s..@s..@s..@susr@slib@snim@[email protected] /home/dirk/.cache/nim/main_d/@m..@s..@s..@s..@susr@slib@snim@[email protected] /home/dirk/.cache/nim/main_d/@m..@s..@s..@s..@susr@slib@snim@[email protected] /home/dirk/.cache/nim/main_d/@m..@s..@s..@s..@susr@slib@snim@[email protected] /home/dirk/.cache/nim/main_d/@m..@s..@s..@s..@susr@slib@[email protected] /home/dirk/.cache/nim/main_d/@m..@[email protected]@[email protected]@ssdl2.nim.c.o /home/dirk/.cache/nim/main_d/@m..@s..@slibs@snim@sstb@sstb_truetype.nim.c.o /home/dirk/.cache/nim/main_d/@m..@s..@s..@s..@susr@slib@snim@[email protected] /home/dirk/.cache/nim/main_d/@m..@[email protected]@[email protected]@sopengl.nim.c.o /home/dirk/.cache/nim/main_d/@m..@s..@s..@s..@susr@slib@snim@[email protected] /home/dirk/.cache/nim/main_d/@m..@s..@s..@s..@susr@slib@snim@[email protected] /home/dirk/.cache/nim/main_d/@m..@s..@s..@s..@susr@slib@snim@[email protected] /home/dirk/.cache/nim/main_d/@mmain.nim.c.o -Wl,-Bstatic -lpthread -Wl,-O1,--sort-common,--as-needed,-z,relro,-z,now'
Anything I can do about that?
See https://stackoverflow.com/questions/55418931/ld-exe-unrecognized-option-z.
Also try --d:gcc.options.linker="" or --d:gcc.options.always="".
See https://stackoverflow.com/questions/55418931/ld-exe-unrecognized-option-z.
Sorry if this sounds completely dumb, but that post talks about ld on Windows in msys2 (which they tell does not support -z), but I am working on Linux.
Also, if -z is not supported (on mingw), why does the Nim compiler use it?
Does everyone who follows the instructions in the manual for cross compiling on Windows have the same issue?
Also try --d:gcc.options.linker="" or --d:gcc.options.always="".
Tried it (I guess you meant to add these options to the nim command?) and it didnt't help, same error.
$ nim c -d:mingw --d:gcc.options.linker="" --path:/home/dirk/libs/nim main.nim
Out of curiosity, what happens when you add two more flags: --cpu:amd64 and --os:windows?
From my experience, cross-compilation from Linux to Windows works with Nim. Just I set it some time ago, and with a different version of mingw.
but I am working on Linux
When you cross-compile, you use the special linker (the one shipped with mingw) for Windows, rather than the one you used to use on Linux.
Also, if -z is not supported (on mingw), why does the Nim compiler use it (when asking it to specifically compile for Windows with mingw)?
Some platforms ship the Nim compiler with a modified version of config files. (which was why I suggested redefining the additional options to empty.) But it seems to not be the case. I now think it's one of your dependencies that adds it.
Out of curiosity, what happens when you add two more flags: --cpu:amd64 and --os:windows?
Very strange, that makes it use gcc instead of mingw (although I specified the d:mingw option) which doesn't work of course. The errors shown are that it can't find io.h and windows.h, but the last line says:
Error: execution of an external compiler program 'gcc -c -w -fmax-errors=3 -mno-ms-bitfields -march=x86-64 -mtune=generic -O2 -pipe -fno-plt -fexceptions -Wp,-D_FORTIFY_SOURCE=2 -Wformat -Werror=format-security -fstack-clash-protection -fcf-protection -DWIN32_LEAN_AND_MEAN -I/usr/lib/nim/lib -I/home/dirk/projects/nim-opengl -o /home/dirk/.cache/nim/main_d/@m..@s..@s..@s..@susr@slib@snim@[email protected] /home/dirk/.cache/nim/main_d/@m..@s..@s..@s..@susr@slib@snim@[email protected]' failed with exit code: 1
But it seems to not be the case. I now think it's one of your dependencies that adds it.
Are you talking about the imports I use? Because I find it strange that they would influence the compiler arguments. Anyway, to prove that it doesn't have to do with that, I made a simple hello world and it gives the same error.
$ cat test.nim
echo "Hello world!"
$ nim c -d:mingw test.nim
Hint: used config file '/etc/nim/nim.cfg' [Conf]
Hint: used config file '/etc/nim/config.nims' [Conf]
........................................................................
CC: ../../../../usr/lib/nim/system/exceptions.nim
CC: ../../../../usr/lib/nim/std/private/digitsutils.nim
CC: ../../../../usr/lib/nim/system/dollars.nim
CC: ../../../../usr/lib/nim/std/exitprocs.nim
CC: ../../../../usr/lib/nim/std/syncio.nim
CC: ../../../../usr/lib/nim/system.nim
CC: test.nim
Hint: [Link]
/usr/lib/gcc/x86_64-w64-mingw32/13.1.0/../../../../x86_64-w64-mingw32/bin/ld: unrecognized option '-z'
/usr/lib/gcc/x86_64-w64-mingw32/13.1.0/../../../../x86_64-w64-mingw32/bin/ld: use the --help option for usage information
collect2: error: ld returned 1 exit status
Error: execution of an external program failed: '/usr/bin/x86_64-w64-mingw32-gcc -o /home/dirk/projects/nim-opengl/test.exe /home/dirk/.cache/nim/test_d/@m..@s..@s..@s..@susr@slib@snim@[email protected] /home/dirk/.cache/nim/test_d/@m..@s..@s..@s..@susr@slib@snim@sstd@[email protected] /home/dirk/.cache/nim/test_d/@m..@s..@s..@s..@susr@slib@snim@[email protected] /home/dirk/.cache/nim/test_d/@m..@s..@s..@s..@susr@slib@snim@[email protected] /home/dirk/.cache/nim/test_d/@m..@s..@s..@s..@susr@slib@snim@[email protected] /home/dirk/.cache/nim/test_d/@m..@s..@s..@s..@susr@slib@[email protected] /home/dirk/.cache/nim/test_d/@mtest.nim.c.o -Wl,-Bstatic -lpthread -Wl,-O1,--sort-common,--as-needed,-z,relro,-z,now'
Adding your earlier suggested arguments doesn't help either.
I see, it seems like the old problem is still here. ;) Here are my all arguments for cross-compile:
nim c -d:mingw --os:windows --cpu:amd64 --amd64.windows.gcc.exe:x86_64-w64-mingw32-gcc --amd64.windows.gcc.linkerexe=x86_64-w64-mingw32-gcc
That is really strange. I think there's something wrong in the config files. Try nim c --os:windows --cpu:amd64 --cc:gcc -d:gcc.exe='x86_64-w64-mingw32-gcc' (without -d:mingw).
You can also try https://github.com/enthus1ast/zigcc if Mingw can't be used.
I see, it seems like the old problem is still here. ;) Here are my all arguments for cross-compile:
nim c -d:mingw --os:windows --cpu:amd64 --amd64.windows.gcc.exe:x86_64-w64-mingw32-gcc --amd64.windows.gcc.linkerexe=x86_64-w64-mingw32-gcc
Still gives the same error.
This works for you? Why doesn't it work for me? Having a -z option added that is not supported must be something that is coded in somewhere. I haven't changed anything in Nim itself and installed mingw from the official Arch repo. This is really weird.
This working for me, but with GCC and mingw 10 on the old stable Debian. I use it to build Linux and Windows versions of my projects. Here is a full command which works for me:
https://github.com/thindil/nimalyzer/blob/trunk/nimalyzer.nimble#L42
Another possible source of the problem. Some distros think that it is funny to add some hidden arguments to the compilation process (Debian in a good example here). I would check if the problematic argument isn't added somewhere.
As I thought, it's the archlinux issue:
gcc.options.linker %= "${gcc.options.linker} -Wl,-O1,--sort-common,--as-needed,-z,relro,-z,now"
That's the line that was added to the /etc/nim.cfg by the package maintainers. It causes issues because -z flag is Linux-specific.
There used to be a similar issue with the Fedora version of the package (when it was still available). I switched to choosenim (which ships the official version of the config files) once noticing it.
Also I think the -march=x86-64 in the first line will cause another problem when cross-compiling for non-x86-64 targets.
There used to be a similar issue with the Fedora version of the package (when it was still available). I switched to choosenim (which ships the official version of the config files) once noticing it
Maybe I should do the same... Thanks for reminding me of choosenim, I had forgotten it exists.