summaryrefslogtreecommitdiffstats
path: root/Source/cmGlobalXCodeGenerator.cxx
diff options
context:
space:
mode:
authorBrad King <brad.king@kitware.com>2006-01-13 23:18:32 (GMT)
committerBrad King <brad.king@kitware.com>2006-01-13 23:18:32 (GMT)
commit22c62c9e65817e25b077f88222c682efa0188ccb (patch)
tree077abb80fc469c06f08cc4509ff72bcbee8384c7 /Source/cmGlobalXCodeGenerator.cxx
parent262295615925c082ec3f98c3fc1f6c259d09ee6f (diff)
downloadCMake-22c62c9e65817e25b077f88222c682efa0188ccb.zip
CMake-22c62c9e65817e25b077f88222c682efa0188ccb.tar.gz
CMake-22c62c9e65817e25b077f88222c682efa0188ccb.tar.bz2
BUG: Sweeping changes to cleanup computation of target names. This should
fix many bugs related to target names being computed inconsistently. - Centralized computation of a target's file name to a method in cmTarget. Now that global knowledge is always available the *_CMAKE_PATH cache variables are no longer needed. - Centralized computation of link library command lines and link directory search order. - Moved computation of link directories needed to link CMake targets to be after evaluation of linking dependencies. This also removed alot of duplicate code in which each version had its own bugs. This commit is surrounded by the tags CMake-TargetNameCentralization1-pre and CMake-TargetNameCentralization1-post so make the large set of changes easy to identify.
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();