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.
...
This commit is contained in:
David Cole 2012-07-24 17:03:46 -04:00 committed by CMake Topic Stage
commit a51e1529e7
27 changed files with 856 additions and 473 deletions

View File

@ -219,6 +219,8 @@ SET(SRCS
cmMakefileExecutableTargetGenerator.cxx cmMakefileExecutableTargetGenerator.cxx
cmMakefileLibraryTargetGenerator.cxx cmMakefileLibraryTargetGenerator.cxx
cmMakefileUtilityTargetGenerator.cxx cmMakefileUtilityTargetGenerator.cxx
cmOSXBundleGenerator.cxx
cmOSXBundleGenerator.h
cmNewLineStyle.h cmNewLineStyle.h
cmNewLineStyle.cxx cmNewLineStyle.cxx
cmOrderDirectories.cxx cmOrderDirectories.cxx
@ -357,40 +359,25 @@ IF (WIN32)
ENDIF(NOT UNIX) ENDIF(NOT UNIX)
ENDIF (WIN32) ENDIF (WIN32)
# Turn on Ninja by default, but disable it # Ninja support
# on platforms where it does not pass all tests. SET(SRCS ${SRCS}
# Enforce Ninja support by setting CMAKE_USE_NINJA cmGlobalNinjaGenerator.cxx
set(_CMAKE_DEFAULT_NINJA_VALUE TRUE) cmGlobalNinjaGenerator.h
if(APPLE) cmNinjaTypes.h
SET(_CMAKE_DEFAULT_NINJA_VALUE FALSE) cmLocalNinjaGenerator.cxx
endif() cmLocalNinjaGenerator.h
SET(CMAKE_ENABLE_NINJA ${_CMAKE_DEFAULT_NINJA_VALUE} CACHE BOOL cmNinjaTargetGenerator.cxx
"Enable the ninja generator for CMake. When enabled, some CMake tests still fail on OSX") cmNinjaTargetGenerator.h
MARK_AS_ADVANCED(CMAKE_ENABLE_NINJA) cmNinjaNormalTargetGenerator.cxx
IF(CMAKE_ENABLE_NINJA) cmNinjaNormalTargetGenerator.h
MESSAGE(STATUS "Ninja generator enabled.") cmNinjaUtilityTargetGenerator.cxx
SET(SRCS ${SRCS} cmNinjaUtilityTargetGenerator.h
cmGlobalNinjaGenerator.cxx )
cmGlobalNinjaGenerator.h IF(WIN32 AND NOT CYGWIN AND NOT BORLAND)
cmNinjaTypes.h SET_SOURCE_FILES_PROPERTIES(cmcldeps.cxx PROPERTIES COMPILE_DEFINITIONS _WIN32_WINNT=0x0501)
cmLocalNinjaGenerator.cxx ADD_EXECUTABLE(cmcldeps cmcldeps.cxx)
cmLocalNinjaGenerator.h TARGET_LINK_LIBRARIES(cmcldeps CMakeLib)
cmNinjaTargetGenerator.cxx INSTALL_TARGETS(/bin cmcldeps)
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")
ENDIF() ENDIF()
# create a library used by the command line and the GUI # create a library used by the command line and the GUI

View File

@ -36,14 +36,14 @@ ELSE(NOT QT4_FOUND)
QMacInstallDialog.cxx QMacInstallDialog.cxx
QMacInstallDialog.h QMacInstallDialog.h
) )
QT4_WRAP_UI(UI_SRCS QT4_WRAP_UI(UI_SRCS
CMakeSetupDialog.ui CMakeSetupDialog.ui
Compilers.ui Compilers.ui
CrossCompiler.ui CrossCompiler.ui
AddCacheEntry.ui AddCacheEntry.ui
MacInstallDialog.ui MacInstallDialog.ui
) )
QT4_WRAP_CPP(MOC_SRCS QT4_WRAP_CPP(MOC_SRCS
AddCacheEntry.h AddCacheEntry.h
Compilers.h Compilers.h
CMakeSetupDialog.h CMakeSetupDialog.h
@ -76,7 +76,7 @@ ELSE(NOT QT4_FOUND)
SET_TARGET_PROPERTIES(cmake-gui PROPERTIES SET_TARGET_PROPERTIES(cmake-gui PROPERTIES
OUTPUT_NAME ${CMAKE_BUNDLE_NAME}) OUTPUT_NAME ${CMAKE_BUNDLE_NAME})
ENDIF(APPLE) ENDIF(APPLE)
SET(CMAKE_INSTALL_DESTINATION_ARGS SET(CMAKE_INSTALL_DESTINATION_ARGS
BUNDLE DESTINATION "${CMAKE_BUNDLE_LOCATION}") BUNDLE DESTINATION "${CMAKE_BUNDLE_LOCATION}")
ENDIF(${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION} GREATER 2.4) ENDIF(${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION} GREATER 2.4)
@ -112,11 +112,12 @@ ELSE(NOT QT4_FOUND)
endif(APPLE) endif(APPLE)
install(CODE " install(CODE "
include(\"${CMake_SOURCE_DIR}/Modules/BundleUtilities.cmake\") include(\"${CMake_SOURCE_DIR}/Modules/BundleUtilities.cmake\")
set(BU_CHMOD_BUNDLE_ITEMS ON)
fixup_bundle(\"${fixup_exe}\" \"\" \"${QT_LIBRARY_DIR};${QT_BINARY_DIR}\") fixup_bundle(\"${fixup_exe}\" \"\" \"${QT_LIBRARY_DIR};${QT_BINARY_DIR}\")
") ")
endif(APPLE OR WIN32) endif(APPLE OR WIN32)
CONFIGURE_FILE("${QtDialog_SOURCE_DIR}/QtDialogCPack.cmake.in" CONFIGURE_FILE("${QtDialog_SOURCE_DIR}/QtDialogCPack.cmake.in"
"${QtDialog_BINARY_DIR}/QtDialogCPack.cmake" @ONLY) "${QtDialog_BINARY_DIR}/QtDialogCPack.cmake" @ONLY)
ENDIF(NOT QT4_FOUND) ENDIF(NOT QT4_FOUND)

View File

@ -60,9 +60,7 @@ cmExtraCodeBlocksGenerator::cmExtraCodeBlocksGenerator()
// disable until somebody actually tests it: // disable until somebody actually tests it:
// this->SupportedGlobalGenerators.push_back("MSYS Makefiles"); // this->SupportedGlobalGenerators.push_back("MSYS Makefiles");
#endif #endif
#ifdef CMAKE_USE_NINJA
this->SupportedGlobalGenerators.push_back("Ninja"); this->SupportedGlobalGenerators.push_back("Ninja");
#endif
this->SupportedGlobalGenerators.push_back("Unix Makefiles"); this->SupportedGlobalGenerators.push_back("Unix Makefiles");
} }

View File

@ -34,9 +34,7 @@ cmExtraEclipseCDT4Generator
this->SupportedGlobalGenerators.push_back("MinGW Makefiles"); this->SupportedGlobalGenerators.push_back("MinGW Makefiles");
// this->SupportedGlobalGenerators.push_back("MSYS Makefiles"); // this->SupportedGlobalGenerators.push_back("MSYS Makefiles");
#endif #endif
#ifdef CMAKE_USE_NINJA
this->SupportedGlobalGenerators.push_back("Ninja"); this->SupportedGlobalGenerators.push_back("Ninja");
#endif
this->SupportedGlobalGenerators.push_back("Unix Makefiles"); this->SupportedGlobalGenerators.push_back("Unix Makefiles");
this->SupportsVirtualFolders = true; this->SupportsVirtualFolders = true;

View File

@ -252,6 +252,48 @@ cmGlobalNinjaGenerator::WriteCustomCommandBuild(const std::string& command,
vars); 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, void cmGlobalNinjaGenerator::WriteRule(std::ostream& os,
const std::string& name, const std::string& name,
const std::string& command, const std::string& command,
@ -781,6 +823,11 @@ void cmGlobalNinjaGenerator::AddDependencyToAll(cmTarget* target)
this->AppendTargetOutputs(target, this->AllDependencies); this->AppendTargetOutputs(target, this->AllDependencies);
} }
void cmGlobalNinjaGenerator::AddDependencyToAll(const std::string& input)
{
this->AllDependencies.push_back(input);
}
void cmGlobalNinjaGenerator::WriteAssumedSourceDependencies() void cmGlobalNinjaGenerator::WriteAssumedSourceDependencies()
{ {
for (std::map<std::string, std::set<std::string> >::iterator for (std::map<std::string, std::set<std::string> >::iterator

View File

@ -103,6 +103,8 @@ public:
const cmNinjaDeps& outputs, const cmNinjaDeps& outputs,
const cmNinjaDeps& deps = cmNinjaDeps(), const cmNinjaDeps& deps = cmNinjaDeps(),
const cmNinjaDeps& orderOnlyDeps = 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, * Write a rule statement named @a name to @a os with the @a comment,
@ -151,6 +153,7 @@ public:
static bool IsMinGW() { return UsingMinGW; } static bool IsMinGW() { return UsingMinGW; }
public: public:
/// Default constructor. /// Default constructor.
cmGlobalNinjaGenerator(); cmGlobalNinjaGenerator();
@ -214,12 +217,12 @@ public:
} }
virtual const char* GetCleanTargetName() const { return "clean"; } virtual const char* GetCleanTargetName() const { return "clean"; }
public:
cmGeneratedFileStream* GetBuildFileStream() const
{ return this->BuildFileStream; }
cmGeneratedFileStream* GetRulesFileStream() const cmGeneratedFileStream* GetBuildFileStream() const {
{ return this->RulesFileStream; } return this->BuildFileStream; }
cmGeneratedFileStream* GetRulesFileStream() const {
return this->RulesFileStream; }
void AddCXXCompileCommand(const std::string &commandLine, void AddCXXCompileCommand(const std::string &commandLine,
const std::string &sourceFile); const std::string &sourceFile);
@ -242,54 +245,12 @@ public:
bool HasRule(const std::string& name); bool HasRule(const std::string& name);
void AddCustomCommandRule(); void AddCustomCommandRule();
void AddMacOSXContentRule();
protected: bool HasCustomCommandOutput(const std::string &output) {
return this->CustomCommandOutputs.find(output) !=
/// Overloaded methods. this->CustomCommandOutputs.end();
/// @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();
void CloseCompileCommandsStream();
void OpenRulesFileStream();
void CloseRulesFileStream();
/// 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);
void WriteTargetAll(std::ostream& os);
void WriteTargetRebuildManifest(std::ostream& os);
void WriteTargetClean(std::ostream& os);
void WriteTargetHelp(std::ostream& os);
/// Called when we have seen the given custom command. Returns true /// Called when we have seen the given custom command. Returns true
/// if we has seen it before. /// if we has seen it before.
@ -305,11 +266,6 @@ private:
this->AssumedSourceDependencies.erase(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, void AddAssumedSourceDependencies(const std::string &source,
const cmNinjaDeps &deps) { const cmNinjaDeps &deps) {
std::set<std::string> &ASD = this->AssumedSourceDependencies[source]; std::set<std::string> &ASD = this->AssumedSourceDependencies[source];
@ -319,11 +275,59 @@ private:
ASD.insert(deps.begin(), deps.end()); ASD.insert(deps.begin(), deps.end());
} }
std::string ninjaCmd() const; 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:
/// Overloaded methods.
/// @see cmGlobalGenerator::CheckALLOW_DUPLICATE_CUSTOM_TARGETS()
virtual bool CheckALLOW_DUPLICATE_CUSTOM_TARGETS() { return true; }
int GetRuleCmdLength(const std::string& name) { return RuleCmdLength[name]; }
private: private:
/// @see cmGlobalGenerator::ComputeTargetObjects
virtual void ComputeTargetObjects(cmGeneratorTarget* gt) const;
void OpenBuildFileStream();
void CloseBuildFileStream();
void CloseCompileCommandsStream();
void OpenRulesFileStream();
void CloseRulesFileStream();
/// Write the common disclaimer text at the top of each build file.
void WriteDisclaimer(std::ostream& os);
void WriteAssumedSourceDependencies();
void WriteTargetAliases(std::ostream& os);
void WriteBuiltinTargets(std::ostream& os);
void WriteTargetAll(std::ostream& os);
void WriteTargetRebuildManifest(std::ostream& os);
void WriteTargetClean(std::ostream& os);
void WriteTargetHelp(std::ostream& os);
std::string ninjaCmd() const;
/// The file containing the build statement. (the relation ship of the /// The file containing the build statement. (the relation ship of the
/// compilation DAG). /// compilation DAG).
cmGeneratedFileStream* BuildFileStream; cmGeneratedFileStream* BuildFileStream;

View File

@ -61,7 +61,7 @@ void cmLocalNinjaGenerator::Generate()
tg->Generate(); tg->Generate();
// Add the target to "all" if required. // Add the target to "all" if required.
if (!this->GetGlobalNinjaGenerator()->IsExcluded( if (!this->GetGlobalNinjaGenerator()->IsExcluded(
this->GetGlobalNinjaGenerator()->LocalGenerators[0], this->GetGlobalNinjaGenerator()->GetLocalGenerators()[0],
t->second)) t->second))
this->GetGlobalNinjaGenerator()->AddDependencyToAll(&t->second); this->GetGlobalNinjaGenerator()->AddDependencyToAll(&t->second);
delete tg; delete tg;

View File

@ -45,7 +45,6 @@ public:
/// Overloaded methods. @see cmLocalGenerator::GetTargetDirectory() /// Overloaded methods. @see cmLocalGenerator::GetTargetDirectory()
virtual std::string GetTargetDirectory(cmTarget const& target) const; virtual std::string GetTargetDirectory(cmTarget const& target) const;
public:
const cmGlobalNinjaGenerator* GetGlobalNinjaGenerator() const; const cmGlobalNinjaGenerator* GetGlobalNinjaGenerator() const;
cmGlobalNinjaGenerator* GetGlobalNinjaGenerator(); cmGlobalNinjaGenerator* GetGlobalNinjaGenerator();
@ -67,17 +66,43 @@ public:
std::string GetHomeRelativeOutputPath() const std::string GetHomeRelativeOutputPath() const
{ return this->HomeRelativeOutputPath; } { return this->HomeRelativeOutputPath; }
protected: std::string ConvertToNinjaPath(const char *path);
struct map_to_ninja_path {
cmLocalNinjaGenerator *LocalGenerator;
map_to_ninja_path(cmLocalNinjaGenerator *LocalGen)
: LocalGenerator(LocalGen) {}
std::string operator()(const std::string &path) {
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 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); virtual std::string ConvertToLinkReference(std::string const& lib);
protected:
virtual std::string ConvertToIncludeReference(std::string const& path); 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: private:
cmGeneratedFileStream& GetBuildFileStream() const; cmGeneratedFileStream& GetBuildFileStream() const;
@ -90,38 +115,13 @@ private:
void SetConfigName(); 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)
: LocalGenerator(LocalGen) {}
std::string operator()(const std::string &path) {
return LocalGenerator->ConvertToNinjaPath(path.c_str());
}
};
map_to_ninja_path MapToNinjaPath() {
return map_to_ninja_path(this);
}
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 AppendCustomCommandLines(const cmCustomCommand *cc,
std::vector<std::string> &cmdLines);
void WriteCustomCommandRule(); void WriteCustomCommandRule();
void WriteCustomCommandBuildStatement(cmCustomCommand const *cc, void WriteCustomCommandBuildStatement(cmCustomCommand const *cc,
const cmNinjaDeps& orderOnlyDeps); const cmNinjaDeps& orderOnlyDeps);
void AddCustomCommandTarget(cmCustomCommand const* cc, cmTarget* target);
void WriteCustomCommandBuildStatements(); void WriteCustomCommandBuildStatements();
private:
std::string ConfigName; std::string ConfigName;
std::string HomeRelativeOutputPath; std::string HomeRelativeOutputPath;

View File

@ -29,13 +29,19 @@ cmMakefileExecutableTargetGenerator
this->TargetNameOut, this->TargetNameReal, this->TargetNameImport, this->TargetNameOut, this->TargetNameReal, this->TargetNameImport,
this->TargetNamePDB, this->ConfigName); this->TargetNamePDB, this->ConfigName);
if(this->Target->IsAppBundleOnApple()) this->OSXBundleGenerator = new cmOSXBundleGenerator(this->Target,
{ this->TargetNameOut,
this->MacContentDirectory = this->Target->GetDirectory(this->ConfigName); this->ConfigName);
this->MacContentDirectory += "/"; this->OSXBundleGenerator->SetMacContentFolders(&this->MacContentFolders);
this->MacContentDirectory += this->TargetNameOut; this->MacContentDirectory =
this->MacContentDirectory += ".app/Contents/"; this->OSXBundleGenerator->GetMacContentDirectory();
} }
//----------------------------------------------------------------------------
cmMakefileExecutableTargetGenerator
::~cmMakefileExecutableTargetGenerator()
{
delete this->OSXBundleGenerator;
} }
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
@ -100,7 +106,7 @@ void cmMakefileExecutableTargetGenerator::WriteExecutableRule(bool relink)
outpath += "/"; outpath += "/";
if(this->Target->IsAppBundleOnApple()) if(this->Target->IsAppBundleOnApple())
{ {
this->CreateAppBundle(targetName, outpath); this->OSXBundleGenerator->CreateAppBundle(targetName, outpath);
} }
std::string outpathImp; std::string outpathImp;
if(relink) if(relink)
@ -129,7 +135,7 @@ void cmMakefileExecutableTargetGenerator::WriteExecutableRule(bool relink)
std::string targetFullPathReal = outpath + targetNameReal; std::string targetFullPathReal = outpath + targetNameReal;
std::string targetFullPathPDB = outpath + targetNamePDB; std::string targetFullPathPDB = outpath + targetNamePDB;
std::string targetFullPathImport = outpathImp + targetNameImport; std::string targetFullPathImport = outpathImp + targetNameImport;
std::string targetOutPathPDB = std::string targetOutPathPDB =
this->Convert(targetFullPathPDB.c_str(), this->Convert(targetFullPathPDB.c_str(),
cmLocalGenerator::NONE, cmLocalGenerator::NONE,
cmLocalGenerator::SHELL); cmLocalGenerator::SHELL);
@ -440,24 +446,3 @@ void cmMakefileExecutableTargetGenerator::WriteExecutableRule(bool relink)
exeCleanFiles.begin(), exeCleanFiles.begin(),
exeCleanFiles.end()); 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());
}

View File

@ -18,14 +18,14 @@ class cmMakefileExecutableTargetGenerator: public cmMakefileTargetGenerator
{ {
public: public:
cmMakefileExecutableTargetGenerator(cmTarget* target); cmMakefileExecutableTargetGenerator(cmTarget* target);
virtual ~cmMakefileExecutableTargetGenerator();
/* the main entry point for this class. Writes the Makefiles associated /* the main entry point for this class. Writes the Makefiles associated
with this target */ with this target */
virtual void WriteRuleFiles(); virtual void WriteRuleFiles();
protected: protected:
virtual void WriteExecutableRule(bool relink); virtual void WriteExecutableRule(bool relink);
void CreateAppBundle(std::string& targetName, std::string& outpath);
}; };
#endif #endif

View File

@ -26,41 +26,26 @@ cmMakefileLibraryTargetGenerator
::cmMakefileLibraryTargetGenerator(cmTarget* target): ::cmMakefileLibraryTargetGenerator(cmTarget* target):
cmMakefileTargetGenerator(target) cmMakefileTargetGenerator(target)
{ {
if(this->Target->IsCFBundleOnApple()) cmOSXBundleGenerator::PrepareTargetProperties(this->Target);
{
target->SetProperty("PREFIX", "");
target->SetProperty("SUFFIX", "");
}
this->CustomCommandDriver = OnDepends; this->CustomCommandDriver = OnDepends;
this->Target->GetLibraryNames( this->Target->GetLibraryNames(
this->TargetNameOut, this->TargetNameSO, this->TargetNameReal, this->TargetNameOut, this->TargetNameSO, this->TargetNameReal,
this->TargetNameImport, this->TargetNamePDB, this->ConfigName); this->TargetNameImport, this->TargetNamePDB, this->ConfigName);
if(this->Target->IsFrameworkOnApple()) this->OSXBundleGenerator = new cmOSXBundleGenerator(this->Target,
{ this->TargetNameOut,
this->FrameworkVersion = this->Target->GetFrameworkVersion(); this->ConfigName);
this->MacContentDirectory = this->Target->GetDirectory(this->ConfigName); this->OSXBundleGenerator->SetMacContentFolders(&this->MacContentFolders);
this->MacContentDirectory += "/"; this->MacContentDirectory =
this->MacContentDirectory += this->TargetNameOut; this->OSXBundleGenerator->GetMacContentDirectory();
this->MacContentDirectory += ".framework/Versions/"; }
this->MacContentDirectory += this->FrameworkVersion;
this->MacContentDirectory += "/"; //----------------------------------------------------------------------------
} cmMakefileLibraryTargetGenerator
else if(this->Target->IsCFBundleOnApple()) ::~cmMakefileLibraryTargetGenerator()
{ {
this->MacContentDirectory = this->Target->GetDirectory(this->ConfigName); delete this->OSXBundleGenerator;
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/";
}
} }
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
@ -199,7 +184,7 @@ void cmMakefileLibraryTargetGenerator::WriteSharedLibraryRules(bool relink)
linkFlagsConfig += cmSystemTools::UpperCase(this->ConfigName); linkFlagsConfig += cmSystemTools::UpperCase(this->ConfigName);
this->LocalGenerator->AppendFlags this->LocalGenerator->AppendFlags
(extraFlags, this->Target->GetProperty(linkFlagsConfig.c_str())); (extraFlags, this->Target->GetProperty(linkFlagsConfig.c_str()));
this->LocalGenerator->AddConfigVariableFlags this->LocalGenerator->AddConfigVariableFlags
(extraFlags, "CMAKE_SHARED_LINKER_FLAGS", this->ConfigName); (extraFlags, "CMAKE_SHARED_LINKER_FLAGS", this->ConfigName);
this->AddModuleDefinitionFlag(extraFlags); this->AddModuleDefinitionFlag(extraFlags);
@ -220,7 +205,7 @@ void cmMakefileLibraryTargetGenerator::WriteModuleLibraryRules(bool relink)
linkRuleVar += "_CREATE_SHARED_MODULE"; linkRuleVar += "_CREATE_SHARED_MODULE";
std::string extraFlags; std::string extraFlags;
this->LocalGenerator->AppendFlags(extraFlags, this->LocalGenerator->AppendFlags(extraFlags,
this->Target->GetProperty("LINK_FLAGS")); this->Target->GetProperty("LINK_FLAGS"));
std::string linkFlagsConfig = "LINK_FLAGS_"; std::string linkFlagsConfig = "LINK_FLAGS_";
linkFlagsConfig += cmSystemTools::UpperCase(this->ConfigName); linkFlagsConfig += cmSystemTools::UpperCase(this->ConfigName);
@ -246,7 +231,7 @@ void cmMakefileLibraryTargetGenerator::WriteFrameworkRules(bool relink)
linkRuleVar += "_CREATE_MACOSX_FRAMEWORK"; linkRuleVar += "_CREATE_MACOSX_FRAMEWORK";
std::string extraFlags; std::string extraFlags;
this->LocalGenerator->AppendFlags(extraFlags, this->LocalGenerator->AppendFlags(extraFlags,
this->Target->GetProperty("LINK_FLAGS")); this->Target->GetProperty("LINK_FLAGS"));
std::string linkFlagsConfig = "LINK_FLAGS_"; std::string linkFlagsConfig = "LINK_FLAGS_";
linkFlagsConfig += cmSystemTools::UpperCase(this->ConfigName); linkFlagsConfig += cmSystemTools::UpperCase(this->ConfigName);
@ -258,115 +243,6 @@ void cmMakefileLibraryTargetGenerator::WriteFrameworkRules(bool relink)
this->WriteLibraryRules(linkRuleVar.c_str(), extraFlags.c_str(), relink); this->WriteLibraryRules(linkRuleVar.c_str(), extraFlags.c_str(), 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 void cmMakefileLibraryTargetGenerator::WriteLibraryRules
(const char* linkRuleVar, const char* extraFlags, bool relink) (const char* linkRuleVar, const char* extraFlags, bool relink)
@ -419,13 +295,13 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules
if(this->Target->IsFrameworkOnApple()) if(this->Target->IsFrameworkOnApple())
{ {
outpath = this->MacContentDirectory; outpath = this->MacContentDirectory;
this->CreateFramework(targetName); this->OSXBundleGenerator->CreateFramework(targetName);
} }
else if(this->Target->IsCFBundleOnApple()) else if(this->Target->IsCFBundleOnApple())
{ {
outpath = this->Target->GetDirectory(this->ConfigName); outpath = this->Target->GetDirectory(this->ConfigName);
outpath += "/"; outpath += "/";
this->CreateCFBundle(targetName, outpath); this->OSXBundleGenerator->CreateCFBundle(targetName, outpath);
} }
else if(relink) else if(relink)
{ {
@ -460,16 +336,16 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules
// Construct the output path version of the names for use in command // Construct the output path version of the names for use in command
// arguments. // arguments.
std::string targetOutPathPDB = std::string targetOutPathPDB =
this->Convert(targetFullPathPDB.c_str(),cmLocalGenerator::NONE, this->Convert(targetFullPathPDB.c_str(),cmLocalGenerator::NONE,
cmLocalGenerator::SHELL); cmLocalGenerator::SHELL);
std::string targetOutPath = std::string targetOutPath =
this->Convert(targetFullPath.c_str(),cmLocalGenerator::START_OUTPUT, this->Convert(targetFullPath.c_str(),cmLocalGenerator::START_OUTPUT,
cmLocalGenerator::SHELL); cmLocalGenerator::SHELL);
std::string targetOutPathSO = std::string targetOutPathSO =
this->Convert(targetFullPathSO.c_str(),cmLocalGenerator::START_OUTPUT, this->Convert(targetFullPathSO.c_str(),cmLocalGenerator::START_OUTPUT,
cmLocalGenerator::SHELL); cmLocalGenerator::SHELL);
std::string targetOutPathReal = std::string targetOutPathReal =
this->Convert(targetFullPathReal.c_str(),cmLocalGenerator::START_OUTPUT, this->Convert(targetFullPathReal.c_str(),cmLocalGenerator::START_OUTPUT,
cmLocalGenerator::SHELL); cmLocalGenerator::SHELL);
std::string targetOutPathImport = std::string targetOutPathImport =
@ -569,7 +445,7 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules
std::vector<std::string> commands1; std::vector<std::string> commands1;
// Add a command to remove any existing files for this library. // 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) if(this->Target->GetType() == cmTarget::STATIC_LIBRARY)
{ {
this->LocalGenerator->AppendCleanCommand(commands1, libCleanFiles, this->LocalGenerator->AppendCleanCommand(commands1, libCleanFiles,

View File

@ -14,16 +14,17 @@
#include "cmMakefileTargetGenerator.h" #include "cmMakefileTargetGenerator.h"
class cmMakefileLibraryTargetGenerator: class cmMakefileLibraryTargetGenerator:
public cmMakefileTargetGenerator public cmMakefileTargetGenerator
{ {
public: public:
cmMakefileLibraryTargetGenerator(cmTarget* target); cmMakefileLibraryTargetGenerator(cmTarget* target);
virtual ~cmMakefileLibraryTargetGenerator();
/* the main entry point for this class. Writes the Makefiles associated /* the main entry point for this class. Writes the Makefiles associated
with this target */ with this target */
virtual void WriteRuleFiles(); virtual void WriteRuleFiles();
protected: protected:
void WriteObjectLibraryRules(); void WriteObjectLibraryRules();
void WriteStaticLibraryRules(); void WriteStaticLibraryRules();
@ -33,8 +34,6 @@ protected:
bool relink); bool relink);
// MacOSX Framework support methods // MacOSX Framework support methods
void WriteFrameworkRules(bool relink); void WriteFrameworkRules(bool relink);
void CreateFramework(std::string const& targetName);
void CreateCFBundle(std::string& targetName, std::string& outpath);
// Store the computd framework version for OS X Frameworks. // Store the computd framework version for OS X Frameworks.
std::string FrameworkVersion; std::string FrameworkVersion;

View File

@ -28,6 +28,8 @@
cmMakefileTargetGenerator::cmMakefileTargetGenerator(cmTarget* target) cmMakefileTargetGenerator::cmMakefileTargetGenerator(cmTarget* target)
: OSXBundleGenerator(0)
, MacOSXContentGenerator(0)
{ {
this->BuildFileStream = 0; this->BuildFileStream = 0;
this->InfoFileStream = 0; this->InfoFileStream = 0;
@ -50,6 +52,12 @@ cmMakefileTargetGenerator::cmMakefileTargetGenerator(cmTarget* target)
{ {
this->NoRuleMessages = cmSystemTools::IsOff(ruleStatus); this->NoRuleMessages = cmSystemTools::IsOff(ruleStatus);
} }
MacOSXContentGenerator = new MacOSXContentGeneratorType(this);
}
cmMakefileTargetGenerator::~cmMakefileTargetGenerator()
{
delete MacOSXContentGenerator;
} }
cmMakefileTargetGenerator * cmMakefileTargetGenerator *
@ -153,8 +161,12 @@ void cmMakefileTargetGenerator::WriteTargetBuildRules()
} }
} }
} }
this->WriteMacOSXContentRules(this->GeneratorTarget->HeaderSources); this->OSXBundleGenerator->GenerateMacOSXContentStatements(
this->WriteMacOSXContentRules(this->GeneratorTarget->ExtraSources); this->GeneratorTarget->HeaderSources,
this->MacOSXContentGenerator);
this->OSXBundleGenerator->GenerateMacOSXContentStatements(
this->GeneratorTarget->ExtraSources,
this->MacOSXContentGenerator);
for(std::vector<cmSourceFile*>::const_iterator for(std::vector<cmSourceFile*>::const_iterator
si = this->GeneratorTarget->ExternalObjects.begin(); si = this->GeneratorTarget->ExternalObjects.begin();
si != this->GeneratorTarget->ExternalObjects.end(); ++si) si != this->GeneratorTarget->ExternalObjects.end(); ++si)
@ -173,7 +185,6 @@ void cmMakefileTargetGenerator::WriteTargetBuildRules()
this->GeneratorTarget->UseObjectLibraries(this->ExternalObjects); this->GeneratorTarget->UseObjectLibraries(this->ExternalObjects);
} }
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
void cmMakefileTargetGenerator::WriteCommonCodeRules() 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, void
const char* pkgloc) cmMakefileTargetGenerator::MacOSXContentGeneratorType::operator()
(cmSourceFile& source, const char* pkgloc)
{ {
// Skip OS X content when not building a Framework or Bundle. // Skip OS X content when not building a Framework or Bundle.
if(this->MacContentDirectory.empty()) if(this->Generator->MacContentDirectory.empty())
{ {
return; return;
} }
// Construct the full path to the content subdirectory. std::string macdir =
std::string macdir = this->MacContentDirectory; this->Generator->OSXBundleGenerator->InitMacOSXContentDirectory(pkgloc);
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);
}
// Get the input file location. // Get the input file location.
std::string input = source.GetFullPath(); std::string input = source.GetFullPath();
@ -389,9 +376,11 @@ void cmMakefileTargetGenerator::WriteMacOSXContentRules(cmSourceFile& source,
std::string output = macdir; std::string output = macdir;
output += "/"; output += "/";
output += cmSystemTools::GetFilenameName(input); output += cmSystemTools::GetFilenameName(input);
this->CleanFiles.push_back(this->Convert(output.c_str(), this->Generator->CleanFiles.push_back(
cmLocalGenerator::START_OUTPUT)); this->Generator->Convert(output.c_str(),
output = this->Convert(output.c_str(), cmLocalGenerator::HOME_OUTPUT); cmLocalGenerator::START_OUTPUT));
output = this->Generator->Convert(output.c_str(),
cmLocalGenerator::HOME_OUTPUT);
// Create a rule to copy the content into the bundle. // Create a rule to copy the content into the bundle.
std::vector<std::string> depends; std::vector<std::string> depends;
@ -399,21 +388,23 @@ void cmMakefileTargetGenerator::WriteMacOSXContentRules(cmSourceFile& source,
depends.push_back(input); depends.push_back(input);
std::string copyEcho = "Copying OS X content "; std::string copyEcho = "Copying OS X content ";
copyEcho += output; copyEcho += output;
this->LocalGenerator->AppendEcho(commands, copyEcho.c_str(), this->Generator->LocalGenerator->AppendEcho(
cmLocalUnixMakefileGenerator3::EchoBuild); commands, copyEcho.c_str(),
cmLocalUnixMakefileGenerator3::EchoBuild);
std::string copyCommand = "$(CMAKE_COMMAND) -E copy "; std::string copyCommand = "$(CMAKE_COMMAND) -E copy ";
copyCommand += this->Convert(input.c_str(), copyCommand += this->Generator->Convert(input.c_str(),
cmLocalGenerator::NONE, cmLocalGenerator::NONE,
cmLocalGenerator::SHELL); cmLocalGenerator::SHELL);
copyCommand += " "; copyCommand += " ";
copyCommand += this->Convert(output.c_str(), copyCommand += this->Generator->Convert(output.c_str(),
cmLocalGenerator::NONE, cmLocalGenerator::NONE,
cmLocalGenerator::SHELL); cmLocalGenerator::SHELL);
commands.push_back(copyCommand); commands.push_back(copyCommand);
this->LocalGenerator->WriteMakeRule(*this->BuildFileStream, 0, this->Generator->LocalGenerator->WriteMakeRule(
output.c_str(), *this->Generator->BuildFileStream, 0,
depends, commands, false); output.c_str(),
this->ExtraFiles.insert(output); depends, commands, false);
this->Generator->ExtraFiles.insert(output);
} }
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------

View File

@ -13,6 +13,7 @@
#define cmMakefileTargetGenerator_h #define cmMakefileTargetGenerator_h
#include "cmLocalUnixMakefileGenerator3.h" #include "cmLocalUnixMakefileGenerator3.h"
#include "cmOSXBundleGenerator.h"
class cmCustomCommand; class cmCustomCommand;
class cmDependInformation; class cmDependInformation;
@ -34,7 +35,7 @@ class cmMakefileTargetGenerator
public: public:
// constructor to set the ivars // constructor to set the ivars
cmMakefileTargetGenerator(cmTarget* target); cmMakefileTargetGenerator(cmTarget* target);
virtual ~cmMakefileTargetGenerator() {}; virtual ~cmMakefileTargetGenerator();
// construct using this factory call // construct using this factory call
static cmMakefileTargetGenerator *New(cmTarget *tgt); static cmMakefileTargetGenerator *New(cmTarget *tgt);
@ -50,6 +51,7 @@ public:
{ return this->ProgressFileNameFull; } { return this->ProgressFileNameFull; }
cmTarget* GetTarget() { return this->Target;} cmTarget* GetTarget() { return this->Target;}
protected: protected:
// create the file and directory etc // create the file and directory etc
@ -73,8 +75,18 @@ protected:
void WriteTargetDependRules(); void WriteTargetDependRules();
// write rules for Mac OS X Application Bundle content. // write rules for Mac OS X Application Bundle content.
void WriteMacOSXContentRules(std::vector<cmSourceFile*> const& sources); struct MacOSXContentGeneratorType :
void WriteMacOSXContentRules(cmSourceFile& source, const char* pkgloc); 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 // write the rules for an object
void WriteObjectRuleFiles(cmSourceFile& source); void WriteObjectRuleFiles(cmSourceFile& source);
@ -223,6 +235,8 @@ protected:
// Mac OS X content info. // Mac OS X content info.
std::string MacContentDirectory; std::string MacContentDirectory;
std::set<cmStdString> MacContentFolders; std::set<cmStdString> MacContentFolders;
cmOSXBundleGenerator* OSXBundleGenerator;
MacOSXContentGeneratorType* MacOSXContentGenerator;
typedef std::map<cmStdString, cmStdString> ByLanguageMap; typedef std::map<cmStdString, cmStdString> ByLanguageMap;
std::string GetFlags(const std::string &l); std::string GetFlags(const std::string &l);

View File

@ -24,6 +24,19 @@ cmMakefileUtilityTargetGenerator
cmMakefileTargetGenerator(target) cmMakefileTargetGenerator(target)
{ {
this->CustomCommandDriver = OnUtility; 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;
} }
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------

View File

@ -14,16 +14,17 @@
#include "cmMakefileTargetGenerator.h" #include "cmMakefileTargetGenerator.h"
class cmMakefileUtilityTargetGenerator: class cmMakefileUtilityTargetGenerator:
public cmMakefileTargetGenerator public cmMakefileTargetGenerator
{ {
public: public:
cmMakefileUtilityTargetGenerator(cmTarget* target); cmMakefileUtilityTargetGenerator(cmTarget* target);
virtual ~cmMakefileUtilityTargetGenerator();
/* the main entry point for this class. Writes the Makefiles associated /* the main entry point for this class. Writes the Makefiles associated
with this target */ with this target */
virtual void WriteRuleFiles(); virtual void WriteRuleFiles();
protected: protected:
}; };

View File

@ -16,6 +16,7 @@
#include "cmSourceFile.h" #include "cmSourceFile.h"
#include "cmGeneratedFileStream.h" #include "cmGeneratedFileStream.h"
#include "cmMakefile.h" #include "cmMakefile.h"
#include "cmOSXBundleGenerator.h"
#include <assert.h> #include <assert.h>
#include <algorithm> #include <algorithm>
@ -33,7 +34,10 @@ cmNinjaNormalTargetGenerator(cmTarget* target)
, TargetNameReal() , TargetNameReal()
, TargetNameImport() , TargetNameImport()
, TargetNamePDB() , TargetNamePDB()
, TargetLinkLanguage(0)
{ {
cmOSXBundleGenerator::PrepareTargetProperties(target);
this->TargetLinkLanguage = target->GetLinkerLanguage(this->GetConfigName()); this->TargetLinkLanguage = target->GetLinkerLanguage(this->GetConfigName());
if (target->GetType() == cmTarget::EXECUTABLE) if (target->GetType() == cmTarget::EXECUTABLE)
target->GetExecutableNames(this->TargetNameOut, target->GetExecutableNames(this->TargetNameOut,
@ -55,10 +59,16 @@ cmNinjaNormalTargetGenerator(cmTarget* target)
// ensure the directory exists (OutDir test) // ensure the directory exists (OutDir test)
EnsureDirectoryExists(target->GetDirectory(this->GetConfigName())); EnsureDirectoryExists(target->GetDirectory(this->GetConfigName()));
} }
this->OSXBundleGenerator = new cmOSXBundleGenerator(target,
this->TargetNameOut,
this->GetConfigName());
this->OSXBundleGenerator->SetMacContentFolders(&this->MacContentFolders);
} }
cmNinjaNormalTargetGenerator::~cmNinjaNormalTargetGenerator() cmNinjaNormalTargetGenerator::~cmNinjaNormalTargetGenerator()
{ {
delete this->OSXBundleGenerator;
} }
void cmNinjaNormalTargetGenerator::Generate() void cmNinjaNormalTargetGenerator::Generate()
@ -115,7 +125,10 @@ const char *cmNinjaNormalTargetGenerator::GetVisibleTypeName() const
case cmTarget::SHARED_LIBRARY: case cmTarget::SHARED_LIBRARY:
return "shared library"; return "shared library";
case cmTarget::MODULE_LIBRARY: case cmTarget::MODULE_LIBRARY:
return "shared module"; if (this->GetTarget()->IsCFBundleOnApple())
return "CFBundle shared module";
else
return "shared module";
case cmTarget::EXECUTABLE: case cmTarget::EXECUTABLE:
return "executable"; return "executable";
default: default:
@ -348,6 +361,40 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement()
{ {
cmTarget::TargetType targetType = this->GetTarget()->GetType(); 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. // Write comments.
cmGlobalNinjaGenerator::WriteDivider(this->GetBuildFileStream()); cmGlobalNinjaGenerator::WriteDivider(this->GetBuildFileStream());
this->GetBuildFileStream() this->GetBuildFileStream()
@ -360,16 +407,6 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement()
cmNinjaDeps emptyDeps; cmNinjaDeps emptyDeps;
cmNinjaVars vars; 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. // Compute the comment.
cmOStringStream comment; cmOStringStream comment;
comment << "Link the " << this->GetVisibleTypeName() << " " comment << "Link the " << this->GetVisibleTypeName() << " "

View File

@ -15,8 +15,12 @@
# include "cmNinjaTargetGenerator.h" # include "cmNinjaTargetGenerator.h"
# include "cmNinjaTypes.h" # include "cmNinjaTypes.h"
# include "cmStandardIncludes.h"
# include <set>
class cmSourceFile; class cmSourceFile;
class cmOSXBundleGenerator;
class cmNinjaNormalTargetGenerator : public cmNinjaTargetGenerator class cmNinjaNormalTargetGenerator : public cmNinjaTargetGenerator
{ {

View File

@ -56,7 +56,11 @@ cmNinjaTargetGenerator::New(cmTarget* target)
} }
cmNinjaTargetGenerator::cmNinjaTargetGenerator(cmTarget* target) cmNinjaTargetGenerator::cmNinjaTargetGenerator(cmTarget* target)
: Target(target), :
MacOSXContentGenerator(0),
OSXBundleGenerator(0),
MacContentFolders(),
Target(target),
Makefile(target->GetMakefile()), Makefile(target->GetMakefile()),
LocalGenerator( LocalGenerator(
static_cast<cmLocalNinjaGenerator*>(Makefile->GetLocalGenerator())), static_cast<cmLocalNinjaGenerator*>(Makefile->GetLocalGenerator())),
@ -64,10 +68,12 @@ cmNinjaTargetGenerator::cmNinjaTargetGenerator(cmTarget* target)
{ {
this->GeneratorTarget = this->GeneratorTarget =
this->GetGlobalGenerator()->GetGeneratorTarget(target); this->GetGlobalGenerator()->GetGeneratorTarget(target);
MacOSXContentGenerator = new MacOSXContentGeneratorType(this);
} }
cmNinjaTargetGenerator::~cmNinjaTargetGenerator() cmNinjaTargetGenerator::~cmNinjaTargetGenerator()
{ {
delete this->MacOSXContentGenerator;
} }
cmGeneratedFileStream& cmNinjaTargetGenerator::GetBuildFileStream() const cmGeneratedFileStream& cmNinjaTargetGenerator::GetBuildFileStream() const
@ -87,7 +93,7 @@ cmGlobalNinjaGenerator* cmNinjaTargetGenerator::GetGlobalGenerator() const
const char* cmNinjaTargetGenerator::GetConfigName() const const char* cmNinjaTargetGenerator::GetConfigName() const
{ {
return this->LocalGenerator->ConfigName.c_str(); return this->LocalGenerator->GetConfigName();
} }
// TODO: Picked up from cmMakefileTargetGenerator. Refactor it. // TODO: Picked up from cmMakefileTargetGenerator. Refactor it.
@ -430,6 +436,12 @@ cmNinjaTargetGenerator
cmCustomCommand const* cc = (*si)->GetCustomCommand(); cmCustomCommand const* cc = (*si)->GetCustomCommand();
this->GetLocalGenerator()->AddCustomCommandTarget(cc, this->GetTarget()); 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 for(std::vector<cmSourceFile*>::const_iterator
si = this->GeneratorTarget->ExternalObjects.begin(); si = this->GeneratorTarget->ExternalObjects.begin();
si != this->GeneratorTarget->ExternalObjects.end(); ++si) si != this->GeneratorTarget->ExternalObjects.end(); ++si)
@ -640,3 +652,38 @@ cmNinjaTargetGenerator
{ {
EnsureDirectoryExists(cmSystemTools::GetParentDirectory(path.c_str())); 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);
}

View File

@ -16,6 +16,7 @@
#include "cmStandardIncludes.h" #include "cmStandardIncludes.h"
#include "cmNinjaTypes.h" #include "cmNinjaTypes.h"
#include "cmLocalNinjaGenerator.h" #include "cmLocalNinjaGenerator.h"
#include "cmOSXBundleGenerator.h"
class cmTarget; class cmTarget;
class cmGlobalNinjaGenerator; class cmGlobalNinjaGenerator;
@ -114,6 +115,27 @@ protected:
void EnsureDirectoryExists(const std::string& dir); void EnsureDirectoryExists(const std::string& dir);
void EnsureParentDirectoryExists(const std::string& path); 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: private:
cmTarget* Target; cmTarget* Target;
cmGeneratorTarget* GeneratorTarget; cmGeneratorTarget* GeneratorTarget;

View File

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

View File

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

View File

@ -2482,6 +2482,16 @@ void cmTarget::MarkAsImported()
this->IsImportedTarget = true; this->IsImportedTarget = true;
} }
//----------------------------------------------------------------------------
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) cmTarget::OutputInfo const* cmTarget::GetOutputInfo(const char* config)
{ {
@ -2492,10 +2502,7 @@ cmTarget::OutputInfo const* cmTarget::GetOutputInfo(const char* config)
} }
// Only libraries and executables have well-defined output files. // Only libraries and executables have well-defined output files.
if(this->GetType() != cmTarget::STATIC_LIBRARY && if(!this->HaveWellDefinedOutputFiles())
this->GetType() != cmTarget::SHARED_LIBRARY &&
this->GetType() != cmTarget::MODULE_LIBRARY &&
this->GetType() != cmTarget::EXECUTABLE)
{ {
std::string msg = "cmTarget::GetOutputInfo called for "; std::string msg = "cmTarget::GetOutputInfo called for ";
msg += this->GetName(); msg += this->GetName();
@ -2586,18 +2593,7 @@ const char* cmTarget::NormalGetLocation(const char* config)
this->Location += cfgid; this->Location += cfgid;
this->Location += "/"; this->Location += "/";
} }
if(this->IsAppBundleOnApple()) this->Location = this->BuildMacContentDirectory(this->Location, config);
{
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->GetFullName(config, false); this->Location += this->GetFullName(config, false);
return this->Location.c_str(); 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, std::string cmTarget::NormalGetFullPath(const char* config, bool implib,
bool realname) bool realname)
{ {
// Start with the output directory for the target. std::string fpath = this->GetMacContentDirectory(config, implib);
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 += "/";
}
// Add the full name of the target. // Add the full name of the target.
if(implib) if(implib)
@ -3707,10 +3688,7 @@ std::string cmTarget::GetInstallNameDirForBuildTree(const char* config,
dir += "/"; dir += "/";
if(this->IsFrameworkOnApple() && !for_xcode) if(this->IsFrameworkOnApple() && !for_xcode)
{ {
dir += this->GetFullName(config, false); dir += this->GetFrameworkDirectory(config);
dir += ".framework/Versions/";
dir += this->GetFrameworkVersion();
dir += "/";
} }
return dir; return dir;
} }
@ -3741,10 +3719,7 @@ std::string cmTarget::GetInstallNameDirForInstallTree(const char* config,
if(this->IsFrameworkOnApple() && !for_xcode) if(this->IsFrameworkOnApple() && !for_xcode)
{ {
dir += this->GetFullName(config, false); dir += this->GetFrameworkDirectory(config);
dir += ".framework/Versions/";
dir += this->GetFrameworkVersion();
dir += "/";
} }
return dir; return dir;
@ -4733,6 +4708,63 @@ std::vector<std::string> cmTarget::GetIncludeDirectories()
return orderedAndUniqueIncludes; return orderedAndUniqueIncludes;
} }
//----------------------------------------------------------------------------
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(cmTargetLinkInformationMap const& r): derived() ::cmTargetLinkInformationMap(cmTargetLinkInformationMap const& r): derived()

View File

@ -465,6 +465,22 @@ public:
/** Get the include directories for this target. */ /** Get the include directories for this target. */
std::vector<std::string> GetIncludeDirectories(); 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: private:
/** /**
* A list of direct dependencies. Use in conjunction with DependencyMap. * A list of direct dependencies. Use in conjunction with DependencyMap.

View File

@ -84,10 +84,8 @@
#else #else
#endif #endif
#include "cmGlobalUnixMakefileGenerator3.h" #include "cmGlobalUnixMakefileGenerator3.h"
#include "cmGlobalNinjaGenerator.h"
#ifdef CMAKE_USE_NINJA
# include "cmGlobalNinjaGenerator.h"
#endif
#if defined(CMAKE_HAVE_VS_GENERATORS) #if defined(CMAKE_HAVE_VS_GENERATORS)
#include "cmCallVisualStudioMacro.h" #include "cmCallVisualStudioMacro.h"
@ -2600,10 +2598,8 @@ void cmake::AddDefaultGenerators()
#endif #endif
this->Generators[cmGlobalUnixMakefileGenerator3::GetActualName()] = this->Generators[cmGlobalUnixMakefileGenerator3::GetActualName()] =
&cmGlobalUnixMakefileGenerator3::New; &cmGlobalUnixMakefileGenerator3::New;
#ifdef CMAKE_USE_NINJA
this->Generators[cmGlobalNinjaGenerator::GetActualName()] = this->Generators[cmGlobalNinjaGenerator::GetActualName()] =
&cmGlobalNinjaGenerator::New; &cmGlobalNinjaGenerator::New;
#endif
#ifdef CMAKE_USE_XCODE #ifdef CMAKE_USE_XCODE
this->Generators[cmGlobalXCodeGenerator::GetActualName()] = this->Generators[cmGlobalXCodeGenerator::GetActualName()] =
&cmGlobalXCodeGenerator::New; &cmGlobalXCodeGenerator::New;

View File

@ -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") LIST(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/VSMidl")
ENDIF(${CMAKE_TEST_GENERATOR} MATCHES "Visual Studio") ENDIF(${CMAKE_TEST_GENERATOR} MATCHES "Visual Studio")
IF (APPLE AND CMAKE_COMPILER_IS_GNUCXX) IF (APPLE)
SET(BundleTestInstallDir if (CMAKE_COMPILER_IS_GNUCXX OR "${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang")
"${CMake_BINARY_DIR}/Tests/BundleTest/InstallDirectory") SET(BundleTestInstallDir
ADD_TEST(BundleTest ${CMAKE_CTEST_COMMAND} "${CMake_BINARY_DIR}/Tests/BundleTest/InstallDirectory")
--build-and-test ADD_TEST(BundleTest ${CMAKE_CTEST_COMMAND}
"${CMake_SOURCE_DIR}/Tests/BundleTest" --build-and-test
"${CMake_BINARY_DIR}/Tests/BundleTest" "${CMake_SOURCE_DIR}/Tests/BundleTest"
--build-two-config "${CMake_BINARY_DIR}/Tests/BundleTest"
--build-generator ${CMAKE_TEST_GENERATOR} --build-two-config
--build-makeprogram ${CMAKE_TEST_MAKEPROGRAM} --build-generator ${CMAKE_TEST_GENERATOR}
--build-project BundleTest --build-makeprogram ${CMAKE_TEST_MAKEPROGRAM}
--build-target install --build-project BundleTest
# --build-target package --build-target install
--build-options "-DCMAKE_INSTALL_PREFIX:PATH=${BundleTestInstallDir}" # --build-target package
"-DCMake_SOURCE_DIR:PATH=${CMake_SOURCE_DIR}" --build-options "-DCMAKE_INSTALL_PREFIX:PATH=${BundleTestInstallDir}"
--test-command "-DCMake_SOURCE_DIR:PATH=${CMake_SOURCE_DIR}"
${BundleTestInstallDir}/Applications/SecondBundleExe.app/Contents/MacOS/SecondBundleExe) --test-command
LIST(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/BundleTest") ${BundleTestInstallDir}/Applications/SecondBundleExe.app/Contents/MacOS/SecondBundleExe)
LIST(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/BundleTest")
ADD_TEST(CFBundleTest ${CMAKE_CTEST_COMMAND} ADD_TEST(CFBundleTest ${CMAKE_CTEST_COMMAND}
--build-and-test --build-and-test
"${CMake_SOURCE_DIR}/Tests/CFBundleTest" "${CMake_SOURCE_DIR}/Tests/CFBundleTest"
"${CMake_BINARY_DIR}/Tests/CFBundleTest" "${CMake_BINARY_DIR}/Tests/CFBundleTest"
--build-two-config --build-two-config
--build-generator ${CMAKE_TEST_GENERATOR} --build-generator ${CMAKE_TEST_GENERATOR}
--build-makeprogram ${CMAKE_TEST_MAKEPROGRAM} --build-makeprogram ${CMAKE_TEST_MAKEPROGRAM}
--build-project CFBundleTest --build-project CFBundleTest
--test-command --test-command
${CMAKE_CMAKE_COMMAND} -DCTEST_CONFIGURATION_TYPE=\${CTEST_CONFIGURATION_TYPE} ${CMAKE_CMAKE_COMMAND} -DCTEST_CONFIGURATION_TYPE=\${CTEST_CONFIGURATION_TYPE}
-Ddir=${CMake_BINARY_DIR}/Tests/CFBundleTest -Ddir=${CMake_BINARY_DIR}/Tests/CFBundleTest
-Dgen=${CMAKE_TEST_GENERATOR} -Dgen=${CMAKE_TEST_GENERATOR}
-P ${CMake_SOURCE_DIR}/Tests/CFBundleTest/VerifyResult.cmake) -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++) ADD_TEST_MACRO(ObjC++ ObjC++)
ENDIF (APPLE AND CMAKE_COMPILER_IS_GNUCXX) ENDIF (CMAKE_COMPILER_IS_GNUCXX OR "${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang")
ENDIF (APPLE)
IF(APPLE AND CTEST_TEST_CPACK) IF(APPLE AND CTEST_TEST_CPACK)
ADD_TEST(BundleGeneratorTest ${CMAKE_CTEST_COMMAND} ADD_TEST(BundleGeneratorTest ${CMAKE_CTEST_COMMAND}

View File

@ -72,14 +72,14 @@ else
cmake_system_darwin=false cmake_system_darwin=false
fi fi
# Determine whether this is BeOS # Determine whether this is BeOS
if echo "${cmake_system}" | grep BeOS >/dev/null 2>&1; then if echo "${cmake_system}" | grep BeOS >/dev/null 2>&1; then
cmake_system_beos=true cmake_system_beos=true
else else
cmake_system_beos=false cmake_system_beos=false
fi fi
# Determine whether this is Haiku # Determine whether this is Haiku
if echo "${cmake_system}" | grep Haiku >/dev/null 2>&1; then if echo "${cmake_system}" | grep Haiku >/dev/null 2>&1; then
cmake_system_haiku=true cmake_system_haiku=true
else else
@ -220,6 +220,7 @@ CMAKE_CXX_SOURCES="\
cmMakefileLibraryTargetGenerator \ cmMakefileLibraryTargetGenerator \
cmMakefileTargetGenerator \ cmMakefileTargetGenerator \
cmMakefileUtilityTargetGenerator \ cmMakefileUtilityTargetGenerator \
cmOSXBundleGenerator \
cmNewLineStyle \ cmNewLineStyle \
cmBootstrapCommands \ cmBootstrapCommands \
cmCommands \ cmCommands \
@ -238,6 +239,11 @@ CMAKE_CXX_SOURCES="\
cmExprLexer \ cmExprLexer \
cmExprParser \ cmExprParser \
cmExprParserHelper \ cmExprParserHelper \
cmGlobalNinjaGenerator \
cmLocalNinjaGenerator \
cmNinjaTargetGenerator \
cmNinjaNormalTargetGenerator \
cmNinjaUtilityTargetGenerator \
" "
if ${cmake_system_mingw}; then if ${cmake_system_mingw}; then
@ -351,7 +357,7 @@ cmake_error()
res=$1 res=$1
shift 1 shift 1
echo "---------------------------------------------" echo "---------------------------------------------"
echo "Error when bootstrapping CMake:" echo "Error when bootstrapping CMake:"
echo "$*" echo "$*"
echo "---------------------------------------------" echo "---------------------------------------------"
if [ -f cmake_bootstrap.log ]; then if [ -f cmake_bootstrap.log ]; then
@ -370,7 +376,7 @@ cmake_replace_string ()
SEARCHFOR="$3" SEARCHFOR="$3"
REPLACEWITH="$4" REPLACEWITH="$4"
if [ -f "${INFILE}" ] || ${cmake_system_openvms}; then if [ -f "${INFILE}" ] || ${cmake_system_openvms}; then
cat "${INFILE}" | cat "${INFILE}" |
sed "s/\@${SEARCHFOR}\@/${REPLACEWITH}/g" > "${OUTFILE}${_tmp}" sed "s/\@${SEARCHFOR}\@/${REPLACEWITH}/g" > "${OUTFILE}${_tmp}"
if [ -f "${OUTFILE}${_tmp}" ]; then if [ -f "${OUTFILE}${_tmp}" ]; then
if "${_diff}" "${OUTFILE}" "${OUTFILE}${_tmp}" > /dev/null 2> /dev/null ; then if "${_diff}" "${OUTFILE}" "${OUTFILE}${_tmp}" > /dev/null 2> /dev/null ; then
@ -393,7 +399,7 @@ cmake_kwsys_config_replace_string ()
APPEND="$*" APPEND="$*"
if [ -f "${INFILE}" ] || ${cmake_system_openvms}; then if [ -f "${INFILE}" ] || ${cmake_system_openvms}; then
echo "${APPEND}" > "${OUTFILE}${_tmp}" echo "${APPEND}" > "${OUTFILE}${_tmp}"
cat "${INFILE}" | cat "${INFILE}" |
sed "/./ {s/\@KWSYS_NAMESPACE\@/cmsys/g; sed "/./ {s/\@KWSYS_NAMESPACE\@/cmsys/g;
s/@KWSYS_BUILD_SHARED@/${KWSYS_BUILD_SHARED}/g; s/@KWSYS_BUILD_SHARED@/${KWSYS_BUILD_SHARED}/g;
s/@KWSYS_LFS_AVAILABLE@/${KWSYS_LFS_AVAILABLE}/g; s/@KWSYS_LFS_AVAILABLE@/${KWSYS_LFS_AVAILABLE}/g;
@ -797,7 +803,7 @@ echo '
# include <iostream.h> # include <iostream.h>
#endif #endif
class NeedCXX class NeedCXX
{ {
public: public:
NeedCXX() { this->Foo = 1; } NeedCXX() { this->Foo = 1; }
@ -1387,12 +1393,12 @@ cmake_kwsys_config_replace_string \
"${cmake_bootstrap_dir}/cmsys/Configure.h" \ "${cmake_bootstrap_dir}/cmsys/Configure.h" \
"${cmake_compiler_settings_comment}" "${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_replace_string "${cmake_source_dir}/Source/kwsys/${a}.in" \
"${cmake_bootstrap_dir}/cmsys/${a}" KWSYS_NAMESPACE cmsys "${cmake_bootstrap_dir}/cmsys/${a}" KWSYS_NAMESPACE cmsys
done 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_replace_string "${cmake_source_dir}/Source/kwsys/kwsys_ios_${a}.h.in" \
"${cmake_bootstrap_dir}/cmsys/ios/${a}" KWSYS_NAMESPACE cmsys "${cmake_bootstrap_dir}/cmsys/ios/${a}" KWSYS_NAMESPACE cmsys
done done