diff options
30 files changed, 223 insertions, 14 deletions
diff --git a/Help/manual/cmake-policies.7.rst b/Help/manual/cmake-policies.7.rst index 5e94f891cb..1e57495228 100644 --- a/Help/manual/cmake-policies.7.rst +++ b/Help/manual/cmake-policies.7.rst @@ -75,3 +75,4 @@ All Policies /policy/CMP0039 /policy/CMP0040 /policy/CMP0041 + /policy/CMP0042 diff --git a/Help/manual/cmake-variables.7.rst b/Help/manual/cmake-variables.7.rst index d86db37df2..aebfe87aec 100644 --- a/Help/manual/cmake-variables.7.rst +++ b/Help/manual/cmake-variables.7.rst @@ -207,6 +207,7 @@ Variables that Control the Build /variable/CMAKE_LINK_LIBRARY_FILE_FLAG /variable/CMAKE_LINK_LIBRARY_FLAG /variable/CMAKE_MACOSX_BUNDLE + /variable/CMAKE_MACOSX_RPATH /variable/CMAKE_MAP_IMPORTED_CONFIG_CONFIG /variable/CMAKE_MODULE_LINKER_FLAGS_CONFIG /variable/CMAKE_MODULE_LINKER_FLAGS diff --git a/Help/policy/CMP0042.rst b/Help/policy/CMP0042.rst new file mode 100644 index 0000000000..0ed3bd1e8f --- /dev/null +++ b/Help/policy/CMP0042.rst @@ -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. diff --git a/Help/prop_tgt/MACOSX_RPATH.rst b/Help/prop_tgt/MACOSX_RPATH.rst index f2d807865e..d3934bae28 100644 --- a/Help/prop_tgt/MACOSX_RPATH.rst +++ b/Help/prop_tgt/MACOSX_RPATH.rst @@ -4,7 +4,15 @@ MACOSX_RPATH Whether to use rpaths on Mac OS X. When this property is set to true, the directory portion of -the"install_name" field of shared libraries will default to -"@rpath".Runtime paths will also be embedded in binaries using this -target.This property is initialized by the value of the variable -CMAKE_MACOSX_RPATH if it is set when a target is created. +the "install_name" field of shared libraries will be ``@rpath`` +unless overridden by :prop_tgt:`INSTALL_NAME_DIR`. Runtime +paths will also be embedded in binaries using this target and +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``. diff --git a/Help/variable/CMAKE_MACOSX_RPATH.rst b/Help/variable/CMAKE_MACOSX_RPATH.rst new file mode 100644 index 0000000000..ac897c0f72 --- /dev/null +++ b/Help/variable/CMAKE_MACOSX_RPATH.rst @@ -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. diff --git a/Source/cmComputeLinkInformation.cxx b/Source/cmComputeLinkInformation.cxx index 0ef3d2e350..1e21216b2f 100644 --- a/Source/cmComputeLinkInformation.cxx +++ b/Source/cmComputeLinkInformation.cxx @@ -1751,7 +1751,7 @@ cmComputeLinkInformation::AddLibraryRuntimeInfo(std::string const& fullPath, // @loader_path or full paths. if(this->Makefile->IsOn("CMAKE_PLATFORM_HAS_INSTALLNAME")) { - if(!target->HasMacOSXRpath(this->Config)) + if(!target->HasMacOSXRpathInstallNameDir(this->Config)) { return; } diff --git a/Source/cmGlobalGenerator.cxx b/Source/cmGlobalGenerator.cxx index e6f3d94358..3ed612dd94 100644 --- a/Source/cmGlobalGenerator.cxx +++ b/Source/cmGlobalGenerator.cxx @@ -1045,6 +1045,12 @@ cmGlobalGenerator::GetExportedTargetsFile(const std::string &filename) const 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() { // If the property is not enabled then okay. @@ -1072,6 +1078,9 @@ void cmGlobalGenerator::Generate() // Start with an empty vector: this->FilesReplacedDuringGenerate.clear(); + // clear targets to issue warning CMP0042 for + this->CMP0042WarnTargets.clear(); + // Check whether this generator is allowed to run. if(!this->CheckALLOW_DUPLICATE_CUSTOM_TARGETS()) { @@ -1203,6 +1212,25 @@ void cmGlobalGenerator::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); } diff --git a/Source/cmGlobalGenerator.h b/Source/cmGlobalGenerator.h index eb720a82ca..b21bc8bb6d 100644 --- a/Source/cmGlobalGenerator.h +++ b/Source/cmGlobalGenerator.h @@ -315,6 +315,8 @@ public: bool GenerateImportFile(const std::string &file); cmExportBuildFileGenerator* GetExportedTargetsFile(const std::string &filename) const; + void AddCMP0042WarnTarget(const std::string& target); + protected: typedef std::vector<cmLocalGenerator*> GeneratorVector; // for a project collect all its targets by following depend @@ -446,6 +448,9 @@ private: // Set of binary directories on disk. std::set<cmStdString> BinaryDirectories; + + // track targets to issue CMP0042 warning for. + std::set<std::string> CMP0042WarnTargets; }; #endif diff --git a/Source/cmLocalXCodeGenerator.cxx b/Source/cmLocalXCodeGenerator.cxx index 7c5f69df5f..a9a27b90c1 100644 --- a/Source/cmLocalXCodeGenerator.cxx +++ b/Source/cmLocalXCodeGenerator.cxx @@ -12,6 +12,7 @@ #include "cmLocalXCodeGenerator.h" #include "cmGlobalXCodeGenerator.h" #include "cmSourceFile.h" +#include "cmMakefile.h" //---------------------------------------------------------------------------- cmLocalXCodeGenerator::cmLocalXCodeGenerator() @@ -42,3 +43,31 @@ void cmLocalXCodeGenerator::AppendFlagEscape(std::string& flags, static_cast<cmGlobalXCodeGenerator*>(this->GlobalGenerator); 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); + } +} diff --git a/Source/cmLocalXCodeGenerator.h b/Source/cmLocalXCodeGenerator.h index d97a41cea6..edd2f5ba27 100644 --- a/Source/cmLocalXCodeGenerator.h +++ b/Source/cmLocalXCodeGenerator.h @@ -29,6 +29,8 @@ public: virtual ~cmLocalXCodeGenerator(); virtual std::string GetTargetDirectory(cmTarget const& target) const; virtual void AppendFlagEscape(std::string& flags, const char* rawFlag); + virtual void Generate(); + virtual void GenerateInstallRules(); private: }; diff --git a/Source/cmPolicies.cxx b/Source/cmPolicies.cxx index 0b3018eb65..987c66356d 100644 --- a/Source/cmPolicies.cxx +++ b/Source/cmPolicies.cxx @@ -311,6 +311,11 @@ cmPolicies::cmPolicies() CMP0041, "CMP0041", "Error on relative include with generator expression.", 3,0,0,0, cmPolicies::WARN); + + this->DefinePolicy( + CMP0042, "CMP0042", + "MACOSX_RPATH is enabled by default.", + 3,0,0,0, cmPolicies::WARN); } cmPolicies::~cmPolicies() diff --git a/Source/cmPolicies.h b/Source/cmPolicies.h index 245ec4b1de..66eaf87571 100644 --- a/Source/cmPolicies.h +++ b/Source/cmPolicies.h @@ -95,6 +95,7 @@ public: CMP0040, ///< The target in the TARGET signature of /// add_custom_command() must exist. CMP0041, ///< Error on relative include with generator expression + CMP0042, ///< Enable MACOSX_RPATH by default /** \brief Always the last entry. * diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx index 38fe945e08..9ea7f07adc 100644 --- a/Source/cmTarget.cxx +++ b/Source/cmTarget.cxx @@ -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 macosx_rpath = this->GetPropertyAsBool("MACOSX_RPATH"); + bool macosx_rpath = false; if(!this->IsImportedTarget) { + if(this->GetType() != cmTarget::SHARED_LIBRARY) + { + return false; + } const char* install_name = this->GetProperty("INSTALL_NAME_DIR"); bool use_install_name = this->GetPropertyAsBool("BUILD_WITH_INSTALL_RPATH"); @@ -3204,6 +3208,10 @@ bool cmTarget::HasMacOSXRpath(const char* config) const { return false; } + if(!install_name_is_rpath) + { + macosx_rpath = this->MacOSXRpathInstallNameDirDefault(); + } } else { @@ -3258,6 +3266,37 @@ bool cmTarget::HasMacOSXRpath(const char* config) const } //---------------------------------------------------------------------------- +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 { if(this->IsImported() && this->GetType() == cmTarget::SHARED_LIBRARY) @@ -3846,7 +3885,8 @@ std::string cmTarget::GetInstallNameDirForBuildTree(const char* config) const !this->GetPropertyAsBool("SKIP_BUILD_RPATH")) { std::string dir; - if(this->GetPropertyAsBool("MACOSX_RPATH")) + bool macosx_rpath = this->MacOSXRpathInstallNameDirDefault(); + if(macosx_rpath) { dir = "@rpath"; } @@ -3880,9 +3920,12 @@ std::string cmTarget::GetInstallNameDirForInstallTree() const dir += "/"; } } - if(!install_name_dir && this->GetPropertyAsBool("MACOSX_RPATH")) + if(!install_name_dir) { - dir = "@rpath/"; + if(this->MacOSXRpathInstallNameDirDefault()) + { + dir = "@rpath/"; + } } return dir; } diff --git a/Source/cmTarget.h b/Source/cmTarget.h index 3f5a5d12f4..e43d13828d 100644 --- a/Source/cmTarget.h +++ b/Source/cmTarget.h @@ -26,7 +26,8 @@ F(CMP0020) \ F(CMP0021) \ F(CMP0022) \ - F(CMP0041) + F(CMP0041) \ + F(CMP0042) class cmake; class cmMakefile; @@ -382,7 +383,10 @@ public: std::string GetSOName(const char* config) const; /** 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 no soname at all. */ diff --git a/Tests/MacRuntimePath/A/CMakeLists.txt b/Tests/MacRuntimePath/A/CMakeLists.txt index 5fc54f4067..ade0a3cfb8 100644 --- a/Tests/MacRuntimePath/A/CMakeLists.txt +++ b/Tests/MacRuntimePath/A/CMakeLists.txt @@ -10,13 +10,15 @@ add_library(shared2 SHARED shared.cpp shared.h) set_target_properties(shared2 PROPERTIES BUILD_WITH_INSTALL_RPATH 1 INSTALL_NAME_DIR "@rpath") +cmake_policy(SET CMP0042 NEW) + # a framework library 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 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 add_executable(test1 test1.cpp) diff --git a/Tests/RunCMake/CMP0022/CMP0022-NOWARN-shared.cmake b/Tests/RunCMake/CMP0022/CMP0022-NOWARN-shared.cmake index 57c3ed0d7c..2e76ee0df0 100644 --- a/Tests/RunCMake/CMP0022/CMP0022-NOWARN-shared.cmake +++ b/Tests/RunCMake/CMP0022/CMP0022-NOWARN-shared.cmake @@ -1,5 +1,7 @@ enable_language(CXX) +cmake_policy(SET CMP0042 NEW) + add_library(foo SHARED empty_vs6_1.cpp) add_library(bar SHARED empty_vs6_2.cpp) target_link_libraries(bar foo) diff --git a/Tests/RunCMake/CMP0022/CMP0022-WARN.cmake b/Tests/RunCMake/CMP0022/CMP0022-WARN.cmake index fe7e858b7a..e3552b2f04 100644 --- a/Tests/RunCMake/CMP0022/CMP0022-WARN.cmake +++ b/Tests/RunCMake/CMP0022/CMP0022-WARN.cmake @@ -1,6 +1,8 @@ project(CMP0022-WARN) +cmake_policy(SET CMP0042 NEW) + add_library(foo SHARED empty_vs6_1.cpp) add_library(bar SHARED empty_vs6_2.cpp) add_library(bat SHARED empty_vs6_3.cpp) diff --git a/Tests/RunCMake/CMP0042/CMP0042-NEW-result.txt b/Tests/RunCMake/CMP0042/CMP0042-NEW-result.txt new file mode 100644 index 0000000000..573541ac97 --- /dev/null +++ b/Tests/RunCMake/CMP0042/CMP0042-NEW-result.txt @@ -0,0 +1 @@ +0 diff --git a/Tests/RunCMake/CMP0042/CMP0042-NEW-stderr.txt b/Tests/RunCMake/CMP0042/CMP0042-NEW-stderr.txt new file mode 100644 index 0000000000..10f32932ee --- /dev/null +++ b/Tests/RunCMake/CMP0042/CMP0042-NEW-stderr.txt @@ -0,0 +1 @@ +^$ diff --git a/Tests/RunCMake/CMP0042/CMP0042-NEW.cmake b/Tests/RunCMake/CMP0042/CMP0042-NEW.cmake new file mode 100644 index 0000000000..778a444311 --- /dev/null +++ b/Tests/RunCMake/CMP0042/CMP0042-NEW.cmake @@ -0,0 +1,4 @@ + +cmake_policy(SET CMP0042 NEW) + +add_library(foo SHARED empty.cpp) diff --git a/Tests/RunCMake/CMP0042/CMP0042-OLD-result.txt b/Tests/RunCMake/CMP0042/CMP0042-OLD-result.txt new file mode 100644 index 0000000000..573541ac97 --- /dev/null +++ b/Tests/RunCMake/CMP0042/CMP0042-OLD-result.txt @@ -0,0 +1 @@ +0 diff --git a/Tests/RunCMake/CMP0042/CMP0042-OLD-stderr.txt b/Tests/RunCMake/CMP0042/CMP0042-OLD-stderr.txt new file mode 100644 index 0000000000..10f32932ee --- /dev/null +++ b/Tests/RunCMake/CMP0042/CMP0042-OLD-stderr.txt @@ -0,0 +1 @@ +^$ diff --git a/Tests/RunCMake/CMP0042/CMP0042-OLD.cmake b/Tests/RunCMake/CMP0042/CMP0042-OLD.cmake new file mode 100644 index 0000000000..1aede967c2 --- /dev/null +++ b/Tests/RunCMake/CMP0042/CMP0042-OLD.cmake @@ -0,0 +1,4 @@ + +cmake_policy(SET CMP0042 OLD) + +add_library(foo SHARED empty.cpp) diff --git a/Tests/RunCMake/CMP0042/CMP0042-WARN-result.txt b/Tests/RunCMake/CMP0042/CMP0042-WARN-result.txt new file mode 100644 index 0000000000..573541ac97 --- /dev/null +++ b/Tests/RunCMake/CMP0042/CMP0042-WARN-result.txt @@ -0,0 +1 @@ +0 diff --git a/Tests/RunCMake/CMP0042/CMP0042-WARN-stderr.txt b/Tests/RunCMake/CMP0042/CMP0042-WARN-stderr.txt new file mode 100644 index 0000000000..f3574a1a56 --- /dev/null +++ b/Tests/RunCMake/CMP0042/CMP0042-WARN-stderr.txt @@ -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. diff --git a/Tests/RunCMake/CMP0042/CMP0042-WARN.cmake b/Tests/RunCMake/CMP0042/CMP0042-WARN.cmake new file mode 100644 index 0000000000..3fa32b16ff --- /dev/null +++ b/Tests/RunCMake/CMP0042/CMP0042-WARN.cmake @@ -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") diff --git a/Tests/RunCMake/CMP0042/CMakeLists.txt b/Tests/RunCMake/CMP0042/CMakeLists.txt new file mode 100644 index 0000000000..11ea636d04 --- /dev/null +++ b/Tests/RunCMake/CMP0042/CMakeLists.txt @@ -0,0 +1,3 @@ +cmake_minimum_required(VERSION 2.8) +project(${RunCMake_TEST} CXX) +include(${RunCMake_TEST}.cmake NO_POLICY_SCOPE) diff --git a/Tests/RunCMake/CMP0042/RunCMakeTest.cmake b/Tests/RunCMake/CMP0042/RunCMakeTest.cmake new file mode 100644 index 0000000000..3b226d74cb --- /dev/null +++ b/Tests/RunCMake/CMP0042/RunCMakeTest.cmake @@ -0,0 +1,5 @@ +include(RunCMake) + +run_cmake(CMP0042-OLD) +run_cmake(CMP0042-NEW) +run_cmake(CMP0042-WARN) diff --git a/Tests/RunCMake/CMP0042/empty.cpp b/Tests/RunCMake/CMP0042/empty.cpp new file mode 100644 index 0000000000..bfbbddeb90 --- /dev/null +++ b/Tests/RunCMake/CMP0042/empty.cpp @@ -0,0 +1,7 @@ +#ifdef _WIN32 +__declspec(dllexport) +#endif +int empty() +{ + return 0; +} diff --git a/Tests/RunCMake/CMakeLists.txt b/Tests/RunCMake/CMakeLists.txt index 96b054382e..96724ce880 100644 --- a/Tests/RunCMake/CMakeLists.txt +++ b/Tests/RunCMake/CMakeLists.txt @@ -61,6 +61,9 @@ add_RunCMake_test(CMP0038) add_RunCMake_test(CMP0039) add_RunCMake_test(CMP0040) 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) if(UNIX AND "${CMAKE_TEST_GENERATOR}" MATCHES "Unix Makefiles") add_RunCMake_test(CompilerChange) |