Merge topic 'rpath-on-mac'
dc1d025
OS X: Add test for rpaths on Mac.8576b3f
OS X: Add support for @rpath in export files.00d71bd
Xcode: Add rpath support in Xcode generator.94e7fef
OS X: Add RPATH support for Mac.
This commit is contained in:
commit
3caf565d07
|
@ -30,6 +30,11 @@ set(CMAKE_SHARED_MODULE_SUFFIX ".so")
|
|||
set(CMAKE_MODULE_EXISTS 1)
|
||||
set(CMAKE_DL_LIBS "")
|
||||
|
||||
# Enable rpath support for 10.5 and greater where it is known to work.
|
||||
if("${DARWIN_MAJOR_VERSION}" GREATER 8)
|
||||
set(CMAKE_SHARED_LIBRARY_RUNTIME_C_FLAG "-Wl,-rpath,")
|
||||
endif()
|
||||
|
||||
set(CMAKE_C_OSX_COMPATIBILITY_VERSION_FLAG "-compatibility_version ")
|
||||
set(CMAKE_C_OSX_CURRENT_VERSION_FLAG "-current_version ")
|
||||
set(CMAKE_CXX_OSX_COMPATIBILITY_VERSION_FLAG "${CMAKE_C_OSX_COMPATIBILITY_VERSION_FLAG}")
|
||||
|
|
|
@ -1730,6 +1730,17 @@ void
|
|||
cmComputeLinkInformation::AddLibraryRuntimeInfo(std::string const& fullPath,
|
||||
cmTarget* target)
|
||||
{
|
||||
// Ignore targets on Apple where install_name is not @rpath.
|
||||
// The dependenty library can be found with other means such as
|
||||
// @loader_path or full paths.
|
||||
if(this->Makefile->IsOn("CMAKE_PLATFORM_HAS_INSTALLNAME"))
|
||||
{
|
||||
if(!target->HasMacOSXRpath(this->Config))
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Libraries with unknown type must be handled using just the file
|
||||
// on disk.
|
||||
if(target->GetType() == cmTarget::UNKNOWN_LIBRARY)
|
||||
|
@ -1762,25 +1773,60 @@ void
|
|||
cmComputeLinkInformation::AddLibraryRuntimeInfo(std::string const& fullPath)
|
||||
{
|
||||
// Get the name of the library from the file name.
|
||||
bool is_shared_library = false;
|
||||
std::string file = cmSystemTools::GetFilenameName(fullPath);
|
||||
if(!this->ExtractSharedLibraryName.find(file.c_str()))
|
||||
|
||||
if(this->Makefile->IsOn("CMAKE_PLATFORM_HAS_INSTALLNAME"))
|
||||
{
|
||||
// Check that @rpath is part of the install name.
|
||||
// If it isn't, return.
|
||||
std::string soname;
|
||||
if(!cmSystemTools::GuessLibraryInstallName(fullPath, soname))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if(soname.find("@rpath") == std::string::npos)
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
is_shared_library = this->ExtractSharedLibraryName.find(file.c_str());
|
||||
|
||||
if(!is_shared_library)
|
||||
{
|
||||
// On some platforms (AIX) a shared library may look static.
|
||||
if(this->ArchivesMayBeShared)
|
||||
{
|
||||
if(!this->ExtractStaticLibraryName.find(file.c_str()))
|
||||
if(this->ExtractStaticLibraryName.find(file.c_str()))
|
||||
{
|
||||
// This is not the name of a shared library or archive.
|
||||
return;
|
||||
// This is the name of a shared library or archive.
|
||||
is_shared_library = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
}
|
||||
|
||||
// It could be an Apple framework
|
||||
if(!is_shared_library)
|
||||
{
|
||||
if(fullPath.find(".framework") != std::string::npos)
|
||||
{
|
||||
// This is not the name of a shared library.
|
||||
return;
|
||||
cmsys::RegularExpression splitFramework;
|
||||
splitFramework.compile("^(.*)/(.*).framework/.*/(.*)$");
|
||||
if(splitFramework.find(fullPath) &&
|
||||
(splitFramework.match(2) == splitFramework.match(3)))
|
||||
{
|
||||
is_shared_library = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(!is_shared_library)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Include this library in the runtime path ordering.
|
||||
this->OrderRuntimeSearchPath->AddRuntimeLibrary(fullPath);
|
||||
if(this->LinkWithRuntimePath)
|
||||
|
|
|
@ -211,3 +211,19 @@ cmExportBuildFileGenerator
|
|||
<< "consider using the APPEND option with multiple separate calls.";
|
||||
this->ExportCommand->ErrorMessage = e.str();
|
||||
}
|
||||
|
||||
std::string
|
||||
cmExportBuildFileGenerator::InstallNameDir(cmTarget* target,
|
||||
const std::string& config)
|
||||
{
|
||||
std::string install_name_dir;
|
||||
|
||||
cmMakefile* mf = target->GetMakefile();
|
||||
if(mf->IsOn("CMAKE_PLATFORM_HAS_INSTALLNAME"))
|
||||
{
|
||||
install_name_dir =
|
||||
target->GetInstallNameDirForBuildTree(config.c_str());
|
||||
}
|
||||
|
||||
return install_name_dir;
|
||||
}
|
||||
|
|
|
@ -61,6 +61,8 @@ protected:
|
|||
cmTarget* target,
|
||||
ImportPropertyMap& properties);
|
||||
|
||||
std::string InstallNameDir(cmTarget* target, const std::string& config);
|
||||
|
||||
std::vector<cmTarget*> const* Exports;
|
||||
cmExportCommand* ExportCommand;
|
||||
};
|
||||
|
|
|
@ -624,8 +624,12 @@ cmExportFileGenerator
|
|||
std::string value;
|
||||
if(target->HasSOName(config))
|
||||
{
|
||||
if(mf->IsOn("CMAKE_PLATFORM_HAS_INSTALLNAME"))
|
||||
{
|
||||
value = this->InstallNameDir(target, config);
|
||||
}
|
||||
prop = "IMPORTED_SONAME";
|
||||
value = target->GetSOName(config);
|
||||
value += target->GetSOName(config);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -159,6 +159,9 @@ private:
|
|||
std::vector<std::string> &missingTargets);
|
||||
|
||||
virtual void ReplaceInstallPrefix(std::string &input);
|
||||
|
||||
virtual std::string InstallNameDir(cmTarget* target,
|
||||
const std::string& config) = 0;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -491,3 +491,19 @@ cmExportInstallFileGenerator
|
|||
}
|
||||
cmSystemTools::Error(e.str().c_str());
|
||||
}
|
||||
|
||||
std::string
|
||||
cmExportInstallFileGenerator::InstallNameDir(cmTarget* target,
|
||||
const std::string&)
|
||||
{
|
||||
std::string install_name_dir;
|
||||
|
||||
cmMakefile* mf = target->GetMakefile();
|
||||
if(mf->IsOn("CMAKE_PLATFORM_HAS_INSTALLNAME"))
|
||||
{
|
||||
install_name_dir =
|
||||
target->GetInstallNameDirForInstallTree();
|
||||
}
|
||||
|
||||
return install_name_dir;
|
||||
}
|
||||
|
|
|
@ -85,6 +85,8 @@ protected:
|
|||
|
||||
void ComplainAboutImportPrefix(cmInstallTargetGenerator* itgen);
|
||||
|
||||
std::string InstallNameDir(cmTarget* target, const std::string& config);
|
||||
|
||||
cmInstallExportGenerator* IEGen;
|
||||
|
||||
std::string ImportPrefix;
|
||||
|
|
|
@ -112,3 +112,18 @@ cmExportTryCompileFileGenerator::PopulateProperties(cmTarget* target,
|
|||
}
|
||||
}
|
||||
}
|
||||
std::string
|
||||
cmExportTryCompileFileGenerator::InstallNameDir(cmTarget* target,
|
||||
const std::string& config)
|
||||
{
|
||||
std::string install_name_dir;
|
||||
|
||||
cmMakefile* mf = target->GetMakefile();
|
||||
if(mf->IsOn("CMAKE_PLATFORM_HAS_INSTALLNAME"))
|
||||
{
|
||||
install_name_dir =
|
||||
target->GetInstallNameDirForBuildTree(config.c_str());
|
||||
}
|
||||
|
||||
return install_name_dir;
|
||||
}
|
||||
|
|
|
@ -43,6 +43,8 @@ protected:
|
|||
ImportPropertyMap& properties,
|
||||
std::set<cmTarget*> &emitted);
|
||||
|
||||
std::string InstallNameDir(cmTarget* target,
|
||||
const std::string& config);
|
||||
private:
|
||||
std::string FindTargets(const char *prop, cmTarget *tgt,
|
||||
std::set<cmTarget*> &emitted);
|
||||
|
|
|
@ -2242,6 +2242,29 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmTarget& target,
|
|||
buildSettings->AddAttribute("INSTALL_PATH",
|
||||
this->CreateString(install_name_dir.c_str()));
|
||||
|
||||
// Create the LD_RUNPATH_SEARCH_PATHS
|
||||
cmComputeLinkInformation* pcli = target.GetLinkInformation(configName);
|
||||
if(pcli)
|
||||
{
|
||||
std::string search_paths;
|
||||
std::vector<std::string> runtimeDirs;
|
||||
pcli->GetRPath(runtimeDirs, false);
|
||||
for(std::vector<std::string>::const_iterator i = runtimeDirs.begin();
|
||||
i != runtimeDirs.end(); ++i)
|
||||
{
|
||||
if(!search_paths.empty())
|
||||
{
|
||||
search_paths += " ";
|
||||
}
|
||||
search_paths += this->XCodeEscapePath((*i).c_str());
|
||||
}
|
||||
if(!search_paths.empty())
|
||||
{
|
||||
buildSettings->AddAttribute("LD_RUNPATH_SEARCH_PATHS",
|
||||
this->CreateString(search_paths.c_str()));
|
||||
}
|
||||
}
|
||||
|
||||
buildSettings->AddAttribute("OTHER_LDFLAGS",
|
||||
this->CreateString(extraLinkOptions.c_str()));
|
||||
buildSettings->AddAttribute("OTHER_REZFLAGS",
|
||||
|
|
|
@ -606,6 +606,12 @@ cmInstallTargetGenerator
|
|||
return;
|
||||
}
|
||||
|
||||
// Skip if on Apple
|
||||
if(this->Target->GetMakefile()->IsOn("CMAKE_PLATFORM_HAS_INSTALLNAME"))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Get the link information for this target.
|
||||
// It can provide the RPATH.
|
||||
cmComputeLinkInformation* cli = this->Target->GetLinkInformation(config);
|
||||
|
@ -645,30 +651,62 @@ cmInstallTargetGenerator
|
|||
return;
|
||||
}
|
||||
|
||||
// Construct the original rpath string to be replaced.
|
||||
std::string oldRpath = cli->GetRPathString(false);
|
||||
|
||||
// Get the install RPATH from the link information.
|
||||
std::string newRpath = cli->GetChrpathString();
|
||||
|
||||
// Skip the rule if the paths are identical
|
||||
if(oldRpath == newRpath)
|
||||
if(this->Target->GetMakefile()->IsOn("CMAKE_PLATFORM_HAS_INSTALLNAME"))
|
||||
{
|
||||
return;
|
||||
}
|
||||
// If using install_name_tool, set up the rules to modify the rpaths.
|
||||
std::string installNameTool =
|
||||
this->Target->GetMakefile()->
|
||||
GetSafeDefinition("CMAKE_INSTALL_NAME_TOOL");
|
||||
|
||||
// Write a rule to run chrpath to set the install-tree RPATH
|
||||
if(newRpath.empty())
|
||||
{
|
||||
os << indent << "FILE(RPATH_REMOVE\n"
|
||||
<< indent << " FILE \"" << toDestDirPath << "\")\n";
|
||||
std::vector<std::string> oldRuntimeDirs, newRuntimeDirs;
|
||||
cli->GetRPath(oldRuntimeDirs, false);
|
||||
cli->GetRPath(newRuntimeDirs, true);
|
||||
|
||||
// Note: These are separate commands to avoid install_name_tool
|
||||
// corruption on 10.6.
|
||||
for(std::vector<std::string>::const_iterator i = oldRuntimeDirs.begin();
|
||||
i != oldRuntimeDirs.end(); ++i)
|
||||
{
|
||||
os << indent << "execute_process(COMMAND " << installNameTool << "\n";
|
||||
os << indent << " -delete_rpath \"" << *i << "\"\n";
|
||||
os << indent << " \"" << toDestDirPath << "\")\n";
|
||||
}
|
||||
|
||||
for(std::vector<std::string>::const_iterator i = newRuntimeDirs.begin();
|
||||
i != newRuntimeDirs.end(); ++i)
|
||||
{
|
||||
os << indent << "execute_process(COMMAND " << installNameTool << "\n";
|
||||
os << indent << " -add_rpath \"" << *i << "\"\n";
|
||||
os << indent << " \"" << toDestDirPath << "\")\n";
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
os << indent << "FILE(RPATH_CHANGE\n"
|
||||
<< indent << " FILE \"" << toDestDirPath << "\"\n"
|
||||
<< indent << " OLD_RPATH \"" << oldRpath << "\"\n"
|
||||
<< indent << " NEW_RPATH \"" << newRpath << "\")\n";
|
||||
// Construct the original rpath string to be replaced.
|
||||
std::string oldRpath = cli->GetRPathString(false);
|
||||
|
||||
// Get the install RPATH from the link information.
|
||||
std::string newRpath = cli->GetChrpathString();
|
||||
|
||||
// Skip the rule if the paths are identical
|
||||
if(oldRpath == newRpath)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Write a rule to run chrpath to set the install-tree RPATH
|
||||
if(newRpath.empty())
|
||||
{
|
||||
os << indent << "FILE(RPATH_REMOVE\n"
|
||||
<< indent << " FILE \"" << toDestDirPath << "\")\n";
|
||||
}
|
||||
else
|
||||
{
|
||||
os << indent << "FILE(RPATH_CHANGE\n"
|
||||
<< indent << " FILE \"" << toDestDirPath << "\"\n"
|
||||
<< indent << " OLD_RPATH \"" << oldRpath << "\"\n"
|
||||
<< indent << " NEW_RPATH \"" << newRpath << "\")\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -36,8 +36,25 @@ public:
|
|||
OD(od), GlobalGenerator(od->GlobalGenerator)
|
||||
{
|
||||
this->FullPath = file;
|
||||
this->Directory = cmSystemTools::GetFilenamePath(file);
|
||||
this->FileName = cmSystemTools::GetFilenameName(file);
|
||||
|
||||
if(file.rfind(".framework") != std::string::npos)
|
||||
{
|
||||
cmsys::RegularExpression splitFramework;
|
||||
splitFramework.compile("^(.*)/(.*).framework/.*/(.*)$");
|
||||
if(splitFramework.find(file) &&
|
||||
(splitFramework.match(2) == splitFramework.match(3)))
|
||||
{
|
||||
this->Directory = splitFramework.match(1);
|
||||
this->FileName =
|
||||
std::string(file.begin() + this->Directory.size() + 1, file.end());
|
||||
}
|
||||
}
|
||||
|
||||
if(this->FileName.empty())
|
||||
{
|
||||
this->Directory = cmSystemTools::GetFilenamePath(file);
|
||||
this->FileName = cmSystemTools::GetFilenameName(file);
|
||||
}
|
||||
}
|
||||
virtual ~cmOrderDirectoriesConstraint() {}
|
||||
|
||||
|
@ -301,22 +318,42 @@ void cmOrderDirectories::AddRuntimeLibrary(std::string const& fullPath,
|
|||
// Add the runtime library at most once.
|
||||
if(this->EmmittedConstraintSOName.insert(fullPath).second)
|
||||
{
|
||||
std::string soname2 = soname ? soname : "";
|
||||
// Implicit link directories need special handling.
|
||||
if(!this->ImplicitDirectories.empty())
|
||||
{
|
||||
std::string dir = cmSystemTools::GetFilenamePath(fullPath);
|
||||
|
||||
if(fullPath.rfind(".framework") != std::string::npos)
|
||||
{
|
||||
cmsys::RegularExpression splitFramework;
|
||||
splitFramework.compile("^(.*)/(.*).framework/(.*)/(.*)$");
|
||||
if(splitFramework.find(fullPath) &&
|
||||
(splitFramework.match(2) == splitFramework.match(4)))
|
||||
{
|
||||
dir = splitFramework.match(1);
|
||||
soname2 = splitFramework.match(2);
|
||||
soname2 += ".framework/";
|
||||
soname2 += splitFramework.match(3);
|
||||
soname2 += "/";
|
||||
soname2 += splitFramework.match(4);
|
||||
}
|
||||
}
|
||||
|
||||
if(this->ImplicitDirectories.find(dir) !=
|
||||
this->ImplicitDirectories.end())
|
||||
{
|
||||
this->ImplicitDirEntries.push_back(
|
||||
new cmOrderDirectoriesConstraintSOName(this, fullPath, soname));
|
||||
new cmOrderDirectoriesConstraintSOName(this, fullPath,
|
||||
soname2.c_str()));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Construct the runtime information entry for this library.
|
||||
this->ConstraintEntries.push_back(
|
||||
new cmOrderDirectoriesConstraintSOName(this, fullPath, soname));
|
||||
new cmOrderDirectoriesConstraintSOName(this, fullPath,
|
||||
soname2.c_str()));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -2412,6 +2412,27 @@ bool cmSystemTools::GuessLibrarySOName(std::string const& fullPath,
|
|||
return false;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool cmSystemTools::GuessLibraryInstallName(std::string const& fullPath,
|
||||
std::string& soname)
|
||||
{
|
||||
std::vector<cmStdString> cmds;
|
||||
cmds.push_back("otool");
|
||||
cmds.push_back("-D");
|
||||
cmds.push_back(fullPath.c_str());
|
||||
|
||||
std::string output;
|
||||
RunSingleCommand(cmds, &output, 0, 0, OUTPUT_NONE);
|
||||
|
||||
std::vector<std::string> strs = cmSystemTools::tokenize(output, "\n");
|
||||
if(strs.size() == 2)
|
||||
{
|
||||
soname = strs[1];
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
#if defined(CMAKE_USE_ELF_PARSER)
|
||||
std::string::size_type cmSystemToolsFindRPath(std::string const& have,
|
||||
|
|
|
@ -439,6 +439,10 @@ public:
|
|||
static bool GuessLibrarySOName(std::string const& fullPath,
|
||||
std::string& soname);
|
||||
|
||||
/** Try to guess the install name of a shared library. */
|
||||
static bool GuessLibraryInstallName(std::string const& fullPath,
|
||||
std::string& soname);
|
||||
|
||||
/** Try to set the RPATH in an ELF binary. */
|
||||
static bool ChangeRPath(std::string const& file,
|
||||
std::string const& oldRPath,
|
||||
|
|
|
@ -1185,6 +1185,15 @@ void cmTarget::DefineProperties(cmake *cm)
|
|||
"If a custom Info.plist is specified by this property it may of course "
|
||||
"hard-code all the settings instead of using the target properties.");
|
||||
|
||||
cm->DefineProperty
|
||||
("MACOSX_RPATH", cmProperty::TARGET,
|
||||
"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.");
|
||||
|
||||
cm->DefineProperty
|
||||
("ENABLE_EXPORTS", cmProperty::TARGET,
|
||||
"Specify whether an executable exports symbols for loadable modules.",
|
||||
|
@ -1513,6 +1522,8 @@ void cmTarget::SetMakefile(cmMakefile* mf)
|
|||
this->SetPropertyDefault("LINK_INTERFACE_LIBRARIES", 0);
|
||||
this->SetPropertyDefault("WIN32_EXECUTABLE", 0);
|
||||
this->SetPropertyDefault("MACOSX_BUNDLE", 0);
|
||||
this->SetPropertyDefault("MACOSX_RPATH", 0);
|
||||
|
||||
|
||||
// Collect the set of configuration types.
|
||||
std::vector<std::string> configNames;
|
||||
|
@ -3886,6 +3897,10 @@ std::string cmTarget::GetSOName(const char* config)
|
|||
else
|
||||
{
|
||||
// Use the soname given if any.
|
||||
if(info->SOName.find("@rpath/") == 0)
|
||||
{
|
||||
return info->SOName.substr(6);
|
||||
}
|
||||
return info->SOName;
|
||||
}
|
||||
}
|
||||
|
@ -3907,6 +3922,75 @@ std::string cmTarget::GetSOName(const char* config)
|
|||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool cmTarget::HasMacOSXRpath(const char* config)
|
||||
{
|
||||
bool install_name_is_rpath = false;
|
||||
bool macosx_rpath = this->GetPropertyAsBool("MACOSX_RPATH");
|
||||
|
||||
if(!this->IsImportedTarget)
|
||||
{
|
||||
const char* install_name = this->GetProperty("INSTALL_NAME_DIR");
|
||||
bool use_install_name =
|
||||
this->GetPropertyAsBool("BUILD_WITH_INSTALL_RPATH");
|
||||
if(install_name && use_install_name &&
|
||||
std::string(install_name) == "@rpath")
|
||||
{
|
||||
install_name_is_rpath = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Lookup the imported soname.
|
||||
if(cmTarget::ImportInfo const* info = this->GetImportInfo(config, this))
|
||||
{
|
||||
if(!info->NoSOName && !info->SOName.empty())
|
||||
{
|
||||
if(info->SOName.find("@rpath/") == 0)
|
||||
{
|
||||
install_name_is_rpath = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
std::string install_name;
|
||||
cmSystemTools::GuessLibraryInstallName(info->Location, install_name);
|
||||
if(install_name.find("@rpath") != std::string::npos)
|
||||
{
|
||||
install_name_is_rpath = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(!install_name_is_rpath && !macosx_rpath)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if(!this->Makefile->IsSet("CMAKE_SHARED_LIBRARY_RUNTIME_C_FLAG"))
|
||||
{
|
||||
cmOStringStream w;
|
||||
w << "Attempting to use";
|
||||
if(macosx_rpath)
|
||||
{
|
||||
w << " MACOSX_RPATH";
|
||||
}
|
||||
else
|
||||
{
|
||||
w << " @rpath";
|
||||
}
|
||||
w << " without CMAKE_SHARED_LIBRARY_RUNTIME_C_FLAG being set.";
|
||||
w << " This could be because you are using a Mac OS X version";
|
||||
w << " less than 10.5 or because CMake's platform configuration is";
|
||||
w << " corrupt.";
|
||||
cmake* cm = this->Makefile->GetCMakeInstance();
|
||||
cm->IssueMessage(cmake::FATAL_ERROR, w.str(), this->GetBacktrace());
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool cmTarget::IsImportedSharedLibWithoutSOName(const char* config)
|
||||
{
|
||||
|
@ -4547,7 +4631,15 @@ std::string cmTarget::GetInstallNameDirForBuildTree(const char* config)
|
|||
!this->Makefile->IsOn("CMAKE_SKIP_RPATH") &&
|
||||
!this->GetPropertyAsBool("SKIP_BUILD_RPATH"))
|
||||
{
|
||||
std::string dir = this->GetDirectory(config);
|
||||
std::string dir;
|
||||
if(this->GetPropertyAsBool("MACOSX_RPATH"))
|
||||
{
|
||||
dir = "@rpath";
|
||||
}
|
||||
else
|
||||
{
|
||||
dir = this->GetDirectory(config);
|
||||
}
|
||||
dir += "/";
|
||||
return dir;
|
||||
}
|
||||
|
@ -4574,6 +4666,10 @@ std::string cmTarget::GetInstallNameDirForInstallTree()
|
|||
dir += "/";
|
||||
}
|
||||
}
|
||||
if(dir.empty() && this->GetPropertyAsBool("MACOSX_RPATH"))
|
||||
{
|
||||
dir = "@rpath/";
|
||||
}
|
||||
return dir;
|
||||
}
|
||||
else
|
||||
|
@ -5155,7 +5251,6 @@ void cmTarget::GetLanguages(std::set<cmStdString>& languages) const
|
|||
//----------------------------------------------------------------------------
|
||||
bool cmTarget::IsChrpathUsed(const char* config)
|
||||
{
|
||||
#if defined(CMAKE_USE_ELF_PARSER)
|
||||
// Only certain target types have an rpath.
|
||||
if(!(this->GetType() == cmTarget::SHARED_LIBRARY ||
|
||||
this->GetType() == cmTarget::MODULE_LIBRARY ||
|
||||
|
@ -5189,6 +5284,12 @@ bool cmTarget::IsChrpathUsed(const char* config)
|
|||
return false;
|
||||
}
|
||||
|
||||
if(this->Makefile->IsOn("CMAKE_PLATFORM_HAS_INSTALLNAME"))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
#if defined(CMAKE_USE_ELF_PARSER)
|
||||
// Enable if the rpath flag uses a separator and the target uses ELF
|
||||
// binaries.
|
||||
if(const char* ll = this->GetLinkerLanguage(config, this))
|
||||
|
|
|
@ -367,6 +367,9 @@ public:
|
|||
/** Get the soname of the target. Allowed only for a shared library. */
|
||||
std::string GetSOName(const char* config);
|
||||
|
||||
/** Whether this library has @rpath and platform supports it. */
|
||||
bool HasMacOSXRpath(const char* config);
|
||||
|
||||
/** Test for special case of a third-party shared library that has
|
||||
no soname at all. */
|
||||
bool IsImportedSharedLibWithoutSOName(const char* config);
|
||||
|
@ -412,7 +415,13 @@ public:
|
|||
/** Return true if builtin chrpath will work for this target */
|
||||
bool IsChrpathUsed(const char* config);
|
||||
|
||||
/** Return the install name directory for the target in the
|
||||
* build tree. For example: "@rpath/", "@loader_path/",
|
||||
* or "/full/path/to/library". */
|
||||
std::string GetInstallNameDirForBuildTree(const char* config);
|
||||
|
||||
/** Return the install name directory for the target in the
|
||||
* install tree. For example: "@rpath/" or "@loader_path/". */
|
||||
std::string GetInstallNameDirForInstallTree();
|
||||
|
||||
cmComputeLinkInformation* GetLinkInformation(const char* config,
|
||||
|
|
|
@ -1233,6 +1233,16 @@ ${CMake_BINARY_DIR}/bin/cmake -DVERSION=master -P ${CMake_SOURCE_DIR}/Utilities/
|
|||
endif()
|
||||
endif()
|
||||
|
||||
if(APPLE AND "${DARWIN_MAJOR_VERSION}" GREATER 9)
|
||||
add_test(MacRuntimePath ${CMAKE_CTEST_COMMAND}
|
||||
--build-and-test
|
||||
"${CMake_SOURCE_DIR}/Tests/MacRuntimePath"
|
||||
"${CMake_BINARY_DIR}/Tests/MacRuntimePath"
|
||||
${build_generator_args}
|
||||
--build-project MacRuntimePath
|
||||
)
|
||||
endif()
|
||||
|
||||
add_test(linkorder1 ${CMAKE_CTEST_COMMAND}
|
||||
--build-and-test
|
||||
"${CMake_SOURCE_DIR}/Tests/LinkLineOrder"
|
||||
|
|
|
@ -0,0 +1,63 @@
|
|||
cmake_minimum_required(VERSION 2.8)
|
||||
project(MacRuntimePath_A)
|
||||
|
||||
# a shared library
|
||||
add_library(shared SHARED shared.cpp shared.h)
|
||||
set_target_properties(shared PROPERTIES MACOSX_RPATH 1)
|
||||
|
||||
# a shared library with custom set @rpath
|
||||
add_library(shared2 SHARED shared.cpp shared.h)
|
||||
set_target_properties(shared2 PROPERTIES
|
||||
BUILD_WITH_INSTALL_RPATH 1 INSTALL_NAME_DIR "@rpath")
|
||||
|
||||
# a framework library
|
||||
add_library(framework SHARED framework.cpp framework.h)
|
||||
set_target_properties(framework PROPERTIES MACOSX_RPATH 1 FRAMEWORK 1)
|
||||
|
||||
# executable to test a shared library dependency with install rpaths
|
||||
add_executable(test1 test1.cpp)
|
||||
target_link_libraries(test1 shared)
|
||||
set_target_properties(test1 PROPERTIES
|
||||
BUILD_WITH_INSTALL_RPATH 1 INSTALL_RPATH "@loader_path/../lib")
|
||||
|
||||
# executable to test a framework library dependency with install rpaths
|
||||
add_executable(test2 test2.cpp)
|
||||
target_link_libraries(test2 framework)
|
||||
set_target_properties(test2 PROPERTIES
|
||||
BUILD_WITH_INSTALL_RPATH 1 INSTALL_RPATH "@loader_path/../lib")
|
||||
|
||||
# executable to test a framework library dependency with build tree rpaths
|
||||
add_executable(test3 test3.cpp)
|
||||
target_link_libraries(test3 framework)
|
||||
|
||||
# executable to test a framework library dependency with build tree rpaths
|
||||
add_executable(test4 test1.cpp)
|
||||
target_link_libraries(test4 shared2)
|
||||
|
||||
set_target_properties(shared shared2 framework PROPERTIES
|
||||
LIBRARY_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/lib")
|
||||
set_target_properties(test1 test2 test3 test4 PROPERTIES
|
||||
RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/bin")
|
||||
foreach(config ${CMAKE_CONFIGURATION_TYPES})
|
||||
string(TOUPPER ${config} CONFIG)
|
||||
set_target_properties(shared shared2 framework PROPERTIES
|
||||
LIBRARY_OUTPUT_DIRECTORY_${CONFIG}
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/${config}/lib")
|
||||
set_target_properties(test1 test2 test3 test4 PROPERTIES
|
||||
RUNTIME_OUTPUT_DIRECTORY_${CONFIG}
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/${config}/bin")
|
||||
endforeach()
|
||||
|
||||
foreach(test test1 test2 test3 test4)
|
||||
add_custom_target(${test}_run ALL
|
||||
COMMAND ${test}
|
||||
DEPENDS ${test}
|
||||
)
|
||||
endforeach()
|
||||
|
||||
export(TARGETS shared shared2 framework FILE "${CMAKE_CURRENT_BINARY_DIR}/exp.cmake")
|
||||
|
||||
install(TARGETS shared EXPORT MyExport DESTINATION lib)
|
||||
install(TARGETS shared2 EXPORT MyExport DESTINATION lib2)
|
||||
install(TARGETS framework EXPORT MyExport DESTINATION lib-fw)
|
||||
install(EXPORT MyExport DESTINATION lib FILE exp.cmake)
|
|
@ -0,0 +1,8 @@
|
|||
|
||||
#include "framework.h"
|
||||
#include "stdio.h"
|
||||
|
||||
void framework()
|
||||
{
|
||||
printf("framework\n");
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
|
||||
#ifndef framework_h
|
||||
#define framework_h
|
||||
|
||||
#ifdef WIN32
|
||||
# ifdef framework_EXPORTS
|
||||
# define FRAMEWORK_EXPORT __declspec(dllexport)
|
||||
# else
|
||||
# define FRAMEWORK_EXPORT __declspec(dllimport)
|
||||
# endif
|
||||
#else
|
||||
# define FRAMEWORK_EXPORT
|
||||
#endif
|
||||
|
||||
void FRAMEWORK_EXPORT framework();
|
||||
|
||||
#endif
|
|
@ -0,0 +1,8 @@
|
|||
|
||||
#include "shared.h"
|
||||
#include "stdio.h"
|
||||
|
||||
void shared()
|
||||
{
|
||||
printf("shared\n");
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
|
||||
#ifndef shared_h
|
||||
#define shared_h
|
||||
|
||||
#ifdef WIN32
|
||||
# ifdef shared_EXPORTS
|
||||
# define SHARED_EXPORT __declspec(dllexport)
|
||||
# else
|
||||
# define SHARED_EXPORT __declspec(dllimport)
|
||||
# endif
|
||||
#else
|
||||
# define SHARED_EXPORT
|
||||
#endif
|
||||
|
||||
void SHARED_EXPORT shared();
|
||||
|
||||
#endif
|
|
@ -0,0 +1,8 @@
|
|||
|
||||
#include "shared.h"
|
||||
|
||||
int main(int, char**)
|
||||
{
|
||||
shared();
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
|
||||
#include "framework.h"
|
||||
|
||||
int main(int, char**)
|
||||
{
|
||||
framework();
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
|
||||
#include "framework.h"
|
||||
|
||||
int main(int, char**)
|
||||
{
|
||||
framework();
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
cmake_minimum_required(VERSION 2.8)
|
||||
project(MacRuntimePath_B)
|
||||
|
||||
include(${MacRuntimePath_B_BINARY_DIR}/../Root/lib/exp.cmake)
|
||||
|
||||
add_executable(testb ${MacRuntimePath_B_SOURCE_DIR}/../A/test3.cpp)
|
||||
|
||||
# test link with rpath enabled targets
|
||||
target_link_libraries(testb shared framework)
|
||||
|
||||
# test link with rpath enabled library by filename
|
||||
target_link_libraries(testb $<TARGET_LINKER_FILE:shared2> framework)
|
||||
|
||||
add_custom_target(testb_run ALL
|
||||
COMMAND testb
|
||||
DEPENDS testb
|
||||
)
|
|
@ -0,0 +1,72 @@
|
|||
cmake_minimum_required (VERSION 2.8)
|
||||
project(MacRuntimePath)
|
||||
|
||||
|
||||
# Wipe out the install tree to make sure the exporter works.
|
||||
add_custom_command(
|
||||
OUTPUT ${MacRuntimePath_BINARY_DIR}/CleanupProject
|
||||
COMMAND ${CMAKE_COMMAND} -E remove_directory ${MacRuntimePath_BINARY_DIR}/Root
|
||||
)
|
||||
add_custom_target(CleanupTarget ALL DEPENDS ${MacRuntimePath_BINARY_DIR}/CleanupProject)
|
||||
set_property(
|
||||
SOURCE ${MacRuntimePath_BINARY_DIR}/CleanupProject
|
||||
PROPERTY SYMBOLIC 1
|
||||
)
|
||||
|
||||
configure_file(${MacRuntimePath_SOURCE_DIR}/InitialCache.cmake.in
|
||||
${MacRuntimePath_BINARY_DIR}/InitialCache.cmake @ONLY)
|
||||
|
||||
if(CMAKE_CONFIGURATION_TYPES)
|
||||
set(NESTED_CONFIG_TYPE -C "${CMAKE_CFG_INTDIR}")
|
||||
else()
|
||||
if(CMAKE_BUILD_TYPE)
|
||||
set(NESTED_CONFIG_TYPE -C "${CMAKE_BUILD_TYPE}")
|
||||
else()
|
||||
set(NESTED_CONFIG_TYPE)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# Build and install the exporter.
|
||||
add_custom_command(
|
||||
OUTPUT ${MacRuntimePath_BINARY_DIR}/ExportProject
|
||||
COMMAND ${CMAKE_CTEST_COMMAND} ${NESTED_CONFIG_TYPE}
|
||||
--build-and-test
|
||||
${MacRuntimePath_SOURCE_DIR}/A
|
||||
${MacRuntimePath_BINARY_DIR}/A
|
||||
--build-noclean
|
||||
--build-project MacRuntimePath_A
|
||||
--build-target install
|
||||
--build-generator ${CMAKE_GENERATOR}
|
||||
--build-generator-toolset "${CMAKE_GENERATOR_TOOLSET}"
|
||||
--build-makeprogram ${CMAKE_MAKE_PROGRAM}
|
||||
--build-options -C${MacRuntimePath_BINARY_DIR}/InitialCache.cmake
|
||||
VERBATIM
|
||||
)
|
||||
add_custom_target(ExportTarget ALL DEPENDS ${MacRuntimePath_BINARY_DIR}/ExportProject)
|
||||
add_dependencies(ExportTarget CleanupTarget)
|
||||
set_property(
|
||||
SOURCE ${MacRuntimePath_BINARY_DIR}/ExportProject
|
||||
PROPERTY SYMBOLIC 1
|
||||
)
|
||||
|
||||
# Build the importer.
|
||||
add_custom_command(
|
||||
OUTPUT ${MacRuntimePath_BINARY_DIR}/ImportProject
|
||||
COMMAND ${CMAKE_CTEST_COMMAND} ${NESTED_CONFIG_TYPE}
|
||||
--build-and-test
|
||||
${MacRuntimePath_SOURCE_DIR}/B
|
||||
${MacRuntimePath_BINARY_DIR}/B
|
||||
--build-noclean
|
||||
--build-project MacRuntimePath_B
|
||||
--build-generator ${CMAKE_GENERATOR}
|
||||
--build-generator-toolset "${CMAKE_GENERATOR_TOOLSET}"
|
||||
--build-makeprogram ${CMAKE_MAKE_PROGRAM}
|
||||
--build-options -C${MacRuntimePath_BINARY_DIR}/InitialCache.cmake
|
||||
VERBATIM
|
||||
)
|
||||
add_custom_target(ImportTarget ALL DEPENDS ${MacRuntimePath_BINARY_DIR}/ImportProject)
|
||||
add_dependencies(ImportTarget ExportTarget)
|
||||
set_property(
|
||||
SOURCE ${MacRuntimePath_BINARY_DIR}/ImportProject
|
||||
PROPERTY SYMBOLIC 1
|
||||
)
|
|
@ -0,0 +1,13 @@
|
|||
set(CMAKE_C_COMPILER "@CMAKE_C_COMPILER@" CACHE STRING "C Compiler")
|
||||
set(CMAKE_C_FLAGS "@CMAKE_C_FLAGS@" CACHE STRING "C Flags")
|
||||
set(CMAKE_C_FLAGS_DEBUG "@CMAKE_C_FLAGS_DEBUG@" CACHE STRING "C Flags")
|
||||
set(CMAKE_C_FLAGS_RELEASE "@CMAKE_C_FLAGS_RELEASE@" CACHE STRING "C Flags")
|
||||
set(CMAKE_C_FLAGS_MINSIZEREL "@CMAKE_C_FLAGS_MINSIZEREL@" CACHE STRING "C Flags")
|
||||
set(CMAKE_C_FLAGS_RELWITHDEBINFO "@CMAKE_C_FLAGS_RELWITHDEBINFO@" CACHE STRING "C Flags")
|
||||
set(CMAKE_CXX_COMPILER "@CMAKE_CXX_COMPILER@" CACHE STRING "C++ Compiler")
|
||||
set(CMAKE_CXX_FLAGS "@CMAKE_CXX_FLAGS@" CACHE STRING "C++ Flags")
|
||||
set(CMAKE_CXX_FLAGS_DEBUG "@CMAKE_CXX_FLAGS_DEBUG@" CACHE STRING "C++ Flags")
|
||||
set(CMAKE_CXX_FLAGS_RELEASE "@CMAKE_CXX_FLAGS_RELEASE@" CACHE STRING "C++ Flags")
|
||||
set(CMAKE_CXX_FLAGS_MINSIZEREL "@CMAKE_CXX_FLAGS_MINSIZEREL@" CACHE STRING "C++ Flags")
|
||||
set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "@CMAKE_CXX_FLAGS_RELWITHDEBINFO@" CACHE STRING "C++ Flags")
|
||||
set(CMAKE_INSTALL_PREFIX "@MacRuntimePath_BINARY_DIR@/Root" CACHE STRING "Installation Prefix")
|
Loading…
Reference in New Issue