Merge topic 'install-prefix-in-interface'

783bce29 Export: Disallow exported interface includes in src/build tree (#14592).
c869984e RunCMake: Allow specifying the source dir and file to test.
This commit is contained in:
Brad King 2014-04-10 09:53:13 -04:00 committed by CMake Topic Stage
commit 5c63c13190
37 changed files with 290 additions and 6 deletions

View File

@ -103,3 +103,4 @@ All Policies
/policy/CMP0049 /policy/CMP0049
/policy/CMP0050 /policy/CMP0050
/policy/CMP0051 /policy/CMP0051
/policy/CMP0052

21
Help/policy/CMP0052.rst Normal file
View File

@ -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.

View File

@ -0,0 +1,5 @@
CMP0052
-------
* Policy :policy:`CMP0052` introduced to control directories in the
:prop_tgt:`INTERFACE_INCLUDE_DIRECTORIES` of exported targets.

View File

@ -279,7 +279,43 @@ static bool checkInterfaceDirs(const std::string &prepro,
} }
if (isSubDirectory(li->c_str(), installDir)) 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)) if (isSubDirectory(li->c_str(), topBinaryDir))
{ {

View File

@ -348,6 +348,12 @@ cmPolicies::cmPolicies()
CMP0051, "CMP0051", CMP0051, "CMP0051",
"List TARGET_OBJECTS in SOURCES target property.", "List TARGET_OBJECTS in SOURCES target property.",
3,1,0, cmPolicies::WARN); 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() cmPolicies::~cmPolicies()

View File

@ -105,6 +105,8 @@ public:
CMP0049, ///< Do not expand variables in target source entries CMP0049, ///< Do not expand variables in target source entries
CMP0050, ///< Disallow add_custom_command SOURCE signatures CMP0050, ///< Disallow add_custom_command SOURCE signatures
CMP0051, ///< List TARGET_OBJECTS in SOURCES target property CMP0051, ///< List TARGET_OBJECTS in SOURCES target property
CMP0052, ///< Reject source and build dirs in installed
/// INTERFACE_INCLUDE_DIRECTORIES
/** \brief Always the last entry. /** \brief Always the last entry.
* *

View File

@ -30,7 +30,8 @@
F(CMP0038) \ F(CMP0038) \
F(CMP0041) \ F(CMP0041) \
F(CMP0042) \ F(CMP0042) \
F(CMP0046) F(CMP0046) \
F(CMP0052)
class cmake; class cmake;
class cmMakefile; class cmMakefile;

View File

@ -25,7 +25,9 @@ function(run_cmake test)
unset(expect_std${o}) unset(expect_std${o})
endif() endif()
endforeach() endforeach()
set(RunCMake_TEST_SOURCE_DIR "${top_src}") if (NOT RunCMake_TEST_SOURCE_DIR)
set(RunCMake_TEST_SOURCE_DIR "${top_src}")
endif()
if(NOT RunCMake_TEST_BINARY_DIR) if(NOT RunCMake_TEST_BINARY_DIR)
set(RunCMake_TEST_BINARY_DIR "${top_bin}/${test}-build") set(RunCMake_TEST_BINARY_DIR "${top_bin}/${test}-build")
endif() endif()
@ -36,6 +38,9 @@ function(run_cmake test)
if(NOT DEFINED RunCMake_TEST_OPTIONS) if(NOT DEFINED RunCMake_TEST_OPTIONS)
set(RunCMake_TEST_OPTIONS "") set(RunCMake_TEST_OPTIONS "")
endif() endif()
if (NOT RunCMake_TEST_FILE)
set(RunCMake_TEST_FILE "${test}")
endif()
if(APPLE) if(APPLE)
list(APPEND RunCMake_TEST_OPTIONS -DCMAKE_POLICY_DEFAULT_CMP0025=NEW) list(APPEND RunCMake_TEST_OPTIONS -DCMAKE_POLICY_DEFAULT_CMP0025=NEW)
endif() endif()
@ -52,7 +57,7 @@ function(run_cmake test)
COMMAND ${CMAKE_COMMAND} "${RunCMake_TEST_SOURCE_DIR}" COMMAND ${CMAKE_COMMAND} "${RunCMake_TEST_SOURCE_DIR}"
-G "${RunCMake_GENERATOR}" -G "${RunCMake_GENERATOR}"
-T "${RunCMake_GENERATOR_TOOLSET}" -T "${RunCMake_GENERATOR_TOOLSET}"
-DRunCMake_TEST=${test} -DRunCMake_TEST=${RunCMake_TEST_FILE}
--no-warn-unused-cli --no-warn-unused-cli
${RunCMake_TEST_OPTIONS} ${RunCMake_TEST_OPTIONS}
WORKING_DIRECTORY "${RunCMake_TEST_BINARY_DIR}" WORKING_DIRECTORY "${RunCMake_TEST_BINARY_DIR}"

View File

@ -16,6 +16,7 @@
\* CMP0041 \* CMP0041
\* CMP0042 \* CMP0042
\* CMP0046 \* CMP0046
\* CMP0052
Call Stack \(most recent call first\): Call Stack \(most recent call first\):
CMakeLists.txt:3 \(include\) CMakeLists.txt:3 \(include\)

View File

@ -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.

View File

@ -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.

View File

@ -1,3 +1,3 @@
cmake_minimum_required(VERSION 2.8.4) cmake_minimum_required(VERSION 3.0)
project(${RunCMake_TEST} CXX) project(${RunCMake_TEST} CXX)
include(${RunCMake_TEST}.cmake) include(${RunCMake_TEST}.cmake)

View File

@ -0,0 +1 @@
1

View File

@ -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.

View File

@ -0,0 +1 @@
1

View File

@ -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.

View File

@ -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)

View File

@ -12,3 +12,128 @@ run_cmake(CMP0021)
run_cmake(install_config) run_cmake(install_config)
run_cmake(incomplete-genex) run_cmake(incomplete-genex)
run_cmake(export-NOWARN) 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)

View File

@ -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.

View File

@ -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.

View File

@ -0,0 +1 @@
0

View File

@ -1,3 +1,3 @@
include(RunCMake) include(RunCMake)
run_cmake(PARENT_SCOPE) run_cmake(ParentScope)