[CMake] $<> expressions in include_directories command

Alexander Neundorf a.neundorf-work at gmx.net
Wed Jul 13 12:10:28 EDT 2011


On Wednesday 13 July 2011, Daniel Pfeifer wrote:
> 2011/7/13 Andreas Pokorny <andreas.pokorny at gmail.com>
> 
> > Such an improvement would be very welcome.. but.. have you considered a
> > different user interface?
> 
> Yes, i have considered that.
> 
> > E.g. take a look at static libraries, CMake already
> > does transitive dependency resolution (if i am not mistaken). It also
> > differs
> > between like "interface libraries" and "link libraries". Couldnt we
> > define something
> > 
> > like:
> >  *  header directories i need for building target A as a property of a
> > 
> > target
> > 
> >  *  header directories other targets need if they depend on target A
> > 
> > then we would write in subdirectory foo:
> > 
> > add_library(foo ....)
> > target_include_paths(foo include/foo )
> > target_include_targets(foo bar)
> 
> target_include_targets would not even be required, target_link_libraries
> could handle that. Whenever a target is linked to a library, it also should
> use the appropriate include directories.

When I talked last time with Brad such a feature was still on his TODO, and is 
there since at least 2007 already, but still more or less at the bottom of the 
list.
So, if you implement this using this appraoch the chances that it will be 
accepted should be higher.

So for setting the include dirs you need when using library foo this 
information should be set via set_target_properties().

add_library(foo ${fooSrcs})
set_target_properties(foo PROPERTIES INCLUDE_DIRS ${...whereever})

This should then also work when exporting/importing targets and with different 
configurations.

You are right that target_link_libraries() could take care of the rest (Brad 
suggested this too), but I wouldn't like that, since it would be a change in 
behaviour and very unobvious.

Right now, to use library Foo, you have to do

   include_directories(${FOO_INCLUDE_DIRS})
   add_executable(hello ${srcs})
   target_link_libraries(${FOO_LIBRARIES})

i.e. both the link libraries and the include dirs are written down 
explicitely, i.e. easy to see (code is read more often than it is written).

If a user who doesn't know the "new" behaviour of target_link_libraries() 
would see the new code, he would have no chance to find out where the include 
dirs are coming from:

   add_executable(hello ${srcs})
   target_link_libraries(hello ${FOO_LIBRARIES})

Actually this would even be a somewhat source incompatible change, since it 
would mean that the same cmake code would suddenly create a different set of 
include dirs.

So I would prefer either an additional command, or a flag for 
target_link_libraries(), e.g.

   add_executable(hello ${srcs})
   target_link_libraries(hello USE_INCLUDE_DIRS ${FOO_LIBRARIES})

or 

   add_executable(hello ${srcs})
   target_include_dirs(hello ${FOO_LIBRARIES})
   target_link_libraries(hello USE_INCLUDE_DIRS ${FOO_LIBRARIES})

or 

   add_executable(hello ${srcs})
   target_use_libraries(hello USE_INCLUDE_DIRS ${FOO_LIBRARIES})

or 

   add_executable(hello ${srcs})
   target_use_bundle(hello USE_INCLUDE_DIRS ${FOO_LIBRARIES})

or something like this, i.e. something which gives the reader a hint that this 
is not simply a normal target_link_libraries() call.


Alex


More information about the CMake mailing list