diff options
author | David Cole <david.cole@kitware.com> | 2012-07-24 21:03:46 (GMT) |
---|---|---|
committer | CMake Topic Stage <kwrobot@kitware.com> | 2012-07-24 21:03:46 (GMT) |
commit | a51e1529e79ef46c8f7f346328c788a4e630e474 (patch) | |
tree | 7fed8476e05fe1278f09a130cdf2080c12762c42 | |
parent | c1bbdbff57651a24fd8d7d5abe67dd24e7e6ed27 (diff) | |
parent | 1fc8df9ca22c23f42afa94a949918cda008b07ce (diff) | |
download | CMake-a51e1529e79ef46c8f7f346328c788a4e630e474.zip CMake-a51e1529e79ef46c8f7f346328c788a4e630e474.tar.gz CMake-a51e1529e79ef46c8f7f346328c788a4e630e474.tar.bz2 |
Merge topic 'ninja-fix-macosx'
1fc8df9 Add missing this->.
7a3ecf5 Fix memory leak in Makefile generator.
9f7dc83 Ninja: also bootstrap ninja files
5d365b2 Ninja: enable ninja support everywhere
d569f3e Ninja: void function can't return a value
52160bf Ninja: enable ninja on Mac so all Mac CDash-builds are tested, cleanup later
56aeac6 Ninja: fixes for bcc
7a6bc9e Ninja: remove 'this' from member initializer list
44ba4cf Ninja: remove warnings
7751966 Ninja: remove 'friend' in ninja code
c3988ee Re-factor OS X content generator start up.
f8e0a51 Re-factor framework directory computation.
f36c7b0 Re-factor Mac OS X content directory computation.
5d885db Re-factor bundle content copying rules generation.
3b2a01e Ninja: Use same echo message as makefiles.
7bb56c5 Re-factor CFBundle generation.
...
27 files changed, 845 insertions, 462 deletions
diff --git a/Source/CMakeLists.txt b/Source/CMakeLists.txt index 14af796..e9c5a58 100644 --- a/Source/CMakeLists.txt +++ b/Source/CMakeLists.txt @@ -219,6 +219,8 @@ SET(SRCS cmMakefileExecutableTargetGenerator.cxx cmMakefileLibraryTargetGenerator.cxx cmMakefileUtilityTargetGenerator.cxx + cmOSXBundleGenerator.cxx + cmOSXBundleGenerator.h cmNewLineStyle.h cmNewLineStyle.cxx cmOrderDirectories.cxx @@ -357,40 +359,25 @@ IF (WIN32) ENDIF(NOT UNIX) ENDIF (WIN32) -# Turn on Ninja by default, but disable it -# on platforms where it does not pass all tests. -# Enforce Ninja support by setting CMAKE_USE_NINJA -set(_CMAKE_DEFAULT_NINJA_VALUE TRUE) -if(APPLE) - SET(_CMAKE_DEFAULT_NINJA_VALUE FALSE) -endif() -SET(CMAKE_ENABLE_NINJA ${_CMAKE_DEFAULT_NINJA_VALUE} CACHE BOOL - "Enable the ninja generator for CMake. When enabled, some CMake tests still fail on OSX") -MARK_AS_ADVANCED(CMAKE_ENABLE_NINJA) -IF(CMAKE_ENABLE_NINJA) - MESSAGE(STATUS "Ninja generator enabled.") - SET(SRCS ${SRCS} - cmGlobalNinjaGenerator.cxx - cmGlobalNinjaGenerator.h - cmNinjaTypes.h - cmLocalNinjaGenerator.cxx - cmLocalNinjaGenerator.h - cmNinjaTargetGenerator.cxx - cmNinjaTargetGenerator.h - cmNinjaNormalTargetGenerator.cxx - cmNinjaNormalTargetGenerator.h - cmNinjaUtilityTargetGenerator.cxx - cmNinjaUtilityTargetGenerator.h - ) - ADD_DEFINITIONS(-DCMAKE_USE_NINJA) - IF(WIN32 AND NOT CYGWIN AND NOT BORLAND) - SET_SOURCE_FILES_PROPERTIES(cmcldeps.cxx PROPERTIES COMPILE_DEFINITIONS _WIN32_WINNT=0x0501) - ADD_EXECUTABLE(cmcldeps cmcldeps.cxx) - TARGET_LINK_LIBRARIES(cmcldeps CMakeLib) - INSTALL_TARGETS(/bin cmcldeps) - ENDIF() -ELSE() - MESSAGE(STATUS "Ninja generator disabled, enable it with -DCMAKE_ENABLE_NINJA=ON") +# Ninja support +SET(SRCS ${SRCS} + cmGlobalNinjaGenerator.cxx + cmGlobalNinjaGenerator.h + cmNinjaTypes.h + cmLocalNinjaGenerator.cxx + cmLocalNinjaGenerator.h + cmNinjaTargetGenerator.cxx + cmNinjaTargetGenerator.h + cmNinjaNormalTargetGenerator.cxx + cmNinjaNormalTargetGenerator.h + cmNinjaUtilityTargetGenerator.cxx + cmNinjaUtilityTargetGenerator.h + ) +IF(WIN32 AND NOT CYGWIN AND NOT BORLAND) + SET_SOURCE_FILES_PROPERTIES(cmcldeps.cxx PROPERTIES COMPILE_DEFINITIONS _WIN32_WINNT=0x0501) + ADD_EXECUTABLE(cmcldeps cmcldeps.cxx) + TARGET_LINK_LIBRARIES(cmcldeps CMakeLib) + INSTALL_TARGETS(/bin cmcldeps) ENDIF() # create a library used by the command line and the GUI diff --git a/Source/QtDialog/CMakeLists.txt b/Source/QtDialog/CMakeLists.txt index 056e48e..07ec106 100644 --- a/Source/QtDialog/CMakeLists.txt +++ b/Source/QtDialog/CMakeLists.txt @@ -36,14 +36,14 @@ ELSE(NOT QT4_FOUND) QMacInstallDialog.cxx QMacInstallDialog.h ) - QT4_WRAP_UI(UI_SRCS + QT4_WRAP_UI(UI_SRCS CMakeSetupDialog.ui Compilers.ui CrossCompiler.ui AddCacheEntry.ui MacInstallDialog.ui ) - QT4_WRAP_CPP(MOC_SRCS + QT4_WRAP_CPP(MOC_SRCS AddCacheEntry.h Compilers.h CMakeSetupDialog.h @@ -76,7 +76,7 @@ ELSE(NOT QT4_FOUND) SET_TARGET_PROPERTIES(cmake-gui PROPERTIES OUTPUT_NAME ${CMAKE_BUNDLE_NAME}) ENDIF(APPLE) - SET(CMAKE_INSTALL_DESTINATION_ARGS + SET(CMAKE_INSTALL_DESTINATION_ARGS BUNDLE DESTINATION "${CMAKE_BUNDLE_LOCATION}") ENDIF(${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION} GREATER 2.4) @@ -112,11 +112,12 @@ ELSE(NOT QT4_FOUND) endif(APPLE) install(CODE " include(\"${CMake_SOURCE_DIR}/Modules/BundleUtilities.cmake\") + set(BU_CHMOD_BUNDLE_ITEMS ON) fixup_bundle(\"${fixup_exe}\" \"\" \"${QT_LIBRARY_DIR};${QT_BINARY_DIR}\") ") endif(APPLE OR WIN32) CONFIGURE_FILE("${QtDialog_SOURCE_DIR}/QtDialogCPack.cmake.in" - "${QtDialog_BINARY_DIR}/QtDialogCPack.cmake" @ONLY) + "${QtDialog_BINARY_DIR}/QtDialogCPack.cmake" @ONLY) ENDIF(NOT QT4_FOUND) diff --git a/Source/cmExtraCodeBlocksGenerator.cxx b/Source/cmExtraCodeBlocksGenerator.cxx index 5df8627..ad4ab76 100644 --- a/Source/cmExtraCodeBlocksGenerator.cxx +++ b/Source/cmExtraCodeBlocksGenerator.cxx @@ -60,9 +60,7 @@ cmExtraCodeBlocksGenerator::cmExtraCodeBlocksGenerator() // disable until somebody actually tests it: // this->SupportedGlobalGenerators.push_back("MSYS Makefiles"); #endif -#ifdef CMAKE_USE_NINJA this->SupportedGlobalGenerators.push_back("Ninja"); -#endif this->SupportedGlobalGenerators.push_back("Unix Makefiles"); } diff --git a/Source/cmExtraEclipseCDT4Generator.cxx b/Source/cmExtraEclipseCDT4Generator.cxx index ab11307..78a8704 100644 --- a/Source/cmExtraEclipseCDT4Generator.cxx +++ b/Source/cmExtraEclipseCDT4Generator.cxx @@ -34,9 +34,7 @@ cmExtraEclipseCDT4Generator this->SupportedGlobalGenerators.push_back("MinGW Makefiles"); // this->SupportedGlobalGenerators.push_back("MSYS Makefiles"); #endif -#ifdef CMAKE_USE_NINJA this->SupportedGlobalGenerators.push_back("Ninja"); -#endif this->SupportedGlobalGenerators.push_back("Unix Makefiles"); this->SupportsVirtualFolders = true; diff --git a/Source/cmGlobalNinjaGenerator.cxx b/Source/cmGlobalNinjaGenerator.cxx index 912e53e..3f3cfbb 100644 --- a/Source/cmGlobalNinjaGenerator.cxx +++ b/Source/cmGlobalNinjaGenerator.cxx @@ -252,6 +252,48 @@ cmGlobalNinjaGenerator::WriteCustomCommandBuild(const std::string& command, vars); } +void +cmGlobalNinjaGenerator::AddMacOSXContentRule() +{ + cmLocalGenerator *lg = this->LocalGenerators[0]; + cmMakefile* mfRoot = lg->GetMakefile(); + + cmOStringStream cmd; + cmd << lg->ConvertToOutputFormat( + mfRoot->GetRequiredDefinition("CMAKE_COMMAND"), + cmLocalGenerator::SHELL) + << " -E copy $in $out"; + + this->AddRule("COPY_OSX_CONTENT", + cmd.str(), + "Copying OS X Content $out", + "Rule for copying OS X bundle content file." + /*depfile*/ "", + /*rspfile*/ ""); +} + +void +cmGlobalNinjaGenerator::WriteMacOSXContentBuild(const std::string& input, + const std::string& output) +{ + this->AddMacOSXContentRule(); + + cmNinjaDeps outputs; + outputs.push_back(output); + cmNinjaDeps deps; + deps.push_back(input); + cmNinjaVars vars; + + cmGlobalNinjaGenerator::WriteBuild(*this->BuildFileStream, + "", + "COPY_OSX_CONTENT", + outputs, + deps, + cmNinjaDeps(), + cmNinjaDeps(), + cmNinjaVars()); +} + void cmGlobalNinjaGenerator::WriteRule(std::ostream& os, const std::string& name, const std::string& command, @@ -781,6 +823,11 @@ void cmGlobalNinjaGenerator::AddDependencyToAll(cmTarget* target) this->AppendTargetOutputs(target, this->AllDependencies); } +void cmGlobalNinjaGenerator::AddDependencyToAll(const std::string& input) +{ + this->AllDependencies.push_back(input); +} + void cmGlobalNinjaGenerator::WriteAssumedSourceDependencies() { for (std::map<std::string, std::set<std::string> >::iterator diff --git a/Source/cmGlobalNinjaGenerator.h b/Source/cmGlobalNinjaGenerator.h index ff4f85d..b2fe243 100644 --- a/Source/cmGlobalNinjaGenerator.h +++ b/Source/cmGlobalNinjaGenerator.h @@ -103,6 +103,8 @@ public: const cmNinjaDeps& outputs, const cmNinjaDeps& deps = cmNinjaDeps(), const cmNinjaDeps& orderOnlyDeps = cmNinjaDeps()); + void WriteMacOSXContentBuild(const std::string& input, + const std::string& output); /** * Write a rule statement named @a name to @a os with the @a comment, @@ -151,6 +153,7 @@ public: static bool IsMinGW() { return UsingMinGW; } + public: /// Default constructor. cmGlobalNinjaGenerator(); @@ -214,12 +217,12 @@ public: } virtual const char* GetCleanTargetName() const { return "clean"; } -public: - cmGeneratedFileStream* GetBuildFileStream() const - { return this->BuildFileStream; } - cmGeneratedFileStream* GetRulesFileStream() const - { return this->RulesFileStream; } + cmGeneratedFileStream* GetBuildFileStream() const { + return this->BuildFileStream; } + + cmGeneratedFileStream* GetRulesFileStream() const { + return this->RulesFileStream; } void AddCXXCompileCommand(const std::string &commandLine, const std::string &sourceFile); @@ -242,6 +245,52 @@ public: bool HasRule(const std::string& name); void AddCustomCommandRule(); + void AddMacOSXContentRule(); + + bool HasCustomCommandOutput(const std::string &output) { + return this->CustomCommandOutputs.find(output) != + this->CustomCommandOutputs.end(); + } + + /// Called when we have seen the given custom command. Returns true + /// if we has seen it before. + bool SeenCustomCommand(cmCustomCommand const *cc) { + return !this->CustomCommands.insert(cc).second; + } + + /// Called when we have seen the given custom command output. + void SeenCustomCommandOutput(const std::string &output) { + this->CustomCommandOutputs.insert(output); + // We don't need the assumed dependencies anymore, because we have + // an output. + this->AssumedSourceDependencies.erase(output); + } + + void AddAssumedSourceDependencies(const std::string &source, + const cmNinjaDeps &deps) { + std::set<std::string> &ASD = this->AssumedSourceDependencies[source]; + // Because we may see the same source file multiple times (same source + // specified in multiple targets), compute the union of any assumed + // dependencies. + ASD.insert(deps.begin(), deps.end()); + } + + void AppendTargetOutputs(cmTarget* target, cmNinjaDeps& outputs); + void AppendTargetDepends(cmTarget* target, cmNinjaDeps& outputs); + void AddDependencyToAll(cmTarget* target); + void AddDependencyToAll(const std::string& input); + + const std::vector<cmLocalGenerator*>& GetLocalGenerators() const { + return LocalGenerators; } + + bool IsExcluded(cmLocalGenerator* root, cmTarget& target) { + return cmGlobalGenerator::IsExcluded(root, target); } + + int GetRuleCmdLength(const std::string& name) { + return RuleCmdLength[name]; } + + void AddTargetAlias(const std::string& alias, cmTarget* target); + protected: @@ -249,21 +298,12 @@ protected: /// @see cmGlobalGenerator::CheckALLOW_DUPLICATE_CUSTOM_TARGETS() virtual bool CheckALLOW_DUPLICATE_CUSTOM_TARGETS() { return true; } + private: /// @see cmGlobalGenerator::ComputeTargetObjects virtual void ComputeTargetObjects(cmGeneratorTarget* gt) const; -private: - // In order to access the AddDependencyToAll() functions and co. - friend class cmLocalNinjaGenerator; - - // In order to access the SeenCustomCommand() function. - friend class cmNinjaTargetGenerator; - friend class cmNinjaNormalTargetGenerator; - friend class cmNinjaUtilityTargetGenerator; - -private: void OpenBuildFileStream(); void CloseBuildFileStream(); @@ -275,14 +315,8 @@ private: /// Write the common disclaimer text at the top of each build file. void WriteDisclaimer(std::ostream& os); - void AddDependencyToAll(cmTarget* target); - void WriteAssumedSourceDependencies(); - void AppendTargetOutputs(cmTarget* target, cmNinjaDeps& outputs); - void AppendTargetDepends(cmTarget* target, cmNinjaDeps& outputs); - - void AddTargetAlias(const std::string& alias, cmTarget* target); void WriteTargetAliases(std::ostream& os); void WriteBuiltinTargets(std::ostream& os); @@ -291,39 +325,9 @@ private: void WriteTargetClean(std::ostream& os); void WriteTargetHelp(std::ostream& os); - /// Called when we have seen the given custom command. Returns true - /// if we has seen it before. - bool SeenCustomCommand(cmCustomCommand const *cc) { - return !this->CustomCommands.insert(cc).second; - } - - /// Called when we have seen the given custom command output. - void SeenCustomCommandOutput(const std::string &output) { - this->CustomCommandOutputs.insert(output); - // We don't need the assumed dependencies anymore, because we have - // an output. - this->AssumedSourceDependencies.erase(output); - } - - bool HasCustomCommandOutput(const std::string &output) { - return this->CustomCommandOutputs.find(output) != - this->CustomCommandOutputs.end(); - } - - void AddAssumedSourceDependencies(const std::string &source, - const cmNinjaDeps &deps) { - std::set<std::string> &ASD = this->AssumedSourceDependencies[source]; - // Because we may see the same source file multiple times (same source - // specified in multiple targets), compute the union of any assumed - // dependencies. - ASD.insert(deps.begin(), deps.end()); - } - std::string ninjaCmd() const; - int GetRuleCmdLength(const std::string& name) { return RuleCmdLength[name]; } -private: /// The file containing the build statement. (the relation ship of the /// compilation DAG). cmGeneratedFileStream* BuildFileStream; diff --git a/Source/cmLocalNinjaGenerator.cxx b/Source/cmLocalNinjaGenerator.cxx index ea9c406..d902f4e 100644 --- a/Source/cmLocalNinjaGenerator.cxx +++ b/Source/cmLocalNinjaGenerator.cxx @@ -61,7 +61,7 @@ void cmLocalNinjaGenerator::Generate() tg->Generate(); // Add the target to "all" if required. if (!this->GetGlobalNinjaGenerator()->IsExcluded( - this->GetGlobalNinjaGenerator()->LocalGenerators[0], + this->GetGlobalNinjaGenerator()->GetLocalGenerators()[0], t->second)) this->GetGlobalNinjaGenerator()->AddDependencyToAll(&t->second); delete tg; diff --git a/Source/cmLocalNinjaGenerator.h b/Source/cmLocalNinjaGenerator.h index ea44b2f..c450841 100644 --- a/Source/cmLocalNinjaGenerator.h +++ b/Source/cmLocalNinjaGenerator.h @@ -45,7 +45,6 @@ public: /// Overloaded methods. @see cmLocalGenerator::GetTargetDirectory() virtual std::string GetTargetDirectory(cmTarget const& target) const; -public: const cmGlobalNinjaGenerator* GetGlobalNinjaGenerator() const; cmGlobalNinjaGenerator* GetGlobalNinjaGenerator(); @@ -67,33 +66,8 @@ public: std::string GetHomeRelativeOutputPath() const { return this->HomeRelativeOutputPath; } -protected: - virtual std::string ConvertToLinkReference(std::string const& lib); - virtual std::string ConvertToIncludeReference(std::string const& path); - -private: - friend class cmGlobalNinjaGenerator; - - // In order to access to protected member of the local generator. - friend class cmNinjaTargetGenerator; - friend class cmNinjaNormalTargetGenerator; - friend class cmNinjaUtilityTargetGenerator; - -private: - cmGeneratedFileStream& GetBuildFileStream() const; - cmGeneratedFileStream& GetRulesFileStream() const; - - void WriteBuildFileTop(); - void WriteProjectHeader(std::ostream& os); - void WriteNinjaFilesInclusion(std::ostream& os); - void WriteProcessedMakefile(std::ostream& os); - - void SetConfigName(); - std::string ConvertToNinjaPath(const char *path); - struct map_to_ninja_path; - friend struct map_to_ninja_path; struct map_to_ninja_path { cmLocalNinjaGenerator *LocalGenerator; map_to_ninja_path(cmLocalNinjaGenerator *LocalGen) @@ -102,26 +76,52 @@ private: return LocalGenerator->ConvertToNinjaPath(path.c_str()); } }; + map_to_ninja_path MapToNinjaPath() { return map_to_ninja_path(this); } + void ExpandRuleVariables(std::string& string, + const RuleVariables& replaceValues) { + cmLocalGenerator::ExpandRuleVariables(string, replaceValues); + } + + std::string BuildCommandLine(const std::vector<std::string> &cmdLines); + void AppendTargetOutputs(cmTarget* target, cmNinjaDeps& outputs); void AppendTargetDepends(cmTarget* target, cmNinjaDeps& outputs); - void AppendCustomCommandDeps(const cmCustomCommand *cc, - cmNinjaDeps &ninjaDeps); - std::string BuildCommandLine(const std::vector<std::string> &cmdLines); + void AddCustomCommandTarget(cmCustomCommand const* cc, cmTarget* target); void AppendCustomCommandLines(const cmCustomCommand *cc, std::vector<std::string> &cmdLines); + void AppendCustomCommandDeps(const cmCustomCommand *cc, + cmNinjaDeps &ninjaDeps); + + virtual std::string ConvertToLinkReference(std::string const& lib); + + +protected: + virtual std::string ConvertToIncludeReference(std::string const& path); + + +private: + cmGeneratedFileStream& GetBuildFileStream() const; + cmGeneratedFileStream& GetRulesFileStream() const; + + void WriteBuildFileTop(); + void WriteProjectHeader(std::ostream& os); + void WriteNinjaFilesInclusion(std::ostream& os); + void WriteProcessedMakefile(std::ostream& os); + + void SetConfigName(); + void WriteCustomCommandRule(); void WriteCustomCommandBuildStatement(cmCustomCommand const *cc, const cmNinjaDeps& orderOnlyDeps); - void AddCustomCommandTarget(cmCustomCommand const* cc, cmTarget* target); void WriteCustomCommandBuildStatements(); -private: + std::string ConfigName; std::string HomeRelativeOutputPath; diff --git a/Source/cmMakefileExecutableTargetGenerator.cxx b/Source/cmMakefileExecutableTargetGenerator.cxx index 78278cb..ab5150a 100644 --- a/Source/cmMakefileExecutableTargetGenerator.cxx +++ b/Source/cmMakefileExecutableTargetGenerator.cxx @@ -29,13 +29,19 @@ cmMakefileExecutableTargetGenerator this->TargetNameOut, this->TargetNameReal, this->TargetNameImport, this->TargetNamePDB, this->ConfigName); - if(this->Target->IsAppBundleOnApple()) - { - this->MacContentDirectory = this->Target->GetDirectory(this->ConfigName); - this->MacContentDirectory += "/"; - this->MacContentDirectory += this->TargetNameOut; - this->MacContentDirectory += ".app/Contents/"; - } + this->OSXBundleGenerator = new cmOSXBundleGenerator(this->Target, + this->TargetNameOut, + this->ConfigName); + this->OSXBundleGenerator->SetMacContentFolders(&this->MacContentFolders); + this->MacContentDirectory = + this->OSXBundleGenerator->GetMacContentDirectory(); +} + +//---------------------------------------------------------------------------- +cmMakefileExecutableTargetGenerator +::~cmMakefileExecutableTargetGenerator() +{ + delete this->OSXBundleGenerator; } //---------------------------------------------------------------------------- @@ -100,7 +106,7 @@ void cmMakefileExecutableTargetGenerator::WriteExecutableRule(bool relink) outpath += "/"; if(this->Target->IsAppBundleOnApple()) { - this->CreateAppBundle(targetName, outpath); + this->OSXBundleGenerator->CreateAppBundle(targetName, outpath); } std::string outpathImp; if(relink) @@ -129,7 +135,7 @@ void cmMakefileExecutableTargetGenerator::WriteExecutableRule(bool relink) std::string targetFullPathReal = outpath + targetNameReal; std::string targetFullPathPDB = outpath + targetNamePDB; std::string targetFullPathImport = outpathImp + targetNameImport; - std::string targetOutPathPDB = + std::string targetOutPathPDB = this->Convert(targetFullPathPDB.c_str(), cmLocalGenerator::NONE, cmLocalGenerator::SHELL); @@ -440,24 +446,3 @@ void cmMakefileExecutableTargetGenerator::WriteExecutableRule(bool relink) exeCleanFiles.begin(), exeCleanFiles.end()); } - -//---------------------------------------------------------------------------- -void -cmMakefileExecutableTargetGenerator::CreateAppBundle(std::string& targetName, - std::string& outpath) -{ - // Compute bundle directory names. - outpath = this->MacContentDirectory; - outpath += "MacOS"; - cmSystemTools::MakeDirectory(outpath.c_str()); - this->Makefile->AddCMakeOutputFile(outpath.c_str()); - outpath += "/"; - - // Configure the Info.plist file. Note that it needs the executable name - // to be set. - std::string plist = this->MacContentDirectory + "Info.plist"; - this->LocalGenerator->GenerateAppleInfoPList(this->Target, - targetName.c_str(), - plist.c_str()); - this->Makefile->AddCMakeOutputFile(plist.c_str()); -} diff --git a/Source/cmMakefileExecutableTargetGenerator.h b/Source/cmMakefileExecutableTargetGenerator.h index 985f207..3b18166 100644 --- a/Source/cmMakefileExecutableTargetGenerator.h +++ b/Source/cmMakefileExecutableTargetGenerator.h @@ -18,14 +18,14 @@ class cmMakefileExecutableTargetGenerator: public cmMakefileTargetGenerator { public: cmMakefileExecutableTargetGenerator(cmTarget* target); + virtual ~cmMakefileExecutableTargetGenerator(); /* the main entry point for this class. Writes the Makefiles associated with this target */ virtual void WriteRuleFiles(); - + protected: virtual void WriteExecutableRule(bool relink); - void CreateAppBundle(std::string& targetName, std::string& outpath); }; #endif diff --git a/Source/cmMakefileLibraryTargetGenerator.cxx b/Source/cmMakefileLibraryTargetGenerator.cxx index db59ffd..577e5fd 100644 --- a/Source/cmMakefileLibraryTargetGenerator.cxx +++ b/Source/cmMakefileLibraryTargetGenerator.cxx @@ -26,41 +26,26 @@ cmMakefileLibraryTargetGenerator ::cmMakefileLibraryTargetGenerator(cmTarget* target): cmMakefileTargetGenerator(target) { - if(this->Target->IsCFBundleOnApple()) - { - target->SetProperty("PREFIX", ""); - target->SetProperty("SUFFIX", ""); - } + cmOSXBundleGenerator::PrepareTargetProperties(this->Target); this->CustomCommandDriver = OnDepends; this->Target->GetLibraryNames( this->TargetNameOut, this->TargetNameSO, this->TargetNameReal, this->TargetNameImport, this->TargetNamePDB, this->ConfigName); - if(this->Target->IsFrameworkOnApple()) - { - this->FrameworkVersion = this->Target->GetFrameworkVersion(); - this->MacContentDirectory = this->Target->GetDirectory(this->ConfigName); - this->MacContentDirectory += "/"; - this->MacContentDirectory += this->TargetNameOut; - this->MacContentDirectory += ".framework/Versions/"; - this->MacContentDirectory += this->FrameworkVersion; - this->MacContentDirectory += "/"; - } - else if(this->Target->IsCFBundleOnApple()) - { - this->MacContentDirectory = this->Target->GetDirectory(this->ConfigName); - this->MacContentDirectory += "/"; - this->MacContentDirectory += this->TargetNameOut; - this->MacContentDirectory += "."; - const char *ext = this->Target->GetProperty("BUNDLE_EXTENSION"); - if (!ext) - { - ext = "bundle"; - } - this->MacContentDirectory += ext; - this->MacContentDirectory += "/Contents/"; - } + this->OSXBundleGenerator = new cmOSXBundleGenerator(this->Target, + this->TargetNameOut, + this->ConfigName); + this->OSXBundleGenerator->SetMacContentFolders(&this->MacContentFolders); + this->MacContentDirectory = + this->OSXBundleGenerator->GetMacContentDirectory(); +} + +//---------------------------------------------------------------------------- +cmMakefileLibraryTargetGenerator +::~cmMakefileLibraryTargetGenerator() +{ + delete this->OSXBundleGenerator; } //---------------------------------------------------------------------------- @@ -199,7 +184,7 @@ void cmMakefileLibraryTargetGenerator::WriteSharedLibraryRules(bool relink) linkFlagsConfig += cmSystemTools::UpperCase(this->ConfigName); this->LocalGenerator->AppendFlags (extraFlags, this->Target->GetProperty(linkFlagsConfig.c_str())); - + this->LocalGenerator->AddConfigVariableFlags (extraFlags, "CMAKE_SHARED_LINKER_FLAGS", this->ConfigName); this->AddModuleDefinitionFlag(extraFlags); @@ -220,7 +205,7 @@ void cmMakefileLibraryTargetGenerator::WriteModuleLibraryRules(bool relink) linkRuleVar += "_CREATE_SHARED_MODULE"; std::string extraFlags; - this->LocalGenerator->AppendFlags(extraFlags, + this->LocalGenerator->AppendFlags(extraFlags, this->Target->GetProperty("LINK_FLAGS")); std::string linkFlagsConfig = "LINK_FLAGS_"; linkFlagsConfig += cmSystemTools::UpperCase(this->ConfigName); @@ -246,7 +231,7 @@ void cmMakefileLibraryTargetGenerator::WriteFrameworkRules(bool relink) linkRuleVar += "_CREATE_MACOSX_FRAMEWORK"; std::string extraFlags; - this->LocalGenerator->AppendFlags(extraFlags, + this->LocalGenerator->AppendFlags(extraFlags, this->Target->GetProperty("LINK_FLAGS")); std::string linkFlagsConfig = "LINK_FLAGS_"; linkFlagsConfig += cmSystemTools::UpperCase(this->ConfigName); @@ -259,115 +244,6 @@ void cmMakefileLibraryTargetGenerator::WriteFrameworkRules(bool relink) } //---------------------------------------------------------------------------- -void -cmMakefileLibraryTargetGenerator -::CreateFramework(std::string const& targetName) -{ - // Configure the Info.plist file into the Resources directory. - this->MacContentFolders.insert("Resources"); - std::string plist = this->MacContentDirectory + "Resources/Info.plist"; - this->LocalGenerator->GenerateFrameworkInfoPList(this->Target, - targetName.c_str(), - plist.c_str()); - - // TODO: Use the cmMakefileTargetGenerator::ExtraFiles vector to - // 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(this->ConfigName); - top += "/"; - top += this->TargetNameOut; - top += ".framework/"; - - // Make foo.framework/Versions - std::string versions = top; - versions += "Versions"; - cmSystemTools::MakeDirectory(versions.c_str()); - - // Make foo.framework/Versions/version - std::string version = versions; - version += "/"; - version += this->FrameworkVersion; - cmSystemTools::MakeDirectory(version.c_str()); - - // Current -> version - oldName = this->FrameworkVersion; - newName = versions; - newName += "/Current"; - cmSystemTools::RemoveFile(newName.c_str()); - cmSystemTools::CreateSymlink(oldName.c_str(), newName.c_str()); - this->Makefile->AddCMakeOutputFile(newName.c_str()); - - // foo -> Versions/Current/foo - oldName = "Versions/Current/"; - oldName += this->TargetNameOut; - newName = top; - newName += this->TargetNameOut; - cmSystemTools::RemoveFile(newName.c_str()); - cmSystemTools::CreateSymlink(oldName.c_str(), newName.c_str()); - this->Makefile->AddCMakeOutputFile(newName.c_str()); - - // Resources -> Versions/Current/Resources - if(this->MacContentFolders.find("Resources") != - this->MacContentFolders.end()) - { - 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 - if(this->MacContentFolders.find("Headers") != - this->MacContentFolders.end()) - { - 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 - if(this->MacContentFolders.find("PrivateHeaders") != - this->MacContentFolders.end()) - { - oldName = "Versions/Current/PrivateHeaders"; - newName = top; - newName += "PrivateHeaders"; - cmSystemTools::RemoveFile(newName.c_str()); - cmSystemTools::CreateSymlink(oldName.c_str(), newName.c_str()); - this->Makefile->AddCMakeOutputFile(newName.c_str()); - } -} - -//---------------------------------------------------------------------------- -void -cmMakefileLibraryTargetGenerator::CreateCFBundle(std::string& targetName, - std::string& outpath) -{ - // Compute bundle directory names. - outpath = this->MacContentDirectory; - outpath += "MacOS"; - cmSystemTools::MakeDirectory(outpath.c_str()); - this->Makefile->AddCMakeOutputFile(outpath.c_str()); - outpath += "/"; - - // Configure the Info.plist file. Note that it needs the executable name - // to be set. - std::string plist = this->MacContentDirectory + "Info.plist"; - this->LocalGenerator->GenerateAppleInfoPList(this->Target, - targetName.c_str(), - plist.c_str()); - this->Makefile->AddCMakeOutputFile(plist.c_str()); -} - -//---------------------------------------------------------------------------- void cmMakefileLibraryTargetGenerator::WriteLibraryRules (const char* linkRuleVar, const char* extraFlags, bool relink) { @@ -419,13 +295,13 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules if(this->Target->IsFrameworkOnApple()) { outpath = this->MacContentDirectory; - this->CreateFramework(targetName); + this->OSXBundleGenerator->CreateFramework(targetName); } else if(this->Target->IsCFBundleOnApple()) { outpath = this->Target->GetDirectory(this->ConfigName); outpath += "/"; - this->CreateCFBundle(targetName, outpath); + this->OSXBundleGenerator->CreateCFBundle(targetName, outpath); } else if(relink) { @@ -460,16 +336,16 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules // Construct the output path version of the names for use in command // arguments. - std::string targetOutPathPDB = + std::string targetOutPathPDB = this->Convert(targetFullPathPDB.c_str(),cmLocalGenerator::NONE, cmLocalGenerator::SHELL); - std::string targetOutPath = + std::string targetOutPath = this->Convert(targetFullPath.c_str(),cmLocalGenerator::START_OUTPUT, cmLocalGenerator::SHELL); - std::string targetOutPathSO = + std::string targetOutPathSO = this->Convert(targetFullPathSO.c_str(),cmLocalGenerator::START_OUTPUT, cmLocalGenerator::SHELL); - std::string targetOutPathReal = + std::string targetOutPathReal = this->Convert(targetFullPathReal.c_str(),cmLocalGenerator::START_OUTPUT, cmLocalGenerator::SHELL); std::string targetOutPathImport = @@ -569,7 +445,7 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules std::vector<std::string> commands1; // Add a command to remove any existing files for this library. - // for static libs only + // for static libs only if(this->Target->GetType() == cmTarget::STATIC_LIBRARY) { this->LocalGenerator->AppendCleanCommand(commands1, libCleanFiles, diff --git a/Source/cmMakefileLibraryTargetGenerator.h b/Source/cmMakefileLibraryTargetGenerator.h index e6a5867..07f828b 100644 --- a/Source/cmMakefileLibraryTargetGenerator.h +++ b/Source/cmMakefileLibraryTargetGenerator.h @@ -14,16 +14,17 @@ #include "cmMakefileTargetGenerator.h" -class cmMakefileLibraryTargetGenerator: +class cmMakefileLibraryTargetGenerator: public cmMakefileTargetGenerator { public: cmMakefileLibraryTargetGenerator(cmTarget* target); + virtual ~cmMakefileLibraryTargetGenerator(); /* the main entry point for this class. Writes the Makefiles associated with this target */ - virtual void WriteRuleFiles(); - + virtual void WriteRuleFiles(); + protected: void WriteObjectLibraryRules(); void WriteStaticLibraryRules(); @@ -33,8 +34,6 @@ protected: bool relink); // MacOSX Framework support methods void WriteFrameworkRules(bool relink); - void CreateFramework(std::string const& targetName); - void CreateCFBundle(std::string& targetName, std::string& outpath); // Store the computd framework version for OS X Frameworks. std::string FrameworkVersion; diff --git a/Source/cmMakefileTargetGenerator.cxx b/Source/cmMakefileTargetGenerator.cxx index 16e3e02..0de182e 100644 --- a/Source/cmMakefileTargetGenerator.cxx +++ b/Source/cmMakefileTargetGenerator.cxx @@ -28,6 +28,8 @@ cmMakefileTargetGenerator::cmMakefileTargetGenerator(cmTarget* target) + : OSXBundleGenerator(0) + , MacOSXContentGenerator(0) { this->BuildFileStream = 0; this->InfoFileStream = 0; @@ -50,6 +52,12 @@ cmMakefileTargetGenerator::cmMakefileTargetGenerator(cmTarget* target) { this->NoRuleMessages = cmSystemTools::IsOff(ruleStatus); } + MacOSXContentGenerator = new MacOSXContentGeneratorType(this); +} + +cmMakefileTargetGenerator::~cmMakefileTargetGenerator() +{ + delete MacOSXContentGenerator; } cmMakefileTargetGenerator * @@ -153,8 +161,12 @@ void cmMakefileTargetGenerator::WriteTargetBuildRules() } } } - this->WriteMacOSXContentRules(this->GeneratorTarget->HeaderSources); - this->WriteMacOSXContentRules(this->GeneratorTarget->ExtraSources); + this->OSXBundleGenerator->GenerateMacOSXContentStatements( + this->GeneratorTarget->HeaderSources, + this->MacOSXContentGenerator); + this->OSXBundleGenerator->GenerateMacOSXContentStatements( + this->GeneratorTarget->ExtraSources, + this->MacOSXContentGenerator); for(std::vector<cmSourceFile*>::const_iterator si = this->GeneratorTarget->ExternalObjects.begin(); si != this->GeneratorTarget->ExternalObjects.end(); ++si) @@ -173,7 +185,6 @@ void cmMakefileTargetGenerator::WriteTargetBuildRules() this->GeneratorTarget->UseObjectLibraries(this->ExternalObjects); } - //---------------------------------------------------------------------------- void cmMakefileTargetGenerator::WriteCommonCodeRules() { @@ -343,44 +354,20 @@ void cmMakefileTargetGenerator::WriteTargetLanguageFlags() } } -//---------------------------------------------------------------------------- -void cmMakefileTargetGenerator::WriteMacOSXContentRules( - std::vector<cmSourceFile*> const& sources) -{ - for(std::vector<cmSourceFile*>::const_iterator - si = sources.begin(); si != sources.end(); ++si) - { - cmTarget::SourceFileFlags tsFlags = - this->Target->GetTargetSourceFileFlags(*si); - if(tsFlags.Type != cmTarget::SourceFileTypeNormal) - { - this->WriteMacOSXContentRules(**si, tsFlags.MacFolder); - } - } -} //---------------------------------------------------------------------------- -void cmMakefileTargetGenerator::WriteMacOSXContentRules(cmSourceFile& source, - const char* pkgloc) +void +cmMakefileTargetGenerator::MacOSXContentGeneratorType::operator() + (cmSourceFile& source, const char* pkgloc) { // Skip OS X content when not building a Framework or Bundle. - if(this->MacContentDirectory.empty()) + if(this->Generator->MacContentDirectory.empty()) { return; } - // Construct the full path to the content subdirectory. - std::string macdir = this->MacContentDirectory; - macdir += pkgloc; - cmSystemTools::MakeDirectory(macdir.c_str()); - - // Record use of this content location. Only the first level - // directory is needed. - { - std::string loc = pkgloc; - loc = loc.substr(0, loc.find('/')); - this->MacContentFolders.insert(loc); - } + std::string macdir = + this->Generator->OSXBundleGenerator->InitMacOSXContentDirectory(pkgloc); // Get the input file location. std::string input = source.GetFullPath(); @@ -389,9 +376,11 @@ void cmMakefileTargetGenerator::WriteMacOSXContentRules(cmSourceFile& source, std::string output = macdir; output += "/"; output += cmSystemTools::GetFilenameName(input); - this->CleanFiles.push_back(this->Convert(output.c_str(), - cmLocalGenerator::START_OUTPUT)); - output = this->Convert(output.c_str(), cmLocalGenerator::HOME_OUTPUT); + this->Generator->CleanFiles.push_back( + this->Generator->Convert(output.c_str(), + cmLocalGenerator::START_OUTPUT)); + output = this->Generator->Convert(output.c_str(), + cmLocalGenerator::HOME_OUTPUT); // Create a rule to copy the content into the bundle. std::vector<std::string> depends; @@ -399,21 +388,23 @@ void cmMakefileTargetGenerator::WriteMacOSXContentRules(cmSourceFile& source, depends.push_back(input); std::string copyEcho = "Copying OS X content "; copyEcho += output; - this->LocalGenerator->AppendEcho(commands, copyEcho.c_str(), - cmLocalUnixMakefileGenerator3::EchoBuild); + this->Generator->LocalGenerator->AppendEcho( + commands, copyEcho.c_str(), + cmLocalUnixMakefileGenerator3::EchoBuild); std::string copyCommand = "$(CMAKE_COMMAND) -E copy "; - copyCommand += this->Convert(input.c_str(), - cmLocalGenerator::NONE, - cmLocalGenerator::SHELL); + copyCommand += this->Generator->Convert(input.c_str(), + cmLocalGenerator::NONE, + cmLocalGenerator::SHELL); copyCommand += " "; - copyCommand += this->Convert(output.c_str(), - cmLocalGenerator::NONE, - cmLocalGenerator::SHELL); + copyCommand += this->Generator->Convert(output.c_str(), + cmLocalGenerator::NONE, + cmLocalGenerator::SHELL); commands.push_back(copyCommand); - this->LocalGenerator->WriteMakeRule(*this->BuildFileStream, 0, - output.c_str(), - depends, commands, false); - this->ExtraFiles.insert(output); + this->Generator->LocalGenerator->WriteMakeRule( + *this->Generator->BuildFileStream, 0, + output.c_str(), + depends, commands, false); + this->Generator->ExtraFiles.insert(output); } //---------------------------------------------------------------------------- diff --git a/Source/cmMakefileTargetGenerator.h b/Source/cmMakefileTargetGenerator.h index 36a1f68..2798e54 100644 --- a/Source/cmMakefileTargetGenerator.h +++ b/Source/cmMakefileTargetGenerator.h @@ -13,6 +13,7 @@ #define cmMakefileTargetGenerator_h #include "cmLocalUnixMakefileGenerator3.h" +#include "cmOSXBundleGenerator.h" class cmCustomCommand; class cmDependInformation; @@ -34,7 +35,7 @@ class cmMakefileTargetGenerator public: // constructor to set the ivars cmMakefileTargetGenerator(cmTarget* target); - virtual ~cmMakefileTargetGenerator() {}; + virtual ~cmMakefileTargetGenerator(); // construct using this factory call static cmMakefileTargetGenerator *New(cmTarget *tgt); @@ -50,6 +51,7 @@ public: { return this->ProgressFileNameFull; } cmTarget* GetTarget() { return this->Target;} + protected: // create the file and directory etc @@ -73,8 +75,18 @@ protected: void WriteTargetDependRules(); // write rules for Mac OS X Application Bundle content. - void WriteMacOSXContentRules(std::vector<cmSourceFile*> const& sources); - void WriteMacOSXContentRules(cmSourceFile& source, const char* pkgloc); + struct MacOSXContentGeneratorType : + cmOSXBundleGenerator::MacOSXContentGeneratorType + { + MacOSXContentGeneratorType(cmMakefileTargetGenerator* gen) : + Generator(gen) {} + + void operator()(cmSourceFile& source, const char* pkgloc); + + private: + cmMakefileTargetGenerator* Generator; + }; + friend struct MacOSXContentGeneratorType; // write the rules for an object void WriteObjectRuleFiles(cmSourceFile& source); @@ -223,6 +235,8 @@ protected: // Mac OS X content info. std::string MacContentDirectory; std::set<cmStdString> MacContentFolders; + cmOSXBundleGenerator* OSXBundleGenerator; + MacOSXContentGeneratorType* MacOSXContentGenerator; typedef std::map<cmStdString, cmStdString> ByLanguageMap; std::string GetFlags(const std::string &l); diff --git a/Source/cmMakefileUtilityTargetGenerator.cxx b/Source/cmMakefileUtilityTargetGenerator.cxx index a82c503..4456aa7 100644 --- a/Source/cmMakefileUtilityTargetGenerator.cxx +++ b/Source/cmMakefileUtilityTargetGenerator.cxx @@ -24,6 +24,19 @@ cmMakefileUtilityTargetGenerator cmMakefileTargetGenerator(target) { this->CustomCommandDriver = OnUtility; + this->OSXBundleGenerator = new cmOSXBundleGenerator(this->Target, + this->TargetNameOut, + this->ConfigName); + this->OSXBundleGenerator->SetMacContentFolders(&this->MacContentFolders); + this->MacContentDirectory = + this->OSXBundleGenerator->GetMacContentDirectory(); +} + +//---------------------------------------------------------------------------- +cmMakefileUtilityTargetGenerator +::~cmMakefileUtilityTargetGenerator() +{ + delete this->OSXBundleGenerator; } //---------------------------------------------------------------------------- diff --git a/Source/cmMakefileUtilityTargetGenerator.h b/Source/cmMakefileUtilityTargetGenerator.h index 99c16fc..fc47b38 100644 --- a/Source/cmMakefileUtilityTargetGenerator.h +++ b/Source/cmMakefileUtilityTargetGenerator.h @@ -14,16 +14,17 @@ #include "cmMakefileTargetGenerator.h" -class cmMakefileUtilityTargetGenerator: +class cmMakefileUtilityTargetGenerator: public cmMakefileTargetGenerator { public: cmMakefileUtilityTargetGenerator(cmTarget* target); + virtual ~cmMakefileUtilityTargetGenerator(); /* the main entry point for this class. Writes the Makefiles associated with this target */ - virtual void WriteRuleFiles(); - + virtual void WriteRuleFiles(); + protected: }; diff --git a/Source/cmNinjaNormalTargetGenerator.cxx b/Source/cmNinjaNormalTargetGenerator.cxx index 7805fe8..a923d60 100644 --- a/Source/cmNinjaNormalTargetGenerator.cxx +++ b/Source/cmNinjaNormalTargetGenerator.cxx @@ -16,6 +16,7 @@ #include "cmSourceFile.h" #include "cmGeneratedFileStream.h" #include "cmMakefile.h" +#include "cmOSXBundleGenerator.h" #include <assert.h> #include <algorithm> @@ -33,7 +34,10 @@ cmNinjaNormalTargetGenerator(cmTarget* target) , TargetNameReal() , TargetNameImport() , TargetNamePDB() + , TargetLinkLanguage(0) { + cmOSXBundleGenerator::PrepareTargetProperties(target); + this->TargetLinkLanguage = target->GetLinkerLanguage(this->GetConfigName()); if (target->GetType() == cmTarget::EXECUTABLE) target->GetExecutableNames(this->TargetNameOut, @@ -55,10 +59,16 @@ cmNinjaNormalTargetGenerator(cmTarget* target) // ensure the directory exists (OutDir test) EnsureDirectoryExists(target->GetDirectory(this->GetConfigName())); } + + this->OSXBundleGenerator = new cmOSXBundleGenerator(target, + this->TargetNameOut, + this->GetConfigName()); + this->OSXBundleGenerator->SetMacContentFolders(&this->MacContentFolders); } cmNinjaNormalTargetGenerator::~cmNinjaNormalTargetGenerator() { + delete this->OSXBundleGenerator; } void cmNinjaNormalTargetGenerator::Generate() @@ -115,7 +125,10 @@ const char *cmNinjaNormalTargetGenerator::GetVisibleTypeName() const case cmTarget::SHARED_LIBRARY: return "shared library"; case cmTarget::MODULE_LIBRARY: - return "shared module"; + if (this->GetTarget()->IsCFBundleOnApple()) + return "CFBundle shared module"; + else + return "shared module"; case cmTarget::EXECUTABLE: return "executable"; default: @@ -348,6 +361,40 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement() { cmTarget::TargetType targetType = this->GetTarget()->GetType(); + std::string targetOutput = ConvertToNinjaPath( + this->GetTarget()->GetFullPath(this->GetConfigName()).c_str()); + std::string targetOutputReal = ConvertToNinjaPath( + this->GetTarget()->GetFullPath(this->GetConfigName(), + /*implib=*/false, + /*realpath=*/true).c_str()); + std::string targetOutputImplib = ConvertToNinjaPath( + this->GetTarget()->GetFullPath(this->GetConfigName(), + /*implib=*/true).c_str()); + + if (this->GetTarget()->IsAppBundleOnApple()) + { + // Create the app bundle + std::string outpath; + this->OSXBundleGenerator->CreateAppBundle(this->TargetNameOut, outpath); + + // Calculate the output path + targetOutput = outpath + this->TargetNameOut; + targetOutput = this->ConvertToNinjaPath(targetOutput.c_str()); + targetOutputReal = outpath + this->TargetNameReal; + targetOutputReal = this->ConvertToNinjaPath(targetOutputReal.c_str()); + } + else if (this->GetTarget()->IsFrameworkOnApple()) + { + // Create the library framework. + this->OSXBundleGenerator->CreateFramework(this->TargetNameOut); + } + else if(this->GetTarget()->IsCFBundleOnApple()) + { + // Create the core foundation bundle. + std::string outpath; + this->OSXBundleGenerator->CreateCFBundle(this->TargetNameOut, outpath); + } + // Write comments. cmGlobalNinjaGenerator::WriteDivider(this->GetBuildFileStream()); this->GetBuildFileStream() @@ -360,16 +407,6 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement() cmNinjaDeps emptyDeps; cmNinjaVars vars; - std::string targetOutput = ConvertToNinjaPath( - this->GetTarget()->GetFullPath(this->GetConfigName()).c_str()); - std::string targetOutputReal = ConvertToNinjaPath( - this->GetTarget()->GetFullPath(this->GetConfigName(), - /*implib=*/false, - /*realpath=*/true).c_str()); - std::string targetOutputImplib = ConvertToNinjaPath( - this->GetTarget()->GetFullPath(this->GetConfigName(), - /*implib=*/true).c_str()); - // Compute the comment. cmOStringStream comment; comment << "Link the " << this->GetVisibleTypeName() << " " diff --git a/Source/cmNinjaNormalTargetGenerator.h b/Source/cmNinjaNormalTargetGenerator.h index 1ef9567..284804b 100644 --- a/Source/cmNinjaNormalTargetGenerator.h +++ b/Source/cmNinjaNormalTargetGenerator.h @@ -15,8 +15,12 @@ # include "cmNinjaTargetGenerator.h" # include "cmNinjaTypes.h" +# include "cmStandardIncludes.h" + +# include <set> class cmSourceFile; +class cmOSXBundleGenerator; class cmNinjaNormalTargetGenerator : public cmNinjaTargetGenerator { diff --git a/Source/cmNinjaTargetGenerator.cxx b/Source/cmNinjaTargetGenerator.cxx index 0d02039..3532c8b 100644 --- a/Source/cmNinjaTargetGenerator.cxx +++ b/Source/cmNinjaTargetGenerator.cxx @@ -56,7 +56,11 @@ cmNinjaTargetGenerator::New(cmTarget* target) } cmNinjaTargetGenerator::cmNinjaTargetGenerator(cmTarget* target) - : Target(target), + : + MacOSXContentGenerator(0), + OSXBundleGenerator(0), + MacContentFolders(), + Target(target), Makefile(target->GetMakefile()), LocalGenerator( static_cast<cmLocalNinjaGenerator*>(Makefile->GetLocalGenerator())), @@ -64,10 +68,12 @@ cmNinjaTargetGenerator::cmNinjaTargetGenerator(cmTarget* target) { this->GeneratorTarget = this->GetGlobalGenerator()->GetGeneratorTarget(target); + MacOSXContentGenerator = new MacOSXContentGeneratorType(this); } cmNinjaTargetGenerator::~cmNinjaTargetGenerator() { + delete this->MacOSXContentGenerator; } cmGeneratedFileStream& cmNinjaTargetGenerator::GetBuildFileStream() const @@ -87,7 +93,7 @@ cmGlobalNinjaGenerator* cmNinjaTargetGenerator::GetGlobalGenerator() const const char* cmNinjaTargetGenerator::GetConfigName() const { - return this->LocalGenerator->ConfigName.c_str(); + return this->LocalGenerator->GetConfigName(); } // TODO: Picked up from cmMakefileTargetGenerator. Refactor it. @@ -430,6 +436,12 @@ cmNinjaTargetGenerator cmCustomCommand const* cc = (*si)->GetCustomCommand(); this->GetLocalGenerator()->AddCustomCommandTarget(cc, this->GetTarget()); } + this->OSXBundleGenerator->GenerateMacOSXContentStatements( + this->GeneratorTarget->HeaderSources, + this->MacOSXContentGenerator); + this->OSXBundleGenerator->GenerateMacOSXContentStatements( + this->GeneratorTarget->ExtraSources, + this->MacOSXContentGenerator); for(std::vector<cmSourceFile*>::const_iterator si = this->GeneratorTarget->ExternalObjects.begin(); si != this->GeneratorTarget->ExternalObjects.end(); ++si) @@ -640,3 +652,38 @@ cmNinjaTargetGenerator { EnsureDirectoryExists(cmSystemTools::GetParentDirectory(path.c_str())); } + + +//---------------------------------------------------------------------------- +void +cmNinjaTargetGenerator::MacOSXContentGeneratorType::operator()( + cmSourceFile& source, const char* pkgloc) +{ + // Skip OS X content when not building a Framework or Bundle. + if(this->Generator->OSXBundleGenerator->GetMacContentDirectory().empty()) + { + return; + } + + std::string macdir = + this->Generator->OSXBundleGenerator->InitMacOSXContentDirectory(pkgloc); + + // Get the input file location. + std::string input = source.GetFullPath(); + input = + this->Generator->GetLocalGenerator()->ConvertToNinjaPath(input.c_str()); + + // Get the output file location. + std::string output = macdir; + output += "/"; + output += cmSystemTools::GetFilenameName(input); + output = + this->Generator->GetLocalGenerator()->ConvertToNinjaPath(output.c_str()); + + // Write a build statement to copy the content into the bundle. + this->Generator->GetGlobalGenerator()->WriteMacOSXContentBuild(input, + output); + + // Add as a dependency of all target so that it gets called. + this->Generator->GetGlobalGenerator()->AddDependencyToAll(output); +} diff --git a/Source/cmNinjaTargetGenerator.h b/Source/cmNinjaTargetGenerator.h index af43a8b..84573ce 100644 --- a/Source/cmNinjaTargetGenerator.h +++ b/Source/cmNinjaTargetGenerator.h @@ -16,6 +16,7 @@ #include "cmStandardIncludes.h" #include "cmNinjaTypes.h" #include "cmLocalNinjaGenerator.h" +#include "cmOSXBundleGenerator.h" class cmTarget; class cmGlobalNinjaGenerator; @@ -114,6 +115,27 @@ protected: void EnsureDirectoryExists(const std::string& dir); void EnsureParentDirectoryExists(const std::string& path); + // write rules for Mac OS X Application Bundle content. + struct MacOSXContentGeneratorType : + cmOSXBundleGenerator::MacOSXContentGeneratorType + { + MacOSXContentGeneratorType(cmNinjaTargetGenerator* g) : + Generator(g) {} + + void operator()(cmSourceFile& source, const char* pkgloc); + + private: + cmNinjaTargetGenerator* Generator; + }; + friend struct MacOSXContentGeneratorType; + +protected: + MacOSXContentGeneratorType* MacOSXContentGenerator; + // Properly initialized by sub-classes. + cmOSXBundleGenerator* OSXBundleGenerator; + std::set<cmStdString> MacContentFolders; + + private: cmTarget* Target; cmGeneratorTarget* GeneratorTarget; diff --git a/Source/cmOSXBundleGenerator.cxx b/Source/cmOSXBundleGenerator.cxx new file mode 100644 index 0000000..42fad07 --- /dev/null +++ b/Source/cmOSXBundleGenerator.cxx @@ -0,0 +1,236 @@ +/*============================================================================ + CMake - Cross Platform Makefile Generator + Copyright 2012 Nicolas Despres <nicolas.despres@gmail.com> + + Distributed under the OSI-approved BSD License (the "License"); + see accompanying file Copyright.txt for details. + + This software is distributed WITHOUT ANY WARRANTY; without even the + implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the License for more information. +============================================================================*/ +#include "cmOSXBundleGenerator.h" +#include "cmMakefile.h" +#include "cmTarget.h" +#include "cmLocalGenerator.h" + +#include <cassert> + +void cmOSXBundleGenerator::PrepareTargetProperties(cmTarget* target) +{ + if(target->IsCFBundleOnApple()) + { + target->SetProperty("PREFIX", ""); + target->SetProperty("SUFFIX", ""); + } +} + +//---------------------------------------------------------------------------- +cmOSXBundleGenerator:: +cmOSXBundleGenerator(cmTarget* target, + std::string targetNameOut, + const char* configName) + : Target(target) + , Makefile(target->GetMakefile()) + , LocalGenerator(Makefile->GetLocalGenerator()) + , TargetNameOut(targetNameOut) + , ConfigName(configName) + , MacContentDirectory() + , FrameworkVersion() + , MacContentFolders(0) +{ + if (this->MustSkip()) + return; + + this->MacContentDirectory = + this->Target->GetMacContentDirectory(this->ConfigName, + /*implib*/ false, + /*includeMacOS*/ false); + if(this->Target->IsFrameworkOnApple()) + this->FrameworkVersion = this->Target->GetFrameworkVersion(); +} + +//---------------------------------------------------------------------------- +bool cmOSXBundleGenerator::MustSkip() +{ + return !this->Target->HaveWellDefinedOutputFiles(); +} + +//---------------------------------------------------------------------------- +void cmOSXBundleGenerator::CreateAppBundle(std::string& targetName, + std::string& outpath) +{ + if (this->MustSkip()) + return; + + // Compute bundle directory names. + outpath = this->MacContentDirectory; + outpath += "MacOS"; + cmSystemTools::MakeDirectory(outpath.c_str()); + outpath += "/"; + this->Makefile->AddCMakeOutputFile(outpath.c_str()); + + // Configure the Info.plist file. Note that it needs the executable name + // to be set. + std::string plist = this->MacContentDirectory + "Info.plist"; + this->LocalGenerator->GenerateAppleInfoPList(this->Target, + targetName.c_str(), + plist.c_str()); + this->Makefile->AddCMakeOutputFile(plist.c_str()); +} + +//---------------------------------------------------------------------------- +void cmOSXBundleGenerator::CreateFramework(std::string const& targetName) +{ + if (this->MustSkip()) + return; + + assert(this->MacContentFolders); + + // Configure the Info.plist file into the Resources directory. + this->MacContentFolders->insert("Resources"); + std::string plist = this->MacContentDirectory + "Resources/Info.plist"; + this->LocalGenerator->GenerateFrameworkInfoPList(this->Target, + targetName.c_str(), + plist.c_str()); + + // TODO: Use the cmMakefileTargetGenerator::ExtraFiles vector to + // 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(this->ConfigName); + top += "/"; + top += this->TargetNameOut; + top += ".framework/"; + + // Make foo.framework/Versions + std::string versions = top; + versions += "Versions"; + cmSystemTools::MakeDirectory(versions.c_str()); + + // Make foo.framework/Versions/version + std::string version = versions; + version += "/"; + version += this->FrameworkVersion; + cmSystemTools::MakeDirectory(version.c_str()); + + // Current -> version + oldName = this->FrameworkVersion; + newName = versions; + newName += "/Current"; + cmSystemTools::RemoveFile(newName.c_str()); + cmSystemTools::CreateSymlink(oldName.c_str(), newName.c_str()); + this->Makefile->AddCMakeOutputFile(newName.c_str()); + + // foo -> Versions/Current/foo + oldName = "Versions/Current/"; + oldName += this->TargetNameOut; + newName = top; + newName += this->TargetNameOut; + cmSystemTools::RemoveFile(newName.c_str()); + cmSystemTools::CreateSymlink(oldName.c_str(), newName.c_str()); + this->Makefile->AddCMakeOutputFile(newName.c_str()); + + // Resources -> Versions/Current/Resources + if(this->MacContentFolders->find("Resources") != + this->MacContentFolders->end()) + { + 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 + if(this->MacContentFolders->find("Headers") != + this->MacContentFolders->end()) + { + 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 + if(this->MacContentFolders->find("PrivateHeaders") != + this->MacContentFolders->end()) + { + oldName = "Versions/Current/PrivateHeaders"; + newName = top; + newName += "PrivateHeaders"; + cmSystemTools::RemoveFile(newName.c_str()); + cmSystemTools::CreateSymlink(oldName.c_str(), newName.c_str()); + this->Makefile->AddCMakeOutputFile(newName.c_str()); + } +} + +//---------------------------------------------------------------------------- +void cmOSXBundleGenerator::CreateCFBundle(std::string& targetName, + std::string& outpath) +{ + if (this->MustSkip()) + return; + + // Compute bundle directory names. + outpath = this->MacContentDirectory; + outpath += "MacOS"; + cmSystemTools::MakeDirectory(outpath.c_str()); + outpath += "/"; + this->Makefile->AddCMakeOutputFile(outpath.c_str()); + + // Configure the Info.plist file. Note that it needs the executable name + // to be set. + std::string plist = this->MacContentDirectory; + plist += "Info.plist"; + this->LocalGenerator->GenerateAppleInfoPList(this->Target, + targetName.c_str(), + plist.c_str()); + this->Makefile->AddCMakeOutputFile(plist.c_str()); +} + +//---------------------------------------------------------------------------- +void +cmOSXBundleGenerator:: +GenerateMacOSXContentStatements(std::vector<cmSourceFile*> const& sources, + MacOSXContentGeneratorType* generator) +{ + if (this->MustSkip()) + return; + + for(std::vector<cmSourceFile*>::const_iterator + si = sources.begin(); si != sources.end(); ++si) + { + cmTarget::SourceFileFlags tsFlags = + this->Target->GetTargetSourceFileFlags(*si); + if(tsFlags.Type != cmTarget::SourceFileTypeNormal) + { + (*generator)(**si, tsFlags.MacFolder); + } + } +} + +//---------------------------------------------------------------------------- +std::string +cmOSXBundleGenerator::InitMacOSXContentDirectory(const char* pkgloc) +{ + // Construct the full path to the content subdirectory. + std::string macdir = this->MacContentDirectory; + macdir += pkgloc; + cmSystemTools::MakeDirectory(macdir.c_str()); + + // Record use of this content location. Only the first level + // directory is needed. + { + std::string loc = pkgloc; + loc = loc.substr(0, loc.find('/')); + this->MacContentFolders->insert(loc); + } + + return macdir; +} diff --git a/Source/cmOSXBundleGenerator.h b/Source/cmOSXBundleGenerator.h new file mode 100644 index 0000000..01e3cbe --- /dev/null +++ b/Source/cmOSXBundleGenerator.h @@ -0,0 +1,71 @@ +/*============================================================================ + CMake - Cross Platform Makefile Generator + Copyright 2012 Nicolas Despres <nicolas.despres@gmail.com> + + Distributed under the OSI-approved BSD License (the "License"); + see accompanying file Copyright.txt for details. + + This software is distributed WITHOUT ANY WARRANTY; without even the + implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the License for more information. +============================================================================*/ +#ifndef cmOSXBundleGenerator_h +#define cmOSXBundleGenerator_h + +#include "cmStandardIncludes.h" +#include "cmSourceFile.h" + +#include <string> +#include <set> + +class cmTarget; +class cmMakefile; +class cmLocalGenerator; + +class cmOSXBundleGenerator +{ +public: + static void PrepareTargetProperties(cmTarget* target); + + cmOSXBundleGenerator(cmTarget* target, + std::string targetNameOut, + const char* configName); + + void CreateAppBundle(std::string& targetName, std::string& outpath); + void CreateFramework(std::string const& targetName); + void CreateCFBundle(std::string& targetName, std::string& outpath); + + struct MacOSXContentGeneratorType + { + virtual ~MacOSXContentGeneratorType() {} + virtual void operator()(cmSourceFile& source, const char* pkgloc) = 0; + }; + + void GenerateMacOSXContentStatements( + std::vector<cmSourceFile*> const& sources, + MacOSXContentGeneratorType* generator); + std::string InitMacOSXContentDirectory(const char* pkgloc); + + std::string GetMacContentDirectory() const + { return this->MacContentDirectory; } + std::string GetFrameworkVersion() const + { return this->FrameworkVersion; } + void SetMacContentFolders(std::set<cmStdString>* macContentFolders) + { this->MacContentFolders = macContentFolders; } + +private: + bool MustSkip(); + +private: + cmTarget* Target; + cmMakefile* Makefile; + cmLocalGenerator* LocalGenerator; + std::string TargetNameOut; + const char* ConfigName; + std::string MacContentDirectory; + std::string FrameworkVersion; + std::set<cmStdString>* MacContentFolders; +}; + + +#endif diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx index 4f3f2c5..775662c 100644 --- a/Source/cmTarget.cxx +++ b/Source/cmTarget.cxx @@ -2483,6 +2483,16 @@ void cmTarget::MarkAsImported() } //---------------------------------------------------------------------------- +bool cmTarget::HaveWellDefinedOutputFiles() +{ + return + this->GetType() == cmTarget::STATIC_LIBRARY || + this->GetType() == cmTarget::SHARED_LIBRARY || + this->GetType() == cmTarget::MODULE_LIBRARY || + this->GetType() == cmTarget::EXECUTABLE; +} + +//---------------------------------------------------------------------------- cmTarget::OutputInfo const* cmTarget::GetOutputInfo(const char* config) { // There is no output information for imported targets. @@ -2492,10 +2502,7 @@ cmTarget::OutputInfo const* cmTarget::GetOutputInfo(const char* config) } // Only libraries and executables have well-defined output files. - if(this->GetType() != cmTarget::STATIC_LIBRARY && - this->GetType() != cmTarget::SHARED_LIBRARY && - this->GetType() != cmTarget::MODULE_LIBRARY && - this->GetType() != cmTarget::EXECUTABLE) + if(!this->HaveWellDefinedOutputFiles()) { std::string msg = "cmTarget::GetOutputInfo called for "; msg += this->GetName(); @@ -2586,18 +2593,7 @@ const char* cmTarget::NormalGetLocation(const char* config) this->Location += cfgid; this->Location += "/"; } - if(this->IsAppBundleOnApple()) - { - this->Location += this->GetFullName(config, false); - this->Location += ".app/Contents/MacOS/"; - } - if(this->IsFrameworkOnApple()) - { - this->Location += this->GetFullName(config, false); - this->Location += ".framework/Versions/"; - this->Location += this->GetFrameworkVersion(); - this->Location += "/"; - } + this->Location = this->BuildMacContentDirectory(this->Location, config); this->Location += this->GetFullName(config, false); return this->Location.c_str(); } @@ -3169,22 +3165,7 @@ std::string cmTarget::GetFullPath(const char* config, bool implib, std::string cmTarget::NormalGetFullPath(const char* config, bool implib, bool realname) { - // Start with the output directory for the target. - std::string fpath = this->GetDirectory(config, implib); - fpath += "/"; - - if(this->IsAppBundleOnApple()) - { - fpath += this->GetFullName(config, false); - fpath += ".app/Contents/MacOS/"; - } - if(this->IsFrameworkOnApple()) - { - fpath += this->GetFullName(config, false); - fpath += ".framework/Versions/"; - fpath += this->GetFrameworkVersion(); - fpath += "/"; - } + std::string fpath = this->GetMacContentDirectory(config, implib); // Add the full name of the target. if(implib) @@ -3707,10 +3688,7 @@ std::string cmTarget::GetInstallNameDirForBuildTree(const char* config, dir += "/"; if(this->IsFrameworkOnApple() && !for_xcode) { - dir += this->GetFullName(config, false); - dir += ".framework/Versions/"; - dir += this->GetFrameworkVersion(); - dir += "/"; + dir += this->GetFrameworkDirectory(config); } return dir; } @@ -3741,10 +3719,7 @@ std::string cmTarget::GetInstallNameDirForInstallTree(const char* config, if(this->IsFrameworkOnApple() && !for_xcode) { - dir += this->GetFullName(config, false); - dir += ".framework/Versions/"; - dir += this->GetFrameworkVersion(); - dir += "/"; + dir += this->GetFrameworkDirectory(config); } return dir; @@ -4734,6 +4709,63 @@ std::vector<std::string> cmTarget::GetIncludeDirectories() } //---------------------------------------------------------------------------- +std::string cmTarget::GetFrameworkDirectory(const char* config) +{ + std::string fpath; + fpath += this->GetFullName(config, false); + fpath += ".framework/Versions/"; + fpath += this->GetFrameworkVersion(); + fpath += "/"; + return fpath; +} + +//---------------------------------------------------------------------------- +std::string cmTarget::BuildMacContentDirectory(const std::string& base, + const char* config, + bool includeMacOS) +{ + std::string fpath = base; + if(this->IsAppBundleOnApple()) + { + fpath += this->GetFullName(config, false); + fpath += ".app/Contents/"; + if(includeMacOS) + fpath += "MacOS/"; + } + if(this->IsFrameworkOnApple()) + { + fpath += this->GetFrameworkDirectory(config); + } + if(this->IsCFBundleOnApple()) + { + fpath += this->GetFullName(config, false); + fpath += "."; + const char *ext = this->GetProperty("BUNDLE_EXTENSION"); + if (!ext) + { + ext = "bundle"; + } + fpath += ext; + fpath += "/Contents/"; + if(includeMacOS) + fpath += "MacOS/"; + } + return fpath; +} + +//---------------------------------------------------------------------------- +std::string cmTarget::GetMacContentDirectory(const char* config, + bool implib, + bool includeMacOS) +{ + // Start with the output directory for the target. + std::string fpath = this->GetDirectory(config, implib); + fpath += "/"; + fpath = this->BuildMacContentDirectory(fpath, config, includeMacOS); + return fpath; +} + +//---------------------------------------------------------------------------- cmTargetLinkInformationMap ::cmTargetLinkInformationMap(cmTargetLinkInformationMap const& r): derived() { diff --git a/Source/cmTarget.h b/Source/cmTarget.h index d70cacd..a89c5d9 100644 --- a/Source/cmTarget.h +++ b/Source/cmTarget.h @@ -465,6 +465,22 @@ public: /** Get the include directories for this target. */ std::vector<std::string> GetIncludeDirectories(); + /** Append to @a base the mac content directory and return it. */ + std::string BuildMacContentDirectory(const std::string& base, + const char* config = 0, + bool includeMacOS = true); + + /** @return the mac content directory for this target. */ + std::string GetMacContentDirectory(const char* config = 0, + bool implib = false, + bool includeMacOS = true); + + /** @return whether this target have a well defined output file name. */ + bool HaveWellDefinedOutputFiles(); + + /** @return the Mac framework directory without the base. */ + std::string GetFrameworkDirectory(const char* config = 0); + private: /** * A list of direct dependencies. Use in conjunction with DependencyMap. diff --git a/Source/cmake.cxx b/Source/cmake.cxx index 451aec8..fdc42fa 100644 --- a/Source/cmake.cxx +++ b/Source/cmake.cxx @@ -84,10 +84,8 @@ #else #endif #include "cmGlobalUnixMakefileGenerator3.h" +#include "cmGlobalNinjaGenerator.h" -#ifdef CMAKE_USE_NINJA -# include "cmGlobalNinjaGenerator.h" -#endif #if defined(CMAKE_HAVE_VS_GENERATORS) #include "cmCallVisualStudioMacro.h" @@ -2600,10 +2598,8 @@ void cmake::AddDefaultGenerators() #endif this->Generators[cmGlobalUnixMakefileGenerator3::GetActualName()] = &cmGlobalUnixMakefileGenerator3::New; -#ifdef CMAKE_USE_NINJA this->Generators[cmGlobalNinjaGenerator::GetActualName()] = &cmGlobalNinjaGenerator::New; -#endif #ifdef CMAKE_USE_XCODE this->Generators[cmGlobalXCodeGenerator::GetActualName()] = &cmGlobalXCodeGenerator::New; diff --git a/Tests/CMakeLists.txt b/Tests/CMakeLists.txt index 80ab362..27ae3a0 100644 --- a/Tests/CMakeLists.txt +++ b/Tests/CMakeLists.txt @@ -1408,42 +1408,44 @@ ${CMake_BINARY_DIR}/bin/cmake -DVERSION=master -P ${CMake_SOURCE_DIR}/Utilities/ LIST(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/VSMidl") ENDIF(${CMAKE_TEST_GENERATOR} MATCHES "Visual Studio") - IF (APPLE AND CMAKE_COMPILER_IS_GNUCXX) - SET(BundleTestInstallDir - "${CMake_BINARY_DIR}/Tests/BundleTest/InstallDirectory") - ADD_TEST(BundleTest ${CMAKE_CTEST_COMMAND} - --build-and-test - "${CMake_SOURCE_DIR}/Tests/BundleTest" - "${CMake_BINARY_DIR}/Tests/BundleTest" - --build-two-config - --build-generator ${CMAKE_TEST_GENERATOR} - --build-makeprogram ${CMAKE_TEST_MAKEPROGRAM} - --build-project BundleTest - --build-target install -# --build-target package - --build-options "-DCMAKE_INSTALL_PREFIX:PATH=${BundleTestInstallDir}" - "-DCMake_SOURCE_DIR:PATH=${CMake_SOURCE_DIR}" - --test-command - ${BundleTestInstallDir}/Applications/SecondBundleExe.app/Contents/MacOS/SecondBundleExe) - LIST(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/BundleTest") - - ADD_TEST(CFBundleTest ${CMAKE_CTEST_COMMAND} - --build-and-test - "${CMake_SOURCE_DIR}/Tests/CFBundleTest" - "${CMake_BINARY_DIR}/Tests/CFBundleTest" - --build-two-config - --build-generator ${CMAKE_TEST_GENERATOR} - --build-makeprogram ${CMAKE_TEST_MAKEPROGRAM} - --build-project CFBundleTest - --test-command - ${CMAKE_CMAKE_COMMAND} -DCTEST_CONFIGURATION_TYPE=\${CTEST_CONFIGURATION_TYPE} + IF (APPLE) + if (CMAKE_COMPILER_IS_GNUCXX OR "${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang") + SET(BundleTestInstallDir + "${CMake_BINARY_DIR}/Tests/BundleTest/InstallDirectory") + ADD_TEST(BundleTest ${CMAKE_CTEST_COMMAND} + --build-and-test + "${CMake_SOURCE_DIR}/Tests/BundleTest" + "${CMake_BINARY_DIR}/Tests/BundleTest" + --build-two-config + --build-generator ${CMAKE_TEST_GENERATOR} + --build-makeprogram ${CMAKE_TEST_MAKEPROGRAM} + --build-project BundleTest + --build-target install +# --build-target package + --build-options "-DCMAKE_INSTALL_PREFIX:PATH=${BundleTestInstallDir}" + "-DCMake_SOURCE_DIR:PATH=${CMake_SOURCE_DIR}" + --test-command + ${BundleTestInstallDir}/Applications/SecondBundleExe.app/Contents/MacOS/SecondBundleExe) + LIST(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/BundleTest") + + ADD_TEST(CFBundleTest ${CMAKE_CTEST_COMMAND} + --build-and-test + "${CMake_SOURCE_DIR}/Tests/CFBundleTest" + "${CMake_BINARY_DIR}/Tests/CFBundleTest" + --build-two-config + --build-generator ${CMAKE_TEST_GENERATOR} + --build-makeprogram ${CMAKE_TEST_MAKEPROGRAM} + --build-project CFBundleTest + --test-command + ${CMAKE_CMAKE_COMMAND} -DCTEST_CONFIGURATION_TYPE=\${CTEST_CONFIGURATION_TYPE} -Ddir=${CMake_BINARY_DIR}/Tests/CFBundleTest -Dgen=${CMAKE_TEST_GENERATOR} -P ${CMake_SOURCE_DIR}/Tests/CFBundleTest/VerifyResult.cmake) - LIST(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/CFBundleTest") + LIST(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/CFBundleTest") - ADD_TEST_MACRO(ObjC++ ObjC++) - ENDIF (APPLE AND CMAKE_COMPILER_IS_GNUCXX) + ADD_TEST_MACRO(ObjC++ ObjC++) + ENDIF (CMAKE_COMPILER_IS_GNUCXX OR "${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang") + ENDIF (APPLE) IF(APPLE AND CTEST_TEST_CPACK) ADD_TEST(BundleGeneratorTest ${CMAKE_CTEST_COMMAND} @@ -72,14 +72,14 @@ else cmake_system_darwin=false fi -# Determine whether this is BeOS +# Determine whether this is BeOS if echo "${cmake_system}" | grep BeOS >/dev/null 2>&1; then cmake_system_beos=true else cmake_system_beos=false fi -# Determine whether this is Haiku +# Determine whether this is Haiku if echo "${cmake_system}" | grep Haiku >/dev/null 2>&1; then cmake_system_haiku=true else @@ -220,6 +220,7 @@ CMAKE_CXX_SOURCES="\ cmMakefileLibraryTargetGenerator \ cmMakefileTargetGenerator \ cmMakefileUtilityTargetGenerator \ + cmOSXBundleGenerator \ cmNewLineStyle \ cmBootstrapCommands \ cmCommands \ @@ -238,6 +239,11 @@ CMAKE_CXX_SOURCES="\ cmExprLexer \ cmExprParser \ cmExprParserHelper \ + cmGlobalNinjaGenerator \ + cmLocalNinjaGenerator \ + cmNinjaTargetGenerator \ + cmNinjaNormalTargetGenerator \ + cmNinjaUtilityTargetGenerator \ " if ${cmake_system_mingw}; then @@ -351,7 +357,7 @@ cmake_error() res=$1 shift 1 echo "---------------------------------------------" - echo "Error when bootstrapping CMake:" + echo "Error when bootstrapping CMake:" echo "$*" echo "---------------------------------------------" if [ -f cmake_bootstrap.log ]; then @@ -370,7 +376,7 @@ cmake_replace_string () SEARCHFOR="$3" REPLACEWITH="$4" if [ -f "${INFILE}" ] || ${cmake_system_openvms}; then - cat "${INFILE}" | + cat "${INFILE}" | sed "s/\@${SEARCHFOR}\@/${REPLACEWITH}/g" > "${OUTFILE}${_tmp}" if [ -f "${OUTFILE}${_tmp}" ]; then if "${_diff}" "${OUTFILE}" "${OUTFILE}${_tmp}" > /dev/null 2> /dev/null ; then @@ -393,7 +399,7 @@ cmake_kwsys_config_replace_string () APPEND="$*" if [ -f "${INFILE}" ] || ${cmake_system_openvms}; then echo "${APPEND}" > "${OUTFILE}${_tmp}" - cat "${INFILE}" | + cat "${INFILE}" | sed "/./ {s/\@KWSYS_NAMESPACE\@/cmsys/g; s/@KWSYS_BUILD_SHARED@/${KWSYS_BUILD_SHARED}/g; s/@KWSYS_LFS_AVAILABLE@/${KWSYS_LFS_AVAILABLE}/g; @@ -797,7 +803,7 @@ echo ' # include <iostream.h> #endif -class NeedCXX +class NeedCXX { public: NeedCXX() { this->Foo = 1; } @@ -1387,12 +1393,12 @@ cmake_kwsys_config_replace_string \ "${cmake_bootstrap_dir}/cmsys/Configure.h" \ "${cmake_compiler_settings_comment}" -for a in ${KWSYS_FILES}; do +for a in ${KWSYS_FILES}; do cmake_replace_string "${cmake_source_dir}/Source/kwsys/${a}.in" \ "${cmake_bootstrap_dir}/cmsys/${a}" KWSYS_NAMESPACE cmsys done -for a in ${KWSYS_IOS_FILES}; do +for a in ${KWSYS_IOS_FILES}; do cmake_replace_string "${cmake_source_dir}/Source/kwsys/kwsys_ios_${a}.h.in" \ "${cmake_bootstrap_dir}/cmsys/ios/${a}" KWSYS_NAMESPACE cmsys done |