Platform Concept

Felix uses a powerful abstract platform concept which is designed to support both personal use and enterprise level operation.

To understand how this works, we need first to understand the notion of a platform, and the platforms involved with Felix.

A platform is basically a specific computer with specific environment configured. Roughly, a Windows box is one platform, a Mac is another, and Linux is a third.

However this is overly simplistic, because for example on Linux you can compile C++ with GNU g++ but you could also use clang. For C code, these produce the different files with the same interfaces, but this is definitely not the case for C++. Even though they share the same ABI, the library templates are different and compiled code using C++ standard library components is not compatible.

Platforms

When you use Felix there are four significant platforms. These are often the same, but they need not be.

The build platform

The build platform is the platform used to build Felix itself. If you build from source that’s your computer, but it may be that one day there is a Debian package for Felix, and in that case the Debian autobuilder is the build platform.

Similarly, if you can get the GitHub posted tarball of Felix to actually work, the build platform for that system is the Travis Continuous Integration Server.

The host platform

The host platform is the system on which you write Felix programs and cause the Felix compiler flxg to be run.

This is usually your computer, the one you are sitting in front of when you edit and compile. However, there are complicated systems where this is not enough of a description. For example Windows 10 can run Ubuntu, and you can write programs for Windows on that Ubuntu.

The target platform

The target platform is the one where the C++ compiler runs. It is usually the same as the host platform, but it need not be.

You can run Ubuntu on Windows 10, and you can run flxg under Ubuntu to produce C++ files, which are then compiled by MSVC++ using the CMD.EXE shell with an environment set up for MSVC++.

The run platform

The run platform is the machine where your generated binary code actually runs.

Commonly on a Mac, the host platform is your Mac, the target is the same Mac, but the run platform is actually iOS because you’re building an iPhone app.

In this case, your target C++ compiler will be clang configured to generate code for the run platform, which is an ARM processor, even though the Mac is an x86_64 processor.

Cross-Cross Compilation Model

What this means is that Felix is actually a cross-cross-compiler, not merely a cross-compiler!

This means generating platform dependent code requires two steps of platform adaption. In the first phase the host Felix system may generate C++ code specific to the downstream build tools.

In the second phase, a C++ cross compiler may compile that code to binaries, specific to the downstream run platform.

For most users, the build platform, host platform, target platform and run platform will all be the same.

Felix target directories

Felix represents the platform model primarily by allowings the user to create a number of distinct target directories.

After building Felix, in the build directory, there are two files:

build/release/share
build/release/host

The directory named host is the default target. It represents the platform chain for which the host, target, and run platformn are all the same and use the defaults set up during the build processes.

On Linux, for example, this will normally be that you are generating C++ code for Unix, using the g++ compiler tool chain compile it, and targetting 64 bit Linux.

If you want to also be able to use the clang tool chain, you would make a new target directory:

build/release/clang

and use it like this:

flx --target=clang hello.flx

This will use the clang toolchain instead of g++, and it will link against libraries built with clang, instead of those built by g++.

In the GNUmakefile there are two ready made make targets for making Felix targets for the iPhone simulator and the iPhone. These look like:

iphonesimulator:
  # prepare directory
  flx_build_prep --target-dir=build/release --target-bin=iphonesimulator --source-dir=build/release \
          --source-bin=host --clean-target-bin-dir --copy-compiler --copy-pkg-db \
          --copy-config-headers --toolchain=toolchain_iphonesimulator --debug
  rm -rf build/rtl-tmp
  # build rtl
  DYLD_LIBRARY_PATH=build/release/host/lib/rtl flx_build_rtl \
    --target-dir=build/release --target-bin=iphonesimulator --static --noexes


iphoneos:
  # prepare directory
  flx_build_prep --target-dir=build/release --target-bin=iphoneos --source-dir=build/release \
          --source-bin=host --clean-target-bin-dir --copy-compiler --copy-pkg-db \
          --copy-config-headers --toolchain=toolchain_iphoneos --debug
  rm -rf build/rtl-tmp
  # build rtl
  DYLD_LIBRARY_PATH=build/release/host/lib/rtl flx_build_rtl \
    --target-dir=build/release --target-bin=iphoneos --static --noexes

These are advanced uses of the Felix build tools which create the extra targets

build/release/iphonesimulator
build/release/iphoneos

which can be used on a Mac to build code for the respective run platforms like

flx --target=iphonesimulator filename.flx
flx --target=iphone filename.flx

These use clang for building the code, with options set for it to cross-compile to the relevant target.

Our purpose here is not meant to explain how to create a new target, merely to show that the Felix architecture is designed to support code generation for multiple targets.

In an enterprise install, the system administrator of a large network would create and install targets for each kind of developer, and put all of them up on a server, so the developers could pick the target they need to use.