Open tshort opened 7 years ago
I haven't experimented with cross-compiling yet. So I'm trying to get the compilation working on each platform separately first; Windows being the most challenging, especially with Travis.
The details on cross-compiling with fpc are quite old and may no longer work in fpc 3.x. But I am trying to get it working for ARM (Raspberry Pi etc.) so once I figured that out, expanding it to different systems shouldn't be too difficult (he says naively).
Good info. Thanks. This was speculative, so there's always a chance things won't work.
Looks like Docker is popular for cross compiling. Here are a couple of examples:
https://github.com/dockcross/dockcross https://github.com/phusion/holy-build-box
For Linux, that covers older versions, as I think they use a Docker image with an older version of Linux. I didn't find anyone that did the same with FPC, but maybe FPC can be added to one of the Docker images from one of these sites. One of the strengths of Docker seems to be that it's easy to layer components on top of other Docker images.
Here's an example of dockcross used with Travis:
I don't think it would be possible, even with docker, to compile a mac dylib on a linux machine. To my understanding, even the example you shared is different versions of linux.
I thought that, too. I thought we'd need to use the Travis Mac machines for that.
But, there's some interesting work going on in the Julia world. See the following for an approach that uses one Travis machine to compile several library versions, including Mac dylibs.
https://github.com/staticfloat/BinDeps2.jl
He has used Travis to compile a C library for mac64, linux64, linuxaarch64, linuxarmv7l, and linuxppc64le. Now, he's working on windows support. I'm not sure how it all works. He's using the following docker image:
https://microbadger.com/images/staticfloat/julia_workerbase
I don't know how FPC would fit into that. We still may need the Mac Travis.
Also, I notice in the docker file above, that an old version of Linux isn't used. Instead, I think he sets the compiler (somehow) to an older version of the glibc library.
How interesting. I can't say I fully follow what is going on though. Perhaps the repo author can weigh in on this topic if they are wish to share more information. Pinging @staticfloat.
I don't follow it well, either. It's still quite new and a work in progress. Im sure it'll be more apparent when the dust settles.
I think he sets up different cross compilers under /opt/target
, so compilation uses what's appropriate. See his dockerfile here:
Yes, you've about got the general idea. I am still experimenting with this, so definitely don't use it for anything important yet. I will write up a blog post or something detailing how we are building binaries once things are more solidified, but I can give you a quick rundown now:
We are attempting to build a big cross-compiler image that allows us to build (with predictable/standard ABIs, glibc versions, etc...) C/C++/Fortran libraries across all the major platforms. By puppeteering environment variables we can convince software to build for just about any platform we want. (We also have to do some things like puppeteer uname
to give the right output on various systems, etc...)
In principle, this kind of an approach should work for any project as long as the following conditions are met:
build
/host
/target
trifecta, but most tools have at most build
/host
), otherwise during bootstrap ppc64le
binaries will attempt to run on x86_64
hardware, for instance.I should warn you that building cross compilers is........annoying, slow, and finnicky. If you choose to run down this path, I salute your courage and fortitude.
Awesome work @staticfloat! I love the idea of compiling and cross-compiling everything under one OS; it sounds great for deployment!
Quick question though: How would you do unit test for different systems though with Travis? I thought tests of dylibs cannot be done natively in Linux, or can they? Especially when your cross-compiler generates multiple libraries for different systems.
Yes, you definitely cannot do unit testing on one machine without some kind of emulation, and although there are some solutions such as Darling for OSX, Wine for Windows, and QEMU + binfmt_misc for other architectures on Linux, none of these are perfect. I don't have a great solution for this on something like Travis, on a more complex system like Buildbot, I have it setup such that tests can be run on separate computers natively after it's been built on a cross-compilation system.
It looks like the existing
Makefile
/.travis.yml
relies on each of the Mac and Linux VM's doing the compilation.I wonder if one Linux VM could cross compile to all of Mac, Linux, and Windows and compile 32- and 64-bit libraries for all of these.
I think FPC/Lazarus can cross compile. It also looks like others have done this for C code, at least for Linux to Windows compiling:
https://github.com/SOCI/soci/issues/247