OS X: Add CMP0042 to enable MACOSX_RPATH by default

Also adding documentation for CMAKE_MACOSX_RPATH, and improving
documentation for MACOSX_RPATH.
This commit is contained in:
Clinton Stimpson 2013-12-18 21:25:29 -07:00 committed by Brad King
parent 2a384e08cc
commit d25ad482e9
30 changed files with 223 additions and 14 deletions

View File

@ -75,3 +75,4 @@ All Policies
/policy/CMP0039 /policy/CMP0039
/policy/CMP0040 /policy/CMP0040
/policy/CMP0041 /policy/CMP0041
/policy/CMP0042

View File

@ -207,6 +207,7 @@ Variables that Control the Build
/variable/CMAKE_LINK_LIBRARY_FILE_FLAG /variable/CMAKE_LINK_LIBRARY_FILE_FLAG
/variable/CMAKE_LINK_LIBRARY_FLAG /variable/CMAKE_LINK_LIBRARY_FLAG
/variable/CMAKE_MACOSX_BUNDLE /variable/CMAKE_MACOSX_BUNDLE
/variable/CMAKE_MACOSX_RPATH
/variable/CMAKE_MAP_IMPORTED_CONFIG_CONFIG /variable/CMAKE_MAP_IMPORTED_CONFIG_CONFIG
/variable/CMAKE_MODULE_LINKER_FLAGS_CONFIG /variable/CMAKE_MODULE_LINKER_FLAGS_CONFIG
/variable/CMAKE_MODULE_LINKER_FLAGS /variable/CMAKE_MODULE_LINKER_FLAGS

19
Help/policy/CMP0042.rst Normal file
View File

@ -0,0 +1,19 @@
CMP0042
-------
:prop_tgt:`MACOSX_RPATH` is enabled by default.
CMake 2.8.12 and newer has support for using ``@rpath`` in a target's install
name. This was enabled by setting the target property
:prop_tgt:`MACOSX_RPATH`. The ``@rpath`` in an install name is a more
flexible and powerful mechanism than ``@executable_path`` or ``@loader_path``
for locating shared libraries.
CMake 3.0.0 and later prefer this property to be ON by default. Projects
wanting ``@rpath`` in a target's install name may remove any setting of
the :prop_tgt:`INSTALL_NAME_DIR` and :variable:`CMAKE_INSTALL_NAME_DIR`
variables.
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.

View File

@ -4,7 +4,15 @@ MACOSX_RPATH
Whether to use rpaths on Mac OS X. Whether to use rpaths on Mac OS X.
When this property is set to true, the directory portion of When this property is set to true, the directory portion of
the"install_name" field of shared libraries will default to the "install_name" field of shared libraries will be ``@rpath``
"@rpath".Runtime paths will also be embedded in binaries using this unless overridden by :prop_tgt:`INSTALL_NAME_DIR`. Runtime
target.This property is initialized by the value of the variable paths will also be embedded in binaries using this target and
CMAKE_MACOSX_RPATH if it is set when a target is created. can be controlled by the :prop_tgt:`INSTALL_RPATH` target property.
This property is initialized by the value of the variable
:variable:`CMAKE_MACOSX_RPATH` if it is set when a target is
created.
Policy CMP0042 was introduced to change the default value of
MACOSX_RPATH to ON. This is because use of ``@rpath`` is a
more flexible and powerful alternative to ``@executable_path`` and
``@loader_path``.

View File

@ -0,0 +1,7 @@
CMAKE_MACOSX_RPATH
-------------------
Whether to use rpaths on Mac OS X.
This variable is used to initialize the :prop_tgt:`MACOSX_RPATH` property on
all targets.

View File

@ -1751,7 +1751,7 @@ cmComputeLinkInformation::AddLibraryRuntimeInfo(std::string const& fullPath,
// @loader_path or full paths. // @loader_path or full paths.
if(this->Makefile->IsOn("CMAKE_PLATFORM_HAS_INSTALLNAME")) if(this->Makefile->IsOn("CMAKE_PLATFORM_HAS_INSTALLNAME"))
{ {
if(!target->HasMacOSXRpath(this->Config)) if(!target->HasMacOSXRpathInstallNameDir(this->Config))
{ {
return; return;
} }

View File

@ -1045,6 +1045,12 @@ cmGlobalGenerator::GetExportedTargetsFile(const std::string &filename) const
return it == this->BuildExportSets.end() ? 0 : it->second; return it == this->BuildExportSets.end() ? 0 : it->second;
} }
//----------------------------------------------------------------------------
void cmGlobalGenerator::AddCMP0042WarnTarget(const std::string& target)
{
this->CMP0042WarnTargets.insert(target);
}
bool cmGlobalGenerator::CheckALLOW_DUPLICATE_CUSTOM_TARGETS() bool cmGlobalGenerator::CheckALLOW_DUPLICATE_CUSTOM_TARGETS()
{ {
// If the property is not enabled then okay. // If the property is not enabled then okay.
@ -1072,6 +1078,9 @@ void cmGlobalGenerator::Generate()
// Start with an empty vector: // Start with an empty vector:
this->FilesReplacedDuringGenerate.clear(); this->FilesReplacedDuringGenerate.clear();
// clear targets to issue warning CMP0042 for
this->CMP0042WarnTargets.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())
{ {
@ -1203,6 +1212,25 @@ void cmGlobalGenerator::Generate()
this->ExtraGenerator->Generate(); this->ExtraGenerator->Generate();
} }
if(!this->CMP0042WarnTargets.empty())
{
cmOStringStream w;
w <<
(this->GetCMakeInstance()->GetPolicies()->
GetPolicyWarning(cmPolicies::CMP0042)) << "\n";
w << "MACOSX_RPATH is not specified for"
" the following targets:\n";
for(std::set<std::string>::iterator
iter = this->CMP0042WarnTargets.begin();
iter != this->CMP0042WarnTargets.end();
++iter)
{
w << " " << *iter << "\n";
}
this->GetCMakeInstance()->IssueMessage(cmake::AUTHOR_WARNING, w.str(),
cmListFileBacktrace());
}
this->CMakeInstance->UpdateProgress("Generating done", -1); this->CMakeInstance->UpdateProgress("Generating done", -1);
} }

View File

@ -315,6 +315,8 @@ public:
bool GenerateImportFile(const std::string &file); bool GenerateImportFile(const std::string &file);
cmExportBuildFileGenerator* cmExportBuildFileGenerator*
GetExportedTargetsFile(const std::string &filename) const; GetExportedTargetsFile(const std::string &filename) const;
void AddCMP0042WarnTarget(const std::string& target);
protected: protected:
typedef std::vector<cmLocalGenerator*> GeneratorVector; typedef std::vector<cmLocalGenerator*> GeneratorVector;
// for a project collect all its targets by following depend // for a project collect all its targets by following depend
@ -446,6 +448,9 @@ private:
// Set of binary directories on disk. // Set of binary directories on disk.
std::set<cmStdString> BinaryDirectories; std::set<cmStdString> BinaryDirectories;
// track targets to issue CMP0042 warning for.
std::set<std::string> CMP0042WarnTargets;
}; };
#endif #endif

View File

@ -12,6 +12,7 @@
#include "cmLocalXCodeGenerator.h" #include "cmLocalXCodeGenerator.h"
#include "cmGlobalXCodeGenerator.h" #include "cmGlobalXCodeGenerator.h"
#include "cmSourceFile.h" #include "cmSourceFile.h"
#include "cmMakefile.h"
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
cmLocalXCodeGenerator::cmLocalXCodeGenerator() cmLocalXCodeGenerator::cmLocalXCodeGenerator()
@ -42,3 +43,31 @@ void cmLocalXCodeGenerator::AppendFlagEscape(std::string& flags,
static_cast<cmGlobalXCodeGenerator*>(this->GlobalGenerator); static_cast<cmGlobalXCodeGenerator*>(this->GlobalGenerator);
gg->AppendFlag(flags, rawFlag); gg->AppendFlag(flags, rawFlag);
} }
//----------------------------------------------------------------------------
void cmLocalXCodeGenerator::Generate()
{
cmLocalGenerator::Generate();
cmTargets& targets = this->Makefile->GetTargets();
for(cmTargets::iterator iter = targets.begin();
iter != targets.end(); ++iter)
{
cmTarget* t = &iter->second;
t->HasMacOSXRpathInstallNameDir(NULL);
}
}
//----------------------------------------------------------------------------
void cmLocalXCodeGenerator::GenerateInstallRules()
{
cmLocalGenerator::GenerateInstallRules();
cmTargets& targets = this->Makefile->GetTargets();
for(cmTargets::iterator iter = targets.begin();
iter != targets.end(); ++iter)
{
cmTarget* t = &iter->second;
t->HasMacOSXRpathInstallNameDir(NULL);
}
}

View File

@ -29,6 +29,8 @@ public:
virtual ~cmLocalXCodeGenerator(); virtual ~cmLocalXCodeGenerator();
virtual std::string GetTargetDirectory(cmTarget const& target) const; virtual std::string GetTargetDirectory(cmTarget const& target) const;
virtual void AppendFlagEscape(std::string& flags, const char* rawFlag); virtual void AppendFlagEscape(std::string& flags, const char* rawFlag);
virtual void Generate();
virtual void GenerateInstallRules();
private: private:
}; };

View File

@ -311,6 +311,11 @@ cmPolicies::cmPolicies()
CMP0041, "CMP0041", CMP0041, "CMP0041",
"Error on relative include with generator expression.", "Error on relative include with generator expression.",
3,0,0,0, cmPolicies::WARN); 3,0,0,0, cmPolicies::WARN);
this->DefinePolicy(
CMP0042, "CMP0042",
"MACOSX_RPATH is enabled by default.",
3,0,0,0, cmPolicies::WARN);
} }
cmPolicies::~cmPolicies() cmPolicies::~cmPolicies()

View File

@ -95,6 +95,7 @@ public:
CMP0040, ///< The target in the TARGET signature of CMP0040, ///< The target in the TARGET signature of
/// add_custom_command() must exist. /// add_custom_command() must exist.
CMP0041, ///< Error on relative include with generator expression CMP0041, ///< Error on relative include with generator expression
CMP0042, ///< Enable MACOSX_RPATH by default
/** \brief Always the last entry. /** \brief Always the last entry.
* *

View File

@ -3185,13 +3185,17 @@ std::string cmTarget::GetSOName(const char* config) const
} }
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
bool cmTarget::HasMacOSXRpath(const char* config) const bool cmTarget::HasMacOSXRpathInstallNameDir(const char* config) const
{ {
bool install_name_is_rpath = false; bool install_name_is_rpath = false;
bool macosx_rpath = this->GetPropertyAsBool("MACOSX_RPATH"); bool macosx_rpath = false;
if(!this->IsImportedTarget) if(!this->IsImportedTarget)
{ {
if(this->GetType() != cmTarget::SHARED_LIBRARY)
{
return false;
}
const char* install_name = this->GetProperty("INSTALL_NAME_DIR"); const char* install_name = this->GetProperty("INSTALL_NAME_DIR");
bool use_install_name = bool use_install_name =
this->GetPropertyAsBool("BUILD_WITH_INSTALL_RPATH"); this->GetPropertyAsBool("BUILD_WITH_INSTALL_RPATH");
@ -3204,6 +3208,10 @@ bool cmTarget::HasMacOSXRpath(const char* config) const
{ {
return false; return false;
} }
if(!install_name_is_rpath)
{
macosx_rpath = this->MacOSXRpathInstallNameDirDefault();
}
} }
else else
{ {
@ -3257,6 +3265,37 @@ bool cmTarget::HasMacOSXRpath(const char* config) const
return true; return true;
} }
//----------------------------------------------------------------------------
bool cmTarget::MacOSXRpathInstallNameDirDefault() const
{
// we can't do rpaths when unsupported
if(!this->Makefile->IsSet("CMAKE_SHARED_LIBRARY_RUNTIME_C_FLAG"))
{
return false;
}
const char* macosx_rpath_str = this->GetProperty("MACOSX_RPATH");
if(macosx_rpath_str)
{
return this->GetPropertyAsBool("MACOSX_RPATH");
}
cmPolicies::PolicyStatus cmp0042 = this->GetPolicyStatusCMP0042();
if(cmp0042 == cmPolicies::WARN)
{
this->Makefile->GetLocalGenerator()->GetGlobalGenerator()->
AddCMP0042WarnTarget(this->GetName());
}
if(cmp0042 == cmPolicies::NEW)
{
return true;
}
return false;
}
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
bool cmTarget::IsImportedSharedLibWithoutSOName(const char* config) const bool cmTarget::IsImportedSharedLibWithoutSOName(const char* config) const
{ {
@ -3846,7 +3885,8 @@ std::string cmTarget::GetInstallNameDirForBuildTree(const char* config) const
!this->GetPropertyAsBool("SKIP_BUILD_RPATH")) !this->GetPropertyAsBool("SKIP_BUILD_RPATH"))
{ {
std::string dir; std::string dir;
if(this->GetPropertyAsBool("MACOSX_RPATH")) bool macosx_rpath = this->MacOSXRpathInstallNameDirDefault();
if(macosx_rpath)
{ {
dir = "@rpath"; dir = "@rpath";
} }
@ -3880,9 +3920,12 @@ std::string cmTarget::GetInstallNameDirForInstallTree() const
dir += "/"; dir += "/";
} }
} }
if(!install_name_dir && this->GetPropertyAsBool("MACOSX_RPATH")) if(!install_name_dir)
{ {
dir = "@rpath/"; if(this->MacOSXRpathInstallNameDirDefault())
{
dir = "@rpath/";
}
} }
return dir; return dir;
} }

View File

@ -26,7 +26,8 @@
F(CMP0020) \ F(CMP0020) \
F(CMP0021) \ F(CMP0021) \
F(CMP0022) \ F(CMP0022) \
F(CMP0041) F(CMP0041) \
F(CMP0042)
class cmake; class cmake;
class cmMakefile; class cmMakefile;
@ -382,7 +383,10 @@ public:
std::string GetSOName(const char* config) const; std::string GetSOName(const char* config) const;
/** Whether this library has \@rpath and platform supports it. */ /** Whether this library has \@rpath and platform supports it. */
bool HasMacOSXRpath(const char* config) const; bool HasMacOSXRpathInstallNameDir(const char* config) const;
/** Whether this library defaults to \@rpath. */
bool MacOSXRpathInstallNameDirDefault() const;
/** Test for special case of a third-party shared library that has /** Test for special case of a third-party shared library that has
no soname at all. */ no soname at all. */

View File

@ -10,13 +10,15 @@ add_library(shared2 SHARED shared.cpp shared.h)
set_target_properties(shared2 PROPERTIES set_target_properties(shared2 PROPERTIES
BUILD_WITH_INSTALL_RPATH 1 INSTALL_NAME_DIR "@rpath") BUILD_WITH_INSTALL_RPATH 1 INSTALL_NAME_DIR "@rpath")
cmake_policy(SET CMP0042 NEW)
# a framework library # a framework library
add_library(framework SHARED framework.cpp framework.h) add_library(framework SHARED framework.cpp framework.h)
set_target_properties(framework PROPERTIES MACOSX_RPATH 1 FRAMEWORK 1) set_target_properties(framework PROPERTIES FRAMEWORK 1)
# another framework # another framework
add_library(framework2 SHARED framework2.cpp framework2.h) add_library(framework2 SHARED framework2.cpp framework2.h)
set_target_properties(framework2 PROPERTIES MACOSX_RPATH 1 FRAMEWORK 1) set_target_properties(framework2 PROPERTIES FRAMEWORK 1)
# executable to test a shared library dependency with install rpaths # executable to test a shared library dependency with install rpaths
add_executable(test1 test1.cpp) add_executable(test1 test1.cpp)

View File

@ -1,5 +1,7 @@
enable_language(CXX) enable_language(CXX)
cmake_policy(SET CMP0042 NEW)
add_library(foo SHARED empty_vs6_1.cpp) add_library(foo SHARED empty_vs6_1.cpp)
add_library(bar SHARED empty_vs6_2.cpp) add_library(bar SHARED empty_vs6_2.cpp)
target_link_libraries(bar foo) target_link_libraries(bar foo)

View File

@ -1,6 +1,8 @@
project(CMP0022-WARN) project(CMP0022-WARN)
cmake_policy(SET CMP0042 NEW)
add_library(foo SHARED empty_vs6_1.cpp) add_library(foo SHARED empty_vs6_1.cpp)
add_library(bar SHARED empty_vs6_2.cpp) add_library(bar SHARED empty_vs6_2.cpp)
add_library(bat SHARED empty_vs6_3.cpp) add_library(bat SHARED empty_vs6_3.cpp)

View File

@ -0,0 +1 @@
0

View File

@ -0,0 +1 @@
^$

View File

@ -0,0 +1,4 @@
cmake_policy(SET CMP0042 NEW)
add_library(foo SHARED empty.cpp)

View File

@ -0,0 +1 @@
0

View File

@ -0,0 +1 @@
^$

View File

@ -0,0 +1,4 @@
cmake_policy(SET CMP0042 OLD)
add_library(foo SHARED empty.cpp)

View File

@ -0,0 +1 @@
0

View File

@ -0,0 +1,10 @@
CMake Warning \(dev\):
Policy CMP0042 is not set: MACOSX_RPATH is enabled by default. Run "cmake
--help-policy CMP0042" for policy details. Use the cmake_policy command to
set the policy and suppress this warning.
MACOSX_RPATH is not specified for the following targets:
foo
This warning is for project developers. Use -Wno-dev to suppress it.

View File

@ -0,0 +1,9 @@
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")

View File

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

View File

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

View File

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

View File

@ -61,6 +61,9 @@ add_RunCMake_test(CMP0038)
add_RunCMake_test(CMP0039) add_RunCMake_test(CMP0039)
add_RunCMake_test(CMP0040) add_RunCMake_test(CMP0040)
add_RunCMake_test(CMP0041) add_RunCMake_test(CMP0041)
if(CMAKE_SYSTEM_NAME MATCHES Darwin AND CMAKE_SHARED_LIBRARY_RUNTIME_C_FLAG)
add_RunCMake_test(CMP0042)
endif()
add_RunCMake_test(CTest) add_RunCMake_test(CTest)
if(UNIX AND "${CMAKE_TEST_GENERATOR}" MATCHES "Unix Makefiles") if(UNIX AND "${CMAKE_TEST_GENERATOR}" MATCHES "Unix Makefiles")
add_RunCMake_test(CompilerChange) add_RunCMake_test(CompilerChange)