[cmake-developers] Convention driven CMAKE_USE_PACKAGE macro

Brad King brad.king at kitware.com
Fri Feb 24 11:10:21 EST 2012


On 2/24/2012 5:31 AM, Stephen Kelly wrote:
> When building with Qt5, we want to change the convention away from USE
> files, and towards a concept of using packages whose variables have
> conventional names, mostly those conventions in the Modules/readme.txt, so
> that after find_package(Foo), Foo_INCLUDE_DIRS contains the include
> directories that targets using Foo need to use, and Foo_COMPILE_DEFINITIONS
> contains the compile definitions that they need etc. This would also be an
> incentive for other packages to follow the convention.

Sounds good.

> macro(cmake_use_package _target _package)

Rather than upstreaming a macro like that I'd rather see effort made
toward first-class "usage requirements" support in CMake.  The new
per-target include directories was a big step necessary to achieve it.

Basically targets (and imported targets) should have new properties
on them that propagate information to application targets that link
to them.  Currently CMake handles transitive linking requirements
automatically but not other requirements such as COMPILE_DEFINITIONS
and INCLUDE_DIRECTORIES.  This will require C++ implementation but
will be much more powerful than the proposed macro.  Just the simple

   target_link_libraries(A B)

command would be enough to propagate B's requirements while compiling
A's source files.  I can go into more detail upon request.

> We can then wrap that macro with some Qt related stuff like this:
>
> macro(qt5_use_package _target _package)
>      cmake_use_package(${_target} Qt5${_package} ${ARGN})

For now I suggest keeping everything inside the qt5_use_package macro.
After it matures there we can always refactor it out later, but you
need to be able to fix things for Qt without waiting for CMake's
release schedule.

>      get_property(_target_type TARGET ${_target} PROPERTY TYPE)
>      if ("${_target_type}" STREQUAL "EXECUTABLE")
>          # TODO: How can I ensure this is done only once?
>          target_link_libraries(${_target} ${Qt5Core_WINMAIN_LIBRARY})

Set a property on the target that records whether it has already
been done.

> # The two target uses Qt5Test and Qt5Xml
> qt5_use_package(two Test)
> qt5_use_package(two Xml)

Nice.

FYI, ITK has something similar for loading modular components with
automatic dependency handling:

   http://itk.org/gitweb?p=ITK.git;a=blob;f=CMake/ITKModuleAPI.cmake;hb=v4.0.0

but it is designed for use when all the components come in a single
package generated by one build tree.

-Brad



More information about the cmake-developers mailing list