Add CMAKE_BUILD_INTERFACE_INCLUDES build-variable.

This makes

 set(CMAKE_BUILD_INTERFACE_INCLUDES ON)

add the equivalent of

 set_property(TARGET tgt APPEND PROPERTY
   INTERFACE_INCLUDE_DIRECTORIES
   $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR};${CMAKE_CURRENT_BINARY_DIR}>
 )

to every target.

If the headers are in CMAKE_CURRENT_SOURCE_DIR, and the generated headers
are in CMAKE_CURRENT_BINARY_DIR, this is a convenient way to build a target
bar, which depends on foo, just by using target_link_libraries() and adding
the INTERFACE_INCLUDE_DIRECTORIES to the INCLUDE_DIRECTORIES of the target
being linked. There will be more-convenient porcelain API to consume the
property in the future.
This commit is contained in:
Stephen Kelly 2012-11-25 01:15:44 +01:00 committed by Brad King
parent c2cde7f104
commit 9ce1b9ef29
7 changed files with 64 additions and 1 deletions

View File

@ -1146,6 +1146,17 @@ void cmDocumentVariables::DefineVariables(cmake* cm)
false, false,
"Variables that Control the Build"); "Variables that Control the Build");
cm->DefineProperty
("CMAKE_BUILD_INTERFACE_INCLUDES", cmProperty::VARIABLE,
"Automatically add the current source- and build directories "
"to the INTERFACE_INCLUDE_DIRECTORIES.",
"If this variable is enabled, CMake automatically adds for each "
"target ${CMAKE_CURRENT_SOURCE_DIR} and ${CMAKE_CURRENT_BINARY_DIR} "
"to the INTERFACE_INCLUDE_DIRECTORIES."
"By default CMAKE_BUILD_INTERFACE_INCLUDES is OFF.",
false,
"Variables that Control the Build");
cm->DefineProperty cm->DefineProperty
("CMAKE_INSTALL_RPATH", cmProperty::VARIABLE, ("CMAKE_INSTALL_RPATH", cmProperty::VARIABLE,
"The rpath to use for installed targets.", "The rpath to use for installed targets.",

View File

@ -938,6 +938,23 @@ void cmGlobalGenerator::Generate()
(*targets)[tit->first] = tit->second; (*targets)[tit->first] = tit->second;
(*targets)[tit->first].SetMakefile(mf); (*targets)[tit->first].SetMakefile(mf);
} }
for ( tit = targets->begin(); tit != targets->end(); ++ tit )
{
if (mf->IsOn("CMAKE_BUILD_INTERFACE_INCLUDES"))
{
const char *binDir = mf->GetStartOutputDirectory();
const char *srcDir = mf->GetStartDirectory();
const std::string dirs = std::string(binDir ? binDir : "")
+ std::string(binDir ? ";" : "")
+ std::string(srcDir ? srcDir : "");
if (!dirs.empty())
{
tit->second.AppendProperty("INTERFACE_INCLUDE_DIRECTORIES",
("$<BUILD_INTERFACE:" + dirs + ">").c_str());
}
}
}
} }
// Add generator specific helper commands // Add generator specific helper commands

View File

@ -53,6 +53,13 @@ set_target_properties(targetA PROPERTIES LINK_INTERFACE_LIBRARIES "")
assert_property(targetA LINK_INTERFACE_LIBRARIES "") assert_property(targetA LINK_INTERFACE_LIBRARIES "")
add_subdirectory(subdir)
target_link_libraries(targetA subdirlib)
set_property(TARGET targetA APPEND PROPERTY
INCLUDE_DIRECTORIES
$<TARGET_PROPERTY:subdirlib,INTERFACE_INCLUDE_DIRECTORIES>
)
target_link_libraries(targetA depB depC) target_link_libraries(targetA depB depC)
assert_property(targetA LINK_INTERFACE_LIBRARIES "") assert_property(targetA LINK_INTERFACE_LIBRARIES "")

View File

@ -0,0 +1,5 @@
set(CMAKE_BUILD_INTERFACE_INCLUDES ON)
add_library(subdirlib SHARED subdirlib.cpp)
generate_export_header(subdirlib)

View File

@ -0,0 +1,7 @@
#include "subdirlib.h"
int SubDirLibObject::foo() const
{
return 0;
}

View File

@ -0,0 +1,12 @@
#ifndef SUBDIRLIB_H
#define SUBDIRLIB_H
#include "subdirlib_export.h"
struct SUBDIRLIB_EXPORT SubDirLibObject
{
int foo() const;
};
#endif

View File

@ -3,6 +3,8 @@
#include "depC.h" #include "depC.h"
#include "depIfaceOnly.h" #include "depIfaceOnly.h"
#include "subdirlib.h"
int main(int argc, char **argv) int main(int argc, char **argv)
{ {
DepA a; DepA a;
@ -11,5 +13,7 @@ int main(int argc, char **argv)
DepIfaceOnly iface_only; DepIfaceOnly iface_only;
return a.foo() + b.foo() + c.foo() + iface_only.foo(); SubDirLibObject sd;
return a.foo() + b.foo() + c.foo() + iface_only.foo() + sd.foo();
} }