summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndy Cedilnik <andy.cedilnik@kitware.com>2006-03-28 13:54:01 (GMT)
committerAndy Cedilnik <andy.cedilnik@kitware.com>2006-03-28 13:54:01 (GMT)
commit40272a16bd99b2a099cb3ef910f6d70c7c3a6f65 (patch)
tree3834eae44422f7342369ae285f2daa99e66eb0bc
parent5d722df21f76087d80603b1df3a6be628c3e1693 (diff)
downloadCMake-40272a16bd99b2a099cb3ef910f6d70c7c3a6f65.zip
CMake-40272a16bd99b2a099cb3ef910f6d70c7c3a6f65.tar.gz
CMake-40272a16bd99b2a099cb3ef910f6d70c7c3a6f65.tar.bz2
ENH: Add support for adding content to bundles
-rw-r--r--Modules/Platform/Darwin.cmake2
-rw-r--r--Source/cmLocalUnixMakefileGenerator3.cxx52
-rw-r--r--Source/cmMakefileExecutableTargetGenerator.cxx45
-rw-r--r--Source/cmMakefileTargetGenerator.cxx11
-rw-r--r--Source/cmMakefileTargetGenerator.h33
-rw-r--r--Source/cmSetSourceFilesPropertiesCommand.cxx40
-rw-r--r--Tests/BundleTest/CMakeLists.txt29
-rw-r--r--Tests/BundleTest/SomeRandomFile.txt0
-rw-r--r--Tests/BundleTest/randomResourceFile.plist.in9
9 files changed, 178 insertions, 43 deletions
diff --git a/Modules/Platform/Darwin.cmake b/Modules/Platform/Darwin.cmake
index 7d18906..4ca7d49 100644
--- a/Modules/Platform/Darwin.cmake
+++ b/Modules/Platform/Darwin.cmake
@@ -47,6 +47,8 @@ IF(NOT XCODE)
SET(CMAKE_SHARED_LIBRARY_SONAME_CXX_FLAG "-install_name")
ENDIF(NOT XCODE)
+SET(CMAKE_MacOSX_Content_COMPILE_OBJECT "\"${CMAKE_COMMAND}\" -E copy_if_different <SOURCE> <OBJECT>")
+
SET(CMAKE_C_CREATE_SHARED_LIBRARY_FORBIDDEN_FLAGS -w)
SET(CMAKE_CXX_CREATE_SHARED_LIBRARY_FORBIDDEN_FLAGS -w)
SET(CMAKE_C_CREATE_SHARED_LIBRARY
diff --git a/Source/cmLocalUnixMakefileGenerator3.cxx b/Source/cmLocalUnixMakefileGenerator3.cxx
index b590ed8..2240345 100644
--- a/Source/cmLocalUnixMakefileGenerator3.cxx
+++ b/Source/cmLocalUnixMakefileGenerator3.cxx
@@ -1542,15 +1542,54 @@ cmLocalUnixMakefileGenerator3
{
objectName = objectName.substr(0, dot_pos);
}
- objectName +=
- this->GlobalGenerator->GetLanguageOutputExtensionFromExtension(
- source.GetSourceExtension().c_str());
+ if ( source.GetPropertyAsBool("KEEP_EXTENSION") )
+ {
+ if ( !source.GetSourceExtension().empty() )
+ {
+ objectName += "." + source.GetSourceExtension();
+ }
+ }
+ else
+ {
+ objectName +=
+ this->GlobalGenerator->GetLanguageOutputExtensionFromExtension(
+ source.GetSourceExtension().c_str());
+ }
// Convert to a safe name.
objectName = this->CreateSafeUniqueObjectFileName(objectName.c_str());
// Prepend the target directory.
- std::string obj = this->GetTargetDirectory(target);
+ std::string obj;
+ const char* fileTargetDirectory = source.GetProperty("MACOSX_PACKAGE_LOCATION");
+ if ( fileTargetDirectory )
+ {
+ std::string targetName;
+ std::string targetNameReal;
+ target.GetExecutableNames(targetName, targetNameReal,
+ this->ConfigurationName.c_str());
+ if ( target.GetPropertyAsBool("MACOSX_BUNDLE") )
+ {
+ // Construct the full path version of the names.
+ obj = this->ExecutableOutputPath;
+ if(obj.empty())
+ {
+ obj = this->Makefile->GetStartOutputDirectory();
+ obj += "/";
+ }
+ obj += targetName + ".app/Contents/";
+ obj += fileTargetDirectory;
+ }
+ else
+ {
+ // Framework not handled yet
+ abort();
+ }
+ }
+ else
+ {
+ obj = this->GetTargetDirectory(target);
+ }
obj += "/";
obj += objectName;
if(nameWithoutTargetDir)
@@ -1763,6 +1802,11 @@ const char*
cmLocalUnixMakefileGenerator3
::GetSourceFileLanguage(const cmSourceFile& source)
{
+ const char* lang = source.GetProperty("LANGUAGE");
+ if ( lang )
+ {
+ return lang;
+ }
// Identify the language of the source file.
return (this->GlobalGenerator
->GetLanguageFromExtension(source.GetSourceExtension().c_str()));
diff --git a/Source/cmMakefileExecutableTargetGenerator.cxx b/Source/cmMakefileExecutableTargetGenerator.cxx
index afdca4d..6922cf0 100644
--- a/Source/cmMakefileExecutableTargetGenerator.cxx
+++ b/Source/cmMakefileExecutableTargetGenerator.cxx
@@ -28,7 +28,7 @@ void cmMakefileExecutableTargetGenerator::WriteRuleFiles()
{
// create the build.make file and directory, put in the common blocks
this->CreateRuleFile();
-
+
// Add in any rules for custom commands
this->WriteCustomCommandsForTarget();
@@ -82,8 +82,8 @@ void cmMakefileExecutableTargetGenerator::WriteExecutableRule(bool relink)
// Add a dependency on the rule file itself.
this->LocalGenerator->AppendRuleDepend(depends,
this->BuildFileNameFull.c_str());
-
- for(std::vector<std::string>::const_iterator obj =
+
+ for(std::vector<std::string>::const_iterator obj =
this->ExternalObjects.begin();
obj != this->ExternalObjects.end(); ++obj)
{
@@ -111,13 +111,13 @@ void cmMakefileExecutableTargetGenerator::WriteExecutableRule(bool relink)
// Make bundle directories
outpath += targetName;
outpath += ".app/Contents/MacOS/";
- std::string f1 =
+ std::string f1 =
this->Makefile->GetModulesFile("MacOSXBundleInfo.plist.in");
if ( f1.size() == 0 )
{
cmSystemTools::Error("could not find Mac OSX bundle template file.");
}
- std::string macdir =
+ std::string macdir =
this->Makefile->GetSafeDefinition("EXECUTABLE_OUTPUT_PATH");
if ( macdir.size() == 0 )
{
@@ -130,6 +130,25 @@ void cmMakefileExecutableTargetGenerator::WriteExecutableRule(bool relink)
macdir += targetName;
macdir += ".app/Contents/";
+ std::vector<cmSourceFile*>::iterator sourceIt;
+ for ( sourceIt = this->Target->GetSourceFiles().begin();
+ sourceIt != this->Target->GetSourceFiles().end();
+ ++ sourceIt )
+ {
+ const char* subDir = (*sourceIt)->GetProperty("MACOSX_PACKAGE_LOCATION");
+ if ( subDir )
+ {
+ std::string newDir = macdir;
+ newDir += subDir;
+ if ( !cmSystemTools::MakeDirectory(newDir.c_str()) )
+ {
+ cmSystemTools::Error("Cannot create a subdirectory for \"",
+ newDir.c_str(), "\".");
+ return;
+ }
+ }
+ }
+
// Configure the Info.plist file. Note that it needs the executable name
// to be set.
std::string f2 = macdir + "Info.plist";
@@ -232,7 +251,7 @@ void cmMakefileExecutableTargetGenerator::WriteExecutableRule(bool relink)
cmLocalGenerator::START_OUTPUT,
cmLocalGenerator::UNCHANGED));
}
- }
+ }
// Add a command to remove any existing files for this executable.
std::vector<std::string> commands1;
@@ -240,7 +259,7 @@ void cmMakefileExecutableTargetGenerator::WriteExecutableRule(bool relink)
*this->Target, "target");
this->LocalGenerator->CreateCDCommand(commands1,
this->Makefile->GetStartOutputDirectory(),
- this->Makefile->GetHomeOutputDirectory());
+ this->Makefile->GetHomeOutputDirectory());
commands.insert(commands.end(), commands1.begin(), commands1.end());
commands1.clear();
@@ -257,7 +276,7 @@ void cmMakefileExecutableTargetGenerator::WriteExecutableRule(bool relink)
std::string linkRuleVar = "CMAKE_";
linkRuleVar += linkLanguage;
linkRuleVar += "_LINK_EXECUTABLE";
- std::string linkRule =
+ std::string linkRule =
this->Makefile->GetRequiredDefinition(linkRuleVar.c_str());
cmSystemTools::ExpandListArgument(linkRule, commands1);
this->LocalGenerator->CreateCDCommand
@@ -317,9 +336,9 @@ void cmMakefileExecutableTargetGenerator::WriteExecutableRule(bool relink)
}
// Write the build rule.
- this->LocalGenerator->WriteMakeRule(*this->BuildFileStream,
+ this->LocalGenerator->WriteMakeRule(*this->BuildFileStream,
0,
- targetFullPathReal.c_str(),
+ targetFullPathReal.c_str(),
depends, commands, false);
// The symlink name for the target should depend on the real target
@@ -331,7 +350,7 @@ void cmMakefileExecutableTargetGenerator::WriteExecutableRule(bool relink)
commands.clear();
depends.push_back(targetFullPathReal.c_str());
this->LocalGenerator->WriteMakeRule(*this->BuildFileStream, 0,
- targetFullPath.c_str(),
+ targetFullPath.c_str(),
depends, commands, false);
}
@@ -341,11 +360,11 @@ void cmMakefileExecutableTargetGenerator::WriteExecutableRule(bool relink)
dir += this->LocalGenerator->GetTargetDirectory(*this->Target);
std::string buildTargetRuleName = dir;
buildTargetRuleName += relink?"/preinstall":"/build";
- buildTargetRuleName =
+ buildTargetRuleName =
this->Convert(buildTargetRuleName.c_str(),
cmLocalGenerator::HOME_OUTPUT,
cmLocalGenerator::MAKEFILE);
- this->LocalGenerator->WriteConvenienceRule(*this->BuildFileStream,
+ this->LocalGenerator->WriteConvenienceRule(*this->BuildFileStream,
targetFullPath.c_str(),
buildTargetRuleName.c_str());
diff --git a/Source/cmMakefileTargetGenerator.cxx b/Source/cmMakefileTargetGenerator.cxx
index d0b5de3..2f5e120 100644
--- a/Source/cmMakefileTargetGenerator.cxx
+++ b/Source/cmMakefileTargetGenerator.cxx
@@ -237,8 +237,6 @@ void cmMakefileTargetGenerator::WriteCommonCodeRules()
}
}
-
-
//----------------------------------------------------------------------------
void cmMakefileTargetGenerator::WriteObjectRuleFiles(cmSourceFile& source)
{
@@ -282,6 +280,10 @@ void cmMakefileTargetGenerator::WriteObjectRuleFiles(cmSourceFile& source)
(this->LocalGenerator->ConvertToFullPath(dir).c_str());
// Save this in the target's list of object files.
+ if ( source.GetPropertyAsBool("EXTRA_CONTENT") )
+ {
+ this->ExtraContent.insert(obj);
+ }
this->Objects.push_back(obj);
std::string relativeObj = this->LocalGenerator->GetHomeRelativeOutputPath();
relativeObj += obj;
@@ -587,6 +589,7 @@ void cmMakefileTargetGenerator
}
}
+//----------------------------------------------------------------------------
void cmMakefileTargetGenerator::WriteCustomCommands()
{
// add custom commands to the clean rules?
@@ -667,6 +670,10 @@ cmMakefileTargetGenerator
for(std::vector<std::string>::const_iterator i = this->Objects.begin();
i != this->Objects.end(); ++i)
{
+ if ( this->ExtraContent.find(i->c_str()) != this->ExtraContent.end() )
+ {
+ continue;
+ }
*this->BuildFileStream << " " << lineContinue << "\n";
if(objName)
{
diff --git a/Source/cmMakefileTargetGenerator.h b/Source/cmMakefileTargetGenerator.h
index 85f0fb2..c2422d7 100644
--- a/Source/cmMakefileTargetGenerator.h
+++ b/Source/cmMakefileTargetGenerator.h
@@ -34,7 +34,7 @@ class cmSourceFile;
* \brief Support Routines for writing makefiles
*
*/
-class cmMakefileTargetGenerator
+class cmMakefileTargetGenerator
{
public:
// constructor to set the ivars
@@ -49,12 +49,12 @@ public:
/* the main entry point for this class. Writes the Makefiles associated
with this target */
virtual void WriteRuleFiles() = 0;
-
+
protected:
// create the file and directory etc
void CreateRuleFile();
-
+
// outputs the rules for any custom commands used by this target
void WriteCustomCommandsForTarget();
@@ -75,38 +75,38 @@ protected:
// write the build rule for an object
void WriteObjectBuildFile(std::string &obj,
- const char *lang,
+ const char *lang,
cmSourceFile& source,
std::vector<std::string>& depends);
-
+
// write the depend.make file for an object
void WriteObjectDependRules(cmSourceFile& source,
std::vector<std::string>& depends);
-
+
// this is responsible for writing all of the rules for all this
// directories custom commands (but not utility targets)
void WriteCustomCommands();
void GenerateCustomRuleFile(const cmCustomCommand& cc);
-
+
// write out the variable that lists the objects for this target
void WriteObjectsVariable(std::string& variableName,
std::string& variableNameExternal);
-
+
// Return the a string with -F flags on apple
std::string GetFrameworkFlags();
-
+
// append intertarget dependencies
void AppendTargetDepends(std::vector<std::string>& depends);
virtual void CloseFileStreams();
- void RemoveForbiddenFlags(const char* flagVar, const char* linkLang,
+ void RemoveForbiddenFlags(const char* flagVar, const char* linkLang,
std::string& linkFlags);
cmStdString TargetName;
cmTarget *Target;
cmLocalUnixMakefileGenerator3 *LocalGenerator;
cmGlobalGenerator *GlobalGenerator;
cmMakefile *Makefile;
-
+
// the full path to the build file
std::string BuildFileName;
std::string BuildFileNameFull;
@@ -132,19 +132,20 @@ protected:
// objects used by this target
std::vector<std::string> Objects;
std::vector<std::string> ExternalObjects;
+ std::set<std::string> ExtraContent;
// Set of object file names that will be built in this directory.
std::set<cmStdString> ObjectFiles;
//==================================================================
- // Convenience routines that do nothing more than forward to
+ // Convenience routines that do nothing more than forward to
// implementaitons
- std::string Convert(const char* source,
- cmLocalGenerator::RelativeRoot relative,
- cmLocalGenerator::OutputFormat output =
+ std::string Convert(const char* source,
+ cmLocalGenerator::RelativeRoot relative,
+ cmLocalGenerator::OutputFormat output =
cmLocalGenerator::UNCHANGED,
- bool optional = false)
+ bool optional = false)
{
return this->LocalGenerator->Convert(source, relative, output, optional);
}
diff --git a/Source/cmSetSourceFilesPropertiesCommand.cxx b/Source/cmSetSourceFilesPropertiesCommand.cxx
index 377eb73..8966c6b 100644
--- a/Source/cmSetSourceFilesPropertiesCommand.cxx
+++ b/Source/cmSetSourceFilesPropertiesCommand.cxx
@@ -9,8 +9,8 @@
Copyright (c) 2002 Kitware, Inc., Insight Consortium. All rights reserved.
See Copyright.txt or http://www.cmake.org/HTML/Copyright.html for details.
- This software is distributed WITHOUT ANY WARRANTY; without even
- the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ This software is distributed WITHOUT ANY WARRANTY; without even
+ the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE. See the above copyright notices for more information.
=========================================================================*/
@@ -63,7 +63,8 @@ bool cmSetSourceFilesPropertiesCommand::InitialPass(
++j;
if(j == args.end())
{
- this->SetError("called with incorrect number of arguments COMPILE_FLAGS with no flags");
+ this->SetError("called with incorrect number of arguments "
+ "COMPILE_FLAGS with no flags");
return false;
}
propertyPairs.push_back(*j);
@@ -85,6 +86,7 @@ bool cmSetSourceFilesPropertiesCommand::InitialPass(
{
// now loop through the rest of the arguments, new style
++j;
+ bool dontPush = false;
while (j != args.end())
{
propertyPairs.push_back(*j);
@@ -96,6 +98,25 @@ bool cmSetSourceFilesPropertiesCommand::InitialPass(
generated = true;
}
}
+ else if(*j == "MACOSX_PACKAGE_LOCATION")
+ {
+ doingFiles = false;
+ ++j;
+ if(j == args.end())
+ {
+ this->SetError("called with incorrect number of arguments "
+ "MACOSX_PACKAGE_LOCATION with no flags");
+ return false;
+ }
+ propertyPairs.push_back(*j);
+ propertyPairs.push_back("EXTRA_CONTENT");
+ propertyPairs.push_back("1");
+ propertyPairs.push_back("KEEP_EXTENSION");
+ propertyPairs.push_back("1");
+ propertyPairs.push_back("LANGUAGE");
+ propertyPairs.push_back("MacOSX_Content");
+ dontPush = true;
+ }
else
{
++j;
@@ -105,8 +126,12 @@ bool cmSetSourceFilesPropertiesCommand::InitialPass(
this->SetError("called with incorrect number of arguments.");
return false;
}
- propertyPairs.push_back(*j);
+ if ( !dontPush )
+ {
+ propertyPairs.push_back(*j);
+ }
++j;
+ dontPush = false;
}
// break out of the loop because j is already == end
break;
@@ -117,16 +142,17 @@ bool cmSetSourceFilesPropertiesCommand::InitialPass(
}
else
{
- this->SetError("called with illegal arguments, maybe missing a PROPERTIES specifier?");
+ this->SetError("called with illegal arguments, maybe missing a "
+ "PROPERTIES specifier?");
return false;
}
}
-
+
// now loop over all the files
int i;
unsigned int k;
for(i = 0; i < numFiles; ++i)
- {
+ {
// get the source file
cmSourceFile* sf =
this->Makefile->GetOrCreateSource(args[i].c_str(), generated);
diff --git a/Tests/BundleTest/CMakeLists.txt b/Tests/BundleTest/CMakeLists.txt
index 9e8cb20..1e90566 100644
--- a/Tests/BundleTest/CMakeLists.txt
+++ b/Tests/BundleTest/CMakeLists.txt
@@ -1,9 +1,36 @@
PROJECT(BundleTest)
SET(MACOSX_BUNDLE_INFO_STRING "bundle_info_string")
+SET(CMAKE_MacOSX_Content_COMPILE_OBJECT "\"${CMAKE_COMMAND}\" -E copy_if_different <SOURCE> <OBJECT>")
+
+ADD_CUSTOM_COMMAND(
+ OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/randomResourceFile.plist"
+ COMMAND /bin/cp
+ ARGS "${CMAKE_CURRENT_SOURCE_DIR}/randomResourceFile.plist.in"
+ "${CMAKE_CURRENT_BINARY_DIR}/randomResourceFile.plist")
+
+SET_SOURCE_FILES_PROPERTIES(
+ "${CMAKE_CURRENT_BINARY_DIR}/randomResourceFile.plist"
+ PROPERTIES
+ MACOSX_PACKAGE_LOCATION Resources
+ )
+
+SET_SOURCE_FILES_PROPERTIES(
+ SomeRandomFile.txt
+ PROPERTIES
+ MACOSX_PACKAGE_LOCATION MacOS
+ )
+
+SET(EXECUTABLE_OUTPUT_PATH "${CMAKE_CURRENT_BINARY_DIR}/foobar")
# Test building a bundle linking to a shared library.
ADD_LIBRARY(BundleTestLib SHARED BundleLib.cxx)
-ADD_EXECUTABLE(BundleTest MACOSX_BUNDLE BundleTest.cxx)
+ADD_EXECUTABLE(BundleTest
+ MACOSX_BUNDLE
+ BundleTest.cxx
+ SomeRandomFile.txt
+ "${CMAKE_CURRENT_BINARY_DIR}/randomResourceFile.plist"
+ )
+
TARGET_LINK_LIBRARIES(BundleTest BundleTestLib)
# Test bundle installation.
diff --git a/Tests/BundleTest/SomeRandomFile.txt b/Tests/BundleTest/SomeRandomFile.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/Tests/BundleTest/SomeRandomFile.txt
diff --git a/Tests/BundleTest/randomResourceFile.plist.in b/Tests/BundleTest/randomResourceFile.plist.in
new file mode 100644
index 0000000..cfe3222
--- /dev/null
+++ b/Tests/BundleTest/randomResourceFile.plist.in
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>Package</key>
+ <string>CMake</string>
+</dict>
+</plist>
+