[CMake] Trying to get build info for a target

Michael Hertling mhertling at online.de
Sun Jan 1 23:22:13 EST 2012


On 01/01/2012 07:47 AM, Gary Kramlich wrote:
> On 12/31/2011 05:03 PM, Robert Dailey wrote:
>> Storing the source directory will require the exact idea you had
>> mentioned. Use an internal cache variable or, even better, a target
>> property. This is how I have done it. Each target that I create
>>  specifies a list of its include directories (where other targets that
>> depend on it can find its header files, and will append this directory
>> to its list of searchable include directories).
> 
> I learned the  hard way, that the target property can't be named
> SOURCE_LOCATION, since it just spit out the value for the LOCATION
> property, which seems like a bug, unless SOURCE_LOCATION was left around
> for compatibility, but I couldn't find it documented anywhere.

A target's sources may reside in arbitrary directories; there is no
guarantee that they're located next to the CMakeLists.txt file which
defines the target. Furthermore, source files with relative path are
searched w.r.t. CMAKE_CURRENT_SOURCE_DIR and - if not found - w.r.t.
CMAKE_CURRENT_BINARY_DIR, so the notion of a "source directory"
associated with a target is not reliable, IMO.

Apart from this, I can confirm that a target property ending in
"_LOCATION" does always yield the same result as the LOCATION
target property:

CMAKE_MINIMUM_REQUIRED(VERSION 2.8 FATAL_ERROR)
PROJECT(LOCATION C)
FILE(WRITE ${CMAKE_BINARY_DIR}/main.c "int main(void){return 0;}\n")
ADD_EXECUTABLE(main main.c)
SET_TARGET_PROPERTIES(main PROPERTIES XYZ_LOCATION "xyz")
GET_TARGET_PROPERTY(p main XYZ_LOCATION)
MESSAGE("XYZ_LOCATION: ${p}")

yields

XYZ_LOCATION: .../main

instead of "xyz", and without the SET_TARGET_PROPERTIES() command, it
still yields the same instead of "p-NOTFOUND". Indeed, this seems to
be strange behavior which is possibly worth a bug report, but maybe,
a CMake developer can provide some enlightenment.

>> For defines, and I think cflags, you can use get_target_property().
> 
> Coming up empty for the target and the directory.  Tried DEFINITIONS,
> COMPILE_DEFINITIONS, and COMPILE_FLAGS.  When used on the target, i get
> a -NOTFOUND, and I get an empty string when used on the source directory.

Each of these properties usually contains only a part of the flags/
definitions used to compile a target's source files, and even their
entirety does not necessarily contain all flags/definitions. AFAIK,
there's no single instance - variable, property or the like - that
one might query in order to retrieve the complete set of flags/
definitions that will be in effect for the compilations.

Moreover, note that these flags/definitions are configuration-specific,
and with multi-config generators, the configuration is chosen at build
time. Thus, gathering such information for a target at configuration
time is generally also not reliable, unless one takes the different
configurations into account.

>> For libraries, I've also maintained a list in a target property. This is
>> how you build recursive dependencies. CMake will automatically set up
>> build order based on your dependencies, however you cannot query these
>> libraries without maintaining them yourself. Also, another benefit to
>> maintaining dependencies in target properties is that you can throw an
>> error message if a target depends on another target that does not yet
>> exist (used to ensure that targets are defined in the proper order in
>> the cmake scripts).
> 
> It looks like I'll have to be setting these up manually too, since even
> though cmake has knowledge about it, it won't give the information out
> to scripts.

The libraries a target's binary will be linked against may also depend
on the configuration - possibly chosen at build time - so predicting
them at configuration time is generally unreliable, too.

Regards,

Michael

> Maybe I'll be better off requiring that this module be included in the
> CMakeLists.txt for the target it's going to work on...  But that's
> really annoying that cmake is dictating how a module can work, even
> though all I'm trying to do is query a target...
> 
>> Hope that helps.
> 
> It helps in the sense that I'm not chasing something that can't be done
> anymore ;)


More information about the CMake mailing list