felix icon indicating copy to clipboard operation
felix copied to clipboard

Cross-compilation

Open Immortalin opened this issue 9 years ago • 4 comments

What should one do if one wants to cross compile Felix code for another platform?

Immortalin avatar Jul 26 '16 14:07 Immortalin

@skaller Is it possible for a user to compile a FLX script to CPP (on say Windows), ship the resultant code to Linux and compile it there? It seems like the run-time library (RTL) would get in the way of that.

gbluma avatar Aug 04 '16 15:08 gbluma

There are two issues.

First, you have to use Windows compliant Felix classes. There are two ways to do that.

Method 1A: Fool Felix into thinking the host is Windows. This is done by settting the macros in build/release/host/lib/plat/flx.flxh. These control Felix level conditional compilation. There is some possibility build/release/host/lib/plat/float.flx might have to be diddled too.

Method 1B: Exactly the same as above, but make a separate target directory, say build/release/linux and make the mods there.

Shortly, you will be able to just download a pre-built target from GitHub, but at the moment you can only do this for Windows.

When you compile, you should be able to say --target=linux to use a different target.

You also have to stop Felix C++ compiling and put stuff where you need it.

flx --target=linux -c --bundle-dir=mycode --nolink filename.flx cp filename.flx mycode

should then do it. The generated C++ ends up in directory mycode instead of the cache.

Now, on the actual target platform you can do this:

flx --nofelix bundle-dir=mycode filename.flx

and it should produce a linux binary. You will of course have to have a Felix installation on that platform to do that.

When you produce the binary, of course you need a library! There is a tool to build it, but of course, it is written in Felix. You can also use fbuild.

Alternatively you can hand build the library, and hand compile the mycode/*.cpp source files. But you will still need one or two generated C++ files. MOST of the RTL is platform adaptive, that is, it uses macros for conditional compilation rather than having fbuild generate the correct C++ for the platform.

Watch out for demux! It has code for each platform and uses some special tricks so you can compile the Windows demux on linux and generate an empty object file you can link.

So the bottom line is: Felix is a cross-cross compiler so you can certainly generate Linux C++ on Windows with a Windows Felix host by setting up a linux target, but you then have to compile the generated C++ on Linux. This includes the RTL.

The easiest way to do this is to git clone a prebuilt Linux version of Felix onto Windows, run the C++ code generation into a bundle directory, port the bundle directory to Linux, download the same prebuilt Linux target, and then finish the compilation on Linux.

There is a prebuilt Windows target already, in felix-lang/win32binary.git. I have not set up Travis to save a prebuilt Linux binary target yet. Until I do you will have to build Felix on the target Linux so the tools and run time library are available.

skaller avatar Aug 04 '16 21:08 skaller

BTW: Method 2 for generating Linux C++ on Windows: instead of fiddling the host, you can specify, in Felix, to use the class instances for Linux instead of Windows. for example instead of using

Filename::join(dir,base)

you use instead

Filename_class[Posix]::join(dir,base)

which guarantees that the code will work on Windows too by replacing Posix with Win32. The way to do this is a master typedef:

typedef mytarget = Posix

Or you can use the platform dependent class name:

PosixFilename::join(dir,base)

which includes the platform independent code for filenames PLUS platform dependent code as well.

Look in src/packages/filesystem.fdoc line 170 or there about, you will see the actual Filename class is conditionally selected to be either PosixFilename or Win32Filename.

Don't confuse the conditional compilation macros PLAT_LINUX, PLAT_WIN32 etc with the phantom types Posix, Win32, etc.

The compexity of the model is there so you get:

(a) parametrically polymorphic platform independent code (b) platform specific code (c) automatically adapted code to the local target

Note also the splitup is not complete. In particular Process is not properly split into an abstract class with virtuals and instances for each platform. So occasionally you may have to use conditional Felix compilation with PLAT_* macros and write code for each platform. You shouldn't need to do that if your code is intended to be portable, it should be done in the library instead.

Note also some of the platform dependencies are hidden from Felix by the run time library. So there is a second level of platform adaption happening in C++ as well.

skaller avatar Aug 04 '16 21:08 skaller

Cross compilation is a continuing pain. The difficulty is primarily building the appropriate target directory. This is because there are no tools to manage configurations. The build system uses a simplified setup now: Felix comes with "pre-configured" setups for most platforms. The source config database is organised in a tree from which you can extract a target config based on the compiler, word size, and OS. The OS macro has to be configured as well.

skaller avatar Mar 09 '20 20:03 skaller