[CMake] library name from subdirectory and setting the CACHE - a "listening" variable?

Clifford Yapp cliffyapp at gmail.com
Wed Jul 28 12:48:18 EDT 2010


OK, I've had more time to play with CMake and subdirectory
CMakeList.txt files, and I'm getting close to the behavior I want.  I
can conditionally override key variables to use either local or system
versions of a library, and I can trigger the builds conditionally as
well.  Using the strings defined by subdir cmake builds in place of
the relevant variable defined by FIND*.cmake seems to allow other
libraries to pull in the local copy of the library.

Where I'm having trouble (or at least don't have a clean solution) is
the case where the names used to identify the locally built library to
CMake's add_library and target_* functions are internally generated as
a result of variable substitution within the local CMake file.  libpng
is the current example - if I'm using the local build I need to pass
"png14" to a target_link_libraries command in another subdirectory.  I
can do this by defining a variable to be either this value or the
results of FindPNG.cmake (in the case where I'm using a system lib)
but the "png14" string is generated by libpng's CMake logic
internally, and no method I've tried yet has allowed the parent or
other subdirectories below the parent to observe the final string
results from libpng, let alone update the parent cache with the new
value.

This is primarily a maintenance headache, since I CAN hard code this
value (and for some libs, like zlib, the target name is a fixed string
and hence this solution is actually adequate.)  But it seems to me the
CORRECT way to do this would be to do something like defining a
"LISTENING_VARIABLE" in the parent that directly updates in the cache
file any change to the set value, by any toplevel or subdirectory
logic.  This means the child subdirectory wouldn't have to know the
variable is "special" in any way (and hence force scope breaking logic
in the child) - the parent would be explicitly saying "I want to
capture value changes to this variable in the CACHE, always, from
everywhere."  Maybe provide an option to warn when that happens, e.g.
LISTENING_VARIABLE(VARNAME WARN) or LISTENING_VARIABLE(VARNAME QUIET)
depending on desired behavior - does anything like this exist in
CMake? If it does not, would it be an acceptable feature to add?  This
seems to me like the least intrusive way to allow a parent to capture
information from a subdirectory build to be used for OTHER
subdirectory builds, without requiring altering of the child logic
(which probably is assuming stand-alone building, not working as part
of a local system.)  I've seen some discussion of the environmental
variable approach, but even assuming I did something wrong when I
tried to get that to work polluting the environment variable namespace
seems to me like an invitation to odd side effects if you accidentally
overwrite a variable something else is using or some other process
alters a variable used by CMake mid-configure - there really should be
a clean way to do this within CMake itself.

Anybody have any thoughts?  Would the CMake devs consider this or some
other mechanism that allows this behavior?

Cheers,
CY


More information about the CMake mailing list