SAFplus Compilation
Building a SAFplus
Building a distribution package
Cross Compilation
Set up for cross compilation
To initiate a cross compilation, you first need to set up your cross compilation environment. Embedded distribution generators such as OpenEmbedded/Yocto will set up this environment for you. An embedded board may also provide this as part of a "dev" kit. However, if you do not have a dev kit and are not building your own embedded distribution, you will need to do this yourself. In this document, we will provide examples using an Ubuntu development environment and an ARM target.
Most modern linux distributions provide crossbuild toolchains in their distribution's package manager. Ubuntu is no exception so let's install it now:
apt-get install g++-arm-linux-gnueabihf
The next step is to copy the system libraries and headers from your embedded target to a location in your development machine (if you are using OE/Yocto or a "dev" kit this is already done; you just need to find the correct directory). You are going to copy the relevant files from your embedded target to your development machine.
The first step is to use the package manager to install the development versions of all the packages that SAFplus (and your application) uses. This is specific to your embedded distribution, but for Debian-family distributions you would boot up your target and type:
apt-get install libprotoc-dev libbz-dev python-dev libboost1.55-all-dev libdb-dev libgdbm-dev libsqlite3-dev libxml2-dev
Even between Debian distributions, you may need to substitute libz2-dev for libz-dev...
For manageability, you will also need:
apt-get install libssh2-1-dev libncurses5-dev
Next, you must copy the complete libraries and headers to your development machine, into an isolated subdirectory. You can accomplish this in many ways; I use rsync with differencing here so if I need to install additional libraries and recopy it will do so efficiently. In this example the prefix directory "/code/armEnv" is used (but you can put it whereever you like), and the target's IP address is 192.168.1.10 (yours will differ).
Note, some of these directories may not exist on your embedded device. Also, if you have headers and libraries in nonstandard locations on your embedded device, you will need to copy them over if you want to use them in the crossbuild.
ssh-copy-id root@192.168.1.10 # Optional: so the password is not requested every time... mkdir /code/armEnv mkdir /code/armEnv/usr mkdir /code/armEnv/usr/local cd /code/armEnv rsync -tavz root@192.168.1.10:/lib/ . rsync -tavz root@192.168.1.10:/include/ . rsync -tavz root@192.168.1.10:/usr/lib/ usr/lib rsync -tavz root@192.168.1.10:/usr/include/ usr/include rsync -tavz root@192.168.1.10:/usr/local/lib/ usr/local/lib rsync -tavz root@192.168.1.10:/usr/local/include/ usr/local/include
Remember this directory! It is called the "sysroot" and will be used in the compilation step
Configuring SAFplus for cross compilation
Now you must tell the SAFplus build system the details about your cross compilation. To do so, create a file called <target>.mk. An example for ARM architectures is provided here: https://github.com/OpenClovis/SAFplus-Availability-Scalability-Platform/blob/s7/src/mk/arm.mk.
This file overrides specific compilation variables to point them to your crossbuild toolchain and environment. All variables defined in https://github.com/OpenClovis/SAFplus-Availability-Scalability-Platform/blob/s7/src/mk/preface.mk are overridable. Depending on the specifics of your cross-compilation, you may need to override more than what is shown for ARM.
These are what needs to be specified and the specific variables required to do so:
- Prefix to the name of the crossbuild tools
CROSSPFX := <prefix to your tools>
for example, if the crossbuild compiler is arm-linux-gnueabihf-g++, use "CROSSPFX := arm-linux-gnueabihf"
- Compiler name
COMPILER := $(CROSSPFX)-g++
Set the compiler to your <cross prefix>-g++ (or whatever name it is called)
- Specify the package config tool
PKG_CONFIG_PATH = $(INSTALL_DIR)/lib/pkgconfig PKG_CONFIG = PKG_CONFIG_LIBDIR=<sysroot>/lib/pkgconfig:$(INSTALL_DIR) PKG_CONFIG_PATH=$(PKG_CONFIG_PATH) pkg-config
The pkgconfig tool is used to discover header files and libraries. It is important that it supply the headers and libraries for your embedded distribution NOT your development system. To do so, you set an environment variable PKG_CONFIG_LIBDIR to point to the target environment that you copied over in the prior step. We also set it to the SAFplus INSTALL_DIR location -- if you manually built any 3rdparty dependencies (like boost or protobufs) rather then getting them from your embedded distribution, this is where they will be located.
- Tell the linker to use your embedded libraries rather than the standard ones.
LINK_FLAGS += --sysroot=$(CROSS_SYS_ROOT) -L/lib/arm-linux-gnueabihf
-sysroot=$(CROSS_SYS_ROOT) may be sufficient. Look into the directory structure of your embeded environment. If it contains atypical directories, like $(CROSS_SYS_ROOT)/lib/arm-linux-gnueabihf you may need to add additional library paths. Note that every library path added is prefixed by the directory you specified in "sysroot".
Cross compilation
At this point, cross compilation is simple. Just add CROSS=<your file> to the make command in any SAFplus directory.
For example, to compile everything for ARM:
cd <SAFplus>/src make CROSS=arm.mk
(if your cross .mk file is not located in <SAFplus>/src/mk then specify the entire path)
This will build SAFplus in the directory <SAFplus>/target/g++ -buildmachine/... This means that you can build for the local machine and different cross-builds without interference.
Troubleshooting
out of dynamic memory in yy_create_buffer()
This may be a compiler bug. It occurs when you specify a sysroot and then a library search path (-L) that includes the sysroot. For example do NOT do:
LINK_FLAGS += --sysroot=/root/myArmEnv -L/root/myArmEnv/lib/arm-linux-gnueabihf
Instead do:
LINK_FLAGS += --sysroot=/root/myArmEnv -L/lib/arm-linux-gnueabihf
Undefined symbols or incompatible version warnings in standard libraries
The compilation is picking up headers that do not match your libraries.
Check the compilation directory search path (-I...) to make sure that NO local system directories are included. That is -I/include -I/usr/include -I/usr/local/include should NOT appear.