Unlike source files written in non-scripting languages such as C++ or Java,
source files written in scripting languages such as Python, Perl, or BASH
do not need to be compiled before their execution. They are interpreted
directly and hence do not need to be build (in case of Python, however,
they are as well compiled by the interpreter itself to improve speed).
On the other side, CMake provides a mechanism to replace CMake
variables in a source file by their respective values which are set in the
CMakeLists.txt
files (or an included CMake script file). As it is often
useful to introduce build specific information in a script file such as
the relative location of auxiliary executables or data files, the
basis_add_executable() and basis_add_library() commands
also provide a means of building script files. How these functions process
scripts during the build of the software is discussed next. Afterwards it is
described how the build of scripts can be configured.
During the build of a script, the CMake variables as given by
@VARIABLE_NAME@
patterns are replaced by the value of the
corresponding CMake variable if defined, or by an empty string otherwise.
Similar to the configuration of source files written in C++ or MATLAB,
the names of the script files which shall be configured by BASIS during
the build step have to end with the .in
suffix.
Otherwise, the script file is not modified by the BASIS build
commands and simply copied to the build tree or installation tree,
respectively. Opposed to configuring the source files already during
the configure step of CMake, as is the case for C++ and MATLAB source files,
script files are configured during the build step to allow for the used
CMake variables to be set differently depending on whether the script is
intended for use inside the build tree or the installation tree.
Moreover, certain properties of the script target can still be modified
after the basis_add_executable() or basis_add_library()
command, respectively, using the basis_set_target_properties() or
basis_set_property() command. Hence, the final values of these
variables are not known before the configuration of the build system has
been completed. Therefore, all CMake variables which are defined when the
basis_add_executable() or basis_add_library()
command is called, are dumped to a CMake script file to preserve their value
at this moment and the dump of the variables is written to a file in the
build tree. This file is loaded again during the build step by the custom
build command which eventually configures the script file using CMake’s
configure_file() command with the @ONLY
option. This build command
configures the script file twice. The first “built” script is intended for
use within the build tree while the second “built” script will be copied
upon installation to the installation tree.
Before each configuration of the (template) script file (the .in
source file in the source tree), the file with the dumped CMake variable
values and the various script configuration files are included in the
following order:
BasisScriptConfig.cmake
).ScriptConfig.cmake
, optional).CONFIG
argument of the
basis_add_executable() or basis_add_library() command.The so-called script configuration is CMake code which defines CMake variables
for use within script files. This code is either saved in a CMake script file
with the .cmake
file name extension or specified directly as argument
of the CONFIG
option of the basis_add_executable() or
basis_add_library() command used to add a script target to the build
system. The variables defined by the script configuration are substituted by
their respective values during the build of the script target. Note that the
CMake code of the script configuration is evaluated during the build of the
script target, not during the configuration of the build system. During the
configuration of the build systems, the script configuration is, however,
configured in order to replace @VARIABLE_NAME@
patterns in the configuration
by their respective values as defined by the build configuration
(CMakeLists.txt
files). Therefore, the variables defined in the script
configuration can be set differently for each of the two builds of the script
files. If the script configuration is evaluated before the configuration of
the script file for use inside the build tree, the CMake variable
BUILD_INSTALL_SCRIPT
is set to FALSE
. Otherwise, if the script
configuration is evaluated during the build of the script for use in the
installation tree, this variable is set to TRUE
instead. It can therefore
be used to set the variables in the script configuration depending on whether
or not the script is build for use in the build tree or the installation tree.
For example, the project structure differs for the build tree and the
installation tree. Hence, relative file paths to the different directories
of data files, for instance, have to be set differently depending on the value
of BUILD_INSTALL_SCRIPT
, i.e.,
if (BUILD_INSTALL_SCRIPT)
set (DATA_DIR "@CMAKE_INSTALL_PREFIX@/@INSTALL_DATA_DIR@")
else ()
set (DATA_DIR "@PROJECT_DATA_DIR@")
endif ()
Avoid the use of absolute paths, however! Instead, use the __DIR__
variable
which is set in the build script to the directory of the output script file
to make these paths relative to this directory which contains the configured
script file. These relative paths which are defined by the script configuration
are then used in the script file as follows:
#! /usr/bin/env bash
. ${BASIS_BASH_UTILITIES} || { echo "Failed to import BASIS utilities!" 1>&2; exit 1; }
exedir EXEDIR && readonly EXEDIR
[ $? -eq 0 ] || { echo 'Failed to determine directory of this executable!'; exit 1; }
readonly DATA_DIR="${EXEDIR}/@DATA_DIR@"
where DATA_DIR
is the relative path to the required data files as determined
during the evaluation of the script configuration. See documentation of
the basis_set_script_path() function for a convenience function which
can be used therefore. Note that this function is defined in the custom build
script generated by BASIS for the build of each script target and hence can only be
used within a script configuration. For example, use this function as follows
in the PROJECT_CONFIG_DIR/ScriptConfig.cmake.in
script configuration
file of your project:
basis_set_script_path(DATA_DIR "@PROJECT_DATA_DIR@" "@INSTALL_DATA_DIR@")
Note that most of the more common variables which are useful for the development of scripts are already defined by the default script configuration file of BASIS. Refer to the documentation of the BasisScriptConfig.cmake file for a list of available variables.