summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Source/cmGlobalXCodeGenerator.cxx16
-rw-r--r--Source/cmLocalUnixMakefileGenerator3.cxx6
-rw-r--r--Source/cmMakefileExecutableTargetGenerator.cxx50
-rw-r--r--Source/cmMakefileExecutableTargetGenerator.h4
-rw-r--r--Source/cmMakefileLibraryTargetGenerator.cxx145
-rw-r--r--Source/cmMakefileLibraryTargetGenerator.h13
-rw-r--r--Source/cmMakefileTargetGenerator.cxx58
-rw-r--r--Source/cmMakefileTargetGenerator.h18
-rw-r--r--Source/cmMakefileUtilityTargetGenerator.cxx4
-rw-r--r--Source/cmMakefileUtilityTargetGenerator.h2
-rw-r--r--Source/cmSourceFile.cxx19
-rw-r--r--Source/cmTarget.cxx157
-rw-r--r--Source/cmTarget.h37
13 files changed, 284 insertions, 245 deletions
diff --git a/Source/cmGlobalXCodeGenerator.cxx b/Source/cmGlobalXCodeGenerator.cxx
index de62e8f..32323e5 100644
--- a/Source/cmGlobalXCodeGenerator.cxx
+++ b/Source/cmGlobalXCodeGenerator.cxx
@@ -493,21 +493,21 @@ cmGlobalXCodeGenerator::CreateXCodeSourceFile(cmLocalGenerator* lg,
// Is this a resource file in this target? Add it to the resources group...
//
cmTarget::SourceFileFlags tsFlags = cmtarget.GetTargetSourceFileFlags(sf);
- bool isResource = tsFlags.Resource;
+ bool isResource = (tsFlags.Type == cmTarget::SourceFileTypeResource);
// Is this a "private" or "public" framework header file?
// Set the ATTRIBUTES attribute appropriately...
//
if(cmtarget.IsFrameworkOnApple())
{
- if(tsFlags.PrivateHeader)
+ if(tsFlags.Type == cmTarget::SourceFileTypePrivateHeader)
{
cmXCodeObject* attrs = this->CreateObject(cmXCodeObject::OBJECT_LIST);
attrs->AddObject(this->CreateString("Private"));
settings->AddAttribute("ATTRIBUTES", attrs);
isResource = true;
}
- else if(tsFlags.PublicHeader)
+ else if(tsFlags.Type == cmTarget::SourceFileTypePublicHeader)
{
cmXCodeObject* attrs = this->CreateObject(cmXCodeObject::OBJECT_LIST);
attrs->AddObject(this->CreateString("Public"));
@@ -698,7 +698,7 @@ cmGlobalXCodeGenerator::CreateXCodeTargets(cmLocalGenerator* gen,
{
headerFiles.push_back(xsf);
}
- else if(tsFlags.Resource)
+ else if(tsFlags.Type == cmTarget::SourceFileTypeResource)
{
resourceFiles.push_back(xsf);
}
@@ -785,12 +785,12 @@ cmGlobalXCodeGenerator::CreateXCodeTargets(cmLocalGenerator* gen,
for(std::vector<cmSourceFile*>::const_iterator i = classes.begin();
i != classes.end(); ++i)
{
- const char* contentLoc = (*i)->GetProperty("MACOSX_PACKAGE_LOCATION");
- if ( !contentLoc || cmStdString(contentLoc) == "Resources" )
+ cmTarget::SourceFileFlags tsFlags =
+ cmtarget.GetTargetSourceFileFlags(*i);
+ if(tsFlags.Type == cmTarget::SourceFileTypeMacContent)
{
- continue;
+ bundleFiles[tsFlags.MacFolder].push_back(*i);
}
- bundleFiles[contentLoc].push_back(*i);
}
mapOfVectorOfSourceFiles::iterator mit;
for ( mit = bundleFiles.begin(); mit != bundleFiles.end(); ++ mit )
diff --git a/Source/cmLocalUnixMakefileGenerator3.cxx b/Source/cmLocalUnixMakefileGenerator3.cxx
index dda9574..396dd75 100644
--- a/Source/cmLocalUnixMakefileGenerator3.cxx
+++ b/Source/cmLocalUnixMakefileGenerator3.cxx
@@ -128,8 +128,8 @@ void cmLocalUnixMakefileGenerator3::Generate()
std::string empty;
for(cmTargets::iterator t = targets.begin(); t != targets.end(); ++t)
{
- cmMakefileTargetGenerator *tg =
- cmMakefileTargetGenerator::New(this, t->first, &(t->second));
+ cmMakefileTargetGenerator *tg =
+ cmMakefileTargetGenerator::New(&(t->second));
if (tg)
{
this->TargetGenerators.push_back(tg);
@@ -168,7 +168,7 @@ unsigned long cmLocalUnixMakefileGenerator3
this->TargetGenerators.begin();
mtgIter != this->TargetGenerators.end(); ++mtgIter)
{
- if (!strcmp(name,(*mtgIter)->GetTargetName()))
+ if (!strcmp(name,(*mtgIter)->GetTarget()->GetName()))
{
return (*mtgIter)->GetNumberOfProgressActions();
}
diff --git a/Source/cmMakefileExecutableTargetGenerator.cxx b/Source/cmMakefileExecutableTargetGenerator.cxx
index d13895a..c1c3b63 100644
--- a/Source/cmMakefileExecutableTargetGenerator.cxx
+++ b/Source/cmMakefileExecutableTargetGenerator.cxx
@@ -25,9 +25,22 @@
#include "cmake.h"
//----------------------------------------------------------------------------
-cmMakefileExecutableTargetGenerator::cmMakefileExecutableTargetGenerator()
+cmMakefileExecutableTargetGenerator
+::cmMakefileExecutableTargetGenerator(cmTarget* target):
+ cmMakefileTargetGenerator(target)
{
this->CustomCommandDriver = OnDepends;
+ this->Target->GetExecutableNames(
+ this->TargetNameOut, this->TargetNameReal, this->TargetNameImport,
+ this->TargetNamePDB, this->LocalGenerator->ConfigurationName.c_str());
+
+ if(this->Target->IsAppBundleOnApple())
+ {
+ this->MacContentDirectory = this->Target->GetDirectory();
+ this->MacContentDirectory += "/";
+ this->MacContentDirectory += this->TargetNameOut;
+ this->MacContentDirectory += ".app/Contents/";
+ }
}
//----------------------------------------------------------------------------
@@ -117,21 +130,7 @@ void cmMakefileExecutableTargetGenerator::WriteExecutableRule(bool relink)
outpath += "/";
if(this->Target->IsAppBundleOnApple())
{
- // Compute bundle directory names.
- std::string macdir = outpath;
- macdir += targetName;
- macdir += ".app/Contents/";
- outpath = macdir;
- outpath += "MacOS";
- cmSystemTools::MakeDirectory(outpath.c_str());
- outpath += "/";
-
- // Configure the Info.plist file. Note that it needs the executable name
- // to be set.
- std::string plist = macdir + "Info.plist";
- this->LocalGenerator->GenerateAppleInfoPList(this->Target,
- targetName.c_str(),
- plist.c_str());
+ this->CreateAppBundle(targetName, outpath);
}
std::string outpathImp;
if(relink)
@@ -469,3 +468,22 @@ void cmMakefileExecutableTargetGenerator::WriteExecutableRule(bool relink)
exeCleanFiles.begin(),
exeCleanFiles.end());
}
+
+//----------------------------------------------------------------------------
+void
+cmMakefileExecutableTargetGenerator::CreateAppBundle(std::string& targetName,
+ std::string& outpath)
+{
+ // Compute bundle directory names.
+ outpath = this->MacContentDirectory;
+ outpath += "MacOS";
+ cmSystemTools::MakeDirectory(outpath.c_str());
+ 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());
+}
diff --git a/Source/cmMakefileExecutableTargetGenerator.h b/Source/cmMakefileExecutableTargetGenerator.h
index 269fd5f..3111c5c 100644
--- a/Source/cmMakefileExecutableTargetGenerator.h
+++ b/Source/cmMakefileExecutableTargetGenerator.h
@@ -22,7 +22,7 @@
class cmMakefileExecutableTargetGenerator: public cmMakefileTargetGenerator
{
public:
- cmMakefileExecutableTargetGenerator();
+ cmMakefileExecutableTargetGenerator(cmTarget* target);
/* the main entry point for this class. Writes the Makefiles associated
with this target */
@@ -30,7 +30,7 @@ public:
protected:
virtual void WriteExecutableRule(bool relink);
-
+ void CreateAppBundle(std::string& targetName, std::string& outpath);
};
#endif
diff --git a/Source/cmMakefileLibraryTargetGenerator.cxx b/Source/cmMakefileLibraryTargetGenerator.cxx
index f611562..bb68d36 100644
--- a/Source/cmMakefileLibraryTargetGenerator.cxx
+++ b/Source/cmMakefileLibraryTargetGenerator.cxx
@@ -27,9 +27,35 @@
#include <memory> // auto_ptr
//----------------------------------------------------------------------------
-cmMakefileLibraryTargetGenerator::cmMakefileLibraryTargetGenerator()
+cmMakefileLibraryTargetGenerator
+::cmMakefileLibraryTargetGenerator(cmTarget* target):
+ cmMakefileTargetGenerator(target)
{
this->CustomCommandDriver = OnDepends;
+ this->Target->GetLibraryNames(
+ this->TargetNameOut, this->TargetNameSO, this->TargetNameReal,
+ this->TargetNameImport, this->TargetNamePDB,
+ this->LocalGenerator->ConfigurationName.c_str());
+
+ if(this->Target->IsFrameworkOnApple())
+ {
+ if(const char* fversion = this->Target->GetProperty("FRAMEWORK_VERSION"))
+ {
+ this->FrameworkVersion = fversion;
+ }
+ else if(const char* tversion = this->Target->GetProperty("VERSION"))
+ {
+ this->FrameworkVersion = tversion;
+ }
+ else
+ {
+ this->FrameworkVersion = "A";
+ }
+ this->MacContentDirectory = this->Target->GetDirectory();
+ this->MacContentDirectory += "/Versions/";
+ this->MacContentDirectory += this->FrameworkVersion;
+ this->MacContentDirectory += "/";
+ }
}
//----------------------------------------------------------------------------
@@ -218,10 +244,9 @@ void cmMakefileLibraryTargetGenerator::WriteFrameworkRules(bool relink)
}
//----------------------------------------------------------------------------
-void cmMakefileLibraryTargetGenerator::CreateFrameworkLinksAndDirs(
+void cmMakefileLibraryTargetGenerator::CreateFramework(
std::string& targetName,
- std::string& outpath,
- const char* version)
+ std::string& outpath)
{
std::string symlink;
std::string symlink2;
@@ -233,7 +258,7 @@ void cmMakefileLibraryTargetGenerator::CreateFrameworkLinksAndDirs(
// cd foo.framework to setup symlinks with relative paths
cmSystemTools::ChangeDirectory((outpath+"Versions").c_str());
// Current -> version
- symlink = version;
+ symlink = this->FrameworkVersion;
symlink2 = "Current";
cmSystemTools::RemoveFile("Current");
cmSystemTools::CreateSymlink(symlink.c_str(), symlink2.c_str());
@@ -266,116 +291,6 @@ void cmMakefileLibraryTargetGenerator::CreateFrameworkLinksAndDirs(
}
//----------------------------------------------------------------------------
-void cmMakefileLibraryTargetGenerator::CopyFrameworkSources(
- std::string& targetName,
- std::string& outpath,
- const char* /*version*/ ,
- const char* propertyName,
- const char* subdir)
-{
- std::string fullOutput = outpath + targetName;
- cmCustomCommandLines commandLines;
- std::vector<std::string> depends;
- const std::vector<cmSourceFile*>& sources =
- this->Target->GetSourceFiles();
-
- std::string propName(propertyName);
-
- for(std::vector<cmSourceFile*>::const_iterator i = sources.begin();
- i != sources.end(); ++i)
- {
- cmSourceFile* sf = *i;
-
- if(!sf)
- {
- cmSystemTools::Error(
- "could not find framework source file", "");
- continue;
- }
-
- cmTarget::SourceFileFlags tsFlags =
- this->Target->GetTargetSourceFileFlags(sf);
-
- // If processing public headers, skip headers also marked with the private
- // property. Private wins.
- //
- if(tsFlags.PrivateHeader && (propName == "PUBLIC_HEADER"))
- {
- continue;
- }
-
- if(tsFlags.PrivateHeader && (propName == "PRIVATE_HEADER") ||
- tsFlags.PublicHeader && (propName == "PUBLIC_HEADER") ||
- tsFlags.Resource && (propName == "RESOURCE"))
- {
- cmCustomCommandLine line;
- std::string dest = outpath + subdir + "/";
- dest += cmSystemTools::GetFilenameName(sf->GetFullPath());
- line.push_back("$(CMAKE_COMMAND)");
- line.push_back("-E");
- line.push_back("copy_if_different");
- line.push_back(sf->GetFullPath());
- depends.push_back(sf->GetFullPath());
- line.push_back(dest);
- commandLines.push_back(line);
- // make sure the target gets rebuilt if any of the headers is removed
- this->GenerateExtraOutput(dest.c_str(), fullOutput.c_str());
- }
- }
-
- // add a set of prebuild commands to run on the target
- if(!commandLines.empty())
- {
- this->Makefile->
- AddCustomCommandToTarget(this->Target->GetName(),
- depends,
- commandLines,
- cmTarget::PRE_BUILD,
- "copy files",
- this->Makefile->GetCurrentOutputDirectory());
- }
-}
-
-//----------------------------------------------------------------------------
-void cmMakefileLibraryTargetGenerator::CreateFramework(
- std::string& targetName,
- std::string& outpath)
-{
- std::string macdir = outpath;
- const char* version = this->Target->GetProperty("FRAMEWORK_VERSION");
- if(!version)
- {
- version = this->Target->GetProperty("VERSION");
- }
- if(!version)
- {
- version = "A";
- }
- // create the symbolic links and directories
- this->CreateFrameworkLinksAndDirs(targetName,
- outpath,
- version);
- macdir += "Versions/";
- macdir += version;
- macdir += "/";
- outpath += "Versions/";
- outpath += version;
- outpath += "/";
-
- //cmSystemTools::MakeDirectory((macdir + "Libraries").c_str());
- cmSystemTools::MakeDirectory((macdir + "Headers").c_str());
-
- this->CopyFrameworkSources(targetName, outpath, version,
- "PRIVATE_HEADER", "PrivateHeaders");
-
- this->CopyFrameworkSources(targetName, outpath, version,
- "PUBLIC_HEADER", "Headers");
-
- this->CopyFrameworkSources(targetName, outpath, version,
- "RESOURCE", "Resources");
-}
-
-//----------------------------------------------------------------------------
void cmMakefileLibraryTargetGenerator::WriteLibraryRules
(const char* linkRuleVar, const char* extraFlags, bool relink)
{
diff --git a/Source/cmMakefileLibraryTargetGenerator.h b/Source/cmMakefileLibraryTargetGenerator.h
index 22741af..a1a4bf7 100644
--- a/Source/cmMakefileLibraryTargetGenerator.h
+++ b/Source/cmMakefileLibraryTargetGenerator.h
@@ -23,7 +23,7 @@ class cmMakefileLibraryTargetGenerator:
public cmMakefileTargetGenerator
{
public:
- cmMakefileLibraryTargetGenerator();
+ cmMakefileLibraryTargetGenerator(cmTarget* target);
/* the main entry point for this class. Writes the Makefiles associated
with this target */
@@ -39,14 +39,9 @@ protected:
void WriteFrameworkRules(bool relink);
void CreateFramework(std::string& targetName,
std::string& outpath);
- void CreateFrameworkLinksAndDirs(std::string& targetName,
- std::string& outpath,
- const char* version);
- void CopyFrameworkSources(std::string& targetName,
- std::string& outpath,
- const char* version,
- const char* propertyName,
- const char* subdir);
+
+ // Store the computd framework version for OS X Frameworks.
+ std::string FrameworkVersion;
};
#endif
diff --git a/Source/cmMakefileTargetGenerator.cxx b/Source/cmMakefileTargetGenerator.cxx
index 3886863..135b199 100644
--- a/Source/cmMakefileTargetGenerator.cxx
+++ b/Source/cmMakefileTargetGenerator.cxx
@@ -30,45 +30,45 @@
#include "cmMakefileUtilityTargetGenerator.h"
-cmMakefileTargetGenerator::cmMakefileTargetGenerator()
+cmMakefileTargetGenerator::cmMakefileTargetGenerator(cmTarget* target)
{
this->BuildFileStream = 0;
this->InfoFileStream = 0;
this->FlagFileStream = 0;
this->CustomCommandDriver = OnBuild;
this->FortranModuleDirectoryComputed = false;
+ this->Target = target;
+ this->Makefile = this->Target->GetMakefile();
+ this->LocalGenerator =
+ static_cast<cmLocalUnixMakefileGenerator3*>(
+ this->Makefile->GetLocalGenerator());
+ this->GlobalGenerator =
+ static_cast<cmGlobalUnixMakefileGenerator3*>(
+ this->LocalGenerator->GetGlobalGenerator());
}
cmMakefileTargetGenerator *
-cmMakefileTargetGenerator::New(cmLocalUnixMakefileGenerator3 *lg,
- cmStdString tgtName, cmTarget *tgt)
+cmMakefileTargetGenerator::New(cmTarget *tgt)
{
cmMakefileTargetGenerator *result = 0;
switch (tgt->GetType())
{
case cmTarget::EXECUTABLE:
- result = new cmMakefileExecutableTargetGenerator;
+ result = new cmMakefileExecutableTargetGenerator(tgt);
break;
case cmTarget::STATIC_LIBRARY:
case cmTarget::SHARED_LIBRARY:
case cmTarget::MODULE_LIBRARY:
- result = new cmMakefileLibraryTargetGenerator;
+ result = new cmMakefileLibraryTargetGenerator(tgt);
break;
case cmTarget::UTILITY:
- result = new cmMakefileUtilityTargetGenerator;
+ result = new cmMakefileUtilityTargetGenerator(tgt);
break;
default:
return result;
// break; /* unreachable */
}
-
- result->TargetName = tgtName;
- result->Target = tgt;
- result->LocalGenerator = lg;
- result->GlobalGenerator =
- static_cast<cmGlobalUnixMakefileGenerator3*>(lg->GetGlobalGenerator());
- result->Makefile = lg->GetMakefile();
return result;
}
@@ -134,6 +134,8 @@ void cmMakefileTargetGenerator::WriteTargetBuildRules()
for(std::vector<cmSourceFile*>::const_iterator source = sources.begin();
source != sources.end(); ++source)
{
+ cmTarget::SourceFileFlags tsFlags =
+ this->Target->GetTargetSourceFileFlags(*source);
if(cmCustomCommand* cc = (*source)->GetCustomCommand())
{
this->GenerateCustomRuleFile(*cc);
@@ -150,10 +152,9 @@ void cmMakefileTargetGenerator::WriteTargetBuildRules()
}
}
}
- else if(const char* pkgloc =
- (*source)->GetProperty("MACOSX_PACKAGE_LOCATION"))
+ else if(tsFlags.Type != cmTarget::SourceFileTypeNormal)
{
- this->WriteMacOSXContentRules(*(*source), pkgloc);
+ this->WriteMacOSXContentRules(*(*source), tsFlags.MacFolder);
}
else if(!(*source)->GetPropertyAsBool("HEADER_FILE_ONLY"))
{
@@ -322,21 +323,14 @@ void cmMakefileTargetGenerator::WriteTargetLanguageFlags()
void cmMakefileTargetGenerator::WriteMacOSXContentRules(cmSourceFile& source,
const char* pkgloc)
{
- // Skip OS X bundle content when not building a bundle.
- if(!this->Target->IsAppBundleOnApple()) { return; }
-
- // Create the directory in which the content is to be placed.
- std::string targetName;
- std::string targetNameReal;
- std::string targetNameImport;
- std::string targetNamePDB;
- this->Target->GetExecutableNames
- (targetName, targetNameReal, targetNameImport, targetNamePDB,
- this->LocalGenerator->ConfigurationName.c_str());
- std::string macdir = this->Target->GetDirectory();
- macdir += "/";
- macdir += targetName;
- macdir += ".app/Contents/";
+ // Skip OS X content when not building a Framework or Bundle.
+ if(this->MacContentDirectory.empty())
+ {
+ return;
+ }
+
+ // Construct the full path to the content subdirectory.
+ std::string macdir = this->MacContentDirectory;
macdir += pkgloc;
cmSystemTools::MakeDirectory(macdir.c_str());
@@ -355,7 +349,7 @@ void cmMakefileTargetGenerator::WriteMacOSXContentRules(cmSourceFile& source,
std::vector<std::string> depends;
std::vector<std::string> commands;
depends.push_back(input);
- std::string copyEcho = "Copying Bundle content ";
+ std::string copyEcho = "Copying OS X content ";
copyEcho += output;
this->LocalGenerator->AppendEcho(commands, copyEcho.c_str(),
cmLocalUnixMakefileGenerator3::EchoBuild);
diff --git a/Source/cmMakefileTargetGenerator.h b/Source/cmMakefileTargetGenerator.h
index 44f57c7..34a736a 100644
--- a/Source/cmMakefileTargetGenerator.h
+++ b/Source/cmMakefileTargetGenerator.h
@@ -37,13 +37,11 @@ class cmMakefileTargetGenerator
{
public:
// constructor to set the ivars
- cmMakefileTargetGenerator();
+ cmMakefileTargetGenerator(cmTarget* target);
virtual ~cmMakefileTargetGenerator() {};
// construct using this factory call
- static cmMakefileTargetGenerator *New(cmLocalUnixMakefileGenerator3 *lg,
- cmStdString tgtName,
- cmTarget *tgt);
+ static cmMakefileTargetGenerator *New(cmTarget *tgt);
/* the main entry point for this class. Writes the Makefiles associated
with this target */
@@ -58,7 +56,6 @@ public:
virtual unsigned long GetNumberOfProgressActions() {
return this->NumberOfProgressActions;}
- const char *GetTargetName() { return this->TargetName.c_str(); }
cmTarget* GetTarget() { return this->Target;}
protected:
@@ -142,7 +139,6 @@ protected:
virtual void CloseFileStreams();
void RemoveForbiddenFlags(const char* flagVar, const char* linkLang,
std::string& linkFlags);
- cmStdString TargetName;
cmTarget *Target;
cmLocalUnixMakefileGenerator3 *LocalGenerator;
cmGlobalUnixMakefileGenerator3 *GlobalGenerator;
@@ -191,6 +187,16 @@ protected:
typedef std::map<cmStdString, cmStdString> MultipleOutputPairsType;
MultipleOutputPairsType MultipleOutputPairs;
+ // Target name info.
+ std::string TargetNameOut;
+ std::string TargetNameSO;
+ std::string TargetNameReal;
+ std::string TargetNameImport;
+ std::string TargetNamePDB;
+
+ // Mac OS X content info.
+ std::string MacContentDirectory;
+
// Target-wide Fortran module output directory.
bool FortranModuleDirectoryComputed;
std::string FortranModuleDirectory;
diff --git a/Source/cmMakefileUtilityTargetGenerator.cxx b/Source/cmMakefileUtilityTargetGenerator.cxx
index 90650f9..da9ca0d 100644
--- a/Source/cmMakefileUtilityTargetGenerator.cxx
+++ b/Source/cmMakefileUtilityTargetGenerator.cxx
@@ -24,7 +24,9 @@
#include "cmTarget.h"
//----------------------------------------------------------------------------
-cmMakefileUtilityTargetGenerator::cmMakefileUtilityTargetGenerator()
+cmMakefileUtilityTargetGenerator
+::cmMakefileUtilityTargetGenerator(cmTarget* target):
+ cmMakefileTargetGenerator(target)
{
this->CustomCommandDriver = OnUtility;
}
diff --git a/Source/cmMakefileUtilityTargetGenerator.h b/Source/cmMakefileUtilityTargetGenerator.h
index 17572a8..519a4d0 100644
--- a/Source/cmMakefileUtilityTargetGenerator.h
+++ b/Source/cmMakefileUtilityTargetGenerator.h
@@ -23,7 +23,7 @@ class cmMakefileUtilityTargetGenerator:
public cmMakefileTargetGenerator
{
public:
- cmMakefileUtilityTargetGenerator();
+ cmMakefileUtilityTargetGenerator(cmTarget* target);
/* the main entry point for this class. Writes the Makefiles associated
with this target */
diff --git a/Source/cmSourceFile.cxx b/Source/cmSourceFile.cxx
index 4aaba43..a9eb668 100644
--- a/Source/cmSourceFile.cxx
+++ b/Source/cmSourceFile.cxx
@@ -460,15 +460,20 @@ void cmSourceFile::DefineProperties(cmake *cm)
cm->DefineProperty
("MACOSX_PACKAGE_LOCATION", cmProperty::SOURCE_FILE,
- "Place a source file inside a Mac OS X application bundle.",
+ "Place a source file inside a Mac OS X bundle or framework.",
"Executable targets with the MACOSX_BUNDLE property set are built "
"as Mac OS X application bundles on Apple platforms. "
- "Source files specified for the target with the "
- "MACOSX_PACKAGE_LOCATION property set will be placed in the "
- "application bundle Contents folder under the directory specified "
- "by the value of the property. "
- "Typically this is set to \"Resources\" for icon files and other "
- "bundle resources.");
+ "Shared library targets with the FRAMEWORK property set are built "
+ "as Mac OS X frameworks on Apple platforms. "
+ "Source files listed in the target with this property set will "
+ "be copied to a directory inside the bundle or framework content "
+ "folder specified by the property value. "
+ "For bundles the content folder is \"<name>.app/Contents\". "
+ "For frameworks the content folder is "
+ "\"<name>.framework/Versions/<version>\". "
+ "See the PUBLIC_HEADER, PRIVATE_HEADER, and RESOURCE target "
+ "properties for specifying files meant for Headers, PrivateHeadres, "
+ "or Resources directories.");
cm->DefineProperty
("OBJECT_DEPENDS", cmProperty::SOURCE_FILE,
diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx
index 0422ffc..d534a04 100644
--- a/Source/cmTarget.cxx
+++ b/Source/cmTarget.cxx
@@ -33,6 +33,19 @@ const char* cmTarget::TargetTypeNames[] = {
};
//----------------------------------------------------------------------------
+class cmTargetInternals
+{
+public:
+ cmTargetInternals()
+ {
+ this->SourceFileFlagsConstructed = false;
+ }
+ typedef cmTarget::SourceFileFlags SourceFileFlags;
+ std::map<cmSourceFile const*, SourceFileFlags> SourceFlagsMap;
+ bool SourceFileFlagsConstructed;
+};
+
+//----------------------------------------------------------------------------
cmTarget::cmTarget()
{
this->Makefile = 0;
@@ -994,76 +1007,101 @@ struct cmTarget::SourceFileFlags
cmTarget::GetTargetSourceFileFlags(const cmSourceFile* sf)
{
struct SourceFileFlags flags;
- const char* files;
- std::vector<std::string>::iterator it;
+ this->ConstructSourceFileFlags();
+ std::map<cmSourceFile const*, SourceFileFlags>::iterator si =
+ this->Internal->SourceFlagsMap.find(sf);
+ if(si != this->Internal->SourceFlagsMap.end())
+ {
+ flags = si->second;
+ }
+ return flags;
+}
- flags.PrivateHeader = false;
- flags.PublicHeader = false;
- flags.Resource = false;
+//----------------------------------------------------------------------------
+void cmTarget::ConstructSourceFileFlags()
+{
+ if(this->Internal->SourceFileFlagsConstructed)
+ {
+ return;
+ }
+ this->Internal->SourceFileFlagsConstructed = true;
- files = this->GetProperty("PRIVATE_HEADER");
- if ((files) && (*files))
+ // Process public headers to mark the source files.
+ if(const char* files = this->GetProperty("PUBLIC_HEADER"))
{
std::vector<std::string> relFiles;
cmSystemTools::ExpandListArgument(files, relFiles);
- for(it = relFiles.begin(); it != relFiles.end(); ++it)
+ for(std::vector<std::string>::iterator it = relFiles.begin();
+ it != relFiles.end(); ++it)
{
- if(sf == this->GetMakefile()->GetSource(it->c_str()))
+ if(cmSourceFile* sf = this->Makefile->GetSource(it->c_str()))
{
- flags.PrivateHeader = true;
- break;
+ SourceFileFlags& flags = this->Internal->SourceFlagsMap[sf];
+ flags.MacFolder = "Headers";
+ flags.Type = cmTarget::SourceFileTypePublicHeader;
}
}
}
- // Only consider marking it as a public header if it is *NOT* already marked
- // as a private header:
- //
- if(!flags.PrivateHeader)
+ // Process private headers after public headers so that they take
+ // precedence if a file is listed in both.
+ if(const char* files = this->GetProperty("PRIVATE_HEADER"))
{
- files = this->GetProperty("PUBLIC_HEADER");
- if ((files) && (*files))
+ std::vector<std::string> relFiles;
+ cmSystemTools::ExpandListArgument(files, relFiles);
+ for(std::vector<std::string>::iterator it = relFiles.begin();
+ it != relFiles.end(); ++it)
{
- std::vector<std::string> relFiles;
- cmSystemTools::ExpandListArgument(files, relFiles);
- for(it = relFiles.begin(); it != relFiles.end(); ++it)
+ if(cmSourceFile* sf = this->Makefile->GetSource(it->c_str()))
{
- if(sf == this->GetMakefile()->GetSource(it->c_str()))
- {
- flags.PublicHeader = true;
- break;
- }
+ SourceFileFlags& flags = this->Internal->SourceFlagsMap[sf];
+ flags.MacFolder = "PrivateHeaders";
+ flags.Type = cmTarget::SourceFileTypePrivateHeader;
}
}
}
- const char* location = sf->GetProperty("MACOSX_PACKAGE_LOCATION");
- if(location && cmStdString(location) == "Resources")
+ // Mark sources listed as resources.
+ if(const char* files = this->GetProperty("RESOURCE"))
{
- flags.Resource = true;
+ std::vector<std::string> relFiles;
+ cmSystemTools::ExpandListArgument(files, relFiles);
+ for(std::vector<std::string>::iterator it = relFiles.begin();
+ it != relFiles.end(); ++it)
+ {
+ if(cmSourceFile* sf = this->Makefile->GetSource(it->c_str()))
+ {
+ SourceFileFlags& flags = this->Internal->SourceFlagsMap[sf];
+ flags.MacFolder = "Resources";
+ flags.Type = cmTarget::SourceFileTypeResource;
+ }
+ }
}
- // Don't bother with the loop if it's already marked as a resource:
- //
- if(!flags.Resource)
+ // Handle the MACOSX_PACKAGE_LOCATION property on source files that
+ // were not listed in one of the other lists.
+ std::vector<cmSourceFile*> const& sources = this->GetSourceFiles();
+ for(std::vector<cmSourceFile*>::const_iterator si = sources.begin();
+ si != sources.end(); ++si)
{
- files = this->GetProperty("RESOURCE");
- if ((files) && (*files))
+ cmSourceFile* sf = *si;
+ if(const char* location = sf->GetProperty("MACOSX_PACKAGE_LOCATION"))
{
- std::vector<std::string> relFiles;
- cmSystemTools::ExpandListArgument(files, relFiles);
- for(it = relFiles.begin(); it != relFiles.end(); ++it)
+ SourceFileFlags& flags = this->Internal->SourceFlagsMap[sf];
+ if(flags.Type == cmTarget::SourceFileTypeNormal)
{
- if(sf == this->GetMakefile()->GetSource(it->c_str()))
+ flags.MacFolder = location;
+ if(strcmp(location, "Resources") == 0)
{
- flags.Resource = true;
- break;
+ flags.Type = cmTarget::SourceFileTypeResource;
+ }
+ else
+ {
+ flags.Type = cmTarget::SourceFileTypeMacContent;
}
}
}
}
-
- return flags;
}
//----------------------------------------------------------------------------
@@ -2872,6 +2910,10 @@ const char* cmTarget::GetAndCreateOutputDir(bool implib, bool create)
cmSystemTools::CollapseFullPath
(out.c_str(), this->Makefile->GetStartOutputDirectory());
+ // TODO: Make AppBundle and Framework directory computation in
+ // target consistent. Why do we add the .framework part here for
+ // frameworks but not the .app part for bundles? We should
+ // probably not add it for either.
if(this->IsFrameworkOnApple())
{
out += "/";
@@ -3392,3 +3434,36 @@ cmTargetLinkInterfaceMap::~cmTargetLinkInterfaceMap()
delete i->second;
}
}
+
+//----------------------------------------------------------------------------
+cmTargetInternalPointer::cmTargetInternalPointer()
+{
+ this->Pointer = new cmTargetInternals;
+}
+
+//----------------------------------------------------------------------------
+cmTargetInternalPointer
+::cmTargetInternalPointer(cmTargetInternalPointer const&)
+{
+ // Ideally cmTarget instances should never be copied. However until
+ // we can make a sweep to remove that, this copy constructor avoids
+ // allowing the resources (Internals) to be copied.
+ this->Pointer = new cmTargetInternals;
+}
+
+//----------------------------------------------------------------------------
+cmTargetInternalPointer::~cmTargetInternalPointer()
+{
+ delete this->Pointer;
+}
+
+//----------------------------------------------------------------------------
+cmTargetInternalPointer&
+cmTargetInternalPointer::operator=(cmTargetInternalPointer const&)
+{
+ // Ideally cmTarget instances should never be copied. However until
+ // we can make a sweep to remove that, this copy constructor avoids
+ // allowing the resources (Internals) to be copied.
+ this->Pointer = new cmTargetInternals;
+ return *this;
+}
diff --git a/Source/cmTarget.h b/Source/cmTarget.h
index 11b7671..ad5a815 100644
--- a/Source/cmTarget.h
+++ b/Source/cmTarget.h
@@ -53,6 +53,19 @@ struct cmTargetLinkInterfaceMap:
~cmTargetLinkInterfaceMap();
};
+class cmTargetInternals;
+class cmTargetInternalPointer
+{
+public:
+ cmTargetInternalPointer();
+ cmTargetInternalPointer(cmTargetInternalPointer const& r);
+ ~cmTargetInternalPointer();
+ cmTargetInternalPointer& operator=(cmTargetInternalPointer const& r);
+ cmTargetInternals* operator->() const { return this->Pointer; }
+private:
+ cmTargetInternals* Pointer;
+};
+
/** \class cmTarget
* \brief Represent a library or executable target loaded from a makefile.
*
@@ -115,12 +128,22 @@ public:
* Flags for a given source file as used in this target. Typically assigned
* via SET_TARGET_PROPERTIES when the property is a list of source files.
*/
+ enum SourceFileType
+ {
+ SourceFileTypeNormal,
+ SourceFileTypePrivateHeader, // is in "PRIVATE_HEADER" target property
+ SourceFileTypePublicHeader, // is in "PUBLIC_HEADER" target property
+ SourceFileTypeResource, // is in "RESOURCE" target property *or*
+ // has MACOSX_PACKAGE_LOCATION=="Resources"
+ SourceFileTypeMacContent // has MACOSX_PACKAGE_LOCATION!="Resources"
+ };
struct SourceFileFlags
{
- bool PrivateHeader; // source is in "PRIVATE_HEADER" target property
- bool PublicHeader; // source is in "PUBLIC_HEADER" target property
- bool Resource; // source is in "RESOURCE" target property *or*
- // source has MACOSX_PACKAGE_LOCATION=="Resources"
+ SourceFileFlags(): Type(SourceFileTypeNormal), MacFolder(0) {}
+ SourceFileFlags(SourceFileFlags const& r):
+ Type(r.Type), MacFolder(r.MacFolder) {}
+ SourceFileType Type;
+ const char* MacFolder; // location inside Mac content folders
};
/**
@@ -497,6 +520,12 @@ private:
// The cmMakefile instance that owns this target. This should
// always be set.
cmMakefile* Makefile;
+
+ // Internal representation details.
+ friend class cmTargetInternals;
+ cmTargetInternalPointer Internal;
+
+ void ConstructSourceFileFlags();
};
typedef std::map<cmStdString,cmTarget> cmTargets;