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... // Is this a resource file in this target? Add it to the resources group...
// //
cmTarget::SourceFileFlags tsFlags = cmtarget.GetTargetSourceFileFlags(sf); 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? // Is this a "private" or "public" framework header file?
// Set the ATTRIBUTES attribute appropriately... // Set the ATTRIBUTES attribute appropriately...
// //
if(cmtarget.IsFrameworkOnApple()) if(cmtarget.IsFrameworkOnApple())
{ {
if(tsFlags.PrivateHeader) if(tsFlags.Type == cmTarget::SourceFileTypePrivateHeader)
{ {
cmXCodeObject* attrs = this->CreateObject(cmXCodeObject::OBJECT_LIST); cmXCodeObject* attrs = this->CreateObject(cmXCodeObject::OBJECT_LIST);
attrs->AddObject(this->CreateString("Private")); attrs->AddObject(this->CreateString("Private"));
settings->AddAttribute("ATTRIBUTES", attrs); settings->AddAttribute("ATTRIBUTES", attrs);
isResource = true; isResource = true;
} }
else if(tsFlags.PublicHeader) else if(tsFlags.Type == cmTarget::SourceFileTypePublicHeader)
{ {
cmXCodeObject* attrs = this->CreateObject(cmXCodeObject::OBJECT_LIST); cmXCodeObject* attrs = this->CreateObject(cmXCodeObject::OBJECT_LIST);
attrs->AddObject(this->CreateString("Public")); attrs->AddObject(this->CreateString("Public"));
@ -698,7 +698,7 @@ cmGlobalXCodeGenerator::CreateXCodeTargets(cmLocalGenerator* gen,
{ {
headerFiles.push_back(xsf); headerFiles.push_back(xsf);
} }
else if(tsFlags.Resource) else if(tsFlags.Type == cmTarget::SourceFileTypeResource)
{ {
resourceFiles.push_back(xsf); resourceFiles.push_back(xsf);
} }
@ -785,12 +785,12 @@ cmGlobalXCodeGenerator::CreateXCodeTargets(cmLocalGenerator* gen,
for(std::vector<cmSourceFile*>::const_iterator i = classes.begin(); for(std::vector<cmSourceFile*>::const_iterator i = classes.begin();
i != classes.end(); ++i) i != classes.end(); ++i)
{ {
const char* contentLoc = (*i)->GetProperty("MACOSX_PACKAGE_LOCATION"); cmTarget::SourceFileFlags tsFlags =
if ( !contentLoc || cmStdString(contentLoc) == "Resources" ) cmtarget.GetTargetSourceFileFlags(*i);
if(tsFlags.Type == cmTarget::SourceFileTypeMacContent)
{ {
continue; bundleFiles[tsFlags.MacFolder].push_back(*i);
} }
bundleFiles[contentLoc].push_back(*i);
} }
mapOfVectorOfSourceFiles::iterator mit; mapOfVectorOfSourceFiles::iterator mit;
for ( mit = bundleFiles.begin(); mit != bundleFiles.end(); ++ mit ) for ( mit = bundleFiles.begin(); mit != bundleFiles.end(); ++ mit )

View File

@ -129,7 +129,7 @@ void cmLocalUnixMakefileGenerator3::Generate()
for(cmTargets::iterator t = targets.begin(); t != targets.end(); ++t) for(cmTargets::iterator t = targets.begin(); t != targets.end(); ++t)
{ {
cmMakefileTargetGenerator *tg = cmMakefileTargetGenerator *tg =
cmMakefileTargetGenerator::New(this, t->first, &(t->second)); cmMakefileTargetGenerator::New(&(t->second));
if (tg) if (tg)
{ {
this->TargetGenerators.push_back(tg); this->TargetGenerators.push_back(tg);
@ -168,7 +168,7 @@ unsigned long cmLocalUnixMakefileGenerator3
this->TargetGenerators.begin(); this->TargetGenerators.begin();
mtgIter != this->TargetGenerators.end(); ++mtgIter) mtgIter != this->TargetGenerators.end(); ++mtgIter)
{ {
if (!strcmp(name,(*mtgIter)->GetTargetName())) if (!strcmp(name,(*mtgIter)->GetTarget()->GetName()))
{ {
return (*mtgIter)->GetNumberOfProgressActions(); return (*mtgIter)->GetNumberOfProgressActions();
} }

View File

@ -25,9 +25,22 @@
#include "cmake.h" #include "cmake.h"
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
cmMakefileExecutableTargetGenerator::cmMakefileExecutableTargetGenerator() cmMakefileExecutableTargetGenerator
::cmMakefileExecutableTargetGenerator(cmTarget* target):
cmMakefileTargetGenerator(target)
{ {
this->CustomCommandDriver = OnDepends; 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 += "/"; outpath += "/";
if(this->Target->IsAppBundleOnApple()) if(this->Target->IsAppBundleOnApple())
{ {
// Compute bundle directory names. this->CreateAppBundle(targetName, outpath);
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());
} }
std::string outpathImp; std::string outpathImp;
if(relink) if(relink)
@ -469,3 +468,22 @@ 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());
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 class cmMakefileExecutableTargetGenerator: public cmMakefileTargetGenerator
{ {
public: public:
cmMakefileExecutableTargetGenerator(); cmMakefileExecutableTargetGenerator(cmTarget* target);
/* 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 */
@ -30,7 +30,7 @@ public:
protected: protected:
virtual void WriteExecutableRule(bool relink); virtual void WriteExecutableRule(bool relink);
void CreateAppBundle(std::string& targetName, std::string& outpath);
}; };
#endif #endif

View File

@ -27,9 +27,35 @@
#include <memory> // auto_ptr #include <memory> // auto_ptr
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
cmMakefileLibraryTargetGenerator::cmMakefileLibraryTargetGenerator() cmMakefileLibraryTargetGenerator
::cmMakefileLibraryTargetGenerator(cmTarget* target):
cmMakefileTargetGenerator(target)
{ {
this->CustomCommandDriver = OnDepends; 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& targetName,
std::string& outpath, std::string& outpath)
const char* version)
{ {
std::string symlink; std::string symlink;
std::string symlink2; std::string symlink2;
@ -233,7 +258,7 @@ void cmMakefileLibraryTargetGenerator::CreateFrameworkLinksAndDirs(
// cd foo.framework to setup symlinks with relative paths // cd foo.framework to setup symlinks with relative paths
cmSystemTools::ChangeDirectory((outpath+"Versions").c_str()); cmSystemTools::ChangeDirectory((outpath+"Versions").c_str());
// Current -> version // Current -> version
symlink = version; symlink = this->FrameworkVersion;
symlink2 = "Current"; symlink2 = "Current";
cmSystemTools::RemoveFile("Current"); cmSystemTools::RemoveFile("Current");
cmSystemTools::CreateSymlink(symlink.c_str(), symlink2.c_str()); cmSystemTools::CreateSymlink(symlink.c_str(), symlink2.c_str());
@ -265,116 +290,6 @@ void cmMakefileLibraryTargetGenerator::CreateFrameworkLinksAndDirs(
cmSystemTools::ChangeDirectory(cwd.c_str()); 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 void cmMakefileLibraryTargetGenerator::WriteLibraryRules
(const char* linkRuleVar, const char* extraFlags, bool relink) (const char* linkRuleVar, const char* extraFlags, bool relink)

View File

@ -23,7 +23,7 @@ class cmMakefileLibraryTargetGenerator:
public cmMakefileTargetGenerator public cmMakefileTargetGenerator
{ {
public: public:
cmMakefileLibraryTargetGenerator(); cmMakefileLibraryTargetGenerator(cmTarget* target);
/* 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 */
@ -39,14 +39,9 @@ protected:
void WriteFrameworkRules(bool relink); void WriteFrameworkRules(bool relink);
void CreateFramework(std::string& targetName, void CreateFramework(std::string& targetName,
std::string& outpath); std::string& outpath);
void CreateFrameworkLinksAndDirs(std::string& targetName,
std::string& outpath, // Store the computd framework version for OS X Frameworks.
const char* version); std::string FrameworkVersion;
void CopyFrameworkSources(std::string& targetName,
std::string& outpath,
const char* version,
const char* propertyName,
const char* subdir);
}; };
#endif #endif

View File

@ -30,45 +30,45 @@
#include "cmMakefileUtilityTargetGenerator.h" #include "cmMakefileUtilityTargetGenerator.h"
cmMakefileTargetGenerator::cmMakefileTargetGenerator() cmMakefileTargetGenerator::cmMakefileTargetGenerator(cmTarget* target)
{ {
this->BuildFileStream = 0; this->BuildFileStream = 0;
this->InfoFileStream = 0; this->InfoFileStream = 0;
this->FlagFileStream = 0; this->FlagFileStream = 0;
this->CustomCommandDriver = OnBuild; this->CustomCommandDriver = OnBuild;
this->FortranModuleDirectoryComputed = false; 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 *
cmMakefileTargetGenerator::New(cmLocalUnixMakefileGenerator3 *lg, cmMakefileTargetGenerator::New(cmTarget *tgt)
cmStdString tgtName, cmTarget *tgt)
{ {
cmMakefileTargetGenerator *result = 0; cmMakefileTargetGenerator *result = 0;
switch (tgt->GetType()) switch (tgt->GetType())
{ {
case cmTarget::EXECUTABLE: case cmTarget::EXECUTABLE:
result = new cmMakefileExecutableTargetGenerator; result = new cmMakefileExecutableTargetGenerator(tgt);
break; break;
case cmTarget::STATIC_LIBRARY: case cmTarget::STATIC_LIBRARY:
case cmTarget::SHARED_LIBRARY: case cmTarget::SHARED_LIBRARY:
case cmTarget::MODULE_LIBRARY: case cmTarget::MODULE_LIBRARY:
result = new cmMakefileLibraryTargetGenerator; result = new cmMakefileLibraryTargetGenerator(tgt);
break; break;
case cmTarget::UTILITY: case cmTarget::UTILITY:
result = new cmMakefileUtilityTargetGenerator; result = new cmMakefileUtilityTargetGenerator(tgt);
break; break;
default: default:
return result; return result;
// break; /* unreachable */ // break; /* unreachable */
} }
result->TargetName = tgtName;
result->Target = tgt;
result->LocalGenerator = lg;
result->GlobalGenerator =
static_cast<cmGlobalUnixMakefileGenerator3*>(lg->GetGlobalGenerator());
result->Makefile = lg->GetMakefile();
return result; return result;
} }
@ -134,6 +134,8 @@ void cmMakefileTargetGenerator::WriteTargetBuildRules()
for(std::vector<cmSourceFile*>::const_iterator source = sources.begin(); for(std::vector<cmSourceFile*>::const_iterator source = sources.begin();
source != sources.end(); ++source) source != sources.end(); ++source)
{ {
cmTarget::SourceFileFlags tsFlags =
this->Target->GetTargetSourceFileFlags(*source);
if(cmCustomCommand* cc = (*source)->GetCustomCommand()) if(cmCustomCommand* cc = (*source)->GetCustomCommand())
{ {
this->GenerateCustomRuleFile(*cc); this->GenerateCustomRuleFile(*cc);
@ -150,10 +152,9 @@ void cmMakefileTargetGenerator::WriteTargetBuildRules()
} }
} }
} }
else if(const char* pkgloc = else if(tsFlags.Type != cmTarget::SourceFileTypeNormal)
(*source)->GetProperty("MACOSX_PACKAGE_LOCATION"))
{ {
this->WriteMacOSXContentRules(*(*source), pkgloc); this->WriteMacOSXContentRules(*(*source), tsFlags.MacFolder);
} }
else if(!(*source)->GetPropertyAsBool("HEADER_FILE_ONLY")) else if(!(*source)->GetPropertyAsBool("HEADER_FILE_ONLY"))
{ {
@ -322,21 +323,14 @@ void cmMakefileTargetGenerator::WriteTargetLanguageFlags()
void cmMakefileTargetGenerator::WriteMacOSXContentRules(cmSourceFile& source, void cmMakefileTargetGenerator::WriteMacOSXContentRules(cmSourceFile& source,
const char* pkgloc) const char* pkgloc)
{ {
// Skip OS X bundle content when not building a bundle. // Skip OS X content when not building a Framework or Bundle.
if(!this->Target->IsAppBundleOnApple()) { return; } if(this->MacContentDirectory.empty())
{
return;
}
// Create the directory in which the content is to be placed. // Construct the full path to the content subdirectory.
std::string targetName; std::string macdir = this->MacContentDirectory;
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/";
macdir += pkgloc; macdir += pkgloc;
cmSystemTools::MakeDirectory(macdir.c_str()); cmSystemTools::MakeDirectory(macdir.c_str());
@ -355,7 +349,7 @@ void cmMakefileTargetGenerator::WriteMacOSXContentRules(cmSourceFile& source,
std::vector<std::string> depends; std::vector<std::string> depends;
std::vector<std::string> commands; std::vector<std::string> commands;
depends.push_back(input); depends.push_back(input);
std::string copyEcho = "Copying Bundle content "; std::string copyEcho = "Copying OS X content ";
copyEcho += output; copyEcho += output;
this->LocalGenerator->AppendEcho(commands, copyEcho.c_str(), this->LocalGenerator->AppendEcho(commands, copyEcho.c_str(),
cmLocalUnixMakefileGenerator3::EchoBuild); cmLocalUnixMakefileGenerator3::EchoBuild);

View File

@ -37,13 +37,11 @@ class cmMakefileTargetGenerator
{ {
public: public:
// constructor to set the ivars // constructor to set the ivars
cmMakefileTargetGenerator(); cmMakefileTargetGenerator(cmTarget* target);
virtual ~cmMakefileTargetGenerator() {}; virtual ~cmMakefileTargetGenerator() {};
// construct using this factory call // construct using this factory call
static cmMakefileTargetGenerator *New(cmLocalUnixMakefileGenerator3 *lg, static cmMakefileTargetGenerator *New(cmTarget *tgt);
cmStdString tgtName,
cmTarget *tgt);
/* 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 */
@ -58,7 +56,6 @@ public:
virtual unsigned long GetNumberOfProgressActions() { virtual unsigned long GetNumberOfProgressActions() {
return this->NumberOfProgressActions;} return this->NumberOfProgressActions;}
const char *GetTargetName() { return this->TargetName.c_str(); }
cmTarget* GetTarget() { return this->Target;} cmTarget* GetTarget() { return this->Target;}
protected: protected:
@ -142,7 +139,6 @@ protected:
virtual void CloseFileStreams(); virtual void CloseFileStreams();
void RemoveForbiddenFlags(const char* flagVar, const char* linkLang, void RemoveForbiddenFlags(const char* flagVar, const char* linkLang,
std::string& linkFlags); std::string& linkFlags);
cmStdString TargetName;
cmTarget *Target; cmTarget *Target;
cmLocalUnixMakefileGenerator3 *LocalGenerator; cmLocalUnixMakefileGenerator3 *LocalGenerator;
cmGlobalUnixMakefileGenerator3 *GlobalGenerator; cmGlobalUnixMakefileGenerator3 *GlobalGenerator;
@ -191,6 +187,16 @@ protected:
typedef std::map<cmStdString, cmStdString> MultipleOutputPairsType; typedef std::map<cmStdString, cmStdString> MultipleOutputPairsType;
MultipleOutputPairsType MultipleOutputPairs; 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. // Target-wide Fortran module output directory.
bool FortranModuleDirectoryComputed; bool FortranModuleDirectoryComputed;
std::string FortranModuleDirectory; std::string FortranModuleDirectory;

View File

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

View File

@ -23,7 +23,7 @@ class cmMakefileUtilityTargetGenerator:
public cmMakefileTargetGenerator public cmMakefileTargetGenerator
{ {
public: public:
cmMakefileUtilityTargetGenerator(); cmMakefileUtilityTargetGenerator(cmTarget* target);
/* 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 */

View File

@ -460,15 +460,20 @@ void cmSourceFile::DefineProperties(cmake *cm)
cm->DefineProperty cm->DefineProperty
("MACOSX_PACKAGE_LOCATION", cmProperty::SOURCE_FILE, ("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 " "Executable targets with the MACOSX_BUNDLE property set are built "
"as Mac OS X application bundles on Apple platforms. " "as Mac OS X application bundles on Apple platforms. "
"Source files specified for the target with the " "Shared library targets with the FRAMEWORK property set are built "
"MACOSX_PACKAGE_LOCATION property set will be placed in the " "as Mac OS X frameworks on Apple platforms. "
"application bundle Contents folder under the directory specified " "Source files listed in the target with this property set will "
"by the value of the property. " "be copied to a directory inside the bundle or framework content "
"Typically this is set to \"Resources\" for icon files and other " "folder specified by the property value. "
"bundle resources."); "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 cm->DefineProperty
("OBJECT_DEPENDS", cmProperty::SOURCE_FILE, ("OBJECT_DEPENDS", cmProperty::SOURCE_FILE,

View File

@ -32,6 +32,19 @@ const char* cmTarget::TargetTypeNames[] = {
"INSTALL_FILES", "INSTALL_PROGRAMS", "INSTALL_DIRECTORY" "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() cmTarget::cmTarget()
{ {
@ -994,78 +1007,103 @@ struct cmTarget::SourceFileFlags
cmTarget::GetTargetSourceFileFlags(const cmSourceFile* sf) cmTarget::GetTargetSourceFileFlags(const cmSourceFile* sf)
{ {
struct SourceFileFlags flags; struct SourceFileFlags flags;
const char* files; this->ConstructSourceFileFlags();
std::vector<std::string>::iterator it; std::map<cmSourceFile const*, SourceFileFlags>::iterator si =
this->Internal->SourceFlagsMap.find(sf);
flags.PrivateHeader = false; if(si != this->Internal->SourceFlagsMap.end())
flags.PublicHeader = false;
flags.Resource = false;
files = this->GetProperty("PRIVATE_HEADER");
if ((files) && (*files))
{ {
std::vector<std::string> relFiles; flags = si->second;
cmSystemTools::ExpandListArgument(files, relFiles);
for(it = relFiles.begin(); it != relFiles.end(); ++it)
{
if(sf == this->GetMakefile()->GetSource(it->c_str()))
{
flags.PrivateHeader = true;
break;
} }
}
}
// Only consider marking it as a public header if it is *NOT* already marked
// as a private header:
//
if(!flags.PrivateHeader)
{
files = this->GetProperty("PUBLIC_HEADER");
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.PublicHeader = true;
break;
}
}
}
}
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; return flags;
} }
//----------------------------------------------------------------------------
void cmTarget::ConstructSourceFileFlags()
{
if(this->Internal->SourceFileFlagsConstructed)
{
return;
}
this->Internal->SourceFileFlagsConstructed = true;
// 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(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 = "Headers";
flags.Type = cmTarget::SourceFileTypePublicHeader;
}
}
}
// 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"))
{
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 = "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.Type = cmTarget::SourceFileTypeResource;
}
else
{
flags.Type = cmTarget::SourceFileTypeMacContent;
}
}
}
}
}
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
void cmTarget::MergeLinkLibraries( cmMakefile& mf, void cmTarget::MergeLinkLibraries( cmMakefile& mf,
const char *selfname, const char *selfname,
@ -2872,6 +2910,10 @@ const char* cmTarget::GetAndCreateOutputDir(bool implib, bool create)
cmSystemTools::CollapseFullPath cmSystemTools::CollapseFullPath
(out.c_str(), this->Makefile->GetStartOutputDirectory()); (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()) if(this->IsFrameworkOnApple())
{ {
out += "/"; out += "/";
@ -3392,3 +3434,36 @@ cmTargetLinkInterfaceMap::~cmTargetLinkInterfaceMap()
delete i->second; 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(); ~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 /** \class cmTarget
* \brief Represent a library or executable target loaded from a makefile. * \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 * 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. * 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 struct SourceFileFlags
{ {
bool PrivateHeader; // source is in "PRIVATE_HEADER" target property SourceFileFlags(): Type(SourceFileTypeNormal), MacFolder(0) {}
bool PublicHeader; // source is in "PUBLIC_HEADER" target property SourceFileFlags(SourceFileFlags const& r):
bool Resource; // source is in "RESOURCE" target property *or* Type(r.Type), MacFolder(r.MacFolder) {}
// source has MACOSX_PACKAGE_LOCATION=="Resources" SourceFileType Type;
const char* MacFolder; // location inside Mac content folders
}; };
/** /**
@ -497,6 +520,12 @@ private:
// The cmMakefile instance that owns this target. This should // The cmMakefile instance that owns this target. This should
// always be set. // always be set.
cmMakefile* Makefile; cmMakefile* Makefile;
// Internal representation details.
friend class cmTargetInternals;
cmTargetInternalPointer Internal;
void ConstructSourceFileFlags();
}; };
typedef std::map<cmStdString,cmTarget> cmTargets; typedef std::map<cmStdString,cmTarget> cmTargets;