ENH: Cleanup impl of PUBLIC_HEADER, PRIVATE_HEADER, and RESOURCE properties

This commit is contained in:
Brad King 2008-02-18 16:38:34 -05:00
parent a3781c85fc
commit 9ed4266306
13 changed files with 293 additions and 254 deletions

View File

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

View File

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

View File

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

View File

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

View File

@ -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());
@ -265,116 +290,6 @@ void cmMakefileLibraryTargetGenerator::CreateFrameworkLinksAndDirs(
cmSystemTools::ChangeDirectory(cwd.c_str());
}
//----------------------------------------------------------------------------
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)

View File

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

View File

@ -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; }
// Skip OS X content when not building a Framework or Bundle.
if(this->MacContentDirectory.empty())
{
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/";
// 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);

View File

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

View File

@ -24,7 +24,9 @@
#include "cmTarget.h"
//----------------------------------------------------------------------------
cmMakefileUtilityTargetGenerator::cmMakefileUtilityTargetGenerator()
cmMakefileUtilityTargetGenerator
::cmMakefileUtilityTargetGenerator(cmTarget* target):
cmMakefileTargetGenerator(target)
{
this->CustomCommandDriver = OnUtility;
}

View File

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

View File

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

View File

@ -32,6 +32,19 @@ const char* cmTarget::TargetTypeNames[] = {
"INSTALL_FILES", "INSTALL_PROGRAMS", "INSTALL_DIRECTORY"
};
//----------------------------------------------------------------------------
class cmTargetInternals
{
public:
cmTargetInternals()
{
this->SourceFileFlagsConstructed = false;
}
typedef cmTarget::SourceFileFlags SourceFileFlags;
std::map<cmSourceFile const*, SourceFileFlags> SourceFlagsMap;
bool SourceFileFlagsConstructed;
};
//----------------------------------------------------------------------------
cmTarget::cmTarget()
{
@ -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()))
SourceFileFlags& flags = this->Internal->SourceFlagsMap[sf];
flags.MacFolder = "PrivateHeaders";
flags.Type = cmTarget::SourceFileTypePrivateHeader;
}
}
}
// Mark sources listed as resources.
if(const char* files = this->GetProperty("RESOURCE"))
{
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;
}
}
}
// 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)
{
cmSourceFile* sf = *si;
if(const char* location = sf->GetProperty("MACOSX_PACKAGE_LOCATION"))
{
SourceFileFlags& flags = this->Internal->SourceFlagsMap[sf];
if(flags.Type == cmTarget::SourceFileTypeNormal)
{
flags.MacFolder = location;
if(strcmp(location, "Resources") == 0)
{
flags.PublicHeader = true;
break;
flags.Type = cmTarget::SourceFileTypeResource;
}
else
{
flags.Type = cmTarget::SourceFileTypeMacContent;
}
}
}
}
const char* location = sf->GetProperty("MACOSX_PACKAGE_LOCATION");
if(location && cmStdString(location) == "Resources")
{
flags.Resource = true;
}
// Don't bother with the loop if it's already marked as a resource:
//
if(!flags.Resource)
{
files = this->GetProperty("RESOURCE");
if ((files) && (*files))
{
std::vector<std::string> relFiles;
cmSystemTools::ExpandListArgument(files, relFiles);
for(it = relFiles.begin(); it != relFiles.end(); ++it)
{
if(sf == this->GetMakefile()->GetSource(it->c_str()))
{
flags.Resource = true;
break;
}
}
}
}
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;
}

View File

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