Commit 5c63c131 authored by Brad King's avatar Brad King Committed by Kitware Robot

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.
parents e983ed7c 783bce29
......@@ -103,3 +103,4 @@ All Policies
/policy/CMP0049
/policy/CMP0050
/policy/CMP0051
/policy/CMP0052
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.
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;
......
......@@ -25,7 +25,9 @@ function(run_cmake test)
unset(expect_std${o})
endif()
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)
set(RunCMake_TEST_BINARY_DIR "${top_bin}/${test}-build")
endif()
......@@ -36,6 +38,9 @@ function(run_cmake test)
if(NOT DEFINED RunCMake_TEST_OPTIONS)
set(RunCMake_TEST_OPTIONS "")
endif()
if (NOT RunCMake_TEST_FILE)
set(RunCMake_TEST_FILE "${test}")
endif()
if(APPLE)
list(APPEND RunCMake_TEST_OPTIONS -DCMAKE_POLICY_DEFAULT_CMP0025=NEW)
endif()
......@@ -52,7 +57,7 @@ function(run_cmake test)
COMMAND ${CMAKE_COMMAND} "${RunCMake_TEST_SOURCE_DIR}"
-G "${RunCMake_GENERATOR}"
-T "${RunCMake_GENERATOR_TOOLSET}"
-DRunCMake_TEST=${test}
-DRunCMake_TEST=${RunCMake_TEST_FILE}
--no-warn-unused-cli
${RunCMake_TEST_OPTIONS}
WORKING_DIRECTORY "${RunCMake_TEST_BINARY_DIR}"
......
......@@ -16,6 +16,7 @@
\* CMP0041
\* CMP0042
\* CMP0046
\* CMP0052
Call Stack \(most recent call first\):
CMakeLists.txt:3 \(include\)
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.
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.
cmake_minimum_required(VERSION 2.8.4)
cmake_minimum_required(VERSION 3.0)
project(${RunCMake_TEST} CXX)
include(${RunCMake_TEST}.cmake)
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.
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.
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)
......@@ -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)
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.
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.
include(RunCMake)
run_cmake(PARENT_SCOPE)
run_cmake(ParentScope)
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment