Nix + OCaml + Cross-compilation to Windows

Hi!
As part of my job, I’m packaging some OCaml software (Tezos and LIGO) with nix. It’s been very nice so far, and building both dynamic and static executables was simple. Now comes the hard part – cross-compiling from Linux to Windows. The most crucial part of that is building an OCaml compiler that would run on Linux, but produce libraries and executables for Windows. The overlay I’m using is https://0x0.st/iMoW.txt , and the full log with error is https://0x0.st/iMo4.txt . What am I doing wrong and how to produce the compiler I need? Any help is greatly appreciated, even if it’s just a pointer.

Are you able to cross-compile without using Nix? If you can get that working first, then you can test integration with Nix. There are few warnings in the output of configure that you might want to review. For example:

./configure: line 1: flexlink: not found
[WARNING] flexlink not found: native shared libraries won't be available.

It is good to have a clean configure output, or disable whatever is not supported. The final error is as follows:

x86_64-w64-mingw32-gcc -e main -DWINDOWS_UNICODE=0 -D_FILE_OFFSET_BITS=64 -DCAML_NAME_SPACE   -o ocamlrun.exe prims.o libcamlrun.a -lws2_32 -lm    

/nix/store/ya53cans3z55sfy4rk2ic3jmkpwwd73a-x86_64-w64-mingw32-binutils-2.31.1/bin/x86_64-w64-mingw32-ld: libcamlrun.a(win32.o):win32.c:(.text+0xffa): undefined reference to `GetFileVersionInfoSizeA'
/nix/store/ya53cans3z55sfy4rk2ic3jmkpwwd73a-x86_64-w64-mingw32-binutils-2.31.1/bin/x86_64-w64-mingw32-ld: libcamlrun.a(win32.o):win32.c:(.text+0x1017): undefined reference to `GetFileVersionInfoA'
/nix/store/ya53cans3z55sfy4rk2ic3jmkpwwd73a-x86_64-w64-mingw32-binutils-2.31.1/bin/x86_64-w64-mingw32-ld: libcamlrun.a(win32.o):win32.c:(.text+0x105e): undefined reference to `VerQueryValueA'
/nix/store/ya53cans3z55sfy4rk2ic3jmkpwwd73a-x86_64-w64-mingw32-binutils-2.31.1/bin/x86_64-w64-mingw32-ld: /nix/store/z4icpcdlgppxh3r0yj2q1rd057zwjlky-mingw-w64-5.0.4-x86_64-w64-mingw32/lib/libmingw32.a(lib64_libmingw32_a-crt0_c.o): in function `main':
/build/mingw-w64-v5.0.4/mingw-w64-crt/crt/crt0_c.c:18: undefined reference to `WinMain'

It looks like the build is not able to find a library that defines WinMain, and the other undefined references mentioned.

1 Like

Thanks for your answer!

Are you able to cross-compile without using Nix? If you can get that working first, then you can test integration with Nix.

I did get that working without nix with opam-cross-windows, and then I tried to move that to Nix without any success (my parser sucks and it’s not able to parse ocaml-windows OPAM file).

There are few warnings in the output of configure that you might want to review. For example:

./configure: line 1: flexlink: not found
[WARNING] flexlink not found: native shared libraries won't be available.

By looking at configure script I thought that this was fine since it disabled the native shared library feature.

It is good to have a clean configure output, or disable whatever is not supported. The final error is as follows:

x86_64-w64-mingw32-gcc -e main -DWINDOWS_UNICODE=0 -D_FILE_OFFSET_BITS=64 -DCAML_NAME_SPACE -o ocamlrun.exe prims.o libcamlrun.a -lws2_32 -lm

/nix/store/ya53cans3z55sfy4rk2ic3jmkpwwd73a-x86_64-w64-mingw32-binutils-2.31.1/bin/x86_64-w64-mingw32-ld: libcamlrun.a(win32.o):win32.c:(.text+0xffa): undefined reference to GetFileVersionInfoSizeA' /nix/store/ya53cans3z55sfy4rk2ic3jmkpwwd73a-x86_64-w64-mingw32-binutils-2.31.1/bin/x86_64-w64-mingw32-ld: libcamlrun.a(win32.o):win32.c:(.text+0x1017): undefined reference to GetFileVersionInfoA’
/nix/store/ya53cans3z55sfy4rk2ic3jmkpwwd73a-x86_64-w64-mingw32-binutils-2.31.1/bin/x86_64-w64-mingw32-ld: libcamlrun.a(win32.o):win32.c:(.text+0x105e): undefined reference to VerQueryValueA' /nix/store/ya53cans3z55sfy4rk2ic3jmkpwwd73a-x86_64-w64-mingw32-binutils-2.31.1/bin/x86_64-w64-mingw32-ld: /nix/store/z4icpcdlgppxh3r0yj2q1rd057zwjlky-mingw-w64-5.0.4-x86_64-w64-mingw32/lib/libmingw32.a(lib64_libmingw32_a-crt0_c.o): in function main’:
/build/mingw-w64-v5.0.4/mingw-w64-crt/crt/crt0_c.c:18: undefined reference to `WinMain’

It looks like the build is not able to find a library that defines WinMain, and the other undefined references mentioned.

Yes, this is why I’m asking for help :slight_smile: I don’t know what library defines WinMain (and other missing symbols). If I knew, I could just supply that library to the build.

So for the command that is failing now, can you find from the build log that ran successfully for opam-cross-windows without Nix, and see what were the libraries provided to the same, and where they were located? You might want to ensure the same are available when you run them through Nix.

@balsoft, did you make any progress with this project?