# Installation Instructions for the CPSW Package ## Copyright Notice This file is part of CPSW. It is subject to the license terms in the LICENSE.txt file found in the top-level directory of this distribution and [here](https://confluence.slac.stanford.edu/display/ppareg/LICENSE.html). No part of CPSW, including this file, may be copied, modified, propagated, or distributed except according to the terms contained in the LICENSE.txt file. ## 1. Makefiles CPSW comes with its own makefile system which borrows ideas from the EPICS build system. The makefiles support building multiple target architectures, shared- and static libraries and programs. The makefiles also support building applications which are layered on top of CPSW (and do not share the CPSW source directory but may be located at an arbitrary location in the filesystem). Consult 'src/makefile.template' for further information. The makefiles consist of (you can skip this explanation if you want to proceed with a vanilla build) - `src/rules.mak`: generic rules; should NOT be modified; lives in the CPSW source directory (included by derived libraries and applications). - `src/defs.mak`: generic definitions; should NOT be modified; lives in the CPSW source directory (included by derived libraries and applications). - `config.mak`: site-specific settings of certain variables that affect the build (AND the build of derived libraries and apps); lives in the CPSW top directory. - `config.local.mak`: local tweaks of variables that affect the build (AND the build of derived libraries and apps); lives in the CPSW top directory. SEE BELOW for what this is for. - `src/makefile`: Defines application/library-specific variables, i.e., mostly lists the targets to build and the files that are required for them (see makefile.template). Can also contain app-specific rules. Lives in the application source directory. Binaries are built under 'O.<architecture>' directories. - `src/local.mak`: Local tweaks which are application/library-specific; lives in the application source directory. ## 2. `config.mak` This file may be edited to define 1. the desired set of target architectures 2. the name and location of the compiler toolchain for each target architecture 3. the location of the dependent 'boost' and 'yaml-cpp' libraries. 4. whether to build a static and/or dynamic CPSW library 5. the installation location The aforementioned definitions may also be overridden from a file `config.local.mak`: in many cases `config.mak` is maintained in git and reflects the site-specific settings. However, a developer may occasionally want to build the package in a different environment (e.g., on a private laptop). This is when `config.local.mak` is useful as it allows the developer to define a 'private' configuration to override the 'normal' one. `config.local.mak` should not be maintained in 'git' but be reserved for such special cases. In the common case of - native-only build - no cross-compilation - 'boost' and 'yaml-cpp' packages natively available (e.g., installed by your distro's package manager) there is no need for any settings in `config.mak` -- an empty file will do. However, you may want to define the installation location (5. above). The following section discusses the settings 1..5 above: #### 2.0.1 Build with C++11 and without boost If a C++11 compiler is available then most dependency on boost can be eliminated except for 'lockfree::stack, lockfree:queue' (which are just templates from headers). In `config.local.mak` the variable `USE_CXX11_<arch>` can be set to `YES` in order to do so. It is also possible to replace the lockfree implementations from boost by trivial (mutex based) implementations thus removing any dependency on boost completely. Set `WITH_BOOST_<arch>` to `NO` for such a configuration. Note, however, that performance may suffer (but it also may only have a minor impact -- no thorough testing has been performed yet). ### 2.1 Select target architectures: Each desired target architecture must be added to the `ARCHES` variable using the `+=` operator, e.g.: ARCHES += buildroot-2016.11.1-x86_64 Binaries for all architectures are build in a `O.<arch>` subdirectory, e.g., `O.linuxRT-x86_64`. Installation (`make install`) also deposits binaries and libraries into a architecture-specific subdirectory, e.g., $(INSTALL_DIR)/buildroot-2016.11.1-x86_64/lib Note that the host architecture is `host` by default. This name may be changed by setting the `HARCH` variable, e.g., HARCH = linux-x86_64 Another example, for some systems with multiple linux distributions: HARCH = rhel6-x86_64 `HARCH` is automatically added to `ARCHES`, so there is no need to do so. #### 2.1.1 Target Architecture-Specific Makefile Variables This subsection contains detailed information - you may skip it if you are just want to build CPSW. An entire set of variables (look for `ARCHSPECIFIC_VARS` in `defs.mak`) is defined in a way so that during expansion a few variants are tried: FOO = $(or $(FOO_$(TARNM)),$(FOO_default)) This means that when building for architecture `bar`, `FOO` expands to the value of `FOO_bar` if such a variable is defined (non-empty). If `$(FOO_bar)` is empty then `FOO` evaluates to the value of `FOO_default`. This scheme allows for precise control over the value `FOO` should have when building for a specific architecture. When working with external packages then usually the build process requires access to headers and libraries. The makefiles provide a mechanism to define variables which point to architecture-specific locations where such headers and libraries can be found. Respective variables are defined, based on stems listed in `ARCHSPECIFIC_LIBVARS`. For each `stem` listed there, definitions stem_DIR=$(or $(stem_DIR_$(TARNM)),$(stem_DIR_default)) steminc_DIR=$(or $(steminc_DIR_$(TARNM),$(steminc_DIR_default),$(addsuffix /include,$(stem_DIR)))) stemlib_DIR=$(or $(stemlib_DIR_$(TARNM),$(stemlib_DIR_default),$(addsuffix /lib,$(stem_DIR)))) are emitted. These definitions cause e.g., `$(steminc_DIR)` to evaluate to the first non-empty value of 1. `steminc_DIR_<arch>` 2. `steminc_DIR_default` 3. `stem_DIR_<arch>/include` 4. `stem_DIR_default/include` It is possible to add your own variables and stems to `ARCHSPECIFIC_VARS` and `ARCHSPECIFIC_LIBVARS`, respectively. You should do so in your `makefile` *before* including `defs.mak`. ### 2.2 Compiler Toolchain The makefiles offer fine-grained control of the selection of tools. Only the most common cases are covered here. Tools are picked in the following way: <architecture-specific-prefix><toolname> Each of these components can be fine-tuned. The default toolnames are `gcc`, `ld`, `install` etc. The architecture-specific prefix is (by default) empty for the host and identical to the architecture with a `-` appended for cross-builds. E.g., the compiler for the `linuxRT-x86_64` architecture would be linuxRT-x86_64-gcc If the such a compiler can indeed be found in the current `PATH` then no special setting in `config.mak` is required. If the tool-prefix requires renaming then this can be achieved by setting CROSS_<archname>=<architecture-specific-prefix> Since makefile variables must not contain any `-` characters all hyphens present in an architecture must be replaced by underscores (`_`) on the left hand side of the above definition. E.g., if the compiler for `linuxRT-x86_64` is really named `x86_64-linux-g++` then remapping of the tool-prefix woud be defined as follows: CROSS_linuxRT_x86_64=x86_64-linux- Note that this requires the compiler to be found in the `PATH`. If this is not desired then an absolute path prefix may simply be added to `CROSS_<archname>`. CROSS_linuxRT_x86_64=/path/to/tools/x86_64-linux- #### 2.2.1 C++11 Support CPSW can be built with a C++-11 compiler. This has the advantage of removing the dependency on `boost` for _applications_. I.e., CPSW itself still requires some features provided by `boost` but these are not exported to the API. The variables USE_CXX11_default USE_CXX11_<architecture> can be set to `YES` or `NO`, respectively in order to enable or disable the use of C++-11. ### 2.3 Dependent 'boost' and 'yaml-cpp' Packages If the 'boost' and 'yaml-cpp' packages are not installed in a standard location then the following variables must be defined and pointed to the correct location(s) for include files and libraries, respectively. boostinc_DIR= boostlib_DIR= yaml_cppinc_DIR= yaml_cpplib_DIR= If different architectures use different locations then you may set boostinc_DIR_xxx=/path/for/arch/xxx boostinc_DIR_default=/path/for/others If includes and libraries are in `include` and `lib` subdirectories under a common parent then setting `boost_DIR` and `yaml_cpp_DIR` or their arch-specific variants is easier. Assume you have yaml-cpp installed natively (for the host) and under `/usr/local/yaml-cpp/0.5.3/` for the `linuxRT-x86_64` architecture (with includes under `/usr/local/yaml-cpp/0.5.3/include` and libraries under `/usr/local/yaml-cpp/0.5.3/lib`). You could then say # no need to do anything for the host since it is installed natively yaml_cpp_DIR_linuxRT_x86_64=/usr/local/yaml-cpp/0.5.3/ Dont' forget to substitute `-` with `_` in gnumake variable names. ### 2.4 Building Static and Shared Libraries. The makefile system can build either static or shared libraries or both. You can tune by explicitly setting WITH_SHARED_LIBRARIES=YES # or 'NO' WITH_STATIC_LIBRARIES=NO # or 'YES' *Note*: It is recommended to build shared libraries (exclusively). Otherwise, run-time loading of drivers/classes may not work unless the application is linked with special linker flags. Also, the python bindings require shared libraries. ### 2.5 Python Bindings CPSW comes with python bindings for python 2.7 or 3.4 (other versions may work but have not been tested). There are three ways of building python bindings: a) using `boost_python` (which is the legacy method). b) using SWIG -- note, however, that this implementation is incomplete and experimental. The effort has been abandoned in favor of c). c) using `cython`. Note that future versions of CPSW will likely deprecate a) and b). #### 2.5.2 Configuration Variables for Python The user must define the location of the for python headers. The build process will look for the following variables in order of precedence: $(pyinc_DIR_<architecture>) $(pyinc_DIR_default) $(py_DIR_<architecture>)/include $(py_DIR_default)/include *Note*: the python bindings require cpsw and dependent *shared libraries*. The resulting python module is called `pycpsw` and may be imported as such into python. Note that the dynamic/run-time linker must be able to locate `libcpsw` and other dependent libraries, e.g., in the environment variable `LD_LIBRARY_PATH` or by some other means (consult `man ld.so` for more information). #### 2.5.2 CYTHON Bindings You need to have cython installed (only if you modify CPSW code; otherwise the pre-built code can be compiled). This is the default option which is enabled if the variables pointing to python headers are non-empty and if shared libraries are enabled. However, the default setting already tries to 'guess the right thing': it will cause python bindings to be built if and only if 1. `pyinc_DIR` evaluates to a nonempty string for the target architecture (i.e., any of `pyinc_DIR_<arch>`, `pyinc_DIR_default`, `py_DIR_<arch>`, `py_DIR_default` is set). 2. `WITH_SHARED_LIBRARIES` evaluates to `YES` for the target architecture #### 2.5.3 `boost_python` Bindings You need the `boost_python` library and headers for building the python bindings as well as the python headers. Defining the location of `boost` has already been discussed. The default name for the `boost_python` library (without pre- and suffix) is `boost_python`. If you need to change this name (e.g., on ubuntu the respective library for python3.4 is called `boost_python-py34`) then you can modify BOOST_PYTHON_LIB_<architecture> BOOST_PYTHON_LIB_default Finally, you may have to define a variant of `WITH_PYCPSW` to `BOOST` in order to instruct the makefiles to actually build the python bindings: WITH_PYCPSW_<architecture> = NO # or BOOST/CYTHON/SWIG WITH_PYCPSW_default = BOOST # or NO ### 2.6 The Installation Location `make install` installs headers into $(INSTALL_DIR)/<ARCH>/include libraries into $(INSTALL_DIR)/<architecture>/lib/ binaries into $(INSTALL_DIR)/<architecture>/bin/ and documentation into $(INSTALL_DIR)/<architecture>/doc/ ## 3. Running `make` The makefiles understand the standard goals `all`, `clean`, `install` and `test` with `all` being the default goal. However, since the makefile system is designed to build recursively for multiple target architectures and subsystem directories it is possible and sometimes necessary to specify goals in a more fine-grained way. Any target for which a rule is defined (either in `rules.mak` or in the `makefile`) - when used as a 'goal' - must be supplied with a prefix which indicates the set of architectures for which the goal should be built. The most common cases are multi-<goal> => builds <goal> for all architectures sub-<arch>@<goal> => builds <goal> for <arch> only Thus, e.g., the aforementioned `all` target is actually an alias for `multi-build`. Since the test programs can only be executed by make on the host system, the 'test' goal is actually an alias for `sub-$(HARCH)@run_tests`. For building the CPSW package it is sufficient to execute make and optionally make install Note that the latter requires `INSTALL_DIR` to be defined either in config.mak or on the command line. For easy de-installation a 'make uninstall' target is available. ## 4. Further Information The `config.mak` file contains comments which explain in a little more detail how to configure the package. `makefile.template` explains how to use the CPSW makefiles for building software which are layered on top of CPSW. Of course, the use of CPSW makefiles for this purpose is entirely optional.