Genex: Allow COMPILE_LANGUAGE when processing include directories.

Issue an error if this is encountered by an IDE generator.
This commit is contained in:
Stephen Kelly 2015-03-04 21:53:15 +01:00
parent 0b945ea9a6
commit b734fa4471
19 changed files with 116 additions and 46 deletions

View File

@ -121,7 +121,8 @@ Available logical expressions are:
target_link_libraries(myapp myapp_c myapp_cxx) target_link_libraries(myapp myapp_c myapp_cxx)
The ``Makefile`` and ``Ninja`` based generators can also use this The ``Makefile`` and ``Ninja`` based generators can also use this
expression to specify compile-language specific compile definitions: expression to specify compile-language specific compile definitions
and include directories:
.. code-block:: cmake .. code-block:: cmake
@ -129,6 +130,9 @@ Available logical expressions are:
target_compile_definitions(myapp target_compile_definitions(myapp
PRIVATE $<$<COMPILE_LANGUAGE:CXX>:COMPILING_CXX> PRIVATE $<$<COMPILE_LANGUAGE:CXX>:COMPILING_CXX>
) )
target_include_directories(myapp
PRIVATE $<$<COMPILE_LANGUAGE:CXX>:/opt/foo/cxx_headers>
)
Informational Expressions Informational Expressions
========================= =========================

View File

@ -851,7 +851,8 @@ static const struct CompileLanguageNode : public cmGeneratorExpressionNode
} }
else if (genName.find("Xcode") != std::string::npos) else if (genName.find("Xcode") != std::string::npos)
{ {
if (dagChecker && dagChecker->EvaluatingCompileDefinitions()) if (dagChecker && (dagChecker->EvaluatingCompileDefinitions()
|| dagChecker->EvaluatingIncludeDirectories()))
{ {
reportError(context, content->GetOriginalExpression(), reportError(context, content->GetOriginalExpression(),
"$<COMPILE_LANGUAGE:...> may only be used with COMPILE_OPTIONS " "$<COMPILE_LANGUAGE:...> may only be used with COMPILE_OPTIONS "

View File

@ -960,9 +960,10 @@ cmGeneratorTarget::GetCreateRuleVariable(std::string const& lang,
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
std::vector<std::string> std::vector<std::string>
cmGeneratorTarget::GetIncludeDirectories(const std::string& config) const cmGeneratorTarget::GetIncludeDirectories(const std::string& config,
const std::string& lang) const
{ {
return this->Target->GetIncludeDirectories(config); return this->Target->GetIncludeDirectories(config, lang);
} }
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------

View File

@ -85,7 +85,7 @@ public:
/** Get the include directories for this target. */ /** Get the include directories for this target. */
std::vector<std::string> GetIncludeDirectories( std::vector<std::string> GetIncludeDirectories(
const std::string& config) const; const std::string& config, const std::string& lang) const;
bool IsSystemIncludeDirectory(const std::string& dir, bool IsSystemIncludeDirectory(const std::string& dir,
const std::string& config) const; const std::string& config) const;

View File

@ -1600,7 +1600,7 @@ void cmLocalGenerator::GetIncludeDirectories(std::vector<std::string>& dirs,
// Get the target-specific include directories. // Get the target-specific include directories.
std::vector<std::string> includes; std::vector<std::string> includes;
includes = target->GetIncludeDirectories(config); includes = target->GetIncludeDirectories(config, lang);
// Support putting all the in-project include directories first if // Support putting all the in-project include directories first if
// it is requested by the project. // it is requested by the project.

View File

@ -2114,6 +2114,32 @@ void cmLocalUnixMakefileGenerator3
cmakefileStream cmakefileStream
<< " )\n"; << " )\n";
} }
// Target-specific include directories:
cmakefileStream
<< "\n"
<< "# The include file search paths:\n";
cmakefileStream
<< "set(CMAKE_" << l->first << "_TARGET_INCLUDE_PATH\n";
std::vector<std::string> includes;
cmGeneratorTarget* gt = this->GetGlobalGenerator()
->GetGeneratorTarget(&target);
const std::string& config =
this->Makefile->GetSafeDefinition("CMAKE_BUILD_TYPE");
this->GetIncludeDirectories(includes, gt,
l->first, config);
for(std::vector<std::string>::iterator i = includes.begin();
i != includes.end(); ++i)
{
cmakefileStream
<< " \""
<< this->Convert(*i, cmLocalGenerator::HOME_OUTPUT)
<< "\"\n";
}
cmakefileStream
<< " )\n";
} }
// Store include transform rule properties. Write the directory // Store include transform rule properties. Write the directory

View File

@ -1056,40 +1056,6 @@ void cmMakefileTargetGenerator::WriteTargetDependRules()
<< "set(CMAKE_Fortran_TARGET_MODULE_DIR \"" << mdir << "\")\n"; << "set(CMAKE_Fortran_TARGET_MODULE_DIR \"" << mdir << "\")\n";
} }
// Target-specific include directories:
*this->InfoFileStream
<< "\n"
<< "# The include file search paths:\n";
*this->InfoFileStream
<< "set(CMAKE_C_TARGET_INCLUDE_PATH\n";
std::vector<std::string> includes;
const std::string& config =
this->Makefile->GetSafeDefinition("CMAKE_BUILD_TYPE");
this->LocalGenerator->GetIncludeDirectories(includes,
this->GeneratorTarget,
"C", config);
for(std::vector<std::string>::iterator i = includes.begin();
i != includes.end(); ++i)
{
*this->InfoFileStream
<< " \""
<< this->LocalGenerator->Convert(*i,
cmLocalGenerator::HOME_OUTPUT)
<< "\"\n";
}
*this->InfoFileStream
<< " )\n";
*this->InfoFileStream
<< "set(CMAKE_CXX_TARGET_INCLUDE_PATH "
<< "${CMAKE_C_TARGET_INCLUDE_PATH})\n";
*this->InfoFileStream
<< "set(CMAKE_Fortran_TARGET_INCLUDE_PATH "
<< "${CMAKE_C_TARGET_INCLUDE_PATH})\n";
*this->InfoFileStream
<< "set(CMAKE_ASM_TARGET_INCLUDE_PATH "
<< "${CMAKE_C_TARGET_INCLUDE_PATH})\n";
// and now write the rule to use it // and now write the rule to use it
std::vector<std::string> depends; std::vector<std::string> depends;
std::vector<std::string> commands; std::vector<std::string> commands;

View File

@ -1979,7 +1979,8 @@ static void processIncludeDirectories(cmTarget const* tgt,
std::vector<std::string> &includes, std::vector<std::string> &includes,
UNORDERED_SET<std::string> &uniqueIncludes, UNORDERED_SET<std::string> &uniqueIncludes,
cmGeneratorExpressionDAGChecker *dagChecker, cmGeneratorExpressionDAGChecker *dagChecker,
const std::string& config, bool debugIncludes) const std::string& config, bool debugIncludes,
const std::string& language)
{ {
cmMakefile *mf = tgt->GetMakefile(); cmMakefile *mf = tgt->GetMakefile();
@ -1995,7 +1996,7 @@ static void processIncludeDirectories(cmTarget const* tgt,
config, config,
false, false,
tgt, tgt,
dagChecker), dagChecker, language),
entryIncludes); entryIncludes);
std::string usedIncludes; std::string usedIncludes;
@ -2106,7 +2107,8 @@ static void processIncludeDirectories(cmTarget const* tgt,
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
std::vector<std::string> std::vector<std::string>
cmTarget::GetIncludeDirectories(const std::string& config) const cmTarget::GetIncludeDirectories(const std::string& config,
const std::string& language) const
{ {
std::vector<std::string> includes; std::vector<std::string> includes;
UNORDERED_SET<std::string> uniqueIncludes; UNORDERED_SET<std::string> uniqueIncludes;
@ -2139,7 +2141,8 @@ cmTarget::GetIncludeDirectories(const std::string& config) const
uniqueIncludes, uniqueIncludes,
&dagChecker, &dagChecker,
config, config,
debugIncludes); debugIncludes,
language);
std::vector<cmTargetInternals::TargetPropertyEntry*> std::vector<cmTargetInternals::TargetPropertyEntry*>
linkInterfaceIncludeDirectoriesEntries; linkInterfaceIncludeDirectoriesEntries;
@ -2179,7 +2182,8 @@ cmTarget::GetIncludeDirectories(const std::string& config) const
uniqueIncludes, uniqueIncludes,
&dagChecker, &dagChecker,
config, config,
debugIncludes); debugIncludes,
language);
deleteAndClear(linkInterfaceIncludeDirectoriesEntries); deleteAndClear(linkInterfaceIncludeDirectoriesEntries);

View File

@ -568,7 +568,8 @@ public:
bool contentOnly) const; bool contentOnly) const;
std::vector<std::string> GetIncludeDirectories( std::vector<std::string> GetIncludeDirectories(
const std::string& config) const; const std::string& config,
const std::string& language) const;
void InsertInclude(const cmValueWithOrigin &entry, void InsertInclude(const cmValueWithOrigin &entry,
bool before = false); bool before = false);
void InsertCompileOption(const cmValueWithOrigin &entry, void InsertCompileOption(const cmValueWithOrigin &entry,

View File

@ -42,6 +42,20 @@ add_executable(consumer
"${CMAKE_CURRENT_SOURCE_DIR}/consumer.cpp" "${CMAKE_CURRENT_SOURCE_DIR}/consumer.cpp"
) )
if (CMAKE_GENERATOR MATCHES "Makefiles" OR CMAKE_GENERATOR MATCHES "Ninja")
target_sources(consumer PRIVATE
"${CMAKE_CURRENT_SOURCE_DIR}/consumer.c"
)
target_include_directories(consumer
PRIVATE
$<$<COMPILE_LANGUAGE:CXX>:${CMAKE_CURRENT_SOURCE_DIR}/cxx_only>
$<$<COMPILE_LANGUAGE:C>:${CMAKE_CURRENT_SOURCE_DIR}/c_only>
)
target_compile_definitions(consumer
PRIVATE -DTEST_LANG_DEFINES
)
endif()
target_include_directories(consumer target_include_directories(consumer
PRIVATE PRIVATE
$<TARGET_PROPERTY:target_include_directories,INTERFACE_INCLUDE_DIRECTORIES> $<TARGET_PROPERTY:target_include_directories,INTERFACE_INCLUDE_DIRECTORIES>

View File

@ -0,0 +1,2 @@
#define C_ONLY_DEFINE

View File

@ -0,0 +1,10 @@
#ifdef TEST_LANG_DEFINES
#include "c_only.h"
#ifndef C_ONLY_DEFINE
#error Expected C_ONLY_DEFINE
#endif
#endif
int consumer_c() { return 0; }

View File

@ -4,6 +4,9 @@
#include "interfaceinclude.h" #include "interfaceinclude.h"
#include "relative_dir.h" #include "relative_dir.h"
#include "consumer.h" #include "consumer.h"
#ifdef TEST_LANG_DEFINES
#include "cxx_only.h"
#endif
#ifdef PRIVATEINCLUDE_DEFINE #ifdef PRIVATEINCLUDE_DEFINE
#error Unexpected PRIVATEINCLUDE_DEFINE #error Unexpected PRIVATEINCLUDE_DEFINE
@ -29,4 +32,10 @@
#error Expected CONSUMER_DEFINE #error Expected CONSUMER_DEFINE
#endif #endif
#ifdef TEST_LANG_DEFINES
#ifndef CXX_ONLY_DEFINE
#error Expected CXX_ONLY_DEFINE
#endif
#endif
int main() { return 0; } int main() { return 0; }

View File

@ -0,0 +1,2 @@
#define CXX_ONLY_DEFINE

View File

@ -0,0 +1,8 @@
CMake Error at IncludeDirectories.cmake:5 \(target_include_directories\):
Error evaluating generator expression:
\$<COMPILE_LANGUAGE:CXX>
\$<COMPILE_LANGUAGE:...> may not be used with Visual Studio generators.
Call Stack \(most recent call first\):
CMakeLists.txt:3 \(include\)

View File

@ -0,0 +1,9 @@
CMake Error at IncludeDirectories.cmake:5 \(target_include_directories\):
Error evaluating generator expression:
\$<COMPILE_LANGUAGE:CXX>
\$<COMPILE_LANGUAGE:...> may only be used with COMPILE_OPTIONS with the
Xcode generator.
Call Stack \(most recent call first\):
CMakeLists.txt:3 \(include\)

View File

@ -0,0 +1,5 @@
enable_language(CXX)
add_executable(main main.cpp)
target_include_directories(main PRIVATE $<$<COMPILE_LANGUAGE:CXX>:anydir>)

View File

@ -11,3 +11,10 @@ elseif (RunCMake_GENERATOR MATCHES "Visual Studio")
set(RunCMake-stderr-file CompileDefinitions-stderr-VS.txt) set(RunCMake-stderr-file CompileDefinitions-stderr-VS.txt)
run_cmake(CompileDefinitions) run_cmake(CompileDefinitions)
endif() endif()
if (RunCMake_GENERATOR STREQUAL "Xcode")
set(RunCMake-stderr-file IncludeDirectories-stderr-Xcode.txt)
run_cmake(IncludeDirectories)
elseif (RunCMake_GENERATOR MATCHES "Visual Studio")
set(RunCMake-stderr-file IncludeDirectories-stderr-VS.txt)
run_cmake(IncludeDirectories)
endif()