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)
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
@ -129,6 +130,9 @@ Available logical expressions are:
target_compile_definitions(myapp
PRIVATE $<$<COMPILE_LANGUAGE:CXX>:COMPILING_CXX>
)
target_include_directories(myapp
PRIVATE $<$<COMPILE_LANGUAGE:CXX>:/opt/foo/cxx_headers>
)
Informational Expressions
=========================

View File

@ -851,7 +851,8 @@ static const struct CompileLanguageNode : public cmGeneratorExpressionNode
}
else if (genName.find("Xcode") != std::string::npos)
{
if (dagChecker && dagChecker->EvaluatingCompileDefinitions())
if (dagChecker && (dagChecker->EvaluatingCompileDefinitions()
|| dagChecker->EvaluatingIncludeDirectories()))
{
reportError(context, content->GetOriginalExpression(),
"$<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>
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. */
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,
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.
std::vector<std::string> includes;
includes = target->GetIncludeDirectories(config);
includes = target->GetIncludeDirectories(config, lang);
// Support putting all the in-project include directories first if
// it is requested by the project.

View File

@ -2114,6 +2114,32 @@ void cmLocalUnixMakefileGenerator3
cmakefileStream
<< " )\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

View File

@ -1056,40 +1056,6 @@ void cmMakefileTargetGenerator::WriteTargetDependRules()
<< "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
std::vector<std::string> depends;
std::vector<std::string> commands;

View File

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

View File

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

View File

@ -42,6 +42,20 @@ add_executable(consumer
"${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
PRIVATE
$<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 "relative_dir.h"
#include "consumer.h"
#ifdef TEST_LANG_DEFINES
#include "cxx_only.h"
#endif
#ifdef PRIVATEINCLUDE_DEFINE
#error Unexpected PRIVATEINCLUDE_DEFINE
@ -29,4 +32,10 @@
#error Expected CONSUMER_DEFINE
#endif
#ifdef TEST_LANG_DEFINES
#ifndef CXX_ONLY_DEFINE
#error Expected CXX_ONLY_DEFINE
#endif
#endif
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)
run_cmake(CompileDefinitions)
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()