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:
Brad King 2008-01-28 13:05:58 -05:00
parent 3d94b3b717
commit 28ea034737
11 changed files with 62 additions and 65 deletions

View File

@ -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);

View File

@ -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";
} }

View File

@ -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;

View File

@ -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;
} }

View File

@ -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());

View File

@ -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;
} }

View File

@ -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 "

View File

@ -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;

View File

@ -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;

View File

@ -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)

View File

@ -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.