Add policy CMP0068 separate install_name and RPATH settings on macOS

BUILD_WITH_INSTALL_RPATH, SKIP_BUILD_RPATH, CMAKE_SKIP_RPATH and
CMAKE_SKIP_INSTALL_RPATH no longer any effect on the install name
of a target on macOS.

Fixes: #16589
This commit is contained in:
Clinton Stimpson
2017-02-09 08:12:10 -07:00
parent f7b9bf41c5
commit 1ba91291e3
22 changed files with 165 additions and 7 deletions

View File

@@ -51,6 +51,14 @@ The :variable:`CMAKE_MINIMUM_REQUIRED_VERSION` variable may also be used
to determine whether to report an error on use of deprecated macros or to determine whether to report an error on use of deprecated macros or
functions. functions.
Policies Introduced by CMake 3.9
================================
.. toctree::
:maxdepth: 1
CMP0068: RPATH settings on macOS do not affect install_name. </policy/CMP0068>
Policies Introduced by CMake 3.8 Policies Introduced by CMake 3.8
================================ ================================

35
Help/policy/CMP0068.rst Normal file
View File

@@ -0,0 +1,35 @@
CMP0068
-------
``RPATH`` settings on macOS do not affect ``install_name``.
CMake 3.9 and newer remove any effect the following settings may have on the
``install_name`` of a target on macOS:
* :prop_tgt:`BUILD_WITH_INSTALL_RPATH` target property
* :prop_tgt:`SKIP_BUILD_RPATH` target property
* :variable:`CMAKE_SKIP_RPATH` variable
* :variable:`CMAKE_SKIP_INSTALL_RPATH` variable
Previously, setting :prop_tgt:`BUILD_WITH_INSTALL_RPATH` had the effect of
setting both the ``install_name`` of a target to :prop_tgt:`INSTALL_NAME_DIR`
and the ``RPATH`` to :prop_tgt:`INSTALL_RPATH`. In CMake 3.9, it only affects
setting of ``RPATH``. However, if one wants :prop_tgt:`INSTALL_NAME_DIR` to
apply to the target in the build tree, one may set
:prop_tgt:`BUILD_WITH_INSTALL_NAME_DIR`.
If :prop_tgt:`SKIP_BUILD_RPATH`, :variable:`CMAKE_SKIP_RPATH` or
:variable:`CMAKE_SKIP_INSTALL_RPATH` were used to strip the directory portion
of the ``install_name`` of a target, one may set ``INSTALL_NAME_DIR=""``
instead.
The ``OLD`` behavior of this policy is to use the ``RPATH`` settings for
``install_name`` on macOS. The ``NEW`` behavior of this policy is to ignore
the ``RPATH`` settings for ``install_name`` on macOS.
This policy was introduced in CMake version 3.9. 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.
.. include:: DEPRECATED.txt

View File

@@ -9,5 +9,5 @@ This property is initialized by the value of the variable
:variable:`CMAKE_BUILD_WITH_INSTALL_NAME_DIR` if it is set when a target is :variable:`CMAKE_BUILD_WITH_INSTALL_NAME_DIR` if it is set when a target is
created. created.
If this property is not set, the value of :prop_tgt:`BUILD_WITH_INSTALL_RPATH` If this property is not set and policy :policy:`CMP0068` is not ``NEW``, the
is used in its place. value of :prop_tgt:`BUILD_WITH_INSTALL_RPATH` is used in its place.

View File

@@ -10,6 +10,6 @@ This property is initialized by the value of the
:variable:`CMAKE_BUILD_WITH_INSTALL_RPATH` variable if it is set when a target :variable:`CMAKE_BUILD_WITH_INSTALL_RPATH` variable if it is set when a target
is created. is created.
This property also controls use of :prop_tgt:`INSTALL_NAME_DIR` in the build If policy :policy:`CMP0068` is not ``NEW``, this property also controls use of
tree on macOS, but defers to the :prop_tgt:`BUILD_WITH_INSTALL_NAME_DIR` target :prop_tgt:`INSTALL_NAME_DIR` in the build tree on macOS. Either way, the
property if the latter is set. :prop_tgt:`BUILD_WITH_INSTALL_NAME_DIR` target property takes precedence.

View File

@@ -6,3 +6,6 @@ install_name_policy
control whether to use the :prop_tgt:`INSTALL_NAME_DIR` target property control whether to use the :prop_tgt:`INSTALL_NAME_DIR` target property
value for binaries in the build tree. This is for macOS ``install_name`` value for binaries in the build tree. This is for macOS ``install_name``
as :prop_tgt:`BUILD_WITH_INSTALL_RPATH` is for ``RPATH``. as :prop_tgt:`BUILD_WITH_INSTALL_RPATH` is for ``RPATH``.
* On macOS, ``RPATH`` settings such as :prop_tgt:`BUILD_WITH_INSTALL_RPATH`
no longer affect the ``install_name`` field. See policy :policy:`CMP0068`.

View File

@@ -1402,14 +1402,30 @@ bool cmGeneratorTarget::MacOSXUseInstallNameDir() const
return cmSystemTools::IsOn(build_with_install_name); return cmSystemTools::IsOn(build_with_install_name);
} }
cmPolicies::PolicyStatus cmp0068 = this->GetPolicyStatusCMP0068();
if (cmp0068 == cmPolicies::NEW) {
return false;
}
bool use_install_name = this->GetPropertyAsBool("BUILD_WITH_INSTALL_RPATH"); bool use_install_name = this->GetPropertyAsBool("BUILD_WITH_INSTALL_RPATH");
if (use_install_name && cmp0068 == cmPolicies::WARN) {
this->LocalGenerator->GetGlobalGenerator()->AddCMP0068WarnTarget(
this->GetName());
}
return use_install_name; return use_install_name;
} }
bool cmGeneratorTarget::CanGenerateInstallNameDir( bool cmGeneratorTarget::CanGenerateInstallNameDir(
InstallNameType name_type) const InstallNameType name_type) const
{ {
cmPolicies::PolicyStatus cmp0068 = this->GetPolicyStatusCMP0068();
if (cmp0068 == cmPolicies::NEW) {
return true;
}
bool skip = this->Makefile->IsOn("CMAKE_SKIP_RPATH"); bool skip = this->Makefile->IsOn("CMAKE_SKIP_RPATH");
if (name_type == INSTALL_NAME_FOR_INSTALL) { if (name_type == INSTALL_NAME_FOR_INSTALL) {
skip |= this->Makefile->IsOn("CMAKE_SKIP_INSTALL_RPATH"); skip |= this->Makefile->IsOn("CMAKE_SKIP_INSTALL_RPATH");
@@ -1417,6 +1433,11 @@ bool cmGeneratorTarget::CanGenerateInstallNameDir(
skip |= this->GetPropertyAsBool("SKIP_BUILD_RPATH"); skip |= this->GetPropertyAsBool("SKIP_BUILD_RPATH");
} }
if (skip && cmp0068 == cmPolicies::WARN) {
this->LocalGenerator->GetGlobalGenerator()->AddCMP0068WarnTarget(
this->GetName());
}
return !skip; return !skip;
} }

View File

@@ -1194,6 +1194,11 @@ void cmGlobalGenerator::AddCMP0042WarnTarget(const std::string& target)
this->CMP0042WarnTargets.insert(target); this->CMP0042WarnTargets.insert(target);
} }
void cmGlobalGenerator::AddCMP0068WarnTarget(const std::string& target)
{
this->CMP0068WarnTargets.insert(target);
}
bool cmGlobalGenerator::CheckALLOW_DUPLICATE_CUSTOM_TARGETS() const bool cmGlobalGenerator::CheckALLOW_DUPLICATE_CUSTOM_TARGETS() const
{ {
// If the property is not enabled then okay. // If the property is not enabled then okay.
@@ -1235,6 +1240,8 @@ bool cmGlobalGenerator::Compute()
// clear targets to issue warning CMP0042 for // clear targets to issue warning CMP0042 for
this->CMP0042WarnTargets.clear(); this->CMP0042WarnTargets.clear();
// clear targets to issue warning CMP0068 for
this->CMP0068WarnTargets.clear();
// Check whether this generator is allowed to run. // Check whether this generator is allowed to run.
if (!this->CheckALLOW_DUPLICATE_CUSTOM_TARGETS()) { if (!this->CheckALLOW_DUPLICATE_CUSTOM_TARGETS()) {
@@ -1366,6 +1373,24 @@ void cmGlobalGenerator::Generate()
this->GetCMakeInstance()->IssueMessage(cmake::AUTHOR_WARNING, w.str()); this->GetCMakeInstance()->IssueMessage(cmake::AUTHOR_WARNING, w.str());
} }
if (!this->CMP0068WarnTargets.empty()) {
std::ostringstream w;
/* clang-format off */
w <<
cmPolicies::GetPolicyWarning(cmPolicies::CMP0068) << "\n"
"For compatibility with older versions of CMake, the install_name "
"fields for the following targets are still affected by RPATH "
"settings:\n"
;
/* clang-format on */
for (std::set<std::string>::iterator iter =
this->CMP0068WarnTargets.begin();
iter != this->CMP0068WarnTargets.end(); ++iter) {
w << " " << *iter << "\n";
}
this->GetCMakeInstance()->IssueMessage(cmake::AUTHOR_WARNING, w.str());
}
this->CMakeInstance->UpdateProgress("Generating done", -1); this->CMakeInstance->UpdateProgress("Generating done", -1);
} }

View File

@@ -357,6 +357,7 @@ public:
cmExportBuildFileGenerator* GetExportedTargetsFile( cmExportBuildFileGenerator* GetExportedTargetsFile(
const std::string& filename) const; const std::string& filename) const;
void AddCMP0042WarnTarget(const std::string& target); void AddCMP0042WarnTarget(const std::string& target);
void AddCMP0068WarnTarget(const std::string& target);
virtual void ComputeTargetObjectDirectory(cmGeneratorTarget* gt) const; virtual void ComputeTargetObjectDirectory(cmGeneratorTarget* gt) const;
@@ -562,6 +563,8 @@ private:
// track targets to issue CMP0042 warning for. // track targets to issue CMP0042 warning for.
std::set<std::string> CMP0042WarnTargets; std::set<std::string> CMP0042WarnTargets;
// track targets to issue CMP0068 warning for.
std::set<std::string> CMP0068WarnTargets;
mutable std::map<cmSourceFile*, std::set<cmGeneratorTarget const*> > mutable std::map<cmSourceFile*, std::set<cmGeneratorTarget const*> >
FilenameTargetDepends; FilenameTargetDepends;

View File

@@ -200,7 +200,10 @@ class cmMakefile;
7, 0, cmPolicies::WARN) \ 7, 0, cmPolicies::WARN) \
SELECT(POLICY, CMP0067, \ SELECT(POLICY, CMP0067, \
"Honor language standard in try_compile() source-file signature.", \ "Honor language standard in try_compile() source-file signature.", \
3, 8, 0, cmPolicies::WARN) 3, 8, 0, cmPolicies::WARN) \
SELECT(POLICY, CMP0068, \
"RPATH settings on macOS do not affect install_name.", 3, 9, 0, \
cmPolicies::WARN)
#define CM_SELECT_ID(F, A1, A2, A3, A4, A5, A6) F(A1) #define CM_SELECT_ID(F, A1, A2, A3, A4, A5, A6) F(A1)
#define CM_FOR_EACH_POLICY_ID(POLICY) \ #define CM_FOR_EACH_POLICY_ID(POLICY) \
@@ -221,7 +224,8 @@ class cmMakefile;
F(CMP0052) \ F(CMP0052) \
F(CMP0060) \ F(CMP0060) \
F(CMP0063) \ F(CMP0063) \
F(CMP0065) F(CMP0065) \
F(CMP0068)
/** \class cmPolicies /** \class cmPolicies
* \brief Handles changes in CMake behavior and policies * \brief Handles changes in CMake behavior and policies

View File

@@ -0,0 +1 @@
0

View File

@@ -0,0 +1,6 @@
cmake_policy(SET CMP0068 NEW)
cmake_policy(SET CMP0042 NEW)
add_library(foo SHARED empty.cpp)
set_target_properties(foo PROPERTIES INSTALL_NAME_DIR "@rpath" INSTALL_RPATH "@loader_path/" BUILD_WITH_INSTALL_RPATH 1)

View File

@@ -0,0 +1 @@
0

View File

@@ -0,0 +1,6 @@
cmake_policy(SET CMP0068 OLD)
cmake_policy(SET CMP0042 NEW)
add_library(foo SHARED empty.cpp)
set_target_properties(foo PROPERTIES INSTALL_NAME_DIR "@rpath" INSTALL_RPATH "@loader_path/" BUILD_WITH_INSTALL_RPATH 1)

View File

@@ -0,0 +1 @@
0

View File

@@ -0,0 +1,12 @@
CMake Warning \(dev\):
Policy CMP0068 is not set: RPATH settings on macOS do not affect
install_name. Run "cmake --help-policy CMP0068" for policy details. Use
the cmake_policy command to set the policy and suppress this warning.
For compatibility with older versions of CMake, the install_name fields for
the following targets are still affected by RPATH settings:
foo3
foo4
This warning is for project developers. Use -Wno-dev to suppress it.

View File

@@ -0,0 +1,12 @@
cmake_policy(SET CMP0042 NEW)
add_library(foo SHARED empty.cpp)
add_library(foo-static STATIC empty.cpp)
add_library(foo2 SHARED empty.cpp)
set_target_properties(foo2 PROPERTIES MACOSX_RPATH 1)
add_library(foo3 SHARED empty.cpp)
set_target_properties(foo3 PROPERTIES BUILD_WITH_INSTALL_RPATH 1 INSTALL_NAME_DIR "@loader_path")
add_library(foo4 SHARED empty.cpp)
set_target_properties(foo4 PROPERTIES BUILD_WITH_INSTALL_RPATH 1 INSTALL_NAME_DIR "@rpath")
add_library(foo5 SHARED empty.cpp)
set_target_properties(foo5 PROPERTIES BUILD_WITH_INSTALL_RPATH 1 BUILD_WITH_INSTALL_NAME_DIR 1 INSTALL_NAME_DIR "@rpath")

View File

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

View File

@@ -0,0 +1,5 @@
include(RunCMake)
run_cmake(CMP0068-OLD)
run_cmake(CMP0068-NEW)
run_cmake(CMP0068-WARN)

View File

@@ -0,0 +1,7 @@
#ifdef _WIN32
__declspec(dllexport)
#endif
int empty()
{
return 0;
}

View File

@@ -104,6 +104,9 @@ add_RunCMake_test(CMP0057)
add_RunCMake_test(CMP0059) add_RunCMake_test(CMP0059)
add_RunCMake_test(CMP0060) add_RunCMake_test(CMP0060)
add_RunCMake_test(CMP0064) add_RunCMake_test(CMP0064)
if(CMAKE_SYSTEM_NAME MATCHES Darwin AND CMAKE_SHARED_LIBRARY_RUNTIME_C_FLAG)
add_RunCMake_test(CMP0068)
endif()
# The test for Policy 65 requires the use of the # The test for Policy 65 requires the use of the
# CMAKE_SHARED_LIBRARY_LINK_CXX_FLAGS variable, which both the VS and Xcode # CMAKE_SHARED_LIBRARY_LINK_CXX_FLAGS variable, which both the VS and Xcode

View File

@@ -20,6 +20,7 @@
\* CMP0060 \* CMP0060
\* CMP0063 \* CMP0063
\* CMP0065 \* CMP0065
\* CMP0068
Call Stack \(most recent call first\): Call Stack \(most recent call first\):
CMakeLists.txt:3 \(include\) CMakeLists.txt:3 \(include\)

View File

@@ -1,5 +1,6 @@
enable_language(C) enable_language(C)
set(CMAKE_BUILD_WITH_INSTALL_RPATH 1) set(CMAKE_BUILD_WITH_INSTALL_RPATH 1)
set(CMAKE_BUILD_WITH_INSTALL_NAME_DIR 1)
add_subdirectory(EXPORT-OldIFace) add_subdirectory(EXPORT-OldIFace)
add_library(foo SHARED empty.c) add_library(foo SHARED empty.c)
target_link_libraries(foo bar) target_link_libraries(foo bar)