Cross compilation from OSX/Windows to Linux

build
cross-compilation

#1

Hi, I wanted to ask if OCaml supports cross compilation and if not if that’s something you guys are working on or need help with.

My background: I’m working a lot with AWS Lambda and other FaaS (Function as a Service) systems. Specifically I’m my job includes contributions to the Serverless Framework: https://github.com/serverless/serverless
A friend of mine and I had the desire to use OCaml/Reason on AWS Lambda and wrote a shim + Serverless Framework plugin. We got everything to work, but without cross compilation the onboarding/development experience got quite complicated. It required the user to either use a Linux system or setup Docker.


#2

The cross compilation terminology is always confusing. You want to compile using a linux executable that run under MacOS/Windows, don’t you?
If so, the title of your post should be “Cross compilation to OSX/Windows from linux”.

TL;DR:

  • Can I compile an executable for windows using an unix machine? Yes, have a look at https://github.com/whitequark/opam-cross-windows but it is in danger.
  • Can I compile an executable for MacOS using a linux machine? I’m not aware of anything

Explanation:
In the past years, some energy has been put in the OCaml compiler itself to make it cross compilation friendly.
As a complete cross-compilation environnement is concern. https://github.com/whitequark/opam-cross-windows, https://github.com/whitequark/opam-cross-ios, https://github.com/whitequark/opam-cross-android are attempts to provide some.
Efforts are not coordinated and there exists also an older but still somehow maintained and containing a different set of packages https://github.com/vouillon/opam-windows-repository. (At the first glance, let say it is better for packages that contains/depend upon C code) I wish the 2 can merge on day if they survive the current OCaml ecosystem tsunami: jbuilder.

Jbuilder, the new cool build system widely discussed on this channel comes with a lot promisses (and pretty good achievement already) but, in order to solve one day the problem of cross compilation in completed case, it is not compatible with the way we implemented cross-compilation in simple ones…
Concretely, it made the choice to not use ocamlfind to “choose” the compiler it uses. Therefore, you have no way for now to ask it to use the cross-compiler instead of the “regular” compiler! Go at https://github.com/janestreet/jbuilder/issues/144 to stay tuned on the issue.

Problem: critical OCaml libraries are now compiled using jbuilder (9 of the 39 packages of opam-cross-windows). Therefore, you cannot cross-compile their cutting edge version (for now) and you won’t be able to follow the evolution of the ecosystem if you want to cross compile.
To take a concrete example, without real responsibility from lwt developers (but the one to rush changing their build system while they had a working one :slight_smile: ) when the next major version of Lwt will go out in a few months, Lwt dependencies will have to choose between staying in lwt 3 forever or not being cross compilable…


#3

I think @nikgraf wants to build a Linux executable in Windows and/or Mac environment without using docker to set up Linux environment. I’m interested in that too.


#4

Sorry for my inaccurate reply then.

The question is then, is there a C cross compiler (and linker and assembler and maybe other binutils…)
for linux under OSX/Windows.
If there is, you will ba able to make an OCaml cross compiler imitating what is done in the opam repository I linked. But I am not aware of anything available out of the box.


#5

I normally do this using Windows Bash: https://github.com/Microsoft/BashOnWindows. It works well, but you should make sure that your target Linux distribution is close to the one used under Windows Bash (as a general remark OCaml does not support the scenario “compile on Linux distribution X, run in Linux distribution Y”).


#6

FWIW, Go has cross compilation feature since v1.5. It is as simple as setting the variables $GOOS and $GOARCH as compilation targets before compiling, and yes, it supports compiling to Linux from OSX/Windows and vice versa. Perhaps it’s an interesting feature to be copied into OCaml…

But before that happens, unfortunately it seems like the most foolproof way is via Docker.