The ACC Build System
Introduction
The build system is simply a collection of scripts (based on
cmake,
python and
bash) used by an Accelerator code developer to build projects against libraries in a ("on-site")
Release or a ("off-site")
Distribution. It will compile C, C++, and Fortran source code into object code and link into libraries and/or executables (programs).
The
Overview and Definitions page gives information on the terminology used.
All syntax in build description files mentioned below conforms to the rules for CMake CMakeLists.txt files as found in the
cmake documentation.
If you need to contact someone for help, please see the
Help and Mailing List Information wiki page.
Prerequisites
- For building on Lab computer systems (building against a Release): Before proceeding with building software using this system, one must have their bash shell environment set up via the ACC environment setup procedure described in the Environment Setup wiki. This step provides several environment variables with the prefix ACC that inform the behavior of the build system.
- For building on computers outside the Lab (building with a Distribution): Setup instructions are here.
Directory Setup
In order to build programs or libraries the first step is to create a base directory which will be called
<base_dir> (The braces "<...>" denotes that in actuality this file can be called anything) . It is possible to have multiple base directories if, say, parallel versions of the same code are needed. For
outside the Lab work it is recommended that <base_dir>
not be the directory tree that makes up the
Distribution. This separates the Distribution code from code developed locally. This is only a recommendation and if the code under development is code in the Distribution it may be advantageous to work in the Distribution area.
The
<base_dir> will contain a set of one or more
project directories. For purposes of illustration, a project directory will be denoted
<proj_dir>.
- A given project can be setup to build a library and/or one or several executables.
- The source code and header files for a project can be in <proj_dir> directly or may be put in some subdirectory or subdirectories of <proj_dir>. There is no restriction on the directory structure of the directory tree of <proj_dir> .
- Production executables will be put in <base_dir>/production/bin. These executables are made with the mk command. Production executables run faster than debug executables.
- Debug executables will be put in the <base_dir>/debug/bin. These executables are made with the mkd command. Debug executables do more error checking and have symbol information for use with a debugger.
- Intermediate files are stored in <proj_dir>/production and <proj_dir>/debug. You never have to look at these files.
Note: The
production and
debug directories are created automatically by the compile scripts. You do not need to create them.
Example directory structure:
<base_dir>
|
+---------+---------------------+-------------------------+
| | |
<proj_dir> production debug
| | |
| +--------+-------+-----+-------+ ...same as production...
| | | | | |
| bin include lib map modules
|
+----------+---------------+---------------+---------+
| | | | |
CMakeLists.txt cmake.project source_file.f90 production debug
The <
base_dir>/production (built using the
mk command) and <
base_dir>/debug (build using the
mkd command) directories have a similar structure. Each has five subdirectories:
bin |
subdirectory holding executables |
include |
subdirectory holding C Header files |
lib |
subdirectory holding libraries |
map |
subdirectory holding map files (shows where the code for a particular program came from) |
modules |
subdirectory holding the compiled fortran modules |
Building Code
Required Files in the
<proj_dir> directory:
- CMakeLists.txt
- To specify the project Library name, and directory name where the source code is.
- Example of a CMakeLists.txt can be found here
- cmake.XXX
- Here XXX is generally the named after the program name. Thus, for example, the Tao program has an associated cmake.tao script file.
- To specify the project Executable name and the directory name where the source code is.
- Detailed information can be found on the Programs section of the ACC Build System wiki page
- Example of a cmake.XXX can be found here
Example CMakeLists.txt and cmake.XXX files are given below. Additionally, such files can be found in a Distribution (if you are building outside the lab ) or in a Release (if you are building on a Lab computer system ).
After the script files have been constructed, using the
mk or
mkd command in
<proj_dir> will build everything.
The Build Commands
Command |
Action |
mk |
Acts upon a build directory containing a CMakeLists.txt file to build production binaries. |
mkd |
Acts upon a build directory containing a CMakeLists.txt file to build debug-equipped binaries. |
mk_mpi |
Like mk but builds with ACC_ENABLE_MPI set to "Y". |
mkd_mpi |
Like mkd but builds with ACC_ENABLE_MPI set to "Y". |
mk[d] clean |
Will remove the object files and binaries of the production[debug] build type. |
mk[d] cleaner |
Will remove the object files and binaries of the production[debug] build type, the generated build directory, the CMake cache file so as to force a CMake reconfiguration upon the next build request, and the ../config/<PROJECT> directory if one was created. |
mk[d] obliterate |
CAUTION!! - Performs the "cleaner" operation in ALL project directories contained in the upper level directory tree and removes the upper level production[debug] directory. For example, If your current-working-directory is "/home/mybuild/bmad", typing "mk obliterate" will perform a "cleaner" on ALL build directories in "/home/mybuild" and removes "/home/mybuild/production". Please use this option carefully!! |
mk[d] -j N |
Acts upon a build directory containing a CMakeLists.txt file to build production binaries using gmake to run in "N" parallel "jobs". The default is "2", setting ACC_SET_GMAKE_JOBS has the same effect. |
mk[d] test |
Acts upon a build directory containing a CMakeLists.txt file and/or acc_build file to run compile-time executable tests - see "/usr/bin/ctest --help" and http://www.cmake.org/Wiki/CMake/Testing_With_CTest |
......................................... |
|
Environment Variables That Control The Build Process
Variable |
Default Value |
Effect On Build Process |
ACC_BMAD_LINK_LIBS |
|
Contains all base libraries needed by any project that depends on the Bmad library. This variable is defined in the ${ACC_UTIL}/build_flags_config file and ${DIST_UTIL}/build_flags_config. Currently set to "xrlf03;xrl;recipes_f-90_LEPP;forest;fgsl;gsl;gslcblas;lapack95;lapack;blas;hdf5hl_fortran;hdf5_hl;hdf5_fortran;hdf5;fftw3;fftw3_omp" |
ACC_BUILD_EXES |
Y |
Enable all executable targets. mk[d] will produce all executables listed in CMakeLists.txt. mk[d] <exe-name>-exe will now produce a single exe. This is the default and is part of the user's environment if they use the environment setup procedure noted in the "Prerequisites" section above. |
ACC_BUILD_TEST_EXES |
N |
Produce "test" binaries, specified in "Set (TEST_EXE_SPECS)" in CMakeLists.txt. |
ACC_ENABLE_FPIC |
N |
Produce a shared object library. |
ACC_ENABLE_PROFILING |
N |
Adds gprof Profiling flag "-pg" when compiling amd linking a library or executable. Only works on Cornell CLASSE Computers |
ACC_ENABLE_SHARED |
Y |
Produce a shared object library if the project has CREATE_SHARED set to TRUE in the CMakeLists.txt file. Set to "N" if ACC_ENABLE_SHARED_ONLY is set to "Y". |
ACC_ENABLE_SHARED_ONLY |
N |
Produce a shared object library (built without any STATIC archive "*.a" library dependancies) if the project has CREATE_SHARED set to TRUE in the CMakeLists.txt file. ACC_ENABLE_SHARED must be set "N". Currently not supported in ACC Release Builds. |
ACC_ENABLE_OPENMP |
N |
Enable OpenMP support during the build. See http://openmp.org, http://software.intel.com/en-us/articles/getting-started-with-openmp and http://gcc.gnu.org/onlinedocs/gfortran/OpenMP.html |
ACC_ENABLE_MPI |
N |
Enable Open MPI support during the build. See http://www.open-mpi.org/doc/ |
ACC_ENABLE_GFORTRAN_OPTIMIZATION |
N |
Enable gfortran -O2 optimization support during the build - Type "gfortran -Q --help=optimizers -O2" to see what optimizations are enabled with the "-O2" flag. Ignored when "mkd" is used. |
ACC_FORCE_BUILTIN_MPI |
N |
Distribution Builds Only - Force the use of system installed Open MPI |
ACC_PLOT_PACKAGE |
pgplot |
By default this is set to "pgplot" but can be set to "plplot" either interactively or in ${DIST_BASE_DIR}/util/dist_prefs - determines the contents of PLOT_LINK_LIBS |
ACC_RELEASE_REQUEST |
current |
Set the ACC Release build environment to build your code against - allowed values: "current", "devel" and "nightly" |
ACC_SET_GMAKE_JOBS |
2 |
Configure gmake to execute that number of recipes or "jobs" at once, effectively running parallel compilations using that number of CPU cores. The default value is "2" and cannot be set lower than "1" - for an explanation of gmake "jobs", please see http://www.gnu.org/software/make/manual/html_node/Parallel.html. |
ACC_SET_F_COMPILER |
ifort |
Configure the Build System to use the specified Fortran compiler. The default value is "ifort" and the only other acceptable value is "gfortran". Please note that end user use of this variable is NOT yet completely supported and will not work until support for ACC_SET_F_COMPILER is configured throughout the Build System and a gfortran version of the "release" and "packages" builds are made. |
PLOT_LINK_LIBS |
|
This variable is defined in the ${ACC_UTIL}/build_flags_config file and ${DIST_UTIL}/build_flags_config. It's contents are determined by the value in ACC_PLOT_PACKAGE. Set to either "pgplot" or "plplotfortran;plplot;csirocsa;qsastime" |
VERBOSE |
Y |
Display all compiler and linker commands and their output. This is a native feature supported by CMake and is also found in the official documentation. |
Preprocessor Options available
The ACC Build System contains some predefined ACC specific Preprocessing Options, as defined in
include/CESR_platform.h
and
Master.cmake
:
Preprocessor Options |
Notes |
ACC_MPI |
Defined when OpenMPI is enabled. Not defined in Release Builds and will be defined in Bmad Distribution Builds or custom compiling if the environment variable ACC_ENABLE_MPI has been set to "Y". Note: For Distributions, ACC_ENABLE_MPI is set in the util/dist_prefs file. |
CESR_LINUX |
Defined when building on Linux or Mac. Not defined when building on Windows. |
CESR_NOPLOT |
Defined when the environment variable ACC_PLOT_PACKAGE is set to "none". |
CESR_PGPLOT |
Defined when the environment variable ACC_PLOT_PACKAGE is set to "pgplot". This is the default for Releases and Distributions. |
CESR_PLPLOT |
Defined when the environment variable ACC_PLOT_PACKAGE is set to "plplot". |
CESR_UNIX |
Same as CESR_LINUX. Deprecated. Do not use. |
CESR_WINCVF |
Defined when building on Windows. Not defined when building elsewhere. |
For more information on the use of the preprocessor, please see:
General Options
Prebuild action: This allows for the user to specify a command to run immediately prior to each build. The prebuild action target allows for the user of the build system to request that a particular action is taken prior to building their project. This allows one to run a preprocessing or code generation tool whose product is required for the build process. The user must specify the path of a single command to run as a string in the variable PREBUILD_ACTION. If this variable is present, the build system will run the specified command in a shell prior to starting the build process. The command cannot have any arguments but it may generate console output along with doing other tasks. The output it generates will show up as part of the output produced during the build process.
Example:
SET(PREBUILD_ACTION ./generate_some_code.sh)
The mpmnet project uses this mechanism and can be consulted as an example.
Building Libraries
Provided a CMakeLists.txt build description file exists in the project directory that you wish to build, invoking the command mk will build a production binary which is suitable for everyday running. The command mkd will build a debug binary that contains debugging symbols for use in an interactive debugger.
The object and other support files are kept in a separate build tree automatically created within the project directory called production or debug, depending on the build type requested.
Build Modifier |
Function |
SET(LIBNAME <name> ) |
Set the name of the library to be produced-- libLIBNAME.a (libLIBNAME.so if shared object libraries have been requested and enabled.) |
SET(INC_DIRS ... ) |
Define the collection of include directories to search for header files during compilation. |
SET(SRC_DIRS ... ) |
Define the collection of directories containing source files with supported filename extensions to incorporate into the build. |
SET(SRC_FILES ... ) |
Define the collection of source files with the PATH and supported filename extensions to incorporate into the build - Required for C++ source code files instead of SRC_DIRS. |
SET(EXE_SPECS ... ) |
Define the collection of executable build description files. One build description file per standalone application desired. |
SET(TEST_EXE_SPECS ... ) |
Define the collection of test executable build description files. One build description file per standalone application desired. You must export ACC_BUILD_TEST_EXE=Y to create executables for files in the TEST_EXE_SPECS list. Use this list to prevent problems with the nightly build of all programs in EXE_SPECS. |
SET(SHARED_DEPS ...) |
Define list of libraries the library to build depends upon. This is required for proper shared-object linking at run-time. |
To control the building of a library, create or copy a file named CMakeLists.txt into <proj_dir>. An example CMakeLists.txt file is shown and annotated here.
The
bold text is boilerplate and must appear verbatim. The remaining sections are meant to be modified by the user to configure the details of the build. This example is used to build the libcesrv.a static library file and to allow for building the cesrv_cl program.
SET(LIBNAME cesrv)
cmake_minimum_required(VERSION $ENV{ACC_CMAKE_VERSION})
project (ACC)
SET(INC_DIRS
../include
../CesrBPM/include
include
)
SET(SRC_DIRS
code
)
SET(EXE_SPECS cmake.cesrv
)
include($ENV{ACC_BUILD_SYSTEM}/Master.cmake)
Building Programs
Build Modifier |
Function |
SET(EXENAME <exename> ) |
Assign a name to the program to produce. |
SET(SRC_FILES ... ) |
Define the collection of explicit filename paths (relative to the project directory root, or an absolute path) to compile when building the program. |
file(GLOB SRC_FILES <file_glob>) |
Like SET(SRC_FILES ...) but here can use wild card characters instead of having to list each file. Example: file(GLOB SRC_FILES "*.f90" "*.cpp") |
SET(SRC_DIRS ... ) |
Define the collection of directories containing source files with supported filename extensions to incorporate into the program. Can be used in conjunction with SRC_FILES. |
SET(LINK_DIRS ... ) |
Can hold a list of additional paths to search for the libraries mentioned in the LINK_LIBS list mentioned below. |
SET(LINK_LIBS ... ) |
Define the collection of static libraries needed for linking of the program. This list must be ordered with dependent libraries appearing BELOW the libraries that they support.
I.e. higher level libraries with the most abstraction appear earlier in the list, and lower level libraries appear later. |
SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ...") |
Set linker flags. |
SET(CFLAGS "..." ) |
Quote-delimited string containing C compiler flags to use when building the files specified using SRC_FILES and/or SRC_DIRS |
SET(FFLAGS "..." ) |
Quote-delimited string containing Fortran compiler flags to use when building the files specified using SRC_FILES and/or SRC_DIRS |
SET(SHARED_LINK_LIBS ... ) |
Define the collection of shared (dynamic) libraries needed for linking of the program. This list is not order dependent. |
SET(EXTRA_SHARED_LINK_LIBS ... ) |
Similar to SHARED_LINK_LIBS except these libraries will not get linked in except if the associated library is being built shared. In particular, this is used with Tao which, when the Tao library is built shared, has a additional set of libraries to link to. |
SET(LINKER_LANGUAGE_PROP <lang> ) |
Set the language of the main program. This is used when mixing code of differnt languages and CMake is not correctly figuring out what language the main program is. Use <lang> = "Fortran" if the main program is Fortran. |
SET(IMPLICIT_LINK_LIBS <lang> ) |
When linking an executable using differnet linker then the one used to build libraries in the LINK_LIBS statement, the user must set IMPLICIT_LINK_LIBS to the language of the libraries in LINK_LIBS. Use <lang> = Fortran if the Libraries were built with Fortran. |
SET(CMAKE_CXX_LINKER_PREFERENCE_PROPAGATES false) |
Prevents automatic use of C++ linker. This prevents a problem when building a library and a program using the same CMakeLists.txt file where the library has a C/C++ routine but the program has a Fortran main program. |
Separate flag lists can be specified for a library and each executable.
To control the building of an executable, create or copy a file named after the program to produce into <proj_dir>. In this example, the supplementary build description file is called cmake.cesrv which will be used to produce the executable file cesrv_cl.
SET(EXENAME cesrv_cl)
SET(SRC_FILES
program/cesrv_cl.f90
)
SET(LINK_LIBS
cesrv
bsim
mpm_utils
instr_utils
cesr_utils
nonlin_bpm
bmad
sim_utils
cbpmfio
CesrBPM
c_utils
mpmnet
cbi_net
pgplot
${ACC_BMAD_LINK_LIBS}
)
This allows the creation of all executables for which <executable>.cmake files have been created and for which references are present in the SET(EXE_SPECS <spec1> <spec2>...) line. Individual executables can be created by using the name of their target after the mk[mkd] command. Program target names have an -exe appended to them. I.e. mk <program_name>-exe.
Even if you wish to only produce a single program with no associated library, you must always have a CMakeLists.txt file. This will be minimal and only reference the <program>.cmake file that describes how to build the desired program.
The FILE(GLOB SRC_FILES ...) construct can be used in place of the SET(SRC_FILES ...) construct. Globbing allows for the standard Unix wild card characters to be used instead of having to list each file to be compiled. There are advantages and disadvantages to this. Globbing can make the .cmake file shorter but listing each file individually ensures that only the files that are needed are used.
Troubleshooting
Program Example
For the 'show' program, for example, a minimum of two files are required:
CMakeLists.txt
cmake_minimum_required(VERSION $ENV{ACC_CMAKE_VERSION})
project (ACC)
SET(EXE_SPECS
cmake.show
)
include($ENV{ACC_BUILD_SYSTEM}/Master.cmake)
cmake.show
SET(EXENAME show)
FILE(GLOB SRC_FILES "*.f90")
SET(LINK_LIBS
bmad
sim_utils
${PLOT_LINK_LIBS}
${ACC_BMAD_LINK_LIBS}
)
Noteworthy Default Behaviors
Reserved Directory Names
Any directory with the name "
config" will be automatically have its contents copied to the directory <base_dir>/config/<PROJECT_DIR>
For example:
You are building in /home/smith/project1
project1/config/... exists with some files and subdirectories.
The build process will create /home/smith/config/project1/... filled with the exact contents of the project's config directory.
Forbidden directory names:
You may
not have a subdirectory within a project with the name "
production" or "
debug".
These are reserved by the build system and directories with those names are automatically created to hold administrative data and intermediate build products.
Matlab MEX Files
For lab builds: If a project is configured to produce a shared object library AND a Makefile.mex file is present in the project directory that can be used to produce Matlab MEX wrappers, when the ACC_ENABLE_SHARED variable is set affirmatively, a build request will build the project as normally done and will then execute a gmake process upon the Makefile.mex file in order to produce those MEX files.
Include Directory Search behavior
NOTE: The possibility exists that if a developer deletes a locally built copy of a library, and initiates a build that requires that library while leaving the local source tree and include files intact, the build system will perform the divergent action of linking against the release version of the library while employing the header file information from the user's LOCAL source tree.
One may prevent confusion by deleting local source trees as soon as they are no longer needed.
Build Errors For Executables
If a project has more than one executable being requested in the CMakeLists.txt file and an error occurs when compiling or linking the code for that executable, the build process will terminate immediately and not attempt to build executables mentioned after the failed one in the list of EXE_SPECS. To force the building of one of the skipped executables, one may run mk[d] <executable_name>-exe for each executable desired.
Example Compiling/Linking and Running of a Bmad Based Program
A working example of a simple Bmad Fortran90 program and associated build scripts is presented here. The program is called
simple_bmad_program
See the chapeter titled
An Example Bmad Based Program in the Bmad manual for a line-by-line description of the program.
Running the Program Without Compiling/Linking
The
simple_bmad_program is automatically built in a
Release or
Distribution so you do not have to do any compiling/linking if you do not want to. To run the program do:
- Configure your environment to use an on-site Release or to use a Distribution.
- Go to the directory:
$ACC_ROOT_DIR/examples/simple_bmad_program
Besides containing the source code for the program, this directory has the two input files needed for running: lat.bmad layout.bmad
- Run the executable
simple_bmad_program
Since your PATH environmental variable has been set to include the directory where the executable resides, you do not need to specify the directory where the executable lives.
Building the Example Program
- Configure your environment to use an on-site Release or to use a Distribution.
- Follow the instructions for the directory setup , substituting first_program_dir for <proj_dir> directory name.
- Copy all the files from the directory $ACC_ROOT_DIR/examples/simple_bmad_program into your first_program_dir directory.
- To build the production version of the executable (see the Build commands section of the ACC Build System wiki), type:
mk
- To run the example executable, type the below command from within the first_program_dir directory:
../production/bin/simple_bmad_program
Resulting Output
To see the correct resulting output
Ix Name Ele_type S Beta_a
0 BEGINNING BEGINNING_ELE 0.0000 0.9379
1 IP_L0 MARKER 0.0000 0.9379
2 CLEO_SOL#3 SOLENOID 0.6223 1.3472
3 DET_00W MARKER 0.6223 1.3472
4 CLEO_SOL#4 SOLENOID 0.6380 1.3682
5 Q00W\CLEO_SOL SOL_QUAD 1.7550 8.0285
6 Q00W#1 QUADRUPOLE 2.1628 16.8607
7 D003 DRIFT 2.4934 28.5769
8 DET_01W MARKER 2.4934 28.5769
9 D004 DRIFT 2.9240 48.4524
10 Q01W QUADRUPOLE 3.8740 66.8800
!---------------------------------------------------------
! Information on element: CLEO_SOL
Element # 872
Element Name: CLEO_SOL
Key: SOLENOID
S: 1.75500
Ref_time: 5.854050E-09
Attribute values [Only non-zero/non-default values shown]:
1 L = 3.5100000E+00
5 KS = -8.4023386E-02
31 L_HARD_EDGE = 3.5100000E+00
49 BS_FIELD = -1.4823578E+00
50 DELTA_REF_TIME = 1.1708100E-08
53 P0C = 5.2890000E+09, BETA = 0.999999995
54 E_TOT = 5.2890000E+09
66 NUM_STEPS = 18
67 DS_STEP = 2.0000000E-01
TRACKING_METHOD = Bmad_Standard
MAT6_CALC_METHOD = Bmad_Standard
SPIN_TRACKING_METHOD = Bmad_Standard
PTC_INTEGRATION_TYPE = Matrix_Kick
FIELD_CALC = Bmad_Standard
APERTURE_AT = Exit_End
OFFSET_MOVES_APERTURE = F
SYMPLECTIFY = F
FIELD_MASTER = F
CSR_CALC_ON = T
Slave_status: FREE
Lord_status: SUPER_LORD
Slaves:
Name Type Index
Q00E\CLEO_SOL SOL_QUAD 865
CLEO_SOL#1 SOLENOID 866
CLEO_SOL#2 SOLENOID 868
CLEO_SOL#3 SOLENOID 2
CLEO_SOL#4 SOLENOID 4
Q00W\CLEO_SOL SOL_QUAD 5