Muxelmann / OpenDSSDirect.make

A set of scripts to download and compile the up to date version of OpenDSS library.
Other
10 stars 4 forks source link

Cross compiling libraries #6

Open tshort opened 7 years ago

tshort commented 7 years ago

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

Muxelmann commented 7 years ago
  1. is correct: you can only compile for the local system, and
  2. is correct: you can cross-compile with fpc.

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).

tshort commented 7 years ago

Good info. Thanks. This was speculative, so there's always a chance things won't work.

tshort commented 7 years ago

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.

tshort commented 7 years ago

Here's an example of dockcross used with Travis:

https://github.com/dockcross/python-manylinux-demo

kdheepak commented 7 years ago

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.

tshort commented 7 years ago

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.

kdheepak commented 7 years ago

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.

tshort commented 7 years ago

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:

https://github.com/staticfloat/julia-docker/blob/sf/crossbuild/workerbase/build/crossbuild-x64/Dockerfile

staticfloat commented 7 years ago

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:

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.

Muxelmann commented 7 years ago

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.

staticfloat commented 7 years ago

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.