BUG: Correct Mac OS X framework behavior
- Place the built library in foo.framework/Versions/A/foo - Do not create unused content symlinks (like PrivateHeaders) - Do not use VERSION/SOVERSION properties for frameworks - Make cmTarget::GetDirectory return by value - Remove the foo.framework part from cmTarget::GetDirectory - Correct install_name construction and conversion on install - Fix MACOSX_PACKAGE_LOCATION under Xcode to use the Versions/<version> directory for frameworks - Update the Framework test to try these things
This commit is contained in:
parent
5c3a5daaf1
commit
67834f2d53
|
@ -611,20 +611,10 @@ void cmComputeLinkInformation::AddItem(std::string const& item, cmTarget* tgt)
|
||||||
std::string lib = tgt->GetFullPath(config, implib, true);
|
std::string lib = tgt->GetFullPath(config, implib, true);
|
||||||
this->Depends.push_back(lib);
|
this->Depends.push_back(lib);
|
||||||
|
|
||||||
if(tgt->IsFrameworkOnApple())
|
|
||||||
{
|
|
||||||
// Frameworks on OS X need only the framework directory to
|
|
||||||
// link.
|
|
||||||
std::string fw = tgt->GetDirectory(config, implib);
|
|
||||||
this->AddFrameworkItem(fw);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
this->AddTargetItem(lib, tgt);
|
this->AddTargetItem(lib, tgt);
|
||||||
this->AddLibraryRuntimeInfo(lib, tgt);
|
this->AddLibraryRuntimeInfo(lib, tgt);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// This is not a CMake target. Use the name given.
|
// This is not a CMake target. Use the name given.
|
||||||
|
@ -1023,7 +1013,7 @@ void cmComputeLinkInformation::AddTargetItem(std::string const& item,
|
||||||
|
|
||||||
// For compatibility with CMake 2.4 include the item's directory in
|
// For compatibility with CMake 2.4 include the item's directory in
|
||||||
// the linker search path.
|
// the linker search path.
|
||||||
if(this->OldLinkDirMode &&
|
if(this->OldLinkDirMode && !target->IsFrameworkOnApple() &&
|
||||||
this->OldLinkDirMask.find(cmSystemTools::GetFilenamePath(item)) ==
|
this->OldLinkDirMask.find(cmSystemTools::GetFilenamePath(item)) ==
|
||||||
this->OldLinkDirMask.end())
|
this->OldLinkDirMask.end())
|
||||||
{
|
{
|
||||||
|
|
|
@ -803,8 +803,14 @@ cmGlobalXCodeGenerator::CreateXCodeTargets(cmLocalGenerator* gen,
|
||||||
copyFilesBuildPhase->AddAttribute("dstSubfolderSpec",
|
copyFilesBuildPhase->AddAttribute("dstSubfolderSpec",
|
||||||
this->CreateString("6"));
|
this->CreateString("6"));
|
||||||
cmOStringStream ostr;
|
cmOStringStream ostr;
|
||||||
if ( mit->first != "MacOS" )
|
if (cmtarget.IsFrameworkOnApple())
|
||||||
{
|
{
|
||||||
|
// dstPath in frameworks is relative to Versions/<version>
|
||||||
|
ostr << mit->first;
|
||||||
|
}
|
||||||
|
else if ( mit->first != "MacOS" )
|
||||||
|
{
|
||||||
|
// dstPath in bundles is relative to Contents/MacOS
|
||||||
ostr << "../" << mit->first.c_str();
|
ostr << "../" << mit->first.c_str();
|
||||||
}
|
}
|
||||||
copyFilesBuildPhase->AddAttribute("dstPath",
|
copyFilesBuildPhase->AddAttribute("dstPath",
|
||||||
|
@ -1357,11 +1363,6 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmTarget& target,
|
||||||
target.GetType() == cmTarget::EXECUTABLE)
|
target.GetType() == cmTarget::EXECUTABLE)
|
||||||
{
|
{
|
||||||
std::string pndir = target.GetDirectory();
|
std::string pndir = target.GetDirectory();
|
||||||
if(target.IsFrameworkOnApple())
|
|
||||||
{
|
|
||||||
pndir += "/..";
|
|
||||||
pndir = cmSystemTools::CollapseFullPath(pndir.c_str());
|
|
||||||
}
|
|
||||||
buildSettings->AddAttribute("SYMROOT",
|
buildSettings->AddAttribute("SYMROOT",
|
||||||
this->CreateString(pndir.c_str()));
|
this->CreateString(pndir.c_str()));
|
||||||
buildSettings->AddAttribute("EXECUTABLE_PREFIX",
|
buildSettings->AddAttribute("EXECUTABLE_PREFIX",
|
||||||
|
@ -1429,17 +1430,9 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmTarget& target,
|
||||||
fileType = "wrapper.framework";
|
fileType = "wrapper.framework";
|
||||||
productType = "com.apple.product-type.framework";
|
productType = "com.apple.product-type.framework";
|
||||||
|
|
||||||
const char* version = target.GetProperty("FRAMEWORK_VERSION");
|
std::string version = target.GetFrameworkVersion();
|
||||||
if(!version)
|
|
||||||
{
|
|
||||||
version = target.GetProperty("VERSION");
|
|
||||||
}
|
|
||||||
if(!version)
|
|
||||||
{
|
|
||||||
version = "A";
|
|
||||||
}
|
|
||||||
buildSettings->AddAttribute("FRAMEWORK_VERSION",
|
buildSettings->AddAttribute("FRAMEWORK_VERSION",
|
||||||
this->CreateString(version));
|
this->CreateString(version.c_str()));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -1649,18 +1642,7 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmTarget& target,
|
||||||
if(target.GetType() == cmTarget::SHARED_LIBRARY)
|
if(target.GetType() == cmTarget::SHARED_LIBRARY)
|
||||||
{
|
{
|
||||||
// Get the install_name directory for the build tree.
|
// Get the install_name directory for the build tree.
|
||||||
install_name_dir = target.GetInstallNameDirForBuildTree(configName);
|
install_name_dir = target.GetInstallNameDirForBuildTree(configName, true);
|
||||||
if(target.GetPropertyAsBool("FRAMEWORK"))
|
|
||||||
{
|
|
||||||
if(install_name_dir.find(".framework") != install_name_dir.npos)
|
|
||||||
{
|
|
||||||
install_name_dir = install_name_dir + "/..";
|
|
||||||
install_name_dir =
|
|
||||||
cmSystemTools::CollapseFullPath(install_name_dir.c_str());
|
|
||||||
//std::cerr << "new install name " << install_name_dir << "\n";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(install_name_dir.empty())
|
if(install_name_dir.empty())
|
||||||
{
|
{
|
||||||
// Xcode will not pass the -install_name option at all if INSTALL_PATH
|
// Xcode will not pass the -install_name option at all if INSTALL_PATH
|
||||||
|
@ -2867,29 +2849,12 @@ cmGlobalXCodeGenerator
|
||||||
if(this->XcodeVersion > 20)
|
if(this->XcodeVersion > 20)
|
||||||
{
|
{
|
||||||
if(config)
|
if(config)
|
||||||
{
|
|
||||||
if(dir.find(".framework") != dir.npos)
|
|
||||||
{
|
|
||||||
// Remove trailing slashes (so that the rfind does not find the one at
|
|
||||||
// the very end...!)
|
|
||||||
//
|
|
||||||
cmSystemTools::ConvertToUnixSlashes(dir);
|
|
||||||
std::string::size_type pos = dir.rfind("/");
|
|
||||||
std::string framework = dir.substr(pos);
|
|
||||||
std::string newDir = dir.substr(0, pos);
|
|
||||||
newDir += "/";
|
|
||||||
newDir += config;
|
|
||||||
dir = newDir;
|
|
||||||
dir += framework;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
dir += prefix;
|
dir += prefix;
|
||||||
dir += config;
|
dir += config;
|
||||||
dir += suffix;
|
dir += suffix;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
|
|
|
@ -239,16 +239,17 @@ cmInstallTargetGenerator
|
||||||
|
|
||||||
// Compute the build tree location of the framework directory
|
// Compute the build tree location of the framework directory
|
||||||
std::string from1 = fromDirConfig;
|
std::string from1 = fromDirConfig;
|
||||||
// Remove trailing slashes... so that from1 ends with ".framework":
|
from1 += targetName;
|
||||||
//
|
from1 += ".framework";
|
||||||
cmSystemTools::ConvertToUnixSlashes(from1);
|
|
||||||
files.push_back(from1);
|
files.push_back(from1);
|
||||||
|
|
||||||
type = cmTarget::INSTALL_DIRECTORY;
|
type = cmTarget::INSTALL_DIRECTORY;
|
||||||
|
|
||||||
// Need to apply install_name_tool and stripping to binary
|
// Need to apply install_name_tool and stripping to binary
|
||||||
// inside framework.
|
// inside framework.
|
||||||
toInstallPath += ".framework/";
|
toInstallPath += ".framework/Versions/";
|
||||||
|
toInstallPath += this->Target->GetFrameworkVersion();
|
||||||
|
toInstallPath += "/";
|
||||||
toInstallPath += this->GetInstallFilename(this->Target, config,
|
toInstallPath += this->GetInstallFilename(this->Target, config,
|
||||||
NameNormal);
|
NameNormal);
|
||||||
|
|
||||||
|
|
|
@ -668,7 +668,7 @@ void cmLocalVisualStudio7Generator::WriteConfiguration(std::ostream& fout,
|
||||||
if ( this->Version >= 8 )
|
if ( this->Version >= 8 )
|
||||||
{
|
{
|
||||||
// Check the filesystem type where the target will be written.
|
// Check the filesystem type where the target will be written.
|
||||||
if(cmLVS6G_IsFAT(target.GetDirectory(configName)))
|
if(cmLVS6G_IsFAT(target.GetDirectory(configName).c_str()))
|
||||||
{
|
{
|
||||||
// Add a flag telling the manifest tool to use a workaround
|
// Add a flag telling the manifest tool to use a workaround
|
||||||
// for FAT32 file systems, which can cause an empty manifest
|
// for FAT32 file systems, which can cause an empty manifest
|
||||||
|
|
|
@ -39,20 +39,11 @@ cmMakefileLibraryTargetGenerator
|
||||||
|
|
||||||
if(this->Target->IsFrameworkOnApple())
|
if(this->Target->IsFrameworkOnApple())
|
||||||
{
|
{
|
||||||
if(const char* fversion = this->Target->GetProperty("FRAMEWORK_VERSION"))
|
this->FrameworkVersion = this->Target->GetFrameworkVersion();
|
||||||
{
|
|
||||||
this->FrameworkVersion = fversion;
|
|
||||||
}
|
|
||||||
else if(const char* tversion = this->Target->GetProperty("VERSION"))
|
|
||||||
{
|
|
||||||
this->FrameworkVersion = tversion;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
this->FrameworkVersion = "A";
|
|
||||||
}
|
|
||||||
this->MacContentDirectory = this->Target->GetDirectory();
|
this->MacContentDirectory = this->Target->GetDirectory();
|
||||||
this->MacContentDirectory += "/Versions/";
|
this->MacContentDirectory += "/";
|
||||||
|
this->MacContentDirectory += this->TargetNameOut;
|
||||||
|
this->MacContentDirectory += ".framework/Versions/";
|
||||||
this->MacContentDirectory += this->FrameworkVersion;
|
this->MacContentDirectory += this->FrameworkVersion;
|
||||||
this->MacContentDirectory += "/";
|
this->MacContentDirectory += "/";
|
||||||
}
|
}
|
||||||
|
@ -244,50 +235,82 @@ void cmMakefileLibraryTargetGenerator::WriteFrameworkRules(bool relink)
|
||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
void cmMakefileLibraryTargetGenerator::CreateFramework(
|
void cmMakefileLibraryTargetGenerator::CreateFramework()
|
||||||
std::string& targetName,
|
|
||||||
std::string& outpath)
|
|
||||||
{
|
{
|
||||||
std::string symlink;
|
// TODO: Use the cmMakefileTargetGenerator::ExtraFiles vector to
|
||||||
std::string symlink2;
|
// drive rules to create these files at build time.
|
||||||
|
std::string oldName;
|
||||||
|
std::string newName;
|
||||||
|
|
||||||
|
// Compute the location of the top-level foo.framework directory.
|
||||||
|
std::string top = this->Target->GetDirectory();
|
||||||
|
top += "/";
|
||||||
|
top += this->TargetNameOut;
|
||||||
|
top += ".framework/";
|
||||||
|
|
||||||
// Make foo.framework/Versions
|
// Make foo.framework/Versions
|
||||||
std::string dir = outpath;
|
std::string versions = top;
|
||||||
dir += "Versions";
|
versions += "Versions";
|
||||||
cmSystemTools::MakeDirectory(dir.c_str());
|
cmSystemTools::MakeDirectory(versions.c_str());
|
||||||
std::string cwd = cmSystemTools::GetCurrentWorkingDirectory();
|
|
||||||
// cd foo.framework to setup symlinks with relative paths
|
// Make foo.framework/Versions/version
|
||||||
cmSystemTools::ChangeDirectory((outpath+"Versions").c_str());
|
std::string version = versions;
|
||||||
|
version += "/";
|
||||||
|
version += this->FrameworkVersion;
|
||||||
|
cmSystemTools::MakeDirectory(version.c_str());
|
||||||
|
|
||||||
// Current -> version
|
// Current -> version
|
||||||
symlink = this->FrameworkVersion;
|
oldName = this->FrameworkVersion;
|
||||||
symlink2 = "Current";
|
newName = versions;
|
||||||
cmSystemTools::RemoveFile("Current");
|
newName += "/Current";
|
||||||
cmSystemTools::CreateSymlink(symlink.c_str(), symlink2.c_str());
|
cmSystemTools::RemoveFile(newName.c_str());
|
||||||
this->Makefile->AddCMakeOutputFile((outpath + "Versions/Current").c_str());
|
cmSystemTools::CreateSymlink(oldName.c_str(), newName.c_str());
|
||||||
// change to top level of framework to create next set of symlinks
|
this->Makefile->AddCMakeOutputFile(newName.c_str());
|
||||||
cmSystemTools::ChangeDirectory(outpath.c_str());
|
|
||||||
// foo -> Versions/Current/foo
|
// foo -> Versions/Current/foo
|
||||||
symlink = "Versions/Current/";
|
oldName = "Versions/Current/";
|
||||||
symlink += targetName;
|
oldName += this->TargetNameOut;
|
||||||
symlink2 = targetName;
|
newName = top;
|
||||||
cmSystemTools::CreateSymlink(symlink.c_str(), symlink2.c_str());
|
newName += this->TargetNameOut;
|
||||||
this->Makefile->AddCMakeOutputFile((outpath + targetName).c_str());
|
cmSystemTools::RemoveFile(newName.c_str());
|
||||||
|
cmSystemTools::CreateSymlink(oldName.c_str(), newName.c_str());
|
||||||
|
this->Makefile->AddCMakeOutputFile(newName.c_str());
|
||||||
|
|
||||||
// Resources -> Versions/Current/Resources
|
// Resources -> Versions/Current/Resources
|
||||||
symlink = "Versions/Current/Resources";
|
if(this->MacContentFolders.find("Resources") !=
|
||||||
symlink2 = "Resources";
|
this->MacContentFolders.end())
|
||||||
cmSystemTools::CreateSymlink(symlink.c_str(), symlink2.c_str());
|
{
|
||||||
this->Makefile->AddCMakeOutputFile((outpath + "Resources").c_str());
|
oldName = "Versions/Current/Resources";
|
||||||
|
newName = top;
|
||||||
|
newName += "Resources";
|
||||||
|
cmSystemTools::RemoveFile(newName.c_str());
|
||||||
|
cmSystemTools::CreateSymlink(oldName.c_str(), newName.c_str());
|
||||||
|
this->Makefile->AddCMakeOutputFile(newName.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
// Headers -> Versions/Current/Headers
|
// Headers -> Versions/Current/Headers
|
||||||
symlink = "Versions/Current/Headers";
|
if(this->MacContentFolders.find("Headers") !=
|
||||||
symlink2 = "Headers";
|
this->MacContentFolders.end())
|
||||||
cmSystemTools::CreateSymlink(symlink.c_str(), symlink2.c_str());
|
{
|
||||||
this->Makefile->AddCMakeOutputFile((outpath + "Headers").c_str());
|
oldName = "Versions/Current/Headers";
|
||||||
|
newName = top;
|
||||||
|
newName += "Headers";
|
||||||
|
cmSystemTools::RemoveFile(newName.c_str());
|
||||||
|
cmSystemTools::CreateSymlink(oldName.c_str(), newName.c_str());
|
||||||
|
this->Makefile->AddCMakeOutputFile(newName.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
// PrivateHeaders -> Versions/Current/PrivateHeaders
|
// PrivateHeaders -> Versions/Current/PrivateHeaders
|
||||||
symlink = "Versions/Current/PrivateHeaders";
|
if(this->MacContentFolders.find("PrivateHeaders") !=
|
||||||
symlink2 = "PrivateHeaders";
|
this->MacContentFolders.end())
|
||||||
cmSystemTools::CreateSymlink(symlink.c_str(), symlink2.c_str());
|
{
|
||||||
this->Makefile->AddCMakeOutputFile((outpath + "PrivateHeaders").c_str());
|
oldName = "Versions/Current/PrivateHeaders";
|
||||||
// go back to where we were
|
newName = top;
|
||||||
cmSystemTools::ChangeDirectory(cwd.c_str());
|
newName += "PrivateHeaders";
|
||||||
|
cmSystemTools::RemoveFile(newName.c_str());
|
||||||
|
cmSystemTools::CreateSymlink(oldName.c_str(), newName.c_str());
|
||||||
|
this->Makefile->AddCMakeOutputFile(newName.c_str());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
|
@ -354,7 +377,12 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules
|
||||||
// Construct the full path version of the names.
|
// Construct the full path version of the names.
|
||||||
std::string outpath;
|
std::string outpath;
|
||||||
std::string outpathImp;
|
std::string outpathImp;
|
||||||
if(relink)
|
if(this->Target->IsFrameworkOnApple())
|
||||||
|
{
|
||||||
|
outpath = this->MacContentDirectory;
|
||||||
|
this->CreateFramework();
|
||||||
|
}
|
||||||
|
else if(relink)
|
||||||
{
|
{
|
||||||
outpath = this->Makefile->GetStartOutputDirectory();
|
outpath = this->Makefile->GetStartOutputDirectory();
|
||||||
outpath += cmake::GetCMakeFilesDirectory();
|
outpath += cmake::GetCMakeFilesDirectory();
|
||||||
|
@ -379,12 +407,6 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// If we're creating a framework, place the output into a framework directory
|
|
||||||
if(this->Target->IsFrameworkOnApple())
|
|
||||||
{
|
|
||||||
this->CreateFramework(targetName, outpath);
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string targetFullPath = outpath + targetName;
|
std::string targetFullPath = outpath + targetName;
|
||||||
std::string targetFullPathPDB = outpath + targetNamePDB;
|
std::string targetFullPathPDB = outpath + targetNamePDB;
|
||||||
std::string targetFullPathSO = outpath + targetNameSO;
|
std::string targetFullPathSO = outpath + targetNameSO;
|
||||||
|
|
|
@ -37,8 +37,7 @@ protected:
|
||||||
bool relink);
|
bool relink);
|
||||||
// MacOSX Framework support methods
|
// MacOSX Framework support methods
|
||||||
void WriteFrameworkRules(bool relink);
|
void WriteFrameworkRules(bool relink);
|
||||||
void CreateFramework(std::string& targetName,
|
void CreateFramework();
|
||||||
std::string& outpath);
|
|
||||||
|
|
||||||
// Store the computd framework version for OS X Frameworks.
|
// Store the computd framework version for OS X Frameworks.
|
||||||
std::string FrameworkVersion;
|
std::string FrameworkVersion;
|
||||||
|
|
|
@ -334,6 +334,9 @@ void cmMakefileTargetGenerator::WriteMacOSXContentRules(cmSourceFile& source,
|
||||||
macdir += pkgloc;
|
macdir += pkgloc;
|
||||||
cmSystemTools::MakeDirectory(macdir.c_str());
|
cmSystemTools::MakeDirectory(macdir.c_str());
|
||||||
|
|
||||||
|
// Record use of this content location.
|
||||||
|
this->MacContentFolders.insert(pkgloc);
|
||||||
|
|
||||||
// Get the input file location.
|
// Get the input file location.
|
||||||
std::string input = source.GetFullPath();
|
std::string input = source.GetFullPath();
|
||||||
|
|
||||||
|
@ -1456,11 +1459,8 @@ void cmMakefileTargetGenerator
|
||||||
if(cmTarget* tgt =
|
if(cmTarget* tgt =
|
||||||
this->GlobalGenerator->FindTarget(0, lib->first.c_str()))
|
this->GlobalGenerator->FindTarget(0, lib->first.c_str()))
|
||||||
{
|
{
|
||||||
if(const char* location =
|
const char* config = this->LocalGenerator->ConfigurationName.c_str();
|
||||||
tgt->GetLocation(this->LocalGenerator->ConfigurationName.c_str()))
|
depends.push_back(tgt->GetFullPath(config, false));
|
||||||
{
|
|
||||||
depends.push_back(location);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
// depend on full path libs as well
|
// depend on full path libs as well
|
||||||
else if(cmSystemTools::FileIsFullPath(lib->first.c_str()))
|
else if(cmSystemTools::FileIsFullPath(lib->first.c_str()))
|
||||||
|
|
|
@ -204,6 +204,7 @@ protected:
|
||||||
|
|
||||||
// Mac OS X content info.
|
// Mac OS X content info.
|
||||||
std::string MacContentDirectory;
|
std::string MacContentDirectory;
|
||||||
|
std::set<cmStdString> MacContentFolders;
|
||||||
|
|
||||||
// Target-wide Fortran module output directory.
|
// Target-wide Fortran module output directory.
|
||||||
bool FortranModuleDirectoryComputed;
|
bool FortranModuleDirectoryComputed;
|
||||||
|
|
|
@ -1626,43 +1626,31 @@ void cmTarget::MarkAsImported()
|
||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
const char* cmTarget::GetDirectory(const char* config, bool implib)
|
std::string cmTarget::GetDirectory(const char* config, bool implib)
|
||||||
{
|
{
|
||||||
if (this->IsImported())
|
if (this->IsImported())
|
||||||
{
|
{
|
||||||
return this->ImportedGetDirectory(config, implib);
|
// Return the directory from which the target is imported.
|
||||||
|
return
|
||||||
|
cmSystemTools::GetFilenamePath(
|
||||||
|
this->ImportedGetFullPath(config, implib));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
return this->NormalGetDirectory(config, implib);
|
// Return the directory in which the target will be built.
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
|
||||||
const char* cmTarget::ImportedGetDirectory(const char* config, bool implib)
|
|
||||||
{
|
|
||||||
this->Directory =
|
|
||||||
cmSystemTools::GetFilenamePath(
|
|
||||||
this->ImportedGetFullPath(config, implib));
|
|
||||||
return this->Directory.c_str();
|
|
||||||
}
|
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
|
||||||
const char* cmTarget::NormalGetDirectory(const char* config, bool implib)
|
|
||||||
{
|
|
||||||
if(config && *config)
|
if(config && *config)
|
||||||
{
|
{
|
||||||
// Do not create the directory when config is given:
|
|
||||||
this->Directory = this->GetOutputDir(implib);
|
|
||||||
// Add the configuration's subdirectory.
|
// Add the configuration's subdirectory.
|
||||||
|
std::string dir = this->GetOutputDir(implib);
|
||||||
this->Makefile->GetLocalGenerator()->GetGlobalGenerator()->
|
this->Makefile->GetLocalGenerator()->GetGlobalGenerator()->
|
||||||
AppendDirectoryForConfig("/", config, "", this->Directory);
|
AppendDirectoryForConfig("/", config, "", dir);
|
||||||
return this->Directory.c_str();
|
return dir;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
return this->GetOutputDir(implib);
|
return this->GetOutputDir(implib);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
|
@ -1688,22 +1676,31 @@ const char* cmTarget::ImportedGetLocation(const char* config)
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
const char* cmTarget::NormalGetLocation(const char* config)
|
const char* cmTarget::NormalGetLocation(const char* config)
|
||||||
{
|
{
|
||||||
this->Location = this->GetDirectory(config);
|
// Handle the configuration-specific case first.
|
||||||
|
if(config)
|
||||||
|
{
|
||||||
|
this->Location = this->GetFullPath(config, false);
|
||||||
|
return this->Location.c_str();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Now handle the deprecated build-time configuration location.
|
||||||
|
this->Location = this->GetDirectory();
|
||||||
if(!this->Location.empty())
|
if(!this->Location.empty())
|
||||||
{
|
{
|
||||||
this->Location += "/";
|
this->Location += "/";
|
||||||
}
|
}
|
||||||
if(!config)
|
|
||||||
{
|
|
||||||
// No specific configuration was given so it will not appear on
|
|
||||||
// the result of GetDirectory. Add a name here to be replaced at
|
|
||||||
// build time.
|
|
||||||
const char* cfgid = this->Makefile->GetDefinition("CMAKE_CFG_INTDIR");
|
const char* cfgid = this->Makefile->GetDefinition("CMAKE_CFG_INTDIR");
|
||||||
if(cfgid && strcmp(cfgid, ".") != 0)
|
if(cfgid && strcmp(cfgid, ".") != 0)
|
||||||
{
|
{
|
||||||
this->Location += cfgid;
|
this->Location += cfgid;
|
||||||
this->Location += "/";
|
this->Location += "/";
|
||||||
}
|
}
|
||||||
|
if(this->IsFrameworkOnApple())
|
||||||
|
{
|
||||||
|
this->Location += this->GetFullName(config, false);
|
||||||
|
this->Location += ".framework/Versions/";
|
||||||
|
this->Location += this->GetFrameworkVersion();
|
||||||
|
this->Location += "/";
|
||||||
}
|
}
|
||||||
this->Location += this->GetFullName(config, false);
|
this->Location += this->GetFullName(config, false);
|
||||||
return this->Location.c_str();
|
return this->Location.c_str();
|
||||||
|
@ -2203,6 +2200,14 @@ std::string cmTarget::NormalGetFullPath(const char* config, bool implib,
|
||||||
std::string fpath = this->GetDirectory(config, implib);
|
std::string fpath = this->GetDirectory(config, implib);
|
||||||
fpath += "/";
|
fpath += "/";
|
||||||
|
|
||||||
|
if(this->IsFrameworkOnApple())
|
||||||
|
{
|
||||||
|
fpath += this->GetFullName(config, false);
|
||||||
|
fpath += ".framework/Versions/";
|
||||||
|
fpath += this->GetFrameworkVersion();
|
||||||
|
fpath += "/";
|
||||||
|
}
|
||||||
|
|
||||||
// Add the full name of the target.
|
// Add the full name of the target.
|
||||||
if(implib)
|
if(implib)
|
||||||
{
|
{
|
||||||
|
@ -2474,7 +2479,8 @@ void cmTarget::GetLibraryNamesInternal(std::string& name,
|
||||||
const char* version = this->GetProperty("VERSION");
|
const char* version = this->GetProperty("VERSION");
|
||||||
const char* soversion = this->GetProperty("SOVERSION");
|
const char* soversion = this->GetProperty("SOVERSION");
|
||||||
if((type != cmTarget::SHARED_LIBRARY && type != cmTarget::MODULE_LIBRARY) ||
|
if((type != cmTarget::SHARED_LIBRARY && type != cmTarget::MODULE_LIBRARY) ||
|
||||||
!this->Makefile->GetDefinition(sonameFlag.c_str()))
|
!this->Makefile->GetDefinition(sonameFlag.c_str()) ||
|
||||||
|
this->IsFrameworkOnApple())
|
||||||
{
|
{
|
||||||
// Versioning is supported only for shared libraries and modules,
|
// Versioning is supported only for shared libraries and modules,
|
||||||
// and then only when the platform supports an soname flag.
|
// and then only when the platform supports an soname flag.
|
||||||
|
@ -2801,13 +2807,14 @@ bool cmTarget::NeedRelinkBeforeInstall()
|
||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
std::string cmTarget::GetInstallNameDirForBuildTree(const char* config)
|
std::string cmTarget::GetInstallNameDirForBuildTree(const char* config,
|
||||||
|
bool for_xcode)
|
||||||
{
|
{
|
||||||
// If building directly for installation then the build tree install_name
|
// If building directly for installation then the build tree install_name
|
||||||
// is the same as the install tree.
|
// is the same as the install tree.
|
||||||
if(this->GetPropertyAsBool("BUILD_WITH_INSTALL_RPATH"))
|
if(this->GetPropertyAsBool("BUILD_WITH_INSTALL_RPATH"))
|
||||||
{
|
{
|
||||||
return GetInstallNameDirForInstallTree(config);
|
return GetInstallNameDirForInstallTree(config, for_xcode);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Use the build tree directory for the target.
|
// Use the build tree directory for the target.
|
||||||
|
@ -2817,6 +2824,13 @@ std::string cmTarget::GetInstallNameDirForBuildTree(const char* config)
|
||||||
{
|
{
|
||||||
std::string dir = this->GetDirectory(config);
|
std::string dir = this->GetDirectory(config);
|
||||||
dir += "/";
|
dir += "/";
|
||||||
|
if(this->IsFrameworkOnApple() && !for_xcode)
|
||||||
|
{
|
||||||
|
dir += this->GetFullName(config, false);
|
||||||
|
dir += ".framework/Versions/";
|
||||||
|
dir += this->GetFrameworkVersion();
|
||||||
|
dir += "/";
|
||||||
|
}
|
||||||
return dir;
|
return dir;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -2826,7 +2840,8 @@ std::string cmTarget::GetInstallNameDirForBuildTree(const char* config)
|
||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
std::string cmTarget::GetInstallNameDirForInstallTree(const char*)
|
std::string cmTarget::GetInstallNameDirForInstallTree(const char* config,
|
||||||
|
bool for_xcode)
|
||||||
{
|
{
|
||||||
// Lookup the target property.
|
// Lookup the target property.
|
||||||
const char* install_name_dir = this->GetProperty("INSTALL_NAME_DIR");
|
const char* install_name_dir = this->GetProperty("INSTALL_NAME_DIR");
|
||||||
|
@ -2836,6 +2851,13 @@ std::string cmTarget::GetInstallNameDirForInstallTree(const char*)
|
||||||
{
|
{
|
||||||
std::string dir = install_name_dir;
|
std::string dir = install_name_dir;
|
||||||
dir += "/";
|
dir += "/";
|
||||||
|
if(this->IsFrameworkOnApple() && !for_xcode)
|
||||||
|
{
|
||||||
|
dir += this->GetFullName(config, false);
|
||||||
|
dir += ".framework/Versions/";
|
||||||
|
dir += this->GetFrameworkVersion();
|
||||||
|
dir += "/";
|
||||||
|
}
|
||||||
return dir;
|
return dir;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -2845,7 +2867,7 @@ std::string cmTarget::GetInstallNameDirForInstallTree(const char*)
|
||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
const char* cmTarget::GetOutputDir(bool implib)
|
std::string cmTarget::GetOutputDir(bool implib)
|
||||||
{
|
{
|
||||||
// The implib option is only allowed for shared libraries, module
|
// The implib option is only allowed for shared libraries, module
|
||||||
// libraries, and executables.
|
// libraries, and executables.
|
||||||
|
@ -2879,12 +2901,22 @@ const char* cmTarget::GetOutputDir(bool implib)
|
||||||
msg.c_str());
|
msg.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return this->ComputeBaseOutputDir(implib);
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
std::string const& cmTarget::ComputeBaseOutputDir(bool implib)
|
||||||
|
{
|
||||||
// Select whether we are constructing the directory for the main
|
// Select whether we are constructing the directory for the main
|
||||||
// target or the import library.
|
// target or the import library.
|
||||||
std::string& out = implib? this->OutputDirImplib : this->OutputDir;
|
std::string& out = implib? this->BaseOutputDirImplib : this->BaseOutputDir;
|
||||||
|
|
||||||
if(out.empty())
|
// Return immediately if the directory has already been computed.
|
||||||
|
if(!out.empty())
|
||||||
{
|
{
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
// Look for a target property defining the target output directory
|
// Look for a target property defining the target output directory
|
||||||
// based on the target type.
|
// based on the target type.
|
||||||
const char* propertyName = 0;
|
const char* propertyName = 0;
|
||||||
|
@ -2970,26 +3002,30 @@ const char* cmTarget::GetOutputDir(bool implib)
|
||||||
// Default to the current output directory.
|
// Default to the current output directory.
|
||||||
out = ".";
|
out = ".";
|
||||||
}
|
}
|
||||||
|
|
||||||
// Convert the output path to a full path in case it is
|
// Convert the output path to a full path in case it is
|
||||||
// specified as a relative path. Treat a relative path as
|
// specified as a relative path. Treat a relative path as
|
||||||
// relative to the current output directory for this makefile.
|
// relative to the current output directory for this makefile.
|
||||||
out =
|
out = (cmSystemTools::CollapseFullPath
|
||||||
cmSystemTools::CollapseFullPath
|
(out.c_str(), this->Makefile->GetStartOutputDirectory()));
|
||||||
(out.c_str(), this->Makefile->GetStartOutputDirectory());
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
// TODO: Make AppBundle and Framework directory computation in
|
//----------------------------------------------------------------------------
|
||||||
// target consistent. Why do we add the .framework part here for
|
std::string cmTarget::GetFrameworkVersion()
|
||||||
// frameworks but not the .app part for bundles? We should
|
{
|
||||||
// probably not add it for either.
|
if(const char* fversion = this->GetProperty("FRAMEWORK_VERSION"))
|
||||||
if(this->IsFrameworkOnApple())
|
|
||||||
{
|
{
|
||||||
out += "/";
|
return fversion;
|
||||||
out += this->GetFullName(0, implib);
|
|
||||||
out += ".framework";
|
|
||||||
}
|
}
|
||||||
|
else if(const char* tversion = this->GetProperty("VERSION"))
|
||||||
|
{
|
||||||
|
return tversion;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return "A";
|
||||||
}
|
}
|
||||||
|
|
||||||
return out.c_str();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
|
|
|
@ -253,7 +253,7 @@ public:
|
||||||
configuration name is given then the generator will add its
|
configuration name is given then the generator will add its
|
||||||
subdirectory for that configuration. Otherwise just the canonical
|
subdirectory for that configuration. Otherwise just the canonical
|
||||||
output directory is given. */
|
output directory is given. */
|
||||||
const char* GetDirectory(const char* config = 0, bool implib = false);
|
std::string GetDirectory(const char* config = 0, bool implib = false);
|
||||||
|
|
||||||
/** Get the location of the target in the build tree for the given
|
/** Get the location of the target in the build tree for the given
|
||||||
configuration. This location is suitable for use as the LOCATION
|
configuration. This location is suitable for use as the LOCATION
|
||||||
|
@ -348,8 +348,10 @@ public:
|
||||||
/** Return true if builtin chrpath will work for this target */
|
/** Return true if builtin chrpath will work for this target */
|
||||||
bool IsChrpathUsed();
|
bool IsChrpathUsed();
|
||||||
|
|
||||||
std::string GetInstallNameDirForBuildTree(const char* config);
|
std::string GetInstallNameDirForBuildTree(const char* config,
|
||||||
std::string GetInstallNameDirForInstallTree(const char* config);
|
bool for_xcode = false);
|
||||||
|
std::string GetInstallNameDirForInstallTree(const char* config,
|
||||||
|
bool for_xcode = false);
|
||||||
|
|
||||||
cmComputeLinkInformation* GetLinkInformation(const char* config);
|
cmComputeLinkInformation* GetLinkInformation(const char* config);
|
||||||
|
|
||||||
|
@ -384,6 +386,10 @@ public:
|
||||||
/** Return whether this target is an executable Bundle on Apple. */
|
/** Return whether this target is an executable Bundle on Apple. */
|
||||||
bool IsAppBundleOnApple();
|
bool IsAppBundleOnApple();
|
||||||
|
|
||||||
|
/** Return the framework version string. Undefined if
|
||||||
|
IsFrameworkOnApple returns false. */
|
||||||
|
std::string GetFrameworkVersion();
|
||||||
|
|
||||||
/** Get a backtrace from the creation of the target. */
|
/** Get a backtrace from the creation of the target. */
|
||||||
cmListFileBacktrace const& GetBacktrace() const;
|
cmListFileBacktrace const& GetBacktrace() const;
|
||||||
|
|
||||||
|
@ -464,16 +470,14 @@ private:
|
||||||
void SetPropertyDefault(const char* property, const char* default_value);
|
void SetPropertyDefault(const char* property, const char* default_value);
|
||||||
|
|
||||||
// Get the full path to the target output directory.
|
// Get the full path to the target output directory.
|
||||||
const char* GetOutputDir(bool implib);
|
std::string GetOutputDir(bool implib);
|
||||||
|
std::string const& cmTarget::ComputeBaseOutputDir(bool implib);
|
||||||
|
|
||||||
const char* ImportedGetLocation(const char* config);
|
const char* ImportedGetLocation(const char* config);
|
||||||
const char* NormalGetLocation(const char* config);
|
const char* NormalGetLocation(const char* config);
|
||||||
|
|
||||||
std::string GetFullNameImported(const char* config, bool implib);
|
std::string GetFullNameImported(const char* config, bool implib);
|
||||||
|
|
||||||
const char* ImportedGetDirectory(const char* config, bool implib);
|
|
||||||
const char* NormalGetDirectory(const char* config, bool implib);
|
|
||||||
|
|
||||||
std::string ImportedGetFullPath(const char* config, bool implib);
|
std::string ImportedGetFullPath(const char* config, bool implib);
|
||||||
std::string NormalGetFullPath(const char* config, bool implib,
|
std::string NormalGetFullPath(const char* config, bool implib,
|
||||||
bool realname);
|
bool realname);
|
||||||
|
@ -500,9 +504,8 @@ private:
|
||||||
bool HaveInstallRule;
|
bool HaveInstallRule;
|
||||||
std::string InstallPath;
|
std::string InstallPath;
|
||||||
std::string RuntimeInstallPath;
|
std::string RuntimeInstallPath;
|
||||||
std::string OutputDir;
|
std::string BaseOutputDir;
|
||||||
std::string OutputDirImplib;
|
std::string BaseOutputDirImplib;
|
||||||
std::string Directory;
|
|
||||||
std::string Location;
|
std::string Location;
|
||||||
std::string ExportMacro;
|
std::string ExportMacro;
|
||||||
std::set<cmStdString> Utilities;
|
std::set<cmStdString> Utilities;
|
||||||
|
|
|
@ -10,8 +10,11 @@ add_library(foo SHARED
|
||||||
fooNeither.h
|
fooNeither.h
|
||||||
fooBoth.h
|
fooBoth.h
|
||||||
test.lua
|
test.lua
|
||||||
|
fooDeepPublic.h
|
||||||
)
|
)
|
||||||
|
set_property(SOURCE fooDeepPublic.h
|
||||||
|
PROPERTY MACOSX_PACKAGE_LOCATION Headers/Deep
|
||||||
|
)
|
||||||
set(foo_ver ver4)
|
set(foo_ver ver4)
|
||||||
|
|
||||||
set_target_properties(foo PROPERTIES
|
set_target_properties(foo PROPERTIES
|
||||||
|
@ -20,6 +23,7 @@ set_target_properties(foo PROPERTIES
|
||||||
PRIVATE_HEADER "fooPrivate.h;fooBoth.h"
|
PRIVATE_HEADER "fooPrivate.h;fooBoth.h"
|
||||||
PUBLIC_HEADER "foo.h;foo2.h;fooPublic.h;fooBoth.h"
|
PUBLIC_HEADER "foo.h;foo2.h;fooPublic.h;fooBoth.h"
|
||||||
RESOURCE "test.lua"
|
RESOURCE "test.lua"
|
||||||
|
INSTALL_NAME_DIR "@executable_path/../../../Library/Frameworks"
|
||||||
)
|
)
|
||||||
# fooBoth.h is listed as both public and private... (private wins...)
|
# fooBoth.h is listed as both public and private... (private wins...)
|
||||||
# fooNeither.h is listed as neither public nor private...
|
# fooNeither.h is listed as neither public nor private...
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
fooDeepPublic
|
Loading…
Reference in New Issue