[cmake-developers] Wrapping functions in CMake

Clifford Yapp cliffyapp at gmail.com
Thu Jul 9 13:35:43 EDT 2015

A problem has arisen with CMake and BRL-CAD in 3.3, and it looks like
it may relate to some command overriding BRL-CAD does in order to
support some of our more advanced build features.  The feature we are
using to do this is an unsupported debug feature, and Brad King
suggested moving over to cmake-developers list to discuss why we are
doing what we're doing and how it might be supported.  (The initial
context of the discussion can be found here:

Our use of function overrides of basic CMake commands is driven by
four primary needs:

1.  First, we need to maintain a list of all files in the source
repository that are known to the build system.  To do this we maintain
a global list of files, define a custom CMAKEFILES command to allow us
to manually specify miscellaneous files as "known", and override all
of the primary target creating commands to add their files to the list
(for example, add_executable is passed a list of source files, and all
of those files are automatically added to the "known files" list by
the function override of add_executable.)  This list is used for both
our "make-clean-in-src-dir" feature and our distcheck build target
(which does a number of verification steps using the version control
system, the build system and the files-on-filesystem information to
make sure the build logic is current.)

2.  Second we maintain global lists of all exec, library, and custom
targets.  This allows us to run timestamping build targets that run at
the very beginning and very end of the build process, by setting up
target dependences for the beginning and ending timestamp targets.
The ending time stamp target must depend on every other build target,
and the beginning timestamp is depended on by every other build
target.  To do this, as far as I know, we need lists of all build
targets so we can set this up with the add_dependencies command.

3.  Third, we override the message function to append all messages
written to the console to a log file.  This is to allow users to send
us a complete record of what they saw on the console during a
configure process.

Normally this sort of thing is handled by custom wrapper functions or
macros, rather than overriding the CMake defaults.  For our own build
targets, we actually do have our own custom wrappers where we do much
more than the above three steps.  The reason these three steps must be
done for "vanilla" CMake commands is that we need this information
from our src/other build dependencies as well.  These dependencies are
separate build logic that does not rely on BRL-CAD macros, and we try
to change the upstream logic as little as possible.  For a number of
reasons, we have found that the best way to handle these src/other
sub-projects is to add them to our overall project build directly.
However, this means we need a way to override the behaviour of their
target generating functions and message outputs to fit into the
overall BRL-CAD system without changing the logic of the src/other

My "ideal" CMake features to accomplish each of the above would be:

1.  Have CMake internally maintain a list (or maybe per-command lists
for more flexibility) of all files with paths relative to the root
source directory that have been "observed" by add_executable,
add_library, add_custom_target, add_subdirectory, and configure_file
that can be accessed via CMake variables (e.g.
is essentially the bookkeeping we are doing manually now, and a CMake
provided global variable set would make it unnecessary to override the
commands to get it.  Files marked as "GENERATED" are not counted in
these lists, as they are considered build output.

2.  Provide similar lists of all defined targets for the various types

3.  Have one or a number of variables that will hold in memory all the
text written out by message (CMAKE_MESSAGES, CMAKE_STATUS_MESSAGES,
CMAKE_ERROR_MESSAGES, etc.) so the CMakeLists.txt file can create log
files reflecting what the user is seeing on the console window.

It's possible some of these features have been added over the years
and I missed the announcements, so if they already exist I'd be
grateful for any pointers.  If they don't exist, would it be practical
to add them?


More information about the cmake-developers mailing list