Export: Disallow exported interface includes in src/build tree (#14592).
Allow directories in the source tree or build tree only if the install tree is a subdirectory of the source tree or build tree, as appropriate. Re-use the test files in the RunCMake.include_directories test to run in multiple scenarios. Bump the required CMake version in the test to 3.0 to ensure that the new policy warnings are emitted correctly.
This commit is contained in:
parent
c869984ea0
commit
783bce295b
|
@ -103,3 +103,4 @@ All Policies
|
|||
/policy/CMP0049
|
||||
/policy/CMP0050
|
||||
/policy/CMP0051
|
||||
/policy/CMP0052
|
||||
|
|
|
@ -0,0 +1,21 @@
|
|||
CMP0052
|
||||
-------
|
||||
|
||||
Reject source and build dirs in installed INTERFACE_INCLUDE_DIRECTORIES.
|
||||
|
||||
CMake 3.0 and lower allowed subdirectories of the source directory or build
|
||||
directory to be in the :prop_tgt:`INTERFACE_INCLUDE_DIRECTORIES` of
|
||||
installed and exported targets, if the directory was also a subdirectory of
|
||||
the installation prefix. This makes the installation depend on the
|
||||
existence of the source dir or binary dir, and the installation will be
|
||||
broken if either are removed after installation.
|
||||
|
||||
The OLD behavior for this policy is to export the content of the
|
||||
:prop_tgt:`INTERFACE_INCLUDE_DIRECTORIES` with the source or binary
|
||||
directory. The NEW behavior for this
|
||||
policy is to issue an error if such a directory is used.
|
||||
|
||||
This policy was introduced in CMake version 3.1.
|
||||
CMake version |release| warns when the policy is not set and uses
|
||||
``OLD`` behavior. Use the :command:`cmake_policy` command to set it
|
||||
to ``OLD`` or ``NEW`` explicitly.
|
|
@ -0,0 +1,5 @@
|
|||
CMP0052
|
||||
-------
|
||||
|
||||
* Policy :policy:`CMP0052` introduced to control directories in the
|
||||
:prop_tgt:`INTERFACE_INCLUDE_DIRECTORIES` of exported targets.
|
|
@ -279,7 +279,43 @@ static bool checkInterfaceDirs(const std::string &prepro,
|
|||
}
|
||||
if (isSubDirectory(li->c_str(), installDir))
|
||||
{
|
||||
continue;
|
||||
// The include directory is inside the install tree. If the
|
||||
// install tree is not inside the source tree or build tree then
|
||||
// fall through to the checks below that the include directory is not
|
||||
// also inside the source tree or build tree.
|
||||
bool shouldContinue =
|
||||
isSubDirectory(installDir, topBinaryDir)
|
||||
|| isSubDirectory(installDir, topSourceDir);
|
||||
|
||||
if (!shouldContinue)
|
||||
{
|
||||
switch(target->GetPolicyStatusCMP0052())
|
||||
{
|
||||
case cmPolicies::WARN:
|
||||
{
|
||||
cmOStringStream s;
|
||||
s << target->GetMakefile()->GetPolicies()
|
||||
->GetPolicyWarning(cmPolicies::CMP0052) << "\n";
|
||||
s << "Directory:\n \"" << *li << "\"\nin "
|
||||
"INTERFACE_INCLUDE_DIRECTORIES of target \""
|
||||
<< target->GetName() << "\" is a subdirectory of the install "
|
||||
"directory:\n \"" << installDir << "\"";
|
||||
target->GetMakefile()->IssueMessage(cmake::AUTHOR_WARNING,
|
||||
s.str());
|
||||
}
|
||||
case cmPolicies::OLD:
|
||||
shouldContinue = true;
|
||||
break;
|
||||
case cmPolicies::REQUIRED_ALWAYS:
|
||||
case cmPolicies::REQUIRED_IF_USED:
|
||||
case cmPolicies::NEW:
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (shouldContinue)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (isSubDirectory(li->c_str(), topBinaryDir))
|
||||
{
|
||||
|
|
|
@ -348,6 +348,12 @@ cmPolicies::cmPolicies()
|
|||
CMP0051, "CMP0051",
|
||||
"List TARGET_OBJECTS in SOURCES target property.",
|
||||
3,1,0, cmPolicies::WARN);
|
||||
|
||||
this->DefinePolicy(
|
||||
CMP0052, "CMP0052",
|
||||
"Reject source and build dirs in installed "
|
||||
"INTERFACE_INCLUDE_DIRECTORIES.",
|
||||
3,1,0, cmPolicies::WARN);
|
||||
}
|
||||
|
||||
cmPolicies::~cmPolicies()
|
||||
|
|
|
@ -105,6 +105,8 @@ public:
|
|||
CMP0049, ///< Do not expand variables in target source entries
|
||||
CMP0050, ///< Disallow add_custom_command SOURCE signatures
|
||||
CMP0051, ///< List TARGET_OBJECTS in SOURCES target property
|
||||
CMP0052, ///< Reject source and build dirs in installed
|
||||
/// INTERFACE_INCLUDE_DIRECTORIES
|
||||
|
||||
/** \brief Always the last entry.
|
||||
*
|
||||
|
|
|
@ -30,7 +30,8 @@
|
|||
F(CMP0038) \
|
||||
F(CMP0041) \
|
||||
F(CMP0042) \
|
||||
F(CMP0046)
|
||||
F(CMP0046) \
|
||||
F(CMP0052)
|
||||
|
||||
class cmake;
|
||||
class cmMakefile;
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
\* CMP0041
|
||||
\* CMP0042
|
||||
\* CMP0046
|
||||
\* CMP0052
|
||||
|
||||
Call Stack \(most recent call first\):
|
||||
CMakeLists.txt:3 \(include\)
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
1
|
|
@ -0,0 +1,6 @@
|
|||
CMake Error in CMakeLists.txt:
|
||||
Target "testTarget" INTERFACE_INCLUDE_DIRECTORIES property contains path:
|
||||
|
||||
".*Tests/RunCMake/include_directories/prefix/BinInInstallPrefix-CMP0052-NEW-build/foo"
|
||||
|
||||
which is prefixed in the build directory.
|
|
@ -0,0 +1 @@
|
|||
0
|
|
@ -0,0 +1 @@
|
|||
^$
|
|
@ -0,0 +1 @@
|
|||
0
|
|
@ -0,0 +1,15 @@
|
|||
CMake Warning \(dev\) in CMakeLists.txt:
|
||||
Policy CMP0052 is not set: Reject source and build dirs in installed
|
||||
INTERFACE_INCLUDE_DIRECTORIES. Run "cmake --help-policy CMP0052" for
|
||||
policy details. Use the cmake_policy command to set the policy and
|
||||
suppress this warning.
|
||||
|
||||
Directory:
|
||||
|
||||
".*Tests/RunCMake/include_directories/prefix/BinInInstallPrefix-CMP0052-WARN-build/foo"
|
||||
|
||||
in INTERFACE_INCLUDE_DIRECTORIES of target "testTarget" is a subdirectory
|
||||
of the install directory:
|
||||
|
||||
".*Tests/RunCMake/include_directories/prefix"
|
||||
This warning is for project developers. Use -Wno-dev to suppress it.
|
|
@ -1,3 +1,3 @@
|
|||
cmake_minimum_required(VERSION 2.8.4)
|
||||
cmake_minimum_required(VERSION 3.0)
|
||||
project(${RunCMake_TEST} CXX)
|
||||
include(${RunCMake_TEST}.cmake)
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
1
|
|
@ -0,0 +1,6 @@
|
|||
CMake Error in CMakeLists.txt:
|
||||
Target "testTarget" INTERFACE_INCLUDE_DIRECTORIES property contains path:
|
||||
|
||||
".*Tests/RunCMake/include_directories/InstallInBinDir-build/foo"
|
||||
|
||||
which is prefixed in the build directory.
|
|
@ -0,0 +1 @@
|
|||
1
|
|
@ -0,0 +1,6 @@
|
|||
CMake Error in CMakeLists.txt:
|
||||
Target "testTarget" INTERFACE_INCLUDE_DIRECTORIES property contains path:
|
||||
|
||||
".*Tests/RunCMake/include_directories/copy/foo"
|
||||
|
||||
which is prefixed in the source directory.
|
|
@ -0,0 +1 @@
|
|||
0
|
|
@ -0,0 +1 @@
|
|||
^$
|
|
@ -0,0 +1,11 @@
|
|||
|
||||
project(InstallPrefixInInterface)
|
||||
|
||||
add_library(testTarget "${CMAKE_CURRENT_SOURCE_DIR}/empty.cpp")
|
||||
target_include_directories(testTarget INTERFACE "${CMAKE_INSTALL_PREFIX}/foo")
|
||||
|
||||
install(TARGETS testTarget EXPORT testTargets
|
||||
DESTINATION lib
|
||||
)
|
||||
|
||||
install(EXPORT testTargets DESTINATION lib/cmake)
|
|
@ -0,0 +1 @@
|
|||
0
|
|
@ -0,0 +1 @@
|
|||
^$
|
|
@ -0,0 +1 @@
|
|||
0
|
|
@ -0,0 +1 @@
|
|||
^$
|
|
@ -12,3 +12,128 @@ run_cmake(CMP0021)
|
|||
run_cmake(install_config)
|
||||
run_cmake(incomplete-genex)
|
||||
run_cmake(export-NOWARN)
|
||||
|
||||
configure_file(
|
||||
"${RunCMake_SOURCE_DIR}/CMakeLists.txt"
|
||||
"${RunCMake_BINARY_DIR}/copy/CMakeLists.txt"
|
||||
COPYONLY
|
||||
)
|
||||
configure_file(
|
||||
"${RunCMake_SOURCE_DIR}/empty.cpp"
|
||||
"${RunCMake_BINARY_DIR}/copy/empty.cpp"
|
||||
COPYONLY
|
||||
)
|
||||
configure_file(
|
||||
"${RunCMake_SOURCE_DIR}/SourceDirectoryInInterface.cmake"
|
||||
"${RunCMake_BINARY_DIR}/copy/SourceDirectoryInInterface.cmake"
|
||||
COPYONLY
|
||||
)
|
||||
set(RunCMake_TEST_OPTIONS "-DCMAKE_INSTALL_PREFIX=${RunCMake_BINARY_DIR}/copy/SourceDirectoryInInterface/prefix")
|
||||
set(RunCMake_TEST_FILE "${RunCMake_BINARY_DIR}/copy/SourceDirectoryInInterface")
|
||||
set(RunCMake_TEST_SOURCE_DIR "${RunCMake_BINARY_DIR}/copy")
|
||||
run_cmake(InstallInSrcDir)
|
||||
unset(RunCMake_TEST_SOURCE_DIR)
|
||||
unset(RunCMake_TEST_FILE)
|
||||
|
||||
set(RunCMake_TEST_OPTIONS "-DCMAKE_INSTALL_PREFIX=${RunCMake_BINARY_DIR}/InstallInBinDir-build/prefix")
|
||||
set(RunCMake_TEST_BINARY_DIR "${RunCMake_BINARY_DIR}/InstallInBinDir-build")
|
||||
set(RunCMake_TEST_FILE "${RunCMake_SOURCE_DIR}/BinaryDirectoryInInterface")
|
||||
run_cmake(InstallInBinDir)
|
||||
unset(RunCMake_TEST_BINARY_DIR)
|
||||
unset(RunCMake_TEST_FILE)
|
||||
|
||||
configure_file(
|
||||
"${RunCMake_SOURCE_DIR}/CMakeLists.txt"
|
||||
"${RunCMake_BINARY_DIR}/prefix/src/CMakeLists.txt"
|
||||
COPYONLY
|
||||
)
|
||||
configure_file(
|
||||
"${RunCMake_SOURCE_DIR}/empty.cpp"
|
||||
"${RunCMake_BINARY_DIR}/prefix/src/empty.cpp"
|
||||
COPYONLY
|
||||
)
|
||||
configure_file(
|
||||
"${RunCMake_SOURCE_DIR}/SourceDirectoryInInterface.cmake"
|
||||
"${RunCMake_BINARY_DIR}/prefix/src/SourceDirectoryInInterface.cmake"
|
||||
COPYONLY
|
||||
)
|
||||
|
||||
foreach(policyStatus "" NEW OLD)
|
||||
if (NOT "${policyStatus}" STREQUAL "")
|
||||
set(policyOption -DCMAKE_POLICY_DEFAULT_CMP0052=${policyStatus})
|
||||
else()
|
||||
unset(policyOption)
|
||||
set(policyStatus WARN)
|
||||
endif()
|
||||
set(RunCMake_TEST_OPTIONS "-DCMAKE_INSTALL_PREFIX=${RunCMake_BINARY_DIR}/prefix" ${policyOption})
|
||||
# Set the RunCMake_TEST_SOURCE_DIR here to the copy too. This is needed to run
|
||||
# the test suite in-source properly. Otherwise the install directory would be
|
||||
# a subdirectory or the source directory, which is allowed and tested separately
|
||||
# below.
|
||||
set(RunCMake_TEST_SOURCE_DIR "${RunCMake_BINARY_DIR}/prefix/src")
|
||||
set(RunCMake_TEST_BINARY_DIR "${RunCMake_BINARY_DIR}/prefix/BinInInstallPrefix-CMP0052-${policyStatus}-build")
|
||||
set(RunCMake_TEST_FILE "${RunCMake_SOURCE_DIR}/BinaryDirectoryInInterface")
|
||||
run_cmake(BinInInstallPrefix-CMP0052-${policyStatus})
|
||||
unset(RunCMake_TEST_BINARY_DIR)
|
||||
unset(RunCMake_TEST_FILE)
|
||||
|
||||
set(RunCMake_TEST_FILE "${RunCMake_BINARY_DIR}/prefix/src/SourceDirectoryInInterface")
|
||||
run_cmake(SrcInInstallPrefix-CMP0052-${policyStatus})
|
||||
unset(RunCMake_TEST_SOURCE_DIR)
|
||||
unset(RunCMake_TEST_FILE)
|
||||
endforeach()
|
||||
|
||||
set(RunCMake_TEST_OPTIONS "-DCMAKE_INSTALL_PREFIX=${RunCMake_BINARY_DIR}/InstallPrefixInInterface-build/prefix")
|
||||
run_cmake(InstallPrefixInInterface)
|
||||
|
||||
configure_file(
|
||||
"${RunCMake_SOURCE_DIR}/CMakeLists.txt"
|
||||
"${RunCMake_BINARY_DIR}/installToSrc/CMakeLists.txt"
|
||||
COPYONLY
|
||||
)
|
||||
configure_file(
|
||||
"${RunCMake_SOURCE_DIR}/empty.cpp"
|
||||
"${RunCMake_BINARY_DIR}/installToSrc/empty.cpp"
|
||||
COPYONLY
|
||||
)
|
||||
configure_file(
|
||||
"${RunCMake_SOURCE_DIR}/InstallPrefixInInterface.cmake"
|
||||
"${RunCMake_BINARY_DIR}/installToSrc/InstallPrefixInInterface.cmake"
|
||||
COPYONLY
|
||||
)
|
||||
set(RunCMake_TEST_OPTIONS "-DCMAKE_INSTALL_PREFIX=${RunCMake_BINARY_DIR}/installToSrc/InstallPrefixInInterface/prefix")
|
||||
set(RunCMake_TEST_FILE "${RunCMake_BINARY_DIR}/installToSrc/InstallPrefixInInterface")
|
||||
set(RunCMake_TEST_SOURCE_DIR "${RunCMake_BINARY_DIR}/installToSrc")
|
||||
run_cmake(InstallToPrefixInSrcDirOutOfSource)
|
||||
unset(RunCMake_TEST_SOURCE_DIR)
|
||||
unset(RunCMake_TEST_FILE)
|
||||
|
||||
|
||||
file(REMOVE_RECURSE "${RunCMake_TEST_BINARY_DIR}/installToSrcInSrc")
|
||||
set(RunCMake_TEST_NO_CLEAN ON)
|
||||
|
||||
configure_file(
|
||||
"${RunCMake_SOURCE_DIR}/CMakeLists.txt"
|
||||
"${RunCMake_BINARY_DIR}/installToSrcInSrc/CMakeLists.txt"
|
||||
COPYONLY
|
||||
)
|
||||
configure_file(
|
||||
"${RunCMake_SOURCE_DIR}/empty.cpp"
|
||||
"${RunCMake_BINARY_DIR}/installToSrcInSrc/empty.cpp"
|
||||
COPYONLY
|
||||
)
|
||||
configure_file(
|
||||
"${RunCMake_SOURCE_DIR}/InstallPrefixInInterface.cmake"
|
||||
"${RunCMake_BINARY_DIR}/installToSrcInSrc/InstallPrefixInInterface.cmake"
|
||||
COPYONLY
|
||||
)
|
||||
|
||||
set(RunCMake_TEST_OPTIONS "-DCMAKE_INSTALL_PREFIX=${RunCMake_BINARY_DIR}/installToSrcInSrc/InstallPrefixInInterface/prefix")
|
||||
set(RunCMake_TEST_FILE "${RunCMake_BINARY_DIR}/installToSrcInSrc/InstallPrefixInInterface")
|
||||
set(RunCMake_TEST_SOURCE_DIR "${RunCMake_BINARY_DIR}/installToSrcInSrc")
|
||||
set(RunCMake_TEST_BINARY_DIR "${RunCMake_BINARY_DIR}/installToSrcInSrc")
|
||||
run_cmake(InstallToPrefixInSrcDirInSource)
|
||||
unset(RunCMake_TEST_SOURCE_DIR)
|
||||
unset(RunCMake_TEST_BINARY_DIR)
|
||||
unset(RunCMake_TEST_FILE)
|
||||
unset(RunCMake_TEST_NO_CLEAN)
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
1
|
|
@ -0,0 +1,6 @@
|
|||
CMake Error in CMakeLists.txt:
|
||||
Target "testTarget" INTERFACE_INCLUDE_DIRECTORIES property contains path:
|
||||
|
||||
".*Tests/RunCMake/include_directories/prefix/src/foo"
|
||||
|
||||
which is prefixed in the source directory.
|
|
@ -0,0 +1 @@
|
|||
0
|
|
@ -0,0 +1 @@
|
|||
^$
|
|
@ -0,0 +1 @@
|
|||
0
|
|
@ -0,0 +1,15 @@
|
|||
CMake Warning \(dev\) in CMakeLists.txt:
|
||||
Policy CMP0052 is not set: Reject source and build dirs in installed
|
||||
INTERFACE_INCLUDE_DIRECTORIES. Run "cmake --help-policy CMP0052" for
|
||||
policy details. Use the cmake_policy command to set the policy and
|
||||
suppress this warning.
|
||||
|
||||
Directory:
|
||||
|
||||
".*Tests/RunCMake/include_directories/prefix/src/foo"
|
||||
|
||||
in INTERFACE_INCLUDE_DIRECTORIES of target "testTarget" is a subdirectory
|
||||
of the install directory:
|
||||
|
||||
".*Tests/RunCMake/include_directories/prefix"
|
||||
This warning is for project developers. Use -Wno-dev to suppress it.
|
Loading…
Reference in New Issue