From 28ea03473785eddce544704306a239407a8f79bb Mon Sep 17 00:00:00 2001 From: Brad King Date: Mon, 28 Jan 2008 13:05:58 -0500 Subject: 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 --- Source/cmComputeLinkInformation.cxx | 6 ++-- Source/cmExportFileGenerator.cxx | 13 +++++++- Source/cmExportInstallFileGenerator.cxx | 13 ++++++-- Source/cmGlobalGenerator.cxx | 3 +- Source/cmGlobalXCodeGenerator.cxx | 9 ++---- Source/cmInstallCommand.cxx | 6 ++-- Source/cmInstallCommand.h | 11 ++++--- Source/cmInstallTargetGenerator.cxx | 3 +- Source/cmMakefileLibraryTargetGenerator.cxx | 11 +++---- Source/cmTarget.cxx | 48 ++++++++++------------------- Source/cmTarget.h | 4 +++ 11 files changed, 62 insertions(+), 65 deletions(-) diff --git a/Source/cmComputeLinkInformation.cxx b/Source/cmComputeLinkInformation.cxx index 4d0d93a..b614de8 100644 --- a/Source/cmComputeLinkInformation.cxx +++ b/Source/cmComputeLinkInformation.cxx @@ -337,9 +337,8 @@ void cmComputeLinkInformation::AddItem(std::string const& item, // Pass the full path to the target file. std::string lib = tgt->GetFullPath(config, implib); this->Depends.push_back(lib); -#ifdef __APPLE__ - if(tgt->GetType() == cmTarget::SHARED_LIBRARY && - tgt->GetPropertyAsBool("FRAMEWORK")) + + if(tgt->IsFrameworkOnApple()) { // Frameworks on OS X need only the framework directory to // link. @@ -347,7 +346,6 @@ void cmComputeLinkInformation::AddItem(std::string const& item, this->AddFrameworkItem(fw); } else -#endif { this->AddTargetItem(lib, tgt); this->AddLibraryRuntimeInfo(lib, tgt); diff --git a/Source/cmExportFileGenerator.cxx b/Source/cmExportFileGenerator.cxx index ec4bc33..2c916e5 100644 --- a/Source/cmExportFileGenerator.cxx +++ b/Source/cmExportFileGenerator.cxx @@ -237,10 +237,21 @@ cmExportFileGenerator default: // should never happen break; } + + // Mark the imported executable if it has exports. if(target->IsExecutableWithExports()) { 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"; } diff --git a/Source/cmExportInstallFileGenerator.cxx b/Source/cmExportInstallFileGenerator.cxx index 8266a96..f378106 100644 --- a/Source/cmExportInstallFileGenerator.cxx +++ b/Source/cmExportInstallFileGenerator.cxx @@ -158,8 +158,9 @@ cmExportInstallFileGenerator te->LibraryGenerator, properties); this->SetImportLocationProperty(config, suffix, te->RuntimeGenerator, properties); + this->SetImportLocationProperty(config, suffix, + te->FrameworkGenerator, properties); - // TODO: Frameworks? // TODO: Bundles? // If any file location was set for the target add it to the @@ -223,7 +224,15 @@ cmExportInstallFileGenerator value += "/"; // 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. properties[prop] = value; diff --git a/Source/cmGlobalGenerator.cxx b/Source/cmGlobalGenerator.cxx index 6c1af53..dfa6e05 100644 --- a/Source/cmGlobalGenerator.cxx +++ b/Source/cmGlobalGenerator.cxx @@ -1359,8 +1359,7 @@ bool cmGlobalGenerator::NameResolvesToFramework(const std::string& libname) if(cmTarget* tgt = this->FindTarget(0, libname.c_str())) { - if(tgt->GetType() == cmTarget::SHARED_LIBRARY && - tgt->GetPropertyAsBool("FRAMEWORK")) + if(tgt->IsFrameworkOnApple()) { return true; } diff --git a/Source/cmGlobalXCodeGenerator.cxx b/Source/cmGlobalXCodeGenerator.cxx index 19394f2..f1a2b71 100644 --- a/Source/cmGlobalXCodeGenerator.cxx +++ b/Source/cmGlobalXCodeGenerator.cxx @@ -498,8 +498,7 @@ cmGlobalXCodeGenerator::CreateXCodeSourceFile(cmLocalGenerator* lg, // Is this a "private" or "public" framework header file? // Set the ATTRIBUTES attribute appropriately... // - if(cmtarget.GetType() == cmTarget::SHARED_LIBRARY && - cmtarget.GetPropertyAsBool("FRAMEWORK")) + if(cmtarget.IsFrameworkOnApple()) { if(tsFlags.PrivateHeader) { @@ -710,8 +709,7 @@ cmGlobalXCodeGenerator::CreateXCodeTargets(cmLocalGenerator* gen, } // some build phases only apply to bundles and/or frameworks - bool isFrameworkTarget = cmtarget.GetType() == cmTarget::SHARED_LIBRARY && - cmtarget.GetPropertyAsBool("FRAMEWORK"); + bool isFrameworkTarget = cmtarget.IsFrameworkOnApple(); bool isBundleTarget = cmtarget.GetPropertyAsBool("MACOSX_BUNDLE"); cmXCodeObject* buildFiles = 0; @@ -1359,8 +1357,7 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmTarget& target, target.GetType() == cmTarget::EXECUTABLE) { std::string pndir = target.GetDirectory(); - if (target.GetType() == cmTarget::SHARED_LIBRARY && - target.GetPropertyAsBool("FRAMEWORK")) + if(target.IsFrameworkOnApple()) { pndir += "/.."; pndir = cmSystemTools::CollapseFullPath(pndir.c_str()); diff --git a/Source/cmInstallCommand.cxx b/Source/cmInstallCommand.cxx index 6c742b9..863f138 100644 --- a/Source/cmInstallCommand.cxx +++ b/Source/cmInstallCommand.cxx @@ -376,7 +376,7 @@ bool cmInstallCommand::HandleTargetsMode(std::vector const& args) // This is a non-DLL platform. // If it is marked with FRAMEWORK property use the FRAMEWORK set of // INSTALL properties. Otherwise, use the LIBRARY properties. - if(target.GetPropertyAsBool("FRAMEWORK")) + if(target.IsFrameworkOnApple()) { // Use the FRAMEWORK properties. if (!frameworkArgs.GetDestination().empty()) @@ -512,9 +512,7 @@ bool cmInstallCommand::HandleTargetsMode(std::vector const& args) // bool createInstallGeneratorsForTargetFileSets = true; - if(cmTarget::SHARED_LIBRARY == target.GetType() && - target.GetPropertyAsBool("FRAMEWORK") && - this->Makefile->IsOn("APPLE")) + if(target.IsFrameworkOnApple()) { createInstallGeneratorsForTargetFileSets = false; } diff --git a/Source/cmInstallCommand.h b/Source/cmInstallCommand.h index 0f5eb16..ed3a3a2 100644 --- a/Source/cmInstallCommand.h +++ b/Source/cmInstallCommand.h @@ -99,7 +99,7 @@ public: "\n" "The TARGETS signature:\n" " install(TARGETS targets... [EXPORT ]\n" - " [[ARCHIVE|LIBRARY|RUNTIME]\n" + " [[ARCHIVE|LIBRARY|RUNTIME|FRAMEWORK]\n" " [DESTINATION ]\n" " [PERMISSIONS permissions...]\n" " [CONFIGURATIONS [Debug|Release|...]]\n" @@ -107,19 +107,20 @@ public: " [OPTIONAL]\n" " ] [...])\n" "The TARGETS form specifies rules for installing targets from a " - "project. There are three kinds of target files that may be " - "installed: archive, library, and runtime. " + "project. There are four kinds of target files that may be " + "installed: archive, library, runtime, and framework. " "Executables are always treated as runtime targets. " "Static libraries are always treated as archive targets. " "Module libraries are always treated as library targets. " "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 " "a runtime target and the corresponding import library is treated as " "an archive target. " "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 " "properties " "apply. If none is given the installation properties apply to " diff --git a/Source/cmInstallTargetGenerator.cxx b/Source/cmInstallTargetGenerator.cxx index 8a56329..ae16288 100644 --- a/Source/cmInstallTargetGenerator.cxx +++ b/Source/cmInstallTargetGenerator.cxx @@ -222,8 +222,7 @@ cmInstallTargetGenerator // An import library looks like a static library. type = cmTarget::STATIC_LIBRARY; } - else if(this->Target->GetMakefile()->IsOn("APPLE") && - this->Target->GetPropertyAsBool("FRAMEWORK")) + else if(this->Target->IsFrameworkOnApple()) { // Compute the build tree location of the framework directory std::string from1 = fromDirConfig; diff --git a/Source/cmMakefileLibraryTargetGenerator.cxx b/Source/cmMakefileLibraryTargetGenerator.cxx index 40bbdf2..9ab4649 100644 --- a/Source/cmMakefileLibraryTargetGenerator.cxx +++ b/Source/cmMakefileLibraryTargetGenerator.cxx @@ -111,13 +111,11 @@ void cmMakefileLibraryTargetGenerator::WriteStaticLibraryRules() //---------------------------------------------------------------------------- void cmMakefileLibraryTargetGenerator::WriteSharedLibraryRules(bool relink) { -#ifdef __APPLE__ - if (this->Target->GetPropertyAsBool("FRAMEWORK")) + if(this->Target->IsFrameworkOnApple()) { this->WriteFrameworkRules(relink); return; } -#endif const char* linkLanguage = this->Target->GetLinkerLanguage(this->GlobalGenerator); std::string linkRuleVar = "CMAKE_"; @@ -479,14 +477,13 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules outpathImp += "/"; } } -#if defined(__APPLE__) + // If we're creating a framework, place the output into a framework directory - if (this->Target->GetType() == cmTarget::SHARED_LIBRARY && - this->Target->GetPropertyAsBool("FRAMEWORK")) + if(this->Target->IsFrameworkOnApple()) { this->CreateFramework(targetName, outpath); } -#endif + std::string targetFullPath = outpath + targetName; std::string targetFullPathPDB = outpath + targetNamePDB; std::string targetFullPathSO = outpath + targetNameSO; diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx index 0fb6f7b..39b8a4e 100644 --- a/Source/cmTarget.cxx +++ b/Source/cmTarget.cxx @@ -125,7 +125,7 @@ void cmTarget::DefineProperties(cmake *cm) cm->DefineProperty ("FRAMEWORK", cmProperty::TARGET, "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 " "directory structure required for a framework and will be suitable " "to be used with the -framework option"); @@ -172,14 +172,6 @@ void cmTarget::DefineProperties(cmake *cm) "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 ("IMPORTED_IMPLIB", cmProperty::TARGET, "Full path to the import library for an IMPORTED target.", "Specifies the location of the \".lib\" part of a windows DLL. " @@ -217,6 +209,8 @@ void cmTarget::DefineProperties(cmake *cm) "library or module. " "For shared libraries on non-DLL platforms this is the location of " "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. " "Ignored for non-imported targets."); @@ -599,20 +593,16 @@ void cmTarget::SetMakefile(cmMakefile* mf) //---------------------------------------------------------------------------- bool cmTarget::IsExecutableWithExports() { - if(this->GetType() == cmTarget::EXECUTABLE) - { - if(this->IsImported()) - { - // The "IMPORTED_" namespace is used for properties exported - // from the project providing imported targets. - return this->GetPropertyAsBool("IMPORTED_ENABLE_EXPORTS"); - } - else - { - return this->GetPropertyAsBool("ENABLE_EXPORTS"); - } - } - return false; + return (this->GetType() == cmTarget::EXECUTABLE && + this->GetPropertyAsBool("ENABLE_EXPORTS")); +} + +//---------------------------------------------------------------------------- +bool cmTarget::IsFrameworkOnApple() +{ + return (this->GetType() == cmTarget::SHARED_LIBRARY && + this->Makefile->IsOn("APPLE") && + this->GetPropertyAsBool("FRAMEWORK")); } //---------------------------------------------------------------------------- @@ -2090,15 +2080,13 @@ void cmTarget::GetFullNameInternal(TargetType type, { targetSuffix = this->Makefile->GetSafeDefinition(suffixVar); } -#if defined(__APPLE__) + // frameworks do not have a prefix or a suffix - if (this->GetType() == cmTarget::SHARED_LIBRARY && - this->GetPropertyAsBool("FRAMEWORK")) + if(this->IsFrameworkOnApple()) { targetPrefix = 0; targetSuffix = 0; } -#endif // Begin the final name with the prefix. outPrefix = targetPrefix?targetPrefix:""; @@ -2715,16 +2703,12 @@ const char* cmTarget::GetAndCreateOutputDir(bool implib, bool create) cmSystemTools::CollapseFullPath (out.c_str(), this->Makefile->GetStartOutputDirectory()); -#if defined(__APPLE__) - // frameworks do not have a prefix or a suffix - if (this->GetType() == cmTarget::SHARED_LIBRARY && - this->GetPropertyAsBool("FRAMEWORK")) + if(this->IsFrameworkOnApple()) { out += "/"; out += this->GetFullName(0, implib); out += ".framework"; } -#endif // Optionally make sure the output path exists on disk. if(create) diff --git a/Source/cmTarget.h b/Source/cmTarget.h index b983629..45359bb 100644 --- a/Source/cmTarget.h +++ b/Source/cmTarget.h @@ -320,6 +320,10 @@ public: enabled. */ bool IsExecutableWithExports(); + /** Return whether this target is a shared library Framework on + Apple. */ + bool IsFrameworkOnApple(); + private: /** * A list of direct dependencies. Use in conjunction with DependencyMap. -- cgit v0.12