Tags

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.

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 (using mk) and <base_dir>/debug (using mkd) 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:
  1. 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
  2. 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 Value Effect On Build Process
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.
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_ENABLE_SHARED Y Produce a shared object library if the project has CREATE_SHARED set to TRUE in the CMakeLists.txt file.
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_FORCE_BUILTIN_MPI N Distribution Builds Only - Force the use of system installed Open MPI
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_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.
ACC_ENABLE_FPIC N Produce a shared object library.
ACC_BUILD_TEST_EXES N Produce "test" binaries, specified in "Set (TEST_EXE_SPECS)" in CMakeLists.txt.



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(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})


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
mpm_utils
cesr_utils
nonlin_bpm
bmad
xsif
xrlf03
xrl
sim_utils
cbpmfio
CesrBPM
c_utils
mpmnet
recipes_f-90_LEPP
cbi_net
pgplot
xsif
forest
lapack95
lapack
blas
)


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})

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
 xsif
 xrlf03
 xrl
 sim_utils
 recipes_f-90_LEPP
 forest
 ${PLOT_LINK_LIBS}
 xsif
 lapack95
 lapack
 fgsl
 gsl
 blas
 gslcblas
 hdf5hl_fortran
 hdf5_hl
 hdf5_fortran
 hdf5
)



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:
  1. Configure your environment to use an on-site Release or to use a Distribution.
  2. 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
  3. 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

  1. Configure your environment to use an on-site Release or to use a Distribution.
  2. Follow the instructions for the directory setup , substituting first_program_dir for <proj_dir> directory name.
  3. Copy all the files from the directory $ACC_ROOT_DIR/examples/simple_bmad_program into your first_program_dir directory.
  4. To build the production version of the executable (see the Build commands section of the ACC Build System wiki), type:
    mk
  5. 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

Topic revision: r23 - 22 Apr 2019, DavidSagan
This site is powered by FoswikiCopyright © by the contributing authors. All material on this collaboration platform is the property of the contributing authors.
Ideas, requests, problems regarding CLASSE Wiki? Send feedback