ENH: Created target property INSTALL_NAME_DIR initalized by CMAKE_INSTALL_NAME_DIR specifying the directory portion of the OSX install_name field in shared libraries. This is the OSX equivalent of RPATH.

This commit is contained in:
Brad King 2006-02-24 13:13:14 -05:00
parent 7db7b981af
commit 586a9427d3
13 changed files with 409 additions and 55 deletions

View File

@ -4,8 +4,11 @@ SET(CMAKE_SHARED_MODULE_PREFIX "lib")
SET(CMAKE_SHARED_MODULE_SUFFIX ".so")
SET(CMAKE_MODULE_EXISTS 1)
SET(CMAKE_DL_LIBS "")
SET(CMAKE_SHARED_LIBRARY_CREATE_C_FLAGS "-dynamiclib")
SET(CMAKE_SHARED_MODULE_CREATE_C_FLAGS "-bundle")
SET(CMAKE_C_LINK_FLAGS "-headerpad_max_install_names")
SET(CMAKE_CXX_LINK_FLAGS "-headerpad_max_install_names")
SET(CMAKE_PLATFORM_HAS_INSTALLNAME 1)
SET(CMAKE_SHARED_LIBRARY_CREATE_C_FLAGS "-dynamiclib -headerpad_max_install_names")
SET(CMAKE_SHARED_MODULE_CREATE_C_FLAGS "-bundle -headerpad_max_install_names")
SET(CMAKE_FIND_LIBRARY_SUFFIXES ".dylib" ".so" ".a")
IF("${CMAKE_BACKWARDS_COMPATIBILITY}" MATCHES "^1\\.[0-6]$")
@ -14,32 +17,17 @@ IF("${CMAKE_BACKWARDS_COMPATIBILITY}" MATCHES "^1\\.[0-6]$")
ENDIF("${CMAKE_BACKWARDS_COMPATIBILITY}" MATCHES "^1\\.[0-6]$")
IF(NOT XCODE)
# Enable shared library versioning.
# Enable shared library versioning. This flag is not actually referenced
# but the fact that the setting exists will cause the generators to support
# soname computation.
SET(CMAKE_SHARED_LIBRARY_SONAME_C_FLAG "-install_name")
SET(CMAKE_SHARED_LIBRARY_SONAME_CXX_FLAG "-install_name")
ENDIF(NOT XCODE)
# OSX does not really implement an rpath, but it does allow a path to
# be specified in the soname field of a dylib.
IF(CMAKE_SKIP_RPATH)
# No rpath requested. Just use the soname directly.
SET(CMAKE_C_CREATE_SHARED_LIBRARY
"<CMAKE_C_COMPILER> <CMAKE_SHARED_LIBRARY_CREATE_C_FLAGS> <LINK_FLAGS> -o <TARGET> <CMAKE_SHARED_LIBRARY_SONAME_C_FLAG> <TARGET_SONAME> <OBJECTS> <LINK_LIBRARIES>")
SET(CMAKE_CXX_CREATE_SHARED_LIBRARY
"<CMAKE_CXX_COMPILER> <CMAKE_SHARED_LIBRARY_CREATE_CXX_FLAGS> <LINK_FLAGS> -o <TARGET> <CMAKE_SHARED_LIBRARY_SONAME_CXX_FLAG> <TARGET_SONAME> <OBJECTS> <LINK_LIBRARIES>")
ELSE(CMAKE_SKIP_RPATH)
# Support for rpath is requested. Approximate it by putting the
# full path to the library in the soname field. Then when executables
# link the library they will copy this full path as the name to use
# to find the library. We can get the directory containing the library
# by using the dirname of the <TARGET>. It may be a relative path
# so we use a "cd ...;pwd" trick to convert it to a full path at
# build time.
SET(CMAKE_C_CREATE_SHARED_LIBRARY
"<CMAKE_C_COMPILER> <CMAKE_SHARED_LIBRARY_CREATE_C_FLAGS> <LINK_FLAGS> -o <TARGET> <CMAKE_SHARED_LIBRARY_SONAME_C_FLAG> \"`cd \\`dirname <TARGET>\\`\;pwd`/<TARGET_SONAME>\" <OBJECTS> <LINK_LIBRARIES>")
SET(CMAKE_CXX_CREATE_SHARED_LIBRARY
"<CMAKE_CXX_COMPILER> <CMAKE_SHARED_LIBRARY_CREATE_CXX_FLAGS> <LINK_FLAGS> -o <TARGET> <CMAKE_SHARED_LIBRARY_SONAME_CXX_FLAG> \"`cd \\`dirname <TARGET>\\`\;pwd`/<TARGET_SONAME>\" <OBJECTS> <LINK_LIBRARIES>")
ENDIF(CMAKE_SKIP_RPATH)
SET(CMAKE_C_CREATE_SHARED_LIBRARY
"<CMAKE_C_COMPILER> <CMAKE_SHARED_LIBRARY_CREATE_C_FLAGS> <LINK_FLAGS> -o <TARGET> -install_name <TARGET_INSTALLNAME_DIR><TARGET_SONAME> <OBJECTS> <LINK_LIBRARIES>")
SET(CMAKE_CXX_CREATE_SHARED_LIBRARY
"<CMAKE_CXX_COMPILER> <CMAKE_SHARED_LIBRARY_CREATE_CXX_FLAGS> <LINK_FLAGS> -o <TARGET> -install_name <TARGET_INSTALLNAME_DIR><TARGET_SONAME> <OBJECTS> <LINK_LIBRARIES>")
SET(CMAKE_CXX_CREATE_SHARED_MODULE
"<CMAKE_CXX_COMPILER> <CMAKE_SHARED_MODULE_CREATE_CXX_FLAGS> <LINK_FLAGS> -o <TARGET> <OBJECTS> <LINK_LIBRARIES>")

View File

@ -1145,13 +1145,30 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmTarget& target,
outflag += "\\\"";
extraLinkOptions += " ";
extraLinkOptions += outflag;
// Add the flags to create an executable.
std::string createFlags =
this->LookupFlags("CMAKE_", lang, "_LINK_FLAGS", "");
if(!createFlags.empty())
{
extraLinkOptions += " ";
extraLinkOptions += createFlags;
}
}
else
{
fileType = "compiled.mach-o.dylib";
productType = "com.apple.product-type.library.dynamic";
extraLinkOptions += " -bundle";
// Add the flags to create a module.
std::string createFlags =
this->LookupFlags("CMAKE_SHARED_MODULE_CREATE_", lang, "_FLAGS",
"-bundle");
if(!createFlags.empty())
{
extraLinkOptions += " ";
extraLinkOptions += createFlags;
}
}
break;
}
@ -1166,13 +1183,31 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmTarget& target,
this->CreateString("1"));
buildSettings->AddAttribute("DYLIB_CURRENT_VERSION",
this->CreateString("1"));
extraLinkOptions += " -dynamiclib";
// Add the flags to create a shared library.
std::string createFlags =
this->LookupFlags("CMAKE_SHARED_LIBRARY_CREATE_", lang, "_FLAGS",
"-dynamiclib");
if(!createFlags.empty())
{
extraLinkOptions += " ";
extraLinkOptions += createFlags;
}
break;
}
case cmTarget::EXECUTABLE:
{
fileType = "compiled.mach-o.executable";
// Add the flags to create an executable.
std::string createFlags =
this->LookupFlags("CMAKE_", lang, "_LINK_FLAGS", "");
if(!createFlags.empty())
{
extraLinkOptions += " ";
extraLinkOptions += createFlags;
}
// Handle bundles and normal executables separately.
if(target.GetPropertyAsBool("MACOSX_BUNDLE"))
{
@ -1284,8 +1319,6 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmTarget& target,
this->CreateString(debugStr));
buildSettings->AddAttribute("GCC_OPTIMIZATION_LEVEL",
this->CreateString(optLevel));
buildSettings->AddAttribute("INSTALL_PATH",
this->CreateString(""));
buildSettings->AddAttribute("OPTIMIZATION_CFLAGS",
this->CreateString(oflagc.c_str()));
if(lang && strcmp(lang, "CXX") == 0)
@ -1307,9 +1340,45 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmTarget& target,
buildSettings->AddAttribute("OTHER_CFLAGS",
this->CreateString(flags.c_str()));
}
// Create the INSTALL_PATH attribute.
std::string install_name_dir;
if(target.GetType() == cmTarget::SHARED_LIBRARY)
{
// Select whether to generate an install_name directory for the
// install tree or the build tree.
if(target.GetPropertyAsBool("BUILD_WITH_INSTALL_RPATH"))
{
install_name_dir =
target.GetInstallNameDirForInstallTree(configName);
}
else
{
install_name_dir =
target.GetInstallNameDirForBuildTree(configName);
}
if(install_name_dir.empty())
{
// Xcode will not pass the -install_name option at all if INSTALL_PATH
// is not given or is empty. We must explicitly put the flag in the
// link flags to create an install_name with just the library soname.
extraLinkOptions += " -install_name ";
extraLinkOptions += productName;
}
else
{
// Convert to a path for the native build tool.
cmSystemTools::ConvertToUnixSlashes(install_name_dir);
install_name_dir =
this->XCodeEscapePath(install_name_dir.c_str());
}
}
buildSettings->AddAttribute("INSTALL_PATH",
this->CreateString(install_name_dir.c_str()));
buildSettings->AddAttribute("OTHER_LDFLAGS",
this->CreateString(extraLinkOptions.c_str()));
buildSettings->AddAttribute("OTHER_REZFLAGS",
this->CreateString(""));
buildSettings->AddAttribute("SECTORDER_FLAGS",
@ -2317,3 +2386,26 @@ cmGlobalXCodeGenerator
}
}
}
//----------------------------------------------------------------------------
std::string cmGlobalXCodeGenerator::LookupFlags(const char* varNamePrefix,
const char* varNameLang,
const char* varNameSuffix,
const char* default_flags)
{
if(varNameLang)
{
std::string varName = varNamePrefix;
varName += varNameLang;
varName += varNameSuffix;
if(const char* varValue =
m_CurrentMakefile->GetDefinition(varName.c_str()))
{
if(*varValue)
{
return varValue;
}
}
}
return default_flags;
}

View File

@ -142,6 +142,11 @@ private:
cmTarget& cmtarget,
const std::vector<cmCustomCommand>&);
void CreateReRunCMakeFile(cmLocalGenerator* root);
std::string LookupFlags(const char* varNamePrefix,
const char* varNameLang,
const char* varNameSuffix,
const char* default_flags);
protected:
int m_XcodeVersion;

View File

@ -52,10 +52,11 @@ void cmInstallTargetGenerator::GenerateScript(std::ostream& os)
}
// Write variable settings to do per-configuration references.
this->PrepareInstallReference(os);
this->PrepareScriptReference(os, this->Target, "BUILD", true, false);
// Create the per-configuration reference.
std::string fromName = this->GetInstallReference();
std::string fromName = this->GetScriptReference(this->Target, "BUILD",
false);
std::string fromFile = fromDir;
fromFile += fromName;
@ -150,12 +151,22 @@ void cmInstallTargetGenerator::GenerateScript(std::ostream& os)
// Write code to install the target file.
this->AddInstallRule(os, this->Destination.c_str(), type, fromFile.c_str(),
this->ImportLibrary, properties);
// Fix the install_name settings in installed binaries.
if(type == cmTarget::SHARED_LIBRARY ||
type == cmTarget::MODULE_LIBRARY ||
type == cmTarget::EXECUTABLE)
{
this->AddInstallNamePatchRule(os);
}
}
//----------------------------------------------------------------------------
void
cmInstallTargetGenerator
::PrepareInstallReference(std::ostream& os)
::PrepareScriptReference(std::ostream& os, cmTarget* target,
const char* place, bool useConfigDir,
bool useSOName)
{
// If the target name may vary with the configuration type then
// store all possible names ahead of time in variables.
@ -164,42 +175,180 @@ cmInstallTargetGenerator
this->ConfigurationTypes->begin();
i != this->ConfigurationTypes->end(); ++i)
{
// Start with the configuration's subdirectory.
// Initialize the name.
fname = "";
this->Target->GetMakefile()->GetLocalGenerator()->GetGlobalGenerator()->
AppendDirectoryForConfig(i->c_str(), fname);
if(useConfigDir)
{
// Start with the configuration's subdirectory.
target->GetMakefile()->GetLocalGenerator()->GetGlobalGenerator()->
AppendDirectoryForConfig(i->c_str(), fname);
}
// Compute the name of the library.
std::string targetName;
std::string targetNameSO;
std::string targetNameReal;
std::string targetNameImport;
target->GetLibraryNames(targetName, targetNameSO, targetNameReal,
targetNameImport, i->c_str());
if(this->ImportLibrary)
{
// Use the import library name.
fname += targetNameImport;
}
else if(useSOName)
{
// Use the soname.
fname += targetNameSO;
}
else
{
// Use the canonical name.
fname += targetName;
}
// Set a variable with the target name for this configuration.
fname += this->Target->GetFullName(i->c_str(), this->ImportLibrary);
os << "SET(" << this->Target->GetName()
os << "SET(" << target->GetName() << "_" << place
<< (this->ImportLibrary? "_IMPNAME_" : "_NAME_") << *i
<< " \"" << fname << "\")\n";
}
}
//----------------------------------------------------------------------------
std::string cmInstallTargetGenerator::GetInstallReference()
std::string cmInstallTargetGenerator::GetScriptReference(cmTarget* target,
const char* place,
bool useSOName)
{
if(this->ConfigurationTypes->empty())
{
// Reference the target by its one configuration name.
return this->Target->GetFullName(this->ConfigurationName,
this->ImportLibrary);
std::string targetName;
std::string targetNameSO;
std::string targetNameReal;
std::string targetNameImport;
target->GetLibraryNames(targetName, targetNameSO, targetNameReal,
targetNameImport, this->ConfigurationName);
if(this->ImportLibrary)
{
// Use the import library name.
return targetNameImport;
}
else if(useSOName)
{
// Use the soname.
return targetNameSO;
}
else
{
// Use the canonical name.
return targetName;
}
}
else
{
// Reference the target using the per-configuration variable.
std::string ref = "${";
ref += this->Target->GetName();
ref += target->GetName();
if(this->ImportLibrary)
{
ref += "_";
ref += place;
ref += "_IMPNAME_";
}
else
{
ref += "_";
ref += place;
ref += "_NAME_";
}
ref += "${CMAKE_INSTALL_CONFIG_NAME}}";
return ref;
}
}
//----------------------------------------------------------------------------
void cmInstallTargetGenerator::AddInstallNamePatchRule(std::ostream& os)
{
// Build a map of build-tree install_name to install-tree install_name for
// shared libraries linked to this target.
std::map<cmStdString, cmStdString> install_name_remap;
cmTarget::LinkLibraryType linkType = cmTarget::OPTIMIZED;
const char* config = this->ConfigurationName;
if(config && cmSystemTools::UpperCase(config) == "DEBUG")
{
linkType = cmTarget::DEBUG;
}
// TODO: Merge with ComputeLinkInformation.
const cmTarget::LinkLibraries& inLibs = this->Target->GetLinkLibraries();
for(cmTarget::LinkLibraries::const_iterator j = inLibs.begin();
j != inLibs.end(); ++j)
{
std::string lib = j->first;
if((this->Target->GetType() == cmTarget::EXECUTABLE ||
lib != this->Target->GetName()) &&
(j->second == cmTarget::GENERAL || j->second == linkType))
{
if(cmTarget* tgt = this->Target->GetMakefile()->GetLocalGenerator()->GetGlobalGenerator()->FindTarget(0, lib.c_str()))
{
if(tgt->GetType() == cmTarget::SHARED_LIBRARY)
{
// If the build tree and install tree use different path components
// of the install_name field then we need to create a mapping to be
// applied after installation.
std::string for_build = tgt->GetInstallNameDirForBuildTree(config);
std::string for_install = tgt->GetInstallNameDirForInstallTree(config);
if(for_build != for_install)
{
// Map from the build-tree install_name.
this->PrepareScriptReference(os, tgt, "REMAP_FROM",
!for_build.empty(), true);
for_build += this->GetScriptReference(tgt, "REMAP_FROM", true);
// Map to the install-tree install_name.
this->PrepareScriptReference(os, tgt, "REMAP_TO",
false, true);
for_install += this->GetScriptReference(tgt, "REMAP_TO", true);
// Store the mapping entry.
install_name_remap[for_build] = for_install;
}
}
}
}
}
// Edit the install_name of the target itself if necessary.
this->PrepareScriptReference(os, this->Target, "REMAPPED", false, true);
std::string new_id;
if(this->Target->GetType() == cmTarget::SHARED_LIBRARY)
{
std::string for_build = this->Target->GetInstallNameDirForBuildTree(config);
std::string for_install = this->Target->GetInstallNameDirForInstallTree(config);
if(for_build != for_install)
{
// Prepare to refer to the install-tree install_name.
new_id = for_install;
new_id += this->GetScriptReference(this->Target, "REMAPPED", true);
}
}
// Write a rule to run install_name_tool to set the install-tree
// install_name value and references.
if(!new_id.empty() || !install_name_remap.empty())
{
os << "EXECUTE_PROCESS(COMMAND install_name_tool";
if(!new_id.empty())
{
os << "\n -id \"" << new_id << "\"";
}
for(std::map<cmStdString, cmStdString>::const_iterator
i = install_name_remap.begin();
i != install_name_remap.end(); ++i)
{
os << "\n -change \"" << i->first << "\" \"" << i->second << "\"";
}
os << "\n \"" << this->Destination.c_str() << "/"
<< this->GetScriptReference(this->Target, "REMAPPED", true) << "\")\n";
}
}

View File

@ -33,8 +33,12 @@ public:
protected:
virtual void GenerateScript(std::ostream& os);
void PrepareInstallReference(std::ostream& os);
std::string GetInstallReference();
void PrepareScriptReference(std::ostream& os, cmTarget* target,
const char* place, bool useConfigDir,
bool useSOName);
std::string GetScriptReference(cmTarget* target, const char* place,
bool useSOName);
void AddInstallNamePatchRule(std::ostream& os);
cmTarget* Target;
std::string Destination;
bool ImportLibrary;

View File

@ -643,6 +643,13 @@ cmLocalGenerator::ExpandRuleVariable(std::string const& variable,
return "";
}
}
if(replaceValues.TargetInstallNameDir)
{
if(variable == "TARGET_INSTALLNAME_DIR")
{
return replaceValues.TargetInstallNameDir;
}
}
if(replaceValues.LinkLibraries)
{
if(variable == "LINK_LIBRARIES")

View File

@ -182,6 +182,7 @@ public:
this->Flags= 0;
this->ObjectsQuoted= 0;
this->TargetSOName= 0;
this->TargetInstallNameDir = 0;
this->LinkFlags= 0;
}
const char* Language;
@ -193,6 +194,7 @@ public:
const char* Flags;
const char* ObjectsQuoted;
const char* TargetSOName;
const char* TargetInstallNameDir;
const char* LinkFlags;
};

View File

@ -392,7 +392,46 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules
vars.ObjectsQuoted = buildObjs.c_str();
vars.TargetSOName= targetNameSO.c_str();
vars.LinkFlags = linkFlags.c_str();
// Compute the directory portion of the install_name setting.
std::string install_name_dir;
if(this->Target->GetType() == cmTarget::SHARED_LIBRARY)
{
// Select whether to generate an install_name directory for the
// install tree or the build tree.
const char* config = this->LocalGenerator->m_ConfigurationName.c_str();
if(this->Target->GetPropertyAsBool("BUILD_WITH_INSTALL_RPATH"))
{
install_name_dir =
this->Target->GetInstallNameDirForInstallTree(config);
}
else
{
install_name_dir =
this->Target->GetInstallNameDirForBuildTree(config);
}
// Set the rule variable replacement value.
if(install_name_dir.empty())
{
vars.TargetInstallNameDir = "";
}
else
{
// Convert to a path for the native build tool.
install_name_dir =
this->LocalGenerator->Convert(install_name_dir.c_str(),
cmLocalGenerator::FULL,
cmLocalGenerator::SHELL, false);
// The Convert method seems to strip trailing slashes, which should
// probably be fixed. Since the only platform supporting install_name
// right now uses forward slashes just add one.
install_name_dir += "/";
vars.TargetInstallNameDir = install_name_dir.c_str();
}
}
// Expand placeholders in the commands.
this->LocalGenerator->m_TargetImplib = targetOutPathImport;
for(std::vector<std::string>::iterator i = commands.begin();

View File

@ -95,10 +95,13 @@ public:
"BUILD_WITH_INSTALL_RPATH is a boolean specifying whether to link "
"the target in the build tree with the INSTALL_RPATH. This takes "
"precedence over SKIP_BUILD_RPATH and avoids the need for relinking "
"before installation. When the target is created the values of "
"the variables CMAKE_INSTALL_RPATH, CMAKE_SKIP_BUILD_RPATH, and "
"CMAKE_BUILD_WITH_INSTALL_RPATH are used to initialize these "
"properties.\n"
"before installation. INSTALL_NAME_DIR is a string specifying the "
"directory portion of the \"install_name\" field of shared libraries "
"on Mac OSX to use in the installed targets. "
"When the target is created the values of "
"the variables CMAKE_INSTALL_RPATH, CMAKE_SKIP_BUILD_RPATH, "
"CMAKE_BUILD_WITH_INSTALL_RPATH, and CMAKE_INSTALL_NAME_DIR "
"are used to initialize these properties.\n"
"PROJECT_LABEL can be used to change the name of "
"the target in an IDE like visual studio. VS_KEYWORD can be set "
"to change the visual studio keyword, for example QT integration "

View File

@ -52,6 +52,7 @@ void cmTarget::SetMakefile(cmMakefile* mf)
m_Makefile = mf;
// Setup default property values.
this->SetPropertyDefault("INSTALL_NAME_DIR", "");
this->SetPropertyDefault("INSTALL_RPATH", "");
this->SetPropertyDefault("SKIP_BUILD_RPATH", "OFF");
this->SetPropertyDefault("BUILD_WITH_INSTALL_RPATH", "OFF");
@ -775,7 +776,7 @@ void cmTarget::SetProperty(const char* prop, const char* value)
m_Properties[prop] = value;
}
const char* cmTarget::GetDirectory()
const char* cmTarget::GetDirectory(const char* config)
{
switch( this->GetType() )
{
@ -794,6 +795,13 @@ const char* cmTarget::GetDirectory()
{
m_Directory = m_Makefile->GetStartOutputDirectory();
}
if(config)
{
// Add the configuration's subdirectory.
m_Directory += "/";
m_Makefile->GetLocalGenerator()->GetGlobalGenerator()->
AppendDirectoryForConfig(config, m_Directory);
}
return m_Directory.c_str();
}
@ -1069,13 +1077,9 @@ void cmTarget::GetFullName(std::string& prefix, std::string& base,
std::string cmTarget::GetFullPath(const char* config, bool implib)
{
// Start with the output directory for the target.
std::string fpath = this->GetDirectory();
std::string fpath = this->GetDirectory(config);
fpath += "/";
// Add the configuration's subdirectory.
m_Makefile->GetLocalGenerator()->GetGlobalGenerator()->
AppendDirectoryForConfig(config, fpath);
// Add the full name of the target.
fpath += this->GetFullName(config, implib);
return fpath;
@ -1440,3 +1444,47 @@ bool cmTarget::NeedRelinkBeforeInstall()
// this target must be relinked.
return this->HaveBuildTreeRPATH() || this->HaveInstallTreeRPATH();
}
//----------------------------------------------------------------------------
std::string cmTarget::GetInstallNameDirForBuildTree(const char* config)
{
// If building directly for installation then the build tree install_name
// is the same as the install tree.
if(this->GetPropertyAsBool("BUILD_WITH_INSTALL_RPATH"))
{
return GetInstallNameDirForInstallTree(config);
}
// Use the build tree directory for the target.
if(m_Makefile->IsOn("CMAKE_PLATFORM_HAS_INSTALLNAME") &&
!m_Makefile->IsOn("CMAKE_SKIP_RPATH") &&
!this->GetPropertyAsBool("SKIP_BUILD_RPATH"))
{
std::string dir = this->GetDirectory(config);
dir += "/";
return dir;
}
else
{
return "";
}
}
//----------------------------------------------------------------------------
std::string cmTarget::GetInstallNameDirForInstallTree(const char*)
{
// Lookup the target property.
const char* install_name_dir = this->GetProperty("INSTALL_NAME_DIR");
if(m_Makefile->IsOn("CMAKE_PLATFORM_HAS_INSTALLNAME") &&
!m_Makefile->IsOn("CMAKE_SKIP_RPATH") &&
install_name_dir && *install_name_dir)
{
std::string dir = install_name_dir;
dir += "/";
return dir;
}
else
{
return "";
}
}

View File

@ -157,7 +157,15 @@ public:
const char *GetProperty(const char *prop);
bool GetPropertyAsBool(const char *prop);
const char* GetDirectory();
/** Get the directory in which this target will be built. If the
configuration name is given then the generator will add its
subdirectory for that configuration. Otherwise just the canonical
output directory is given. */
const char* GetDirectory(const char* config = 0);
/** Get the location of the target in the build tree for the given
configuration. This location is suitable for use as the LOCATION
target property. */
const char* GetLocation(const char* config);
/**
@ -222,6 +230,9 @@ public:
bool HaveBuildTreeRPATH();
bool HaveInstallTreeRPATH();
std::string GetInstallNameDirForBuildTree(const char* config);
std::string GetInstallNameDirForInstallTree(const char* config);
private:
/**
* A list of direct dependencies. Use in conjunction with DependencyMap.

View File

@ -9,6 +9,9 @@ SET(LIBRARY_OUTPUT_PATH "${EXECUTABLE_OUTPUT_PATH}")
# tree.
SET(CMAKE_SKIP_BUILD_RPATH 1)
# Make sure the executable can run from the install tree.
SET(CMAKE_INSTALL_NAME_DIR ${CMAKE_INSTALL_PREFIX}/lib)
# Skip the dependency that causes a build when installing. This
# avoids infinite loops when the post-build rule below installs.
SET(CMAKE_SKIP_INSTALL_ALL_DEPENDENCY 1)

View File

@ -9,6 +9,9 @@ SET(LIBRARY_OUTPUT_PATH "${EXECUTABLE_OUTPUT_PATH}")
# tree.
SET(CMAKE_SKIP_BUILD_RPATH 1)
# Make sure the executable can run from the install tree.
SET(CMAKE_INSTALL_NAME_DIR ${CMAKE_INSTALL_PREFIX}/lib)
# Skip the dependency that causes a build when installing. This
# avoids infinite loops when the post-build rule below installs.
SET(CMAKE_SKIP_INSTALL_ALL_DEPENDENCY 1)