ENH: Support exporting/importing of Framework targets.
- Imported frameworks have the FRAMEWORK property set - Added cmTarget::IsFrameworkOnApple method to simplify checks - Also remove separate IMPORTED_ENABLE_EXPORTS property and just use ENABLE_EXPORTS since, like FRAMEWORK, it just represents the target type. - Document FRAMEWORK keyword in INSTALL command. - Updated IMPORTED_LOCATION property documentation for Frameworks
This commit is contained in:
parent
3d94b3b717
commit
28ea034737
@ -337,9 +337,8 @@ void cmComputeLinkInformation::AddItem(std::string const& item,
|
|||||||
// Pass the full path to the target file.
|
// Pass the full path to the target file.
|
||||||
std::string lib = tgt->GetFullPath(config, implib);
|
std::string lib = tgt->GetFullPath(config, implib);
|
||||||
this->Depends.push_back(lib);
|
this->Depends.push_back(lib);
|
||||||
#ifdef __APPLE__
|
|
||||||
if(tgt->GetType() == cmTarget::SHARED_LIBRARY &&
|
if(tgt->IsFrameworkOnApple())
|
||||||
tgt->GetPropertyAsBool("FRAMEWORK"))
|
|
||||||
{
|
{
|
||||||
// Frameworks on OS X need only the framework directory to
|
// Frameworks on OS X need only the framework directory to
|
||||||
// link.
|
// link.
|
||||||
@ -347,7 +346,6 @@ void cmComputeLinkInformation::AddItem(std::string const& item,
|
|||||||
this->AddFrameworkItem(fw);
|
this->AddFrameworkItem(fw);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
#endif
|
|
||||||
{
|
{
|
||||||
this->AddTargetItem(lib, tgt);
|
this->AddTargetItem(lib, tgt);
|
||||||
this->AddLibraryRuntimeInfo(lib, tgt);
|
this->AddLibraryRuntimeInfo(lib, tgt);
|
||||||
|
@ -237,10 +237,21 @@ cmExportFileGenerator
|
|||||||
default: // should never happen
|
default: // should never happen
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Mark the imported executable if it has exports.
|
||||||
if(target->IsExecutableWithExports())
|
if(target->IsExecutableWithExports())
|
||||||
{
|
{
|
||||||
os << "SET_PROPERTY(TARGET " << targetName
|
os << "SET_PROPERTY(TARGET " << targetName
|
||||||
<< " PROPERTY IMPORTED_ENABLE_EXPORTS 1)\n";
|
<< " PROPERTY ENABLE_EXPORTS 1)\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
// Mark the imported framework. This is done even on non-Apple
|
||||||
|
// platforms for reference and consistency purposes.
|
||||||
|
if(target->GetType() == cmTarget::SHARED_LIBRARY &&
|
||||||
|
target->GetPropertyAsBool("FRAMEWORK"))
|
||||||
|
{
|
||||||
|
os << "SET_PROPERTY(TARGET " << targetName
|
||||||
|
<< " PROPERTY FRAMEWORK 1)\n";
|
||||||
}
|
}
|
||||||
os << "\n";
|
os << "\n";
|
||||||
}
|
}
|
||||||
|
@ -158,8 +158,9 @@ cmExportInstallFileGenerator
|
|||||||
te->LibraryGenerator, properties);
|
te->LibraryGenerator, properties);
|
||||||
this->SetImportLocationProperty(config, suffix,
|
this->SetImportLocationProperty(config, suffix,
|
||||||
te->RuntimeGenerator, properties);
|
te->RuntimeGenerator, properties);
|
||||||
|
this->SetImportLocationProperty(config, suffix,
|
||||||
|
te->FrameworkGenerator, properties);
|
||||||
|
|
||||||
// TODO: Frameworks?
|
|
||||||
// TODO: Bundles?
|
// TODO: Bundles?
|
||||||
|
|
||||||
// If any file location was set for the target add it to the
|
// If any file location was set for the target add it to the
|
||||||
@ -223,7 +224,15 @@ cmExportInstallFileGenerator
|
|||||||
value += "/";
|
value += "/";
|
||||||
|
|
||||||
// Append the installed file name.
|
// Append the installed file name.
|
||||||
value += itgen->GetInstallFilename(config);
|
std::string fname = itgen->GetInstallFilename(config);
|
||||||
|
value += fname;
|
||||||
|
|
||||||
|
// Fix name for frameworks.
|
||||||
|
if(itgen->GetTarget()->IsFrameworkOnApple())
|
||||||
|
{
|
||||||
|
value += ".framework/";
|
||||||
|
value += fname;
|
||||||
|
}
|
||||||
|
|
||||||
// Store the property.
|
// Store the property.
|
||||||
properties[prop] = value;
|
properties[prop] = value;
|
||||||
|
@ -1359,8 +1359,7 @@ bool cmGlobalGenerator::NameResolvesToFramework(const std::string& libname)
|
|||||||
|
|
||||||
if(cmTarget* tgt = this->FindTarget(0, libname.c_str()))
|
if(cmTarget* tgt = this->FindTarget(0, libname.c_str()))
|
||||||
{
|
{
|
||||||
if(tgt->GetType() == cmTarget::SHARED_LIBRARY &&
|
if(tgt->IsFrameworkOnApple())
|
||||||
tgt->GetPropertyAsBool("FRAMEWORK"))
|
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -498,8 +498,7 @@ cmGlobalXCodeGenerator::CreateXCodeSourceFile(cmLocalGenerator* lg,
|
|||||||
// Is this a "private" or "public" framework header file?
|
// Is this a "private" or "public" framework header file?
|
||||||
// Set the ATTRIBUTES attribute appropriately...
|
// Set the ATTRIBUTES attribute appropriately...
|
||||||
//
|
//
|
||||||
if(cmtarget.GetType() == cmTarget::SHARED_LIBRARY &&
|
if(cmtarget.IsFrameworkOnApple())
|
||||||
cmtarget.GetPropertyAsBool("FRAMEWORK"))
|
|
||||||
{
|
{
|
||||||
if(tsFlags.PrivateHeader)
|
if(tsFlags.PrivateHeader)
|
||||||
{
|
{
|
||||||
@ -710,8 +709,7 @@ cmGlobalXCodeGenerator::CreateXCodeTargets(cmLocalGenerator* gen,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// some build phases only apply to bundles and/or frameworks
|
// some build phases only apply to bundles and/or frameworks
|
||||||
bool isFrameworkTarget = cmtarget.GetType() == cmTarget::SHARED_LIBRARY &&
|
bool isFrameworkTarget = cmtarget.IsFrameworkOnApple();
|
||||||
cmtarget.GetPropertyAsBool("FRAMEWORK");
|
|
||||||
bool isBundleTarget = cmtarget.GetPropertyAsBool("MACOSX_BUNDLE");
|
bool isBundleTarget = cmtarget.GetPropertyAsBool("MACOSX_BUNDLE");
|
||||||
|
|
||||||
cmXCodeObject* buildFiles = 0;
|
cmXCodeObject* buildFiles = 0;
|
||||||
@ -1359,8 +1357,7 @@ 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.GetType() == cmTarget::SHARED_LIBRARY &&
|
if(target.IsFrameworkOnApple())
|
||||||
target.GetPropertyAsBool("FRAMEWORK"))
|
|
||||||
{
|
{
|
||||||
pndir += "/..";
|
pndir += "/..";
|
||||||
pndir = cmSystemTools::CollapseFullPath(pndir.c_str());
|
pndir = cmSystemTools::CollapseFullPath(pndir.c_str());
|
||||||
|
@ -376,7 +376,7 @@ bool cmInstallCommand::HandleTargetsMode(std::vector<std::string> const& args)
|
|||||||
// This is a non-DLL platform.
|
// This is a non-DLL platform.
|
||||||
// If it is marked with FRAMEWORK property use the FRAMEWORK set of
|
// If it is marked with FRAMEWORK property use the FRAMEWORK set of
|
||||||
// INSTALL properties. Otherwise, use the LIBRARY properties.
|
// INSTALL properties. Otherwise, use the LIBRARY properties.
|
||||||
if(target.GetPropertyAsBool("FRAMEWORK"))
|
if(target.IsFrameworkOnApple())
|
||||||
{
|
{
|
||||||
// Use the FRAMEWORK properties.
|
// Use the FRAMEWORK properties.
|
||||||
if (!frameworkArgs.GetDestination().empty())
|
if (!frameworkArgs.GetDestination().empty())
|
||||||
@ -512,9 +512,7 @@ bool cmInstallCommand::HandleTargetsMode(std::vector<std::string> const& args)
|
|||||||
//
|
//
|
||||||
bool createInstallGeneratorsForTargetFileSets = true;
|
bool createInstallGeneratorsForTargetFileSets = true;
|
||||||
|
|
||||||
if(cmTarget::SHARED_LIBRARY == target.GetType() &&
|
if(target.IsFrameworkOnApple())
|
||||||
target.GetPropertyAsBool("FRAMEWORK") &&
|
|
||||||
this->Makefile->IsOn("APPLE"))
|
|
||||||
{
|
{
|
||||||
createInstallGeneratorsForTargetFileSets = false;
|
createInstallGeneratorsForTargetFileSets = false;
|
||||||
}
|
}
|
||||||
|
@ -99,7 +99,7 @@ public:
|
|||||||
"\n"
|
"\n"
|
||||||
"The TARGETS signature:\n"
|
"The TARGETS signature:\n"
|
||||||
" install(TARGETS targets... [EXPORT <export-name>]\n"
|
" install(TARGETS targets... [EXPORT <export-name>]\n"
|
||||||
" [[ARCHIVE|LIBRARY|RUNTIME]\n"
|
" [[ARCHIVE|LIBRARY|RUNTIME|FRAMEWORK]\n"
|
||||||
" [DESTINATION <dir>]\n"
|
" [DESTINATION <dir>]\n"
|
||||||
" [PERMISSIONS permissions...]\n"
|
" [PERMISSIONS permissions...]\n"
|
||||||
" [CONFIGURATIONS [Debug|Release|...]]\n"
|
" [CONFIGURATIONS [Debug|Release|...]]\n"
|
||||||
@ -107,19 +107,20 @@ public:
|
|||||||
" [OPTIONAL]\n"
|
" [OPTIONAL]\n"
|
||||||
" ] [...])\n"
|
" ] [...])\n"
|
||||||
"The TARGETS form specifies rules for installing targets from a "
|
"The TARGETS form specifies rules for installing targets from a "
|
||||||
"project. There are three kinds of target files that may be "
|
"project. There are four kinds of target files that may be "
|
||||||
"installed: archive, library, and runtime. "
|
"installed: archive, library, runtime, and framework. "
|
||||||
|
|
||||||
"Executables are always treated as runtime targets. "
|
"Executables are always treated as runtime targets. "
|
||||||
"Static libraries are always treated as archive targets. "
|
"Static libraries are always treated as archive targets. "
|
||||||
"Module libraries are always treated as library targets. "
|
"Module libraries are always treated as library targets. "
|
||||||
"For non-DLL platforms shared libraries are treated as library "
|
"For non-DLL platforms shared libraries are treated as library "
|
||||||
"targets. "
|
"targets, except that those marked with the FRAMEWORK property "
|
||||||
|
"are treated as framework targets on OS X. "
|
||||||
"For DLL platforms the DLL part of a shared library is treated as "
|
"For DLL platforms the DLL part of a shared library is treated as "
|
||||||
"a runtime target and the corresponding import library is treated as "
|
"a runtime target and the corresponding import library is treated as "
|
||||||
"an archive target. "
|
"an archive target. "
|
||||||
"All Windows-based systems including Cygwin are DLL platforms. "
|
"All Windows-based systems including Cygwin are DLL platforms. "
|
||||||
"The ARCHIVE, LIBRARY, and RUNTIME "
|
"The ARCHIVE, LIBRARY, RUNTIME, and FRAMEWORK "
|
||||||
"arguments change the type of target to which the subsequent "
|
"arguments change the type of target to which the subsequent "
|
||||||
"properties "
|
"properties "
|
||||||
"apply. If none is given the installation properties apply to "
|
"apply. If none is given the installation properties apply to "
|
||||||
|
@ -222,8 +222,7 @@ cmInstallTargetGenerator
|
|||||||
// An import library looks like a static library.
|
// An import library looks like a static library.
|
||||||
type = cmTarget::STATIC_LIBRARY;
|
type = cmTarget::STATIC_LIBRARY;
|
||||||
}
|
}
|
||||||
else if(this->Target->GetMakefile()->IsOn("APPLE") &&
|
else if(this->Target->IsFrameworkOnApple())
|
||||||
this->Target->GetPropertyAsBool("FRAMEWORK"))
|
|
||||||
{
|
{
|
||||||
// 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;
|
||||||
|
@ -111,13 +111,11 @@ void cmMakefileLibraryTargetGenerator::WriteStaticLibraryRules()
|
|||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
void cmMakefileLibraryTargetGenerator::WriteSharedLibraryRules(bool relink)
|
void cmMakefileLibraryTargetGenerator::WriteSharedLibraryRules(bool relink)
|
||||||
{
|
{
|
||||||
#ifdef __APPLE__
|
if(this->Target->IsFrameworkOnApple())
|
||||||
if (this->Target->GetPropertyAsBool("FRAMEWORK"))
|
|
||||||
{
|
{
|
||||||
this->WriteFrameworkRules(relink);
|
this->WriteFrameworkRules(relink);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
const char* linkLanguage =
|
const char* linkLanguage =
|
||||||
this->Target->GetLinkerLanguage(this->GlobalGenerator);
|
this->Target->GetLinkerLanguage(this->GlobalGenerator);
|
||||||
std::string linkRuleVar = "CMAKE_";
|
std::string linkRuleVar = "CMAKE_";
|
||||||
@ -479,14 +477,13 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules
|
|||||||
outpathImp += "/";
|
outpathImp += "/";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#if defined(__APPLE__)
|
|
||||||
// If we're creating a framework, place the output into a framework directory
|
// If we're creating a framework, place the output into a framework directory
|
||||||
if (this->Target->GetType() == cmTarget::SHARED_LIBRARY &&
|
if(this->Target->IsFrameworkOnApple())
|
||||||
this->Target->GetPropertyAsBool("FRAMEWORK"))
|
|
||||||
{
|
{
|
||||||
this->CreateFramework(targetName, outpath);
|
this->CreateFramework(targetName, outpath);
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
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;
|
||||||
|
@ -125,7 +125,7 @@ void cmTarget::DefineProperties(cmake *cm)
|
|||||||
cm->DefineProperty
|
cm->DefineProperty
|
||||||
("FRAMEWORK", cmProperty::TARGET,
|
("FRAMEWORK", cmProperty::TARGET,
|
||||||
"This target is a framework on the Mac.",
|
"This target is a framework on the Mac.",
|
||||||
"Is set to true then if this target is a shared library, it will "
|
"If a shared library target has this property set to true it will "
|
||||||
"be built as a framework when built on the mac. It will have the "
|
"be built as a framework when built on the mac. It will have the "
|
||||||
"directory structure required for a framework and will be suitable "
|
"directory structure required for a framework and will be suitable "
|
||||||
"to be used with the -framework option");
|
"to be used with the -framework option");
|
||||||
@ -171,14 +171,6 @@ void cmTarget::DefineProperties(cmake *cm)
|
|||||||
"property. "
|
"property. "
|
||||||
"Ignored for non-imported targets.");
|
"Ignored for non-imported targets.");
|
||||||
|
|
||||||
cm->DefineProperty
|
|
||||||
("IMPORTED_ENABLE_EXPORTS", cmProperty::TARGET,
|
|
||||||
"Enable linking to an IMPORTED executable target.",
|
|
||||||
"Indicates that an IMPORTED executable target exports symbols for "
|
|
||||||
"use by plugin modules. "
|
|
||||||
"This is the imported target equivalent of the ENABLE_EXPORTS "
|
|
||||||
"property.");
|
|
||||||
|
|
||||||
cm->DefineProperty
|
cm->DefineProperty
|
||||||
("IMPORTED_IMPLIB", cmProperty::TARGET,
|
("IMPORTED_IMPLIB", cmProperty::TARGET,
|
||||||
"Full path to the import library for an IMPORTED target.",
|
"Full path to the import library for an IMPORTED target.",
|
||||||
@ -217,6 +209,8 @@ void cmTarget::DefineProperties(cmake *cm)
|
|||||||
"library or module. "
|
"library or module. "
|
||||||
"For shared libraries on non-DLL platforms this is the location of "
|
"For shared libraries on non-DLL platforms this is the location of "
|
||||||
"the shared library. "
|
"the shared library. "
|
||||||
|
"For frameworks on OS X this is the location of the library file "
|
||||||
|
"symlink just inside the framework folder. "
|
||||||
"For DLLs this is the location of the \".dll\" part of the library. "
|
"For DLLs this is the location of the \".dll\" part of the library. "
|
||||||
"Ignored for non-imported targets.");
|
"Ignored for non-imported targets.");
|
||||||
|
|
||||||
@ -599,20 +593,16 @@ void cmTarget::SetMakefile(cmMakefile* mf)
|
|||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
bool cmTarget::IsExecutableWithExports()
|
bool cmTarget::IsExecutableWithExports()
|
||||||
{
|
{
|
||||||
if(this->GetType() == cmTarget::EXECUTABLE)
|
return (this->GetType() == cmTarget::EXECUTABLE &&
|
||||||
{
|
this->GetPropertyAsBool("ENABLE_EXPORTS"));
|
||||||
if(this->IsImported())
|
}
|
||||||
{
|
|
||||||
// The "IMPORTED_" namespace is used for properties exported
|
//----------------------------------------------------------------------------
|
||||||
// from the project providing imported targets.
|
bool cmTarget::IsFrameworkOnApple()
|
||||||
return this->GetPropertyAsBool("IMPORTED_ENABLE_EXPORTS");
|
{
|
||||||
}
|
return (this->GetType() == cmTarget::SHARED_LIBRARY &&
|
||||||
else
|
this->Makefile->IsOn("APPLE") &&
|
||||||
{
|
this->GetPropertyAsBool("FRAMEWORK"));
|
||||||
return this->GetPropertyAsBool("ENABLE_EXPORTS");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
@ -2090,15 +2080,13 @@ void cmTarget::GetFullNameInternal(TargetType type,
|
|||||||
{
|
{
|
||||||
targetSuffix = this->Makefile->GetSafeDefinition(suffixVar);
|
targetSuffix = this->Makefile->GetSafeDefinition(suffixVar);
|
||||||
}
|
}
|
||||||
#if defined(__APPLE__)
|
|
||||||
// frameworks do not have a prefix or a suffix
|
// frameworks do not have a prefix or a suffix
|
||||||
if (this->GetType() == cmTarget::SHARED_LIBRARY &&
|
if(this->IsFrameworkOnApple())
|
||||||
this->GetPropertyAsBool("FRAMEWORK"))
|
|
||||||
{
|
{
|
||||||
targetPrefix = 0;
|
targetPrefix = 0;
|
||||||
targetSuffix = 0;
|
targetSuffix = 0;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
// Begin the final name with the prefix.
|
// Begin the final name with the prefix.
|
||||||
outPrefix = targetPrefix?targetPrefix:"";
|
outPrefix = targetPrefix?targetPrefix:"";
|
||||||
@ -2715,16 +2703,12 @@ const char* cmTarget::GetAndCreateOutputDir(bool implib, bool create)
|
|||||||
cmSystemTools::CollapseFullPath
|
cmSystemTools::CollapseFullPath
|
||||||
(out.c_str(), this->Makefile->GetStartOutputDirectory());
|
(out.c_str(), this->Makefile->GetStartOutputDirectory());
|
||||||
|
|
||||||
#if defined(__APPLE__)
|
if(this->IsFrameworkOnApple())
|
||||||
// frameworks do not have a prefix or a suffix
|
|
||||||
if (this->GetType() == cmTarget::SHARED_LIBRARY &&
|
|
||||||
this->GetPropertyAsBool("FRAMEWORK"))
|
|
||||||
{
|
{
|
||||||
out += "/";
|
out += "/";
|
||||||
out += this->GetFullName(0, implib);
|
out += this->GetFullName(0, implib);
|
||||||
out += ".framework";
|
out += ".framework";
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
// Optionally make sure the output path exists on disk.
|
// Optionally make sure the output path exists on disk.
|
||||||
if(create)
|
if(create)
|
||||||
|
@ -320,6 +320,10 @@ public:
|
|||||||
enabled. */
|
enabled. */
|
||||||
bool IsExecutableWithExports();
|
bool IsExecutableWithExports();
|
||||||
|
|
||||||
|
/** Return whether this target is a shared library Framework on
|
||||||
|
Apple. */
|
||||||
|
bool IsFrameworkOnApple();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/**
|
/**
|
||||||
* A list of direct dependencies. Use in conjunction with DependencyMap.
|
* A list of direct dependencies. Use in conjunction with DependencyMap.
|
||||||
|
Loading…
x
Reference in New Issue
Block a user