[cmake-developers] Extracting target metadata, IDE integration

Stephen Kelly steveire at gmail.com
Mon Sep 22 10:03:44 EDT 2014


Tobias Hunger wrote:

> The first is should this be run in a terminal or is this a GUI. Not
> sure whether cmake has that information.

CMake only knows whether the WIN32_EXECUTABLE property has been set on a 
target.

 http://www.cmake.org/cmake/help/v3.0/prop_tgt/WIN32_EXECUTABLE.html

The property is harmless on non-Windows, so KDE sets it on non-Windows for 
gui applications IIRC, but others may not.

> Secondly the linker flags would be nice to know. That way the
> LD_LIBRARY_PATH can be set correctly by the IDE so that all the
> libraries are found.

If the linker flags were provided, you would have to parse them. Maybe a 
runtimeLinkDirectories/linkDependentLibraries can be provided, similar to 
the content passed to the option -rpath. I have no idea if similar 
information can be acquired for MSVC/Windows. As Nils said, CMake might not 
know the location of the import library.

> Combined with CMAKE_EXPORT_COMPILE_COMMANDS this should allow for a
> pretty good integration into creator. Ideally the exported compile
> commands would be a bit more aggregated along the lines of "the
> following list of files will be build using these defines/include
> paths/flags", just because that would be way shorter and most likely
> faster to parse.

What would that looks like? I guess listing the sources in a target together 
with its includes/defines should be possible, together with extra per-source 
defines, if present?

[
  "name" : "testc1"
  "sources" : ["foo.cpp", "bar.cpp"]
  "defines" : ["BUILD_TEST=1", "QT_CORE_LIB"]
  "includes" : ["/opt/bat/include", "/usr/include/qt5"]
  "extraDefines" : {
    "foo.cpp" : ["EXTRA_FOO=1"]
  }
]

> With this target description and the compile commands there is just
> one piece of the puzzle missing for a great Qt Creator integration: We
> need to generate a list of files that are part of the project. I
> currently do not know how to extract that list from cmake. This list
> must include all the header files that belong to the project, which is
> what makes this hard to get this information from cmake -- at least at
> the time I stopped working with cmake.

Afaik, CMake does not know all the files included by your cpp files. 
However, some buildsystems can add them to the list of sources if desired 
for better IDE integration.

 https://gitorious.org/grantlee/grantlee/commit/3eb40cf94

> Ideally we could get the list of files that belong to the project in
> general and the files that are actually part of the currently
> configured built.

In CMake master at least, the user can list config-specific files 
declaratively. Eg, add the foo_debug.cpp file only in the debug 
configuration:

 add_library(foo
   foo.cpp
   $<$<CONFIG:Debug>:foo_debug.cpp>
 )

> But how can I know that "something_win.h" will not be used when
> building on my Linux box?

The current style is indeed difficult to parse, where that might be inside 
an if() inside a macro etc. Again though, CMake master will allow users to 
do better:

 add_library(foo
   foo.cpp
   $<$<PLATFORM_ID:Windows>:foo_win.cpp>
 )

I wonder how those kinds of conditions would need to be represented in the 
ProjectTargets.json file. One option would be to write them directly to the 
json, instead of, for example, creating individual lists for each 
configuration, and expecting the consumer to evaluate the expressions. A 
possible problem with that is that consumers would have to transitively 
evaluate each property over the link closure. Apart from the potential for 
bugs, that would mean there would need to be a target entry for each 
IMPORTED target too.

It would probably be easier to try to generate something like

 "defines" : {
   "noconfig" : ["FOO=1", "QT_CORE_LIB"]
   "debug" :  ["QT_DEBUG"]
   "release" : ["RELEASE_MODE=1"]
  }

from 

 target_compile_definitions(foo PRIVATE 
   FOO=1
   $<$<CONFIG:Release>:RELEASE_MODE=1>
 )
 target_link_libraries(foo PRIVATE 
   Qt5::Core # Uses the Qt defines in the foo target.
 )

But that will mean adding more complexity to generator expression evaluation 
to find out which condition groups are needed (Eg, Do I need to create per-
platform/per-config/per-compiler groups?).

So, we'd have to decide how much exactness to aim for, and how much 
complexity to push to the user.

Thanks,

Steve.





More information about the cmake-developers mailing list