Export: Report error on relative include with genex.
Diagnostics which check the sanity of exported include paths previously skipped over any path containing a generator expression. Introduce a policy to issue an error message in such cases. The export files created in the OLD behavior are not usable, because they contain relative paths or paths to the source or build location which are not suitable for use on installation. CMake will report an error on import.
This commit is contained in:
parent
7a3e45b9d4
commit
5838aba1aa
|
@ -74,3 +74,4 @@ All Policies
|
|||
/policy/CMP0038
|
||||
/policy/CMP0039
|
||||
/policy/CMP0040
|
||||
/policy/CMP0041
|
||||
|
|
|
@ -0,0 +1,25 @@
|
|||
CMP0041
|
||||
-------
|
||||
|
||||
Error on relative include with generator expression.
|
||||
|
||||
Diagnostics in CMake 2.8.12 and lower silently ignored an entry in the
|
||||
:prop_tgt:`INTERFACE_INCLUDE_DIRECTORIES` of a target if it contained a generator
|
||||
expression at any position.
|
||||
|
||||
The path entries in that target property should not be relative. High-level
|
||||
API should ensure that by adding either a source directory or a install
|
||||
directory prefix, as appropriate.
|
||||
|
||||
As an additional diagnostic, the :prop_tgt:`INTERFACE_INCLUDE_DIRECTORIES` generated
|
||||
on an :prop_tgt:`IMPORTED` target for the install location should not contain
|
||||
paths in the source directory or the build directory.
|
||||
|
||||
The OLD behavior for this policy is to ignore relative path entries if they
|
||||
contain a generator expression. The NEW behavior for this policy is to report
|
||||
an error if a generator expression appears in another location and the path is
|
||||
relative.
|
||||
|
||||
This policy was introduced in CMake version 3.0.0. CMake version
|
||||
|release| warns when the policy is not set and uses OLD behavior. Use
|
||||
the cmake_policy command to set it to OLD or NEW explicitly.
|
|
@ -233,26 +233,46 @@ static bool checkInterfaceDirs(const std::string &prepro,
|
|||
|
||||
const bool inSourceBuild = strcmp(topSourceDir, topBinaryDir) == 0;
|
||||
|
||||
bool hadFatalError = false;
|
||||
|
||||
for(std::vector<std::string>::iterator li = parts.begin();
|
||||
li != parts.end(); ++li)
|
||||
{
|
||||
if (cmGeneratorExpression::Find(*li) != std::string::npos)
|
||||
size_t genexPos = cmGeneratorExpression::Find(*li);
|
||||
if (genexPos == 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
cmake::MessageType messageType = cmake::FATAL_ERROR;
|
||||
cmOStringStream e;
|
||||
if (genexPos != std::string::npos)
|
||||
{
|
||||
switch (target->GetPolicyStatusCMP0041())
|
||||
{
|
||||
case cmPolicies::WARN:
|
||||
messageType = cmake::WARNING;
|
||||
e << target->GetMakefile()->GetPolicies()
|
||||
->GetPolicyWarning(cmPolicies::CMP0041) << "\n";
|
||||
break;
|
||||
case cmPolicies::OLD:
|
||||
continue;
|
||||
case cmPolicies::REQUIRED_IF_USED:
|
||||
case cmPolicies::REQUIRED_ALWAYS:
|
||||
case cmPolicies::NEW:
|
||||
hadFatalError = true;
|
||||
break; // Issue fatal message.
|
||||
}
|
||||
}
|
||||
if (cmHasLiteralPrefix(li->c_str(), "${_IMPORT_PREFIX}"))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if (!cmSystemTools::FileIsFullPath(li->c_str()))
|
||||
{
|
||||
cmOStringStream e;
|
||||
e << "Target \"" << target->GetName() << "\" "
|
||||
"INTERFACE_INCLUDE_DIRECTORIES property contains relative path:\n"
|
||||
" \"" << *li << "\"";
|
||||
target->GetMakefile()->IssueMessage(cmake::FATAL_ERROR,
|
||||
e.str().c_str());
|
||||
return false;
|
||||
target->GetMakefile()->IssueMessage(messageType, e.str().c_str());
|
||||
}
|
||||
if (isSubDirectory(li->c_str(), installDir))
|
||||
{
|
||||
|
@ -260,29 +280,23 @@ static bool checkInterfaceDirs(const std::string &prepro,
|
|||
}
|
||||
if (isSubDirectory(li->c_str(), topBinaryDir))
|
||||
{
|
||||
cmOStringStream e;
|
||||
e << "Target \"" << target->GetName() << "\" "
|
||||
"INTERFACE_INCLUDE_DIRECTORIES property contains path:\n"
|
||||
" \"" << *li << "\"\nwhich is prefixed in the build directory.";
|
||||
target->GetMakefile()->IssueMessage(cmake::FATAL_ERROR,
|
||||
e.str().c_str());
|
||||
return false;
|
||||
target->GetMakefile()->IssueMessage(messageType, e.str().c_str());
|
||||
}
|
||||
if (!inSourceBuild)
|
||||
{
|
||||
if (isSubDirectory(li->c_str(), topSourceDir))
|
||||
{
|
||||
cmOStringStream e;
|
||||
e << "Target \"" << target->GetName() << "\" "
|
||||
"INTERFACE_INCLUDE_DIRECTORIES property contains path:\n"
|
||||
" \"" << *li << "\"\nwhich is prefixed in the source directory.";
|
||||
target->GetMakefile()->IssueMessage(cmake::FATAL_ERROR,
|
||||
e.str().c_str());
|
||||
return false;
|
||||
target->GetMakefile()->IssueMessage(messageType, e.str().c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
return !hadFatalError;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
|
|
|
@ -306,6 +306,11 @@ cmPolicies::cmPolicies()
|
|||
CMP0040, "CMP0040",
|
||||
"The target in the TARGET signature of add_custom_command() must exist.",
|
||||
3,0,0,0, cmPolicies::WARN);
|
||||
|
||||
this->DefinePolicy(
|
||||
CMP0041, "CMP0041",
|
||||
"Error on relative include with generator expression.",
|
||||
3,0,0,0, cmPolicies::WARN);
|
||||
}
|
||||
|
||||
cmPolicies::~cmPolicies()
|
||||
|
|
|
@ -94,6 +94,7 @@ public:
|
|||
CMP0039, ///< Utility targets may not have link dependencies
|
||||
CMP0040, ///< The target in the TARGET signature of
|
||||
/// add_custom_command() must exist.
|
||||
CMP0041, ///< Error on relative include with generator expression
|
||||
|
||||
/** \brief Always the last entry.
|
||||
*
|
||||
|
|
|
@ -25,7 +25,8 @@
|
|||
F(CMP0008) \
|
||||
F(CMP0020) \
|
||||
F(CMP0021) \
|
||||
F(CMP0022)
|
||||
F(CMP0022) \
|
||||
F(CMP0041)
|
||||
|
||||
class cmake;
|
||||
class cmMakefile;
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
1
|
|
@ -0,0 +1,20 @@
|
|||
CMake Error in CMakeLists.txt:
|
||||
Target "foo" INTERFACE_INCLUDE_DIRECTORIES property contains relative path:
|
||||
|
||||
"include/\$<TARGET_PROPERTY:NAME>"
|
||||
|
||||
|
||||
CMake Error in CMakeLists.txt:
|
||||
Target "foo" INTERFACE_INCLUDE_DIRECTORIES property contains path:
|
||||
|
||||
".*/Tests/RunCMake/CMP0041/include/\$<TARGET_PROPERTY:NAME>"
|
||||
|
||||
which is prefixed in the source directory.
|
||||
|
||||
|
||||
CMake Error in CMakeLists.txt:
|
||||
Target "foo" INTERFACE_INCLUDE_DIRECTORIES property contains path:
|
||||
|
||||
".*/Tests/RunCMake/CMP0041/CMP0041-NEW-build/include/\$<TARGET_PROPERTY:NAME>"
|
||||
|
||||
which is prefixed in the build directory.
|
|
@ -0,0 +1,12 @@
|
|||
|
||||
cmake_policy(SET CMP0041 NEW)
|
||||
|
||||
add_library(foo empty.cpp)
|
||||
set_property(TARGET foo
|
||||
PROPERTY INTERFACE_INCLUDE_DIRECTORIES
|
||||
include/$<TARGET_PROPERTY:NAME>
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/include/$<TARGET_PROPERTY:NAME>
|
||||
${CMAKE_CURRENT_BINARY_DIR}/include/$<TARGET_PROPERTY:NAME>
|
||||
)
|
||||
install(TARGETS foo EXPORT FooExport DESTINATION lib)
|
||||
install(EXPORT FooExport DESTINATION lib/cmake)
|
|
@ -0,0 +1 @@
|
|||
0
|
|
@ -0,0 +1 @@
|
|||
^$
|
|
@ -0,0 +1,12 @@
|
|||
|
||||
cmake_policy(SET CMP0041 OLD)
|
||||
|
||||
add_library(foo empty.cpp)
|
||||
set_property(TARGET foo
|
||||
PROPERTY INTERFACE_INCLUDE_DIRECTORIES
|
||||
include/$<TARGET_PROPERTY:NAME>
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/include/$<TARGET_PROPERTY:NAME>
|
||||
${CMAKE_CURRENT_BINARY_DIR}/include/$<TARGET_PROPERTY:NAME>
|
||||
)
|
||||
install(TARGETS foo EXPORT FooExport DESTINATION lib)
|
||||
install(EXPORT FooExport DESTINATION lib/cmake)
|
|
@ -0,0 +1 @@
|
|||
0
|
|
@ -0,0 +1,32 @@
|
|||
CMake Warning in CMakeLists.txt:
|
||||
Policy CMP0041 is not set: Error on relative include with generator
|
||||
expression. Run "cmake --help-policy CMP0041" for policy details. Use the
|
||||
cmake_policy command to set the policy and suppress this warning.
|
||||
|
||||
Target "foo" INTERFACE_INCLUDE_DIRECTORIES property contains relative path:
|
||||
|
||||
"include/\$<TARGET_PROPERTY:NAME>"
|
||||
|
||||
|
||||
CMake Warning in CMakeLists.txt:
|
||||
Policy CMP0041 is not set: Error on relative include with generator
|
||||
expression. Run "cmake --help-policy CMP0041" for policy details. Use the
|
||||
cmake_policy command to set the policy and suppress this warning.
|
||||
|
||||
Target "foo" INTERFACE_INCLUDE_DIRECTORIES property contains path:
|
||||
|
||||
".*/Tests/RunCMake/CMP0041/include/\$<TARGET_PROPERTY:NAME>"
|
||||
|
||||
which is prefixed in the source directory.
|
||||
|
||||
|
||||
CMake Warning in CMakeLists.txt:
|
||||
Policy CMP0041 is not set: Error on relative include with generator
|
||||
expression. Run "cmake --help-policy CMP0041" for policy details. Use the
|
||||
cmake_policy command to set the policy and suppress this warning.
|
||||
|
||||
Target "foo" INTERFACE_INCLUDE_DIRECTORIES property contains path:
|
||||
|
||||
".*/Tests/RunCMake/CMP0041/CMP0041-WARN-build/include/\$<TARGET_PROPERTY:NAME>"
|
||||
|
||||
which is prefixed in the build directory.
|
|
@ -0,0 +1,10 @@
|
|||
|
||||
add_library(foo empty.cpp)
|
||||
set_property(TARGET foo
|
||||
PROPERTY INTERFACE_INCLUDE_DIRECTORIES
|
||||
include/$<TARGET_PROPERTY:NAME>
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/include/$<TARGET_PROPERTY:NAME>
|
||||
${CMAKE_CURRENT_BINARY_DIR}/include/$<TARGET_PROPERTY:NAME>
|
||||
)
|
||||
install(TARGETS foo EXPORT FooExport DESTINATION lib)
|
||||
install(EXPORT FooExport DESTINATION lib/cmake)
|
|
@ -0,0 +1 @@
|
|||
1
|
|
@ -0,0 +1,22 @@
|
|||
CMake Error in CMakeLists.txt:
|
||||
Target "foo" INTERFACE_INCLUDE_DIRECTORIES property contains path:
|
||||
|
||||
".*/Tests/RunCMake/CMP0041/include/\$<TARGET_PROPERTY:NAME>"
|
||||
|
||||
which is prefixed in the source directory.
|
||||
|
||||
|
||||
CMake Error in CMakeLists.txt:
|
||||
Target "foo" INTERFACE_INCLUDE_DIRECTORIES property contains path:
|
||||
|
||||
".*/Tests/RunCMake/CMP0041/include/\$<TARGET_PROPERTY:NAME>"
|
||||
|
||||
which is prefixed in the source directory.
|
||||
|
||||
|
||||
CMake Error in CMakeLists.txt:
|
||||
Target "foo" INTERFACE_INCLUDE_DIRECTORIES property contains path:
|
||||
|
||||
".*/Tests/RunCMake/CMP0041/CMP0041-tid-NEW-build/include/\$<TARGET_PROPERTY:NAME>"
|
||||
|
||||
which is prefixed in the build directory.
|
|
@ -0,0 +1,11 @@
|
|||
|
||||
cmake_policy(SET CMP0041 NEW)
|
||||
|
||||
add_library(foo empty.cpp)
|
||||
target_include_directories(foo INTERFACE
|
||||
include/$<TARGET_PROPERTY:NAME>
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/include/$<TARGET_PROPERTY:NAME>
|
||||
${CMAKE_CURRENT_BINARY_DIR}/include/$<TARGET_PROPERTY:NAME>
|
||||
)
|
||||
install(TARGETS foo EXPORT FooExport DESTINATION lib)
|
||||
install(EXPORT FooExport DESTINATION lib/cmake)
|
|
@ -0,0 +1 @@
|
|||
0
|
|
@ -0,0 +1 @@
|
|||
^$
|
|
@ -0,0 +1,11 @@
|
|||
|
||||
cmake_policy(SET CMP0041 OLD)
|
||||
|
||||
add_library(foo empty.cpp)
|
||||
target_include_directories(foo INTERFACE
|
||||
include/$<TARGET_PROPERTY:NAME>
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/include/$<TARGET_PROPERTY:NAME>
|
||||
${CMAKE_CURRENT_BINARY_DIR}/include/$<TARGET_PROPERTY:NAME>
|
||||
)
|
||||
install(TARGETS foo EXPORT FooExport DESTINATION lib)
|
||||
install(EXPORT FooExport DESTINATION lib/cmake)
|
|
@ -0,0 +1 @@
|
|||
0
|
|
@ -0,0 +1,34 @@
|
|||
CMake Warning in CMakeLists.txt:
|
||||
Policy CMP0041 is not set: Error on relative include with generator
|
||||
expression. Run "cmake --help-policy CMP0041" for policy details. Use the
|
||||
cmake_policy command to set the policy and suppress this warning.
|
||||
|
||||
Target "foo" INTERFACE_INCLUDE_DIRECTORIES property contains path:
|
||||
|
||||
".*/Tests/RunCMake/CMP0041/include/\$<TARGET_PROPERTY:NAME>"
|
||||
|
||||
which is prefixed in the source directory.
|
||||
|
||||
|
||||
CMake Warning in CMakeLists.txt:
|
||||
Policy CMP0041 is not set: Error on relative include with generator
|
||||
expression. Run "cmake --help-policy CMP0041" for policy details. Use the
|
||||
cmake_policy command to set the policy and suppress this warning.
|
||||
|
||||
Target "foo" INTERFACE_INCLUDE_DIRECTORIES property contains path:
|
||||
|
||||
".*/Tests/RunCMake/CMP0041/include/\$<TARGET_PROPERTY:NAME>"
|
||||
|
||||
which is prefixed in the source directory.
|
||||
|
||||
|
||||
CMake Warning in CMakeLists.txt:
|
||||
Policy CMP0041 is not set: Error on relative include with generator
|
||||
expression. Run "cmake --help-policy CMP0041" for policy details. Use the
|
||||
cmake_policy command to set the policy and suppress this warning.
|
||||
|
||||
Target "foo" INTERFACE_INCLUDE_DIRECTORIES property contains path:
|
||||
|
||||
".*/Tests/RunCMake/CMP0041/CMP0041-tid-WARN-build/include/\$<TARGET_PROPERTY:NAME>"
|
||||
|
||||
which is prefixed in the build directory.
|
|
@ -0,0 +1,9 @@
|
|||
|
||||
add_library(foo empty.cpp)
|
||||
target_include_directories(foo INTERFACE
|
||||
include/$<TARGET_PROPERTY:NAME>
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/include/$<TARGET_PROPERTY:NAME>
|
||||
${CMAKE_CURRENT_BINARY_DIR}/include/$<TARGET_PROPERTY:NAME>
|
||||
)
|
||||
install(TARGETS foo EXPORT FooExport DESTINATION lib)
|
||||
install(EXPORT FooExport DESTINATION lib/cmake)
|
|
@ -0,0 +1,3 @@
|
|||
cmake_minimum_required(VERSION 2.8)
|
||||
project(${RunCMake_TEST} CXX)
|
||||
include(${RunCMake_TEST}.cmake NO_POLICY_SCOPE)
|
|
@ -0,0 +1,8 @@
|
|||
include(RunCMake)
|
||||
|
||||
run_cmake(CMP0041-OLD)
|
||||
run_cmake(CMP0041-NEW)
|
||||
run_cmake(CMP0041-WARN)
|
||||
run_cmake(CMP0041-tid-OLD)
|
||||
run_cmake(CMP0041-tid-NEW)
|
||||
run_cmake(CMP0041-tid-WARN)
|
|
@ -0,0 +1,7 @@
|
|||
#ifdef _WIN32
|
||||
__declspec(dllexport)
|
||||
#endif
|
||||
int empty()
|
||||
{
|
||||
return 0;
|
||||
}
|
|
@ -60,6 +60,7 @@ add_RunCMake_test(CMP0037)
|
|||
add_RunCMake_test(CMP0038)
|
||||
add_RunCMake_test(CMP0039)
|
||||
add_RunCMake_test(CMP0040)
|
||||
add_RunCMake_test(CMP0041)
|
||||
add_RunCMake_test(CTest)
|
||||
if(UNIX AND "${CMAKE_TEST_GENERATOR}" MATCHES "Unix Makefiles")
|
||||
add_RunCMake_test(CompilerChange)
|
||||
|
|
Loading…
Reference in New Issue