summaryrefslogtreecommitdiffstats
path: root/Source/cmGlobalXCodeGenerator.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'Source/cmGlobalXCodeGenerator.cxx')
-rw-r--r--Source/cmGlobalXCodeGenerator.cxx648
1 files changed, 343 insertions, 305 deletions
diff --git a/Source/cmGlobalXCodeGenerator.cxx b/Source/cmGlobalXCodeGenerator.cxx
index 017c908..5a41790 100644
--- a/Source/cmGlobalXCodeGenerator.cxx
+++ b/Source/cmGlobalXCodeGenerator.cxx
@@ -136,7 +136,6 @@ std::string cmGlobalXCodeGenerator::GenerateBuildCommand(const char* makeProgram
const char* config, bool ignoreErrors)
{
// Config is not used yet
- (void) config;
(void) ignoreErrors;
// now build the test
@@ -188,7 +187,8 @@ std::string cmGlobalXCodeGenerator::GenerateBuildCommand(const char* makeProgram
}
else
{
- makeCommand += " -configuration Debug";
+ makeCommand += " -configuration ";
+ makeCommand += config?config:"Debug";
}
if ( additionalOptions )
{
@@ -331,6 +331,10 @@ cmGlobalXCodeGenerator::AddExtraTargets(cmLocalGenerator* root,
makecommand.push_back(dir.c_str());
makecommand.push_back("-f");
makecommand.push_back(m_CurrentXCodeHackMakefile.c_str());
+ if(m_XcodeVersion > 20)
+ {
+ makecommand.push_back("all.$(CONFIGURATION)");
+ }
cmCustomCommandLines commandLines;
commandLines.push_back(makecommand);
mf->AddUtilityCommand("XCODE_DEPEND_HELPER", false, no_output, no_depends,
@@ -575,6 +579,29 @@ void cmGlobalXCodeGenerator::SetCurrentLocalGenerator(cmLocalGenerator* gen)
cmSystemTools::CollapseFullPath(m_CurrentMakefile->
GetCurrentOutputDirectory());
cmSystemTools::SplitPath(outdir.c_str(), m_CurrentOutputDirectoryComponents);
+
+ // Select the current set of configuration types.
+ m_CurrentConfigurationTypes.clear();
+ if(m_XcodeVersion > 20)
+ {
+ if(const char* types =
+ m_CurrentMakefile->GetDefinition("CMAKE_CONFIGURATION_TYPES"))
+ {
+ cmSystemTools::ExpandListArgument(types, m_CurrentConfigurationTypes);
+ }
+ }
+ if(m_CurrentConfigurationTypes.empty())
+ {
+ if(const char* buildType =
+ m_CurrentMakefile->GetDefinition("CMAKE_BUILD_TYPE"))
+ {
+ m_CurrentConfigurationTypes.push_back(buildType);
+ }
+ else
+ {
+ m_CurrentConfigurationTypes.push_back("");
+ }
+ }
}
@@ -585,7 +612,7 @@ cmGlobalXCodeGenerator::CreateXCodeTargets(cmLocalGenerator* gen,
targets)
{
this->SetCurrentLocalGenerator(gen);
- cmTargets &tgts = gen->GetMakefile()->GetTargets();
+ cmTargets &tgts = m_CurrentMakefile->GetTargets();
for(cmTargets::iterator l = tgts.begin(); l != tgts.end(); l++)
{
cmTarget& cmtarget = l->second;
@@ -622,7 +649,8 @@ cmGlobalXCodeGenerator::CreateXCodeTargets(cmLocalGenerator* gen,
for(std::vector<cmSourceFile*>::iterator i = classes.begin();
i != classes.end(); ++i)
{
- cmXCodeObject* xsf = this->CreateXCodeSourceFile(gen, *i);
+ cmXCodeObject* xsf =
+ this->CreateXCodeSourceFile(m_CurrentLocalGenerator, *i);
cmXCodeObject* fr = xsf->GetObject("fileRef");
cmXCodeObject* filetype =
fr->GetObject()->GetObject("lastKnownFileType");
@@ -724,7 +752,6 @@ void cmGlobalXCodeGenerator::CreateCustomCommands(cmXCodeObject* buildPhases,
= cmtarget.GetPreLinkCommands();
std::vector<cmCustomCommand> const & postbuild
= cmtarget.GetPostBuildCommands();
- cmtarget.TraceVSDependencies(cmtarget.GetName(), m_CurrentMakefile);
std::vector<cmSourceFile*> &classes = cmtarget.GetSourceFiles();
// add all the sources
std::vector<cmCustomCommand> commands;
@@ -958,7 +985,7 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmTarget& target,
std::string& fileType,
std::string& productType,
std::string& productName,
- const char* buildtype)
+ const char* configName)
{
this->ConfigureOutputPaths();
std::string flags;
@@ -983,9 +1010,12 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmTarget& target,
std::string cflags;
if(lang)
{
- if(buildtype)
+ // Temporarily set the CMAKE_BUILD_TYPE so the local generator can use
+ // it. TODO: The local generator methods should take the configuration
+ // name as input.
+ if(configName)
{
- m_CurrentMakefile->AddDefinition("CMAKE_BUILD_TYPE", buildtype);
+ m_CurrentMakefile->AddDefinition("CMAKE_BUILD_TYPE", configName);
}
// for c++ projects get the c flags as well
if(strcmp(lang, "CXX") == 0)
@@ -998,6 +1028,8 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmTarget& target,
// Add shared-library flags if needed.
m_CurrentLocalGenerator->AddSharedFlags(flags, lang, shared);
+
+ // Remove the temporary CMAKE_BUILD_TYPE definition.
m_CurrentMakefile->AddDefinition("CMAKE_BUILD_TYPE", "");
}
@@ -1014,7 +1046,6 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmTarget& target,
this->CreateString("CMAKE_INTDIR=\\\\\\\"$(CONFIGURATION)\\\\\\\""));
}
- productName = target.GetName();
std::string extraLinkOptions;
if(target.GetType() == cmTarget::EXECUTABLE)
{
@@ -1039,22 +1070,42 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmTarget& target,
extraLinkOptions += targetLinkFlags;
}
+ // The product name is the full name of the target for this configuration.
+ productName = target.GetFullName(configName);
+
+ // Get the product name components.
+ std::string pnprefix;
+ std::string pnbase;
+ std::string pnsuffix;
+ target.GetFullName(pnprefix, pnbase, pnsuffix, configName);
+
+ // Store the product name for all target types.
+ buildSettings->AddAttribute("PRODUCT_NAME",
+ this->CreateString(pnbase.c_str()));
+
+ // Set attributes to specify the proper name for the target.
+ if(target.GetType() == cmTarget::STATIC_LIBRARY ||
+ target.GetType() == cmTarget::SHARED_LIBRARY ||
+ target.GetType() == cmTarget::MODULE_LIBRARY ||
+ target.GetType() == cmTarget::EXECUTABLE)
+ {
+ std::string pndir = target.GetDirectory();
+ buildSettings->AddAttribute("SYMROOT",
+ this->CreateString(pndir.c_str()));
+ buildSettings->AddAttribute("EXECUTABLE_PREFIX",
+ this->CreateString(pnprefix.c_str()));
+ buildSettings->AddAttribute("EXECUTABLE_SUFFIX",
+ this->CreateString(pnsuffix.c_str()));
+ }
+
+ // Handle settings for each target type.
switch(target.GetType())
{
case cmTarget::STATIC_LIBRARY:
{
- if(m_LibraryOutputPath.size())
- {
- buildSettings->AddAttribute("SYMROOT",
- this->CreateString
- (m_LibraryOutputPath.c_str()));
- }
- productName += ".a";
- std::string t = "lib";
- t += productName;
- productName = t;
- productType = "com.apple.product-type.library.static";
fileType = "archive.ar";
+ productType = "com.apple.product-type.library.static";
+
buildSettings->AddAttribute("LIBRARY_STYLE",
this->CreateString("STATIC"));
break;
@@ -1062,25 +1113,13 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmTarget& target,
case cmTarget::MODULE_LIBRARY:
{
- if(m_LibraryOutputPath.size())
- {
- buildSettings->AddAttribute("SYMROOT",
- this->CreateString
- (m_LibraryOutputPath.c_str()));
- }
-
- buildSettings->AddAttribute("EXECUTABLE_PREFIX",
- this->CreateString("lib"));
- buildSettings->AddAttribute("EXECUTABLE_EXTENSION",
- this->CreateString("so"));
buildSettings->AddAttribute("LIBRARY_STYLE",
this->CreateString("BUNDLE"));
- productName += ".so";
- std::string t = "lib";
- t += productName;
- productName = t;
if(m_XcodeVersion >= 22)
{
+ fileType = "compiled.mach-o.executable";
+ productType = "com.apple.product-type.tool";
+
buildSettings->AddAttribute("MACH_O_TYPE",
this->CreateString("mh_bundle"));
buildSettings->AddAttribute("GCC_DYNAMIC_NO_PIC",
@@ -1094,62 +1133,38 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmTarget& target,
outflag += "\\\"";
extraLinkOptions += " ";
extraLinkOptions += outflag;
- productType = "com.apple.product-type.tool";
- fileType = "compiled.mach-o.executable";
}
else
{
- extraLinkOptions += " -bundle";
- productType = "com.apple.product-type.library.dynamic";
fileType = "compiled.mach-o.dylib";
+ productType = "com.apple.product-type.library.dynamic";
+
+ extraLinkOptions += " -bundle";
}
break;
}
case cmTarget::SHARED_LIBRARY:
{
- if(m_LibraryOutputPath.size())
- {
- buildSettings->AddAttribute("SYMROOT",
- this->CreateString
- (m_LibraryOutputPath.c_str()));
- }
+ fileType = "compiled.mach-o.dylib";
+ productType = "com.apple.product-type.library.dynamic";
+
buildSettings->AddAttribute("LIBRARY_STYLE",
this->CreateString("DYNAMIC"));
- productName += ".dylib";
- std::string t = "lib";
- t += productName;
- productName = t;
buildSettings->AddAttribute("DYLIB_COMPATIBILITY_VERSION",
this->CreateString("1"));
buildSettings->AddAttribute("DYLIB_CURRENT_VERSION",
this->CreateString("1"));
extraLinkOptions += " -dynamiclib";
- productType = "com.apple.product-type.library.dynamic";
- fileType = "compiled.mach-o.dylib";
break;
}
case cmTarget::EXECUTABLE:
{
- const char* outname = target.GetProperty("OUTPUT_NAME");
- std::string name;
- if(outname)
- {
- productName = outname;
- name = outname;
- }
- else
- {
- name = target.GetName();
- }
- std::string symRoot;
- if(m_ExecutableOutputPath.size())
- {
- std::string path = m_ExecutableOutputPath;
- symRoot = path;
- }
fileType = "compiled.mach-o.executable";
+
+ // Handle bundles and normal executables separately.
if(target.GetPropertyAsBool("MACOSX_BUNDLE"))
{
+ productType = "com.apple.product-type.application";
std::string f1 =
m_CurrentMakefile->GetModulesFile("MacOSXBundleInfo.plist.in");
if ( f1.size() == 0 )
@@ -1160,7 +1175,6 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmTarget& target,
f2 += "/Info.plist";
m_CurrentMakefile->ConfigureFile(f1.c_str(), f2.c_str(),
false, false, false);
- productType = "com.apple.product-type.application";
std::string path =
this->ConvertToRelativeForXCode(f2.c_str());
buildSettings->AddAttribute("INFOPLIST_FILE",
@@ -1171,20 +1185,9 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmTarget& target,
{
productType = "com.apple.product-type.tool";
}
- if(symRoot.size())
- {
- buildSettings->AddAttribute("SYMROOT",
- this->CreateString
- (symRoot.c_str()));
- }
}
break;
- case cmTarget::UTILITY:
-
- break;
- case cmTarget::INSTALL_FILES:
- break;
- case cmTarget::INSTALL_PROGRAMS:
+ default:
break;
}
@@ -1305,20 +1308,6 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmTarget& target,
this->CreateString(
"-Wmost -Wno-four-char-constants"
" -Wno-unknown-pragmas"));
- std::string pname;
- if(target.GetType() == cmTarget::SHARED_LIBRARY)
- {
- pname = "lib";
- }
- pname += target.GetName();
- if(target.GetType() == cmTarget::EXECUTABLE
- && target.GetProperty("OUTPUT_NAME") )
- {
- pname = target.GetProperty("OUTPUT_NAME");
- }
-
- buildSettings->AddAttribute("PRODUCT_NAME",
- this->CreateString(pname.c_str()));
}
//----------------------------------------------------------------------------
@@ -1400,10 +1389,10 @@ void cmGlobalXCodeGenerator::AddConfigurations(cmXCodeObject* target,
std::string fileTypeString;
std::string productTypeString;
std::string productName;
- std::string buildtype = cmSystemTools::UpperCase(configVector[i]);
this->CreateBuildSettings(cmtarget,
buildSettings, fileTypeString,
- productTypeString, productName, buildtype.c_str());
+ productTypeString, productName,
+ configVector[i].c_str());
config->AddAttribute("name", this->CreateString(configVector[i].c_str()));
config->SetComment(configVector[i].c_str());
config->AddAttribute("buildSettings", buildSettings);
@@ -1564,86 +1553,45 @@ void cmGlobalXCodeGenerator::AppendOrAddBuildSetting(cmXCodeObject* settings,
//----------------------------------------------------------------------------
void cmGlobalXCodeGenerator::AppendBuildSettingAttribute(cmXCodeObject* target,
const char* attribute,
- const char* value)
+ const char* value,
+ const char* configName)
{
if(m_XcodeVersion < 21)
{
+ // There is only one configuration. Add the setting to the buildSettings
+ // of the target.
this->AppendOrAddBuildSetting(target->GetObject("buildSettings"),
attribute, value);
}
else
{
+ // There are multiple configurations. Add the setting to the
+ // buildSettings of the configuration name given.
cmXCodeObject* configurationList = target->GetObject("buildConfigurationList")->GetObject();
cmXCodeObject* buildConfigs = configurationList->GetObject("buildConfigurations");
std::vector<cmXCodeObject*> list = buildConfigs->GetObjectList();
// each configuration and the target itself has a buildSettings in it
- list.push_back(target);
+ //list.push_back(target);
for(std::vector<cmXCodeObject*>::iterator i = list.begin(); i != list.end(); ++i)
{
- cmXCodeObject* settings = (*i)->GetObject("buildSettings");
- this->AppendOrAddBuildSetting(settings, attribute, value);
+ if(configName)
+ {
+ if(strcmp((*i)->GetObject("name")->GetString(), configName) == 0)
+ {
+ cmXCodeObject* settings = (*i)->GetObject("buildSettings");
+ this->AppendOrAddBuildSetting(settings, attribute, value);
+ }
+ }
+ else
+ {
+ cmXCodeObject* settings = (*i)->GetObject("buildSettings");
+ this->AppendOrAddBuildSetting(settings, attribute, value);
+ }
}
}
}
//----------------------------------------------------------------------------
-void cmGlobalXCodeGenerator::AddLinkLibrary(cmXCodeObject* target,
- const char* library,
- cmTarget* dtarget)
-{
- if(dtarget)
- {
- target->AddDependLibrary(this->GetTargetFullPath(dtarget).c_str());
- }
-
- // if the library is not a full path then add it with a -l flag
- // to the settings of the target
- cmsys::RegularExpression reg("^([ \t]*\\-[lLWRBF])|([ \t]*\\-framework)|(\\${)|([ \t]*\\-pthread)|([ \t]*`)");
- // if the library is not already in the form required by the compiler
- // add a -l infront of the name
- std::string link;
- if(!reg.find(library))
- {
- link += "-l";
- }
- link += library;
- this->AppendBuildSettingAttribute(target, "OTHER_LDFLAGS", link.c_str());
-}
-
-//----------------------------------------------------------------------------
-std::string cmGlobalXCodeGenerator::GetTargetFullPath(cmTarget* target)
-{
- std::string libPath;
- cmXCodeObject* xtarget = this->FindXCodeTarget(target);
- cmXCodeObject* bset = xtarget->GetObject("buildSettings");
- cmXCodeObject* spath = bset->GetObject("SYMROOT");
- if(m_XcodeVersion > 15)
- {
- libPath += "$(CONFIGURATION)/";
- }
-
- libPath = spath->GetString();
- libPath = libPath.substr(1, libPath.size()-2);
- if(target->GetType() == cmTarget::STATIC_LIBRARY)
- {
- libPath += "lib";
- libPath += target->GetName();
- libPath += ".a";
- }
- else if(target->GetType() == cmTarget::SHARED_LIBRARY)
- {
- libPath += "lib";
- libPath += target->GetName();
- libPath += ".dylib";
- }
- else
- {
- libPath += target->GetName();
- }
- return libPath;
-}
-
-//----------------------------------------------------------------------------
void cmGlobalXCodeGenerator::AddDependAndLinkInformation(cmXCodeObject* target)
{
cmTarget* cmtarget = target->GetcmTarget();
@@ -1652,81 +1600,32 @@ void cmGlobalXCodeGenerator::AddDependAndLinkInformation(cmXCodeObject* target)
cmSystemTools::Error("Error no target on xobject\n");
return;
}
- // compute the correct order for link libraries
- cmOrderLinkDirectories orderLibs;
- std::string ext =
- m_CurrentMakefile->GetSafeDefinition("CMAKE_STATIC_LIBRARY_SUFFIX");
- if(ext.size())
- {
- orderLibs.AddLinkExtension(ext.c_str());
- }
- ext =
- m_CurrentMakefile->GetSafeDefinition("CMAKE_STATIC_LIBRARY_PREFIX");
- if(ext.size())
- {
- orderLibs.SetLinkPrefix(ext.c_str());
- }
- ext =
- m_CurrentMakefile->GetSafeDefinition("CMAKE_SHARED_LIBRARY_SUFFIX");
- if(ext.size())
- {
- orderLibs.AddLinkExtension(ext.c_str());
- }
- ext =
- m_CurrentMakefile->GetSafeDefinition("CMAKE_LINK_LIBRARY_SUFFIX");
- if(ext.size())
- {
- orderLibs.AddLinkExtension(ext.c_str());
- }
- const char* targetLibrary = cmtarget->GetName();
- if(cmtarget->GetType() == cmTarget::EXECUTABLE)
- {
- targetLibrary = 0;
- }
- orderLibs.SetLinkInformation(*cmtarget, cmTarget::GENERAL, targetLibrary);
- orderLibs.DetermineLibraryPathOrder();
- std::vector<cmStdString> libdirs;
- std::vector<cmStdString> linkItems;
- orderLibs.GetLinkerInformation(libdirs, linkItems);
- std::string linkDirs;
- // add the library search paths
- for(std::vector<cmStdString>::const_iterator libDir = libdirs.begin();
- libDir != libdirs.end(); ++libDir)
- {
- if(libDir->size() && *libDir != "/usr/lib")
- {
- if(m_XcodeVersion > 15)
- {
- // now add the same one but append $(CONFIGURATION) to it:
- linkDirs += " ";
- linkDirs += this->XCodeEscapePath(libDir->c_str());
- linkDirs += "/$(CONFIGURATION)";
- }
- linkDirs += " ";
- linkDirs += this->XCodeEscapePath(libDir->c_str());
- }
- }
- this->AppendBuildSettingAttribute(target, "LIBRARY_SEARCH_PATHS", linkDirs.c_str());
- // now add the link libraries
- for(std::vector<cmStdString>::iterator lib = linkItems.begin();
- lib != linkItems.end(); ++lib)
+
+ // Add dependencies on other CMake targets.
+ if(cmtarget->GetType() != cmTarget::STATIC_LIBRARY)
{
- cmTarget* t = this->FindTarget(m_CurrentProject.c_str(),
- lib->c_str());
- cmXCodeObject* dptarget = this->FindXCodeTarget(t);
- if(dptarget)
- {
- this->AddDependTarget(target, dptarget);
- if(cmtarget->GetType() != cmTarget::STATIC_LIBRARY)
- {
- this->AddLinkLibrary(target, t->GetName(), t);
- }
- }
- else
+ // Keep track of dependencies already listed.
+ std::set<cmStdString> emitted;
+
+ // A target should not depend on itself.
+ emitted.insert(cmtarget->GetName());
+
+ // Loop over all library dependencies.
+ const cmTarget::LinkLibraries& tlibs = cmtarget->GetLinkLibraries();
+ for(cmTarget::LinkLibraries::const_iterator lib = tlibs.begin();
+ lib != tlibs.end(); ++lib)
{
- if(cmtarget->GetType() != cmTarget::STATIC_LIBRARY)
+ // Don't emit the same library twice for this target.
+ if(emitted.insert(lib->first).second)
{
- this->AddLinkLibrary(target, lib->c_str());
+ // Add this dependency.
+ cmTarget* t = this->FindTarget(m_CurrentProject.c_str(),
+ lib->first.c_str());
+ cmXCodeObject* dptarget = this->FindXCodeTarget(t);
+ if(dptarget)
+ {
+ this->AddDependTarget(target, dptarget);
+ }
}
}
}
@@ -1769,12 +1668,64 @@ void cmGlobalXCodeGenerator::AddDependAndLinkInformation(cmXCodeObject* target)
}
}
}
- std::vector<cmStdString> fullPathLibs;
- orderLibs.GetFullPathLibraries(fullPathLibs);
- for(std::vector<cmStdString>::iterator i = fullPathLibs.begin();
- i != fullPathLibs.end(); ++i)
+
+ // Loop over configuration types and set per-configuration info.
+ for(std::vector<std::string>::iterator i =
+ m_CurrentConfigurationTypes.begin();
+ i != m_CurrentConfigurationTypes.end(); ++i)
{
- target->AddDependLibrary(i->c_str());
+ // Get the current configuration name.
+ const char* configName = i->c_str();
+ if(!*configName)
+ {
+ configName = 0;
+ }
+
+ // Compute the link library and directory information.
+ std::vector<cmStdString> libNames;
+ std::vector<cmStdString> libDirs;
+ std::vector<cmStdString> fullPathLibs;
+ m_CurrentLocalGenerator->ComputeLinkInformation(*cmtarget, configName,
+ libNames, libDirs,
+ &fullPathLibs);
+
+ // Add dependencies directly on library files.
+ for(std::vector<cmStdString>::iterator j = fullPathLibs.begin();
+ j != fullPathLibs.end(); ++j)
+ {
+ target->AddDependLibrary(configName, j->c_str());
+ }
+
+ std::string linkDirs;
+ // add the library search paths
+ for(std::vector<cmStdString>::const_iterator libDir = libDirs.begin();
+ libDir != libDirs.end(); ++libDir)
+ {
+ if(libDir->size() && *libDir != "/usr/lib")
+ {
+ if(m_XcodeVersion > 15)
+ {
+ // now add the same one but append $(CONFIGURATION) to it:
+ linkDirs += " ";
+ linkDirs += this->XCodeEscapePath(libDir->c_str());
+ linkDirs += "/$(CONFIGURATION)";
+ }
+ linkDirs += " ";
+ linkDirs += this->XCodeEscapePath(libDir->c_str());
+ }
+ }
+ this->AppendBuildSettingAttribute(target, "LIBRARY_SEARCH_PATHS",
+ linkDirs.c_str(), configName);
+ // now add the link libraries
+ if(cmtarget->GetType() != cmTarget::STATIC_LIBRARY)
+ {
+ for(std::vector<cmStdString>::iterator lib = libNames.begin();
+ lib != libNames.end(); ++lib)
+ {
+ this->AppendBuildSettingAttribute(target, "OTHER_LDFLAGS",
+ lib->c_str(), configName);
+ }
+ }
}
}
@@ -2041,22 +1992,39 @@ cmGlobalXCodeGenerator::CreateXCodeDependHackTarget(
makefileStream << "# This makefile makes sure all linkable targets are \n";
makefileStream
<< "# up-to-date with anything they link to,avoiding a bug in XCode 1.5\n";
- makefileStream << "all: ";
- for(std::vector<cmXCodeObject*>::iterator i = targets.begin();
- i != targets.end(); ++i)
+ for(std::vector<std::string>::const_iterator
+ ct = m_CurrentConfigurationTypes.begin();
+ ct != m_CurrentConfigurationTypes.end(); ++ct)
{
- cmXCodeObject* target = *i;
- cmTarget* t =target->GetcmTarget();
- if(t->GetType() == cmTarget::EXECUTABLE ||
- t->GetType() == cmTarget::SHARED_LIBRARY ||
- t->GetType() == cmTarget::MODULE_LIBRARY)
+ if(m_XcodeVersion < 21 || ct->empty())
+ {
+ makefileStream << "all: ";
+ }
+ else
{
- makefileStream << "\\\n\t"
- << this->AddConfigDir(this->
- ConvertToRelativeForMake(this->GetTargetFullPath(target->GetcmTarget()).c_str()).c_str());
+ makefileStream << "all." << *ct << ": ";
+ }
+ const char* configName = 0;
+ if(!ct->empty())
+ {
+ configName = ct->c_str();
+ }
+ for(std::vector<cmXCodeObject*>::iterator i = targets.begin();
+ i != targets.end(); ++i)
+ {
+ cmXCodeObject* target = *i;
+ cmTarget* t =target->GetcmTarget();
+ if(t->GetType() == cmTarget::EXECUTABLE ||
+ t->GetType() == cmTarget::SHARED_LIBRARY ||
+ t->GetType() == cmTarget::MODULE_LIBRARY)
+ {
+ makefileStream << "\\\n\t" <<
+ this->ConvertToRelativeForMake(
+ t->GetFullPath(configName).c_str());
+ }
}
+ makefileStream << "\n\n";
}
- makefileStream << "\n\n";
makefileStream
<< "# For each target create a dummy rule "
"so the target does not have to exist\n";
@@ -2065,79 +2033,77 @@ cmGlobalXCodeGenerator::CreateXCodeDependHackTarget(
i != targets.end(); ++i)
{
cmXCodeObject* target = *i;
- std::vector<cmStdString> const& deplibs = target->GetDependLibraries();
- for(std::vector<cmStdString>::const_iterator d = deplibs.begin();
- d != deplibs.end(); ++d)
+ std::map<cmStdString, cmXCodeObject::StringVec> const& deplibs =
+ target->GetDependLibraries();
+ for(std::map<cmStdString, cmXCodeObject::StringVec>::const_iterator ci = deplibs.begin();
+ ci != deplibs.end(); ++ci)
{
- if(emitted.insert(*d).second)
+ for(cmXCodeObject::StringVec::const_iterator d = ci->second.begin();
+ d != ci->second.end(); ++d)
{
- makefileStream <<
- this->AddConfigDir(this->ConvertToRelativeForMake(d->c_str()).c_str())
- << ":\n";
+ if(emitted.insert(*d).second)
+ {
+ makefileStream <<
+ this->ConvertToRelativeForMake(d->c_str()) << ":\n";
+ }
}
}
}
makefileStream << "\n\n";
+
+ // Write rules to help Xcode relink things at the right time.
makefileStream <<
- "# Each linkable target depends on everything it links to.\n";
- makefileStream
- << "#And the target is removed if it is older than what it linkes to\n";
-
- for(std::vector<cmXCodeObject*>::iterator i = targets.begin();
- i != targets.end(); ++i)
- {
- cmXCodeObject* target = *i;
- cmTarget* t =target->GetcmTarget();
- if(t->GetType() == cmTarget::EXECUTABLE ||
- t->GetType() == cmTarget::SHARED_LIBRARY ||
- t->GetType() == cmTarget::MODULE_LIBRARY)
+ "# Rules to remove targets that are older than anything to which they\n"
+ "# link. This forces Xcode to relink the targets from scratch. It\n"
+ "# does not seem to check these dependencies itself.\n";
+ for(std::vector<std::string>::const_iterator
+ ct = m_CurrentConfigurationTypes.begin();
+ ct != m_CurrentConfigurationTypes.end(); ++ct)
+ {
+ const char* configName = 0;
+ if(!ct->empty())
+ {
+ configName = ct->c_str();
+ }
+ for(std::vector<cmXCodeObject*>::iterator i = targets.begin();
+ i != targets.end(); ++i)
{
- std::vector<cmStdString> const& deplibs = target->GetDependLibraries();
- std::string tfull = this->GetTargetFullPath(target->GetcmTarget());
- makefileStream << this->AddConfigDir(
- this->ConvertToRelativeForMake(tfull.c_str()).c_str()) << ": ";
- for(std::vector<cmStdString>::const_iterator d = deplibs.begin();
- d != deplibs.end(); ++d)
+ cmXCodeObject* target = *i;
+ cmTarget* t =target->GetcmTarget();
+ if(t->GetType() == cmTarget::EXECUTABLE ||
+ t->GetType() == cmTarget::SHARED_LIBRARY ||
+ t->GetType() == cmTarget::MODULE_LIBRARY)
{
- makefileStream << "\\\n\t" <<
- this->AddConfigDir(
- this->ConvertToRelativeForMake(d->c_str()).c_str());
+ // Create a rule for this target.
+ std::string tfull = t->GetFullPath(configName);
+ makefileStream << this->ConvertToRelativeForMake(tfull.c_str()) << ":";
+
+ // List dependencies if any exist.
+ std::map<cmStdString, cmXCodeObject::StringVec>::const_iterator
+ x = target->GetDependLibraries().find(*ct);
+ if(x != target->GetDependLibraries().end())
+ {
+ std::vector<cmStdString> const& deplibs = x->second;
+ for(std::vector<cmStdString>::const_iterator d = deplibs.begin();
+ d != deplibs.end(); ++d)
+ {
+ makefileStream << "\\\n\t" <<
+ this->ConvertToRelativeForMake(d->c_str());
+ }
+ }
+
+ // Write the action to remove the target if it is out of date.
+ makefileStream << "\n";
+ makefileStream << "\t/bin/rm -f "
+ << this->ConvertToRelativeForMake(tfull.c_str())
+ << "\n";
+ makefileStream << "\n\n";
}
- makefileStream << "\n";
- makefileStream << "\t/bin/rm -f "
- <<
- this->AddConfigDir(
- this->ConvertToRelativeForMake(tfull.c_str()).c_str())
- << "\n";
- makefileStream << "\n\n";
}
}
}
//----------------------------------------------------------------------------
-std::string
-cmGlobalXCodeGenerator::AddConfigDir(const char* d)
-{
- if(m_XcodeVersion == 15)
- {
- return std::string(d);
- }
- std::string dir = d;
- if(cmSystemTools::FileExists(d))
- {
- return dir;
- }
- std::string::size_type pos = dir.rfind("/");
- if(pos == dir.npos)
- {
- return dir;
- }
- std::string ret = dir.substr(0, pos);
- ret += "/${CONFIGURATION}";
- ret += dir.substr(pos);
- return ret;
-}
-//----------------------------------------------------------------------------
void
cmGlobalXCodeGenerator::OutputXCodeProject(cmLocalGenerator* root,
std::vector<cmLocalGenerator*>&
@@ -2147,6 +2113,78 @@ cmGlobalXCodeGenerator::OutputXCodeProject(cmLocalGenerator* root,
{
return;
}
+#if 1
+ // TODO: This block should be moved to a central location for all
+ // generators. It is duplicated in every generator.
+ for(std::vector<cmLocalGenerator*>::iterator i = generators.begin();
+ i != generators.end(); ++i)
+ {
+ if(this->IsExcluded(root, *i))
+ {
+ continue;
+ }
+ cmMakefile* mf = (*i)->GetMakefile();
+ std::vector<cmSourceGroup> sourceGroups = mf->GetSourceGroups();
+ cmTargets &tgts = mf->GetTargets();
+ // Call TraceVSDependencies on all targets
+ for(cmTargets::iterator l = tgts.begin();
+ l != tgts.end(); l++)
+ {
+ // INCLUDE_EXTERNAL_MSPROJECT command only affects the workspace
+ // so don't build a projectfile for it
+ if ((l->second.GetType() != cmTarget::INSTALL_FILES)
+ && (l->second.GetType() != cmTarget::INSTALL_PROGRAMS)
+ && (strncmp(l->first.c_str(), "INCLUDE_EXTERNAL_MSPROJECT", 26) != 0))
+ {
+ cmTarget& target = l->second;
+ target.TraceVSDependencies(target.GetName(), mf);
+ }
+ }
+ // now for all custom commands that are not used directly in a
+ // target, add them to all targets in the current directory or
+ // makefile
+ std::set<cmStdString> banned;
+ banned.insert("ALL_BUILD");
+ banned.insert("XCODE_DEPEND_HELPER");
+ banned.insert("install");
+ std::vector<cmSourceFile*> & classesmf = mf->GetSourceFiles();
+ for(std::vector<cmSourceFile*>::const_iterator i = classesmf.begin();
+ i != classesmf.end(); i++)
+ {
+ if(cmCustomCommand* cc = (*i)->GetCustomCommand())
+ {
+ if(!cc->IsUsed())
+ {
+ for(cmTargets::iterator l = tgts.begin();
+ l != tgts.end(); l++)
+ {
+ if ((l->second.GetType() != cmTarget::INSTALL_FILES)
+ && (l->second.GetType() != cmTarget::INSTALL_PROGRAMS)
+ && (strncmp(l->first.c_str(), "INCLUDE_EXTERNAL_MSPROJECT", 26) != 0)
+ && banned.find(l->second.GetName()) == banned.end())
+ {
+ cmTarget& target = l->second;
+ bool sameAsTarget = false;
+ // make sure we don't add a custom command that depends on
+ // this target
+ for(unsigned int k =0; k < cc->GetDepends().size(); k++)
+ {
+ if(cmSystemTools::GetFilenameName(cc->GetDepends()[k]) == target.GetFullName())
+ {
+ sameAsTarget = true;
+ }
+ }
+ if(!sameAsTarget)
+ {
+ target.GetSourceFiles().push_back(*i);
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+#endif
this->CreateXCodeObjects(root,
generators);
std::string xcodeDir = root->GetMakefile()->GetStartOutputDirectory();