= SAFplus Compilation = == Building SAFplus == This section describes how to build SAFplus itself, not how to build your application on top of SAFplus. This document describes the process based on an Ubuntu 14.04 LTS distribution. You may need to make changes based on your chosen Linux distribution or version. To build SAFplus first install or build necessary dependencies. {{{ apt-get install libprotoc-dev libz-dev python-dev libboost1.55-all-dev libdb-dev libgdbm-dev libsqlite3-dev libxml2-dev }}} For manageability, you will also need: {{{ apt-get install libssh2-1-dev libncurses5-dev zlib1g-dev }}} Next go to the source directory and run "make": {{{ $ cd src $ make }}} SAFplus will be built. === Troubleshooting === ""protoc version error"" The SAFplus project uses the Google Protobuf code generator to create RPC calls. We commit this generated code to source control. If your installed protobuf version is different than the one the SAFplus project used to generate code you will get this error. You can either switch your protobuf to the version used in SAFplus using your package manager, or regenerate the protobuf code in SAFplus. Regenerating the protobuf code is not automatic; it will require that you examine and work with the SAFplus code base. But in general, go to the directory with the error and type {{{ make gen }}} or sometimes {{{ make genrpc }}}. Next, use "git diff" to look at the differences between the generated code and the original SAFplus code. You need to merge these differences: in general, keep the newly generated code, but also keep the implementations of the RPC calls found in the original code. == Building a distribution package == First build SAFplus as described above. === Debian derived distributions === Install the following required packages: {{{ apt-get install dh-make reprepro }}} Now go to the root SAFplus directory and run: {{{ make deb }}} You will find .deb files in the "build" subdirectory {{{ clovis@u1404:~/safplus$ ls -l build total 9464 -rw-r--r-- 1 clovis clovis 2597840 Nov 5 13:50 safplus_7-0-1_amd64.deb -rw-r--r-- 1 clovis clovis 7087208 Nov 5 13:51 safplus-src_7-0-1_amd64.deb clovis@u1404:~/safplus$ }}} === Redhat derived distributions === TBD == 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 [[https://www.yoctoproject.org/ | 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 gcc-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). This is necessary so that the crossbuild can include the embedded boards' headers and link with its libraries. Your board manufacturer may provide this crossbuild environment. If so, install it and note the environment's "base" directory (the directory that corresponds to "/" on the actual device). Unfortunately, your board manufacturer's crossbuild environment may not provide all the libraries required by SAFplus. In this case, you must either acquire these libraries in the manner described below, or download them from source, crossbuild them for your target (use --prefix=[embedded environment's "base" directory]), and install them on your target. Accomplishing this is beyond the scope of this document, however you may get some hints by looking at the SAFplus 3rdparty Makefile. Step 2: Copy the embedded environment relevant files from your embedded target to your development machine. On the embedded target, 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 libz-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 .mk. An example for ARM architectures is provided here: [[/src/mk/arm.mk | 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 [[ preface.mk | 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 := }}} 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 -g++ (or whatever name it is called) * Specify the package config tool {{{ PKG_CONFIG_PATH = $(INSTALL_DIR)/lib/pkgconfig PKG_CONFIG = PKG_CONFIG_LIBDIR=/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= to the make command in any SAFplus directory. For example, to compile everything for ARM: {{{ cd /src make CROSS=arm.mk }}} (if your cross .mk file is not located in /src/mk then specify the entire path) This will build SAFplus in the directory /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.