summaryrefslogtreecommitdiffstats
path: root/Source/cmGlobalXCodeGenerator.cxx
diff options
context:
space:
mode:
authorBill Hoffman <bill.hoffman@kitware.com>2005-02-18 18:32:51 (GMT)
committerBill Hoffman <bill.hoffman@kitware.com>2005-02-18 18:32:51 (GMT)
commit785b0dc012a2623e83886066fd4929b4e361cea9 (patch)
treeb996432683a83a1716dcc722d12c87fab97d332d /Source/cmGlobalXCodeGenerator.cxx
parentb5ca101fd76554df01d60f210677df85e19af65e (diff)
downloadCMake-785b0dc012a2623e83886066fd4929b4e361cea9.zip
CMake-785b0dc012a2623e83886066fd4929b4e361cea9.tar.gz
CMake-785b0dc012a2623e83886066fd4929b4e361cea9.tar.bz2
ENH: all tests are passing for XCode
Diffstat (limited to 'Source/cmGlobalXCodeGenerator.cxx')
-rw-r--r--Source/cmGlobalXCodeGenerator.cxx304
1 files changed, 213 insertions, 91 deletions
diff --git a/Source/cmGlobalXCodeGenerator.cxx b/Source/cmGlobalXCodeGenerator.cxx
index 7b6099e..fe149c7 100644
--- a/Source/cmGlobalXCodeGenerator.cxx
+++ b/Source/cmGlobalXCodeGenerator.cxx
@@ -58,6 +58,8 @@ cmGlobalXCodeGenerator::cmGlobalXCodeGenerator()
m_RootObject = 0;
m_MainGroupChildren = 0;
m_SourcesGroupChildren = 0;
+ m_CurrentMakefile = 0;
+ m_CurrentLocalGenerator = 0;
m_ExternalGroupChildren = 0;
}
@@ -99,11 +101,6 @@ int cmGlobalXCodeGenerator::TryCompile(const char *,
*/
std::string cwd = cmSystemTools::GetCurrentWorkingDirectory();
cmSystemTools::ChangeDirectory(bindir);
-// Usage: xcodebuild [-project <projectname>] [-activetarget]
-// [-alltargets] [-target <targetname>]... [-activebuildstyle]
-// [-buildstyle <buildstylename>] [-optionalbuildstyle <buildstylename>]
-// [<buildsetting>=<value>]... [<buildaction>]...
-// xcodebuild [-list]
makeCommand += " -project ";
makeCommand += projectName;
@@ -134,7 +131,7 @@ int cmGlobalXCodeGenerator::TryCompile(const char *,
return retVal;
}
-
+//----------------------------------------------------------------------------
void cmGlobalXCodeGenerator::ConfigureOutputPaths()
{
// Format the library and executable output paths.
@@ -188,66 +185,98 @@ cmLocalGenerator *cmGlobalXCodeGenerator::CreateLocalGenerator()
void cmGlobalXCodeGenerator::Generate()
{
this->cmGlobalGenerator::Generate();
- std::vector<std::string> srcs;
std::map<cmStdString, std::vector<cmLocalGenerator*> >::iterator it;
for(it = m_ProjectMap.begin(); it!= m_ProjectMap.end(); ++it)
- {
+ {
cmLocalGenerator* root = it->second[0];
- cmMakefile* mf = root->GetMakefile();
- // add a ALL_BUILD target to the first makefile of each project
- mf->AddUtilityCommand("ALL_BUILD", "echo",
- "\"Build all projects\"",false,srcs);
- cmTarget* allbuild = mf->FindTarget("ALL_BUILD");
+ m_CurrentMakefile = root->GetMakefile();
+ m_OutputDir = m_CurrentMakefile->GetHomeOutputDirectory();
+ m_OutputDir = cmSystemTools::CollapseFullPath(m_OutputDir.c_str());
+ m_CurrentLocalGenerator = root;
+ // add ALL_BUILD, INSTALL, etc
+ this->AddExtraTargets(root, it->second);
+ // now create the project
+ this->OutputXCodeProject(root, it->second);
+ }
+}
- std::string dir = root->ConvertToRelativeOutputPath(
- mf->GetCurrentOutputDirectory());
- m_CurrentXCodeHackMakefile = dir;
- m_CurrentXCodeHackMakefile += "/XCODE_DEPEND_HELPER.make";
- std::string makecommand = "make -C ";
- makecommand += dir;
- makecommand += " -f ";
- makecommand += m_CurrentXCodeHackMakefile;
- mf->AddUtilityCommand("XCODE_DEPEND_HELPER", makecommand.c_str(),
+//----------------------------------------------------------------------------
+void
+cmGlobalXCodeGenerator::AddExtraTargets(cmLocalGenerator* root,
+ std::vector<cmLocalGenerator*>& gens)
+{
+ std::vector<std::string> srcs; // dummy list
+ cmMakefile* mf = root->GetMakefile();
+ // Add ALL_BUILD
+ mf->AddUtilityCommand("ALL_BUILD", "echo",
+ "\"Build all projects\"",false,srcs);
+ cmTarget* allbuild = mf->FindTarget("ALL_BUILD");
+ // ADD install
+ std::string cmake_command = mf->GetRequiredDefinition("CMAKE_COMMAND");
+ mf->AddUtilityCommand("install", cmake_command.c_str(),
+ "-P cmake_install.cmake",false,srcs);
+ // Add RUN_TESTS target if testing has been enabled
+ std::string fname;
+ fname = mf->GetStartOutputDirectory();
+ fname += "/";
+ fname += "DartTestfile.txt";
+ if (cmSystemTools::FileExists(fname.c_str()))
+ {
+ std::string ctest_command =
+ mf->GetRequiredDefinition("CMAKE_CTEST_COMMAND");
+ mf->AddUtilityCommand("RUN_TESTS", ctest_command.c_str(), "",false,srcs);
+ }
+ // Add install
+ mf->AddUtilityCommand("install", cmake_command.c_str(),
+ "-P cmake_install.cmake", false, srcs);
+ // Add XCODE depend helper
+ std::string dir = this->ConvertToRelativeOutputPath(
+ mf->GetCurrentOutputDirectory());
+ m_CurrentXCodeHackMakefile = dir;
+ m_CurrentXCodeHackMakefile += "/XCODE_DEPEND_HELPER.make";
+ std::string makecommand = "make -C ";
+ makecommand += dir;
+ makecommand += " -f ";
+ makecommand += m_CurrentXCodeHackMakefile;
+ mf->AddUtilityCommand("XCODE_DEPEND_HELPER", makecommand.c_str(),
"",
false,srcs);
- cmTarget* xcodedephack = mf->FindTarget("XCODE_DEPEND_HELPER");
- // now make the allbuild depend on all the non-utility targets
- // in the project
- for(std::vector<cmLocalGenerator*>::iterator i = it->second.begin();
- i != it->second.end(); ++i)
+ // now make the allbuild depend on all the non-utility targets
+ // in the project
+ for(std::vector<cmLocalGenerator*>::iterator i = gens.begin();
+ i != gens.end(); ++i)
+ {
+ cmLocalGenerator* lg = *i;
+ if(this->IsExcluded(root, *i))
+ {
+ continue;
+ }
+ cmTargets& tgts = lg->GetMakefile()->GetTargets();
+ for(cmTargets::iterator l = tgts.begin(); l != tgts.end(); l++)
{
- cmLocalGenerator* lg = *i;
- if(this->IsExcluded(root, *i))
+ cmTarget& target = l->second;
+ // make all exe, shared libs and modules depend
+ // on the XCODE_DEPEND_HELPER target
+ if((target.GetType() == cmTarget::EXECUTABLE ||
+ target.GetType() == cmTarget::SHARED_LIBRARY ||
+ target.GetType() == cmTarget::MODULE_LIBRARY))
{
- continue;
+ target.AddUtility("XCODE_DEPEND_HELPER");
}
- cmTargets& tgts = lg->GetMakefile()->GetTargets();
- for(cmTargets::iterator l = tgts.begin(); l != tgts.end(); l++)
+
+ if(target.IsInAll())
{
- cmTarget& target = l->second;
- // make all exe, shared libs and modules depend
- // on the XCODE_DEPEND_HELPER target
- if((target.GetType() == cmTarget::EXECUTABLE ||
- target.GetType() == cmTarget::SHARED_LIBRARY ||
- target.GetType() == cmTarget::MODULE_LIBRARY))
- {
- target.AddUtility(xcodedephack->GetName());
- }
-
- if(target.IsInAll())
- {
- allbuild->AddUtility(target.GetName());
- }
+ allbuild->AddUtility(target.GetName());
}
}
- // now create the project
- this->OutputXCodeProject(it->second[0], it->second);
}
}
+
//----------------------------------------------------------------------------
void cmGlobalXCodeGenerator::ClearXCodeObjects()
{
+ m_TargetDoneSet.clear();
for(unsigned int i = 0; i < m_XCodeObjects.size(); ++i)
{
delete m_XCodeObjects[i];
@@ -273,6 +302,7 @@ cmGlobalXCodeGenerator::CreateObject(cmXCodeObject::Type type)
return obj;
}
+//----------------------------------------------------------------------------
cmXCodeObject*
cmGlobalXCodeGenerator::CreateString(const char* s)
{
@@ -280,6 +310,8 @@ cmGlobalXCodeGenerator::CreateString(const char* s)
obj->SetString(s);
return obj;
}
+
+//----------------------------------------------------------------------------
cmXCodeObject* cmGlobalXCodeGenerator::CreateObjectReference(cmXCodeObject* ref)
{
cmXCodeObject* obj = this->CreateObject(cmXCodeObject::OBJECT_REF);
@@ -287,6 +319,7 @@ cmXCodeObject* cmGlobalXCodeGenerator::CreateObjectReference(cmXCodeObject* ref)
return obj;
}
+//----------------------------------------------------------------------------
cmXCodeObject*
cmGlobalXCodeGenerator::CreateXCodeSourceFile(cmLocalGenerator* lg,
cmSourceFile* sf)
@@ -307,17 +340,21 @@ cmGlobalXCodeGenerator::CreateXCodeSourceFile(cmLocalGenerator* lg,
const char* lang =
this->GetLanguageFromExtension(sf->GetSourceExtension().c_str());
std::string sourcecode = "sourcecode";
- if(!lang)
+ if(sf->GetSourceExtension() == "o")
{
- std::string ext = ".";
- ext = sf->GetSourceExtension();
- sourcecode += ext;
- sourcecode += ext;
+ sourcecode = "compiled.mach-o.objfile";
}
else if(sf->GetSourceExtension() == "mm")
{
sourcecode += ".cpp.objcpp";
}
+ else if(!lang)
+ {
+ std::string ext = ".";
+ ext = sf->GetSourceExtension();
+ sourcecode += ext;
+ sourcecode += ext;
+ }
else if(strcmp(lang, "C") == 0)
{
sourcecode += ".c.c";
@@ -329,14 +366,39 @@ cmGlobalXCodeGenerator::CreateXCodeSourceFile(cmLocalGenerator* lg,
fileRef->AddAttribute("lastKnownFileType",
this->CreateString(sourcecode.c_str()));
- fileRef->AddAttribute("path", this->CreateString(
- lg->ConvertToRelativeOutputPath(sf->GetFullPath().c_str()).c_str()));
+ std::string path =
+ this->ConvertToRelativeOutputPath(sf->GetFullPath().c_str());
+ fileRef->AddAttribute("path", this->CreateString(path.c_str()));
fileRef->AddAttribute("refType", this->CreateString("4"));
- fileRef->AddAttribute("sourceTree", this->CreateString("<absolute>"));
+ if(path.size() > 1 && path[0] == '.' && path[1] == '.')
+ {
+ fileRef->AddAttribute("sourceTree", this->CreateString("<group>"));
+ }
+ else
+ {
+ fileRef->AddAttribute("sourceTree", this->CreateString("<absolute>"));
+ }
return buildFile;
}
//----------------------------------------------------------------------------
+bool cmGlobalXCodeGenerator::SpecialTargetEmitted(std::string const& tname)
+{
+ if(tname == "ALL_BUILD" || tname == "XCODE_DEPEND_HELPER" ||
+ tname == "install" || tname == "RUN_TESTS")
+ {
+ if(m_TargetDoneSet.find(tname) != m_TargetDoneSet.end())
+ {
+ return true;
+ }
+ m_TargetDoneSet.insert(tname);
+ return false;
+ }
+ return false;
+}
+
+
+//----------------------------------------------------------------------------
void
cmGlobalXCodeGenerator::CreateXCodeTargets(cmLocalGenerator* gen,
std::vector<cmXCodeObject*>&
@@ -348,23 +410,10 @@ cmGlobalXCodeGenerator::CreateXCodeTargets(cmLocalGenerator* gen,
for(cmTargets::iterator l = tgts.begin(); l != tgts.end(); l++)
{
cmTarget& cmtarget = l->second;
- // make sure ALL_BUILD is only done once
- if(l->first == "ALL_BUILD")
- {
- if(m_DoneAllBuild)
- {
- continue;
- }
- m_DoneAllBuild = true;
- }
- // make sure ALL_BUILD is only done once
- if(l->first == "XCODE_DEPEND_HELPER")
+ // make sure ALL_BUILD, INSTALL, etc are only done once
+ if(this->SpecialTargetEmitted(l->first.c_str()))
{
- if(m_DoneXCodeHack)
- {
- continue;
- }
- m_DoneXCodeHack = true;
+ continue;
}
if(cmtarget.GetType() == cmTarget::UTILITY ||
cmtarget.GetType() == cmTarget::INSTALL_FILES ||
@@ -388,10 +437,22 @@ cmGlobalXCodeGenerator::CreateXCodeTargets(cmLocalGenerator* gen,
this->CreateString("0"));
std::vector<cmSourceFile*> &classes = l->second.GetSourceFiles();
// add all the sources
+ std::vector<cmXCodeObject*> externalObjFiles;
for(std::vector<cmSourceFile*>::iterator i = classes.begin();
i != classes.end(); ++i)
{
- buildFiles->AddObject(this->CreateXCodeSourceFile(gen, *i));
+ cmXCodeObject* xsf = this->CreateXCodeSourceFile(gen, *i);
+ cmXCodeObject* fr = xsf->GetObject("fileRef");
+ cmXCodeObject* filetype =
+ fr->GetObject()->GetObject("lastKnownFileType");
+ if(strcmp(filetype->GetString(), "\"compiled.mach-o.objfile\"") == 0)
+ {
+ externalObjFiles.push_back(xsf);
+ }
+ else
+ {
+ buildFiles->AddObject(xsf);
+ }
}
// create header build phase
cmXCodeObject* headerBuildPhase =
@@ -410,6 +471,11 @@ cmGlobalXCodeGenerator::CreateXCodeTargets(cmLocalGenerator* gen,
this->CreateString("2147483647"));
buildFiles = this->CreateObject(cmXCodeObject::OBJECT_LIST);
frameworkBuildPhase->AddAttribute("files", buildFiles);
+ for(std::vector<cmXCodeObject*>::iterator i = externalObjFiles.begin();
+ i != externalObjFiles.end(); ++i)
+ {
+ buildFiles->AddObject(*i);
+ }
frameworkBuildPhase->AddAttribute("runOnlyForDeploymentPostprocessing",
this->CreateString("0"));
cmXCodeObject* buildPhases =
@@ -421,6 +487,7 @@ cmGlobalXCodeGenerator::CreateXCodeTargets(cmLocalGenerator* gen,
}
}
+//----------------------------------------------------------------------------
void cmGlobalXCodeGenerator::CreateCustomCommands(cmXCodeObject* buildPhases,
cmXCodeObject*
sourceBuildPhase,
@@ -553,6 +620,7 @@ void cmGlobalXCodeGenerator::CreateCustomCommands(cmXCodeObject* buildPhases,
}
}
+//----------------------------------------------------------------------------
void
cmGlobalXCodeGenerator::AddCommandsToBuildPhase(cmXCodeObject* buildphase,
cmTarget& target,
@@ -587,8 +655,8 @@ cmGlobalXCodeGenerator::AddCommandsToBuildPhase(cmXCodeObject* buildphase,
{
if(cc.GetOutput().size())
{
- makefileStream << "\\\n\t" << m_CurrentLocalGenerator
- ->ConvertToRelativeOutputPath(cc.GetOutput().c_str());
+ makefileStream << "\\\n\t" << this->
+ ConvertToRelativeOutputPath(cc.GetOutput().c_str());
}
else
{
@@ -611,7 +679,7 @@ cmGlobalXCodeGenerator::AddCommandsToBuildPhase(cmXCodeObject* buildphase,
cc.GetComment() << "\n";
if(cc.GetOutput().size())
{
- makefileStream << m_CurrentLocalGenerator
+ makefileStream << this
->ConvertToRelativeOutputPath(cc.GetOutput().c_str()) << ": ";
}
else
@@ -639,7 +707,7 @@ cmGlobalXCodeGenerator::AddCommandsToBuildPhase(cmXCodeObject* buildphase,
}
}
- std::string dir = cmSystemTools::ConvertToOutputPath(
+ std::string dir = this->ConvertToRelativeOutputPath(
m_CurrentMakefile->GetCurrentOutputDirectory());
std::string makecmd = "make -C ";
makecmd += dir;
@@ -649,6 +717,7 @@ cmGlobalXCodeGenerator::AddCommandsToBuildPhase(cmXCodeObject* buildphase,
}
+//----------------------------------------------------------------------------
void cmGlobalXCodeGenerator::CreateBuildSettings(cmTarget& target,
cmXCodeObject* buildSettings,
std::string& fileType,
@@ -794,7 +863,7 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmTarget& target,
l != linkdirs.end(); ++l)
{
std::string libpath =
- m_CurrentLocalGenerator->ConvertToOutputForExisting(l->c_str());
+ this->ConvertToRelativeOutputPath(l->c_str());
if(emitted.insert(libpath).second)
{
dirs += libpath + " ";
@@ -813,7 +882,7 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmTarget& target,
for(;i != includes.end(); ++i)
{
std::string incpath =
- m_CurrentLocalGenerator->ConvertToOutputForExisting(i->c_str());
+ this->ConvertToRelativeOutputPath(i->c_str());
dirs += incpath + " ";
}
if(dirs.size())
@@ -849,6 +918,7 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmTarget& target,
this->CreateString(pname.c_str()));
}
+//----------------------------------------------------------------------------
cmXCodeObject*
cmGlobalXCodeGenerator::CreateUtilityTarget(cmTarget& cmtarget)
{
@@ -893,6 +963,7 @@ cmGlobalXCodeGenerator::CreateUtilityTarget(cmTarget& cmtarget)
return target;
}
+//----------------------------------------------------------------------------
cmXCodeObject*
cmGlobalXCodeGenerator::CreateXCodeTarget(cmTarget& cmtarget,
cmXCodeObject* buildPhases)
@@ -933,6 +1004,7 @@ cmGlobalXCodeGenerator::CreateXCodeTarget(cmTarget& cmtarget,
return target;
}
+//----------------------------------------------------------------------------
cmXCodeObject* cmGlobalXCodeGenerator::FindXCodeTarget(cmTarget* t)
{
if(!t)
@@ -951,7 +1023,7 @@ cmXCodeObject* cmGlobalXCodeGenerator::FindXCodeTarget(cmTarget* t)
return 0;
}
-
+//----------------------------------------------------------------------------
void cmGlobalXCodeGenerator::AddDependTarget(cmXCodeObject* target,
cmXCodeObject* dependTarget)
{
@@ -1005,7 +1077,7 @@ void cmGlobalXCodeGenerator::AddDependTarget(cmXCodeObject* target,
}
}
-
+//----------------------------------------------------------------------------
void cmGlobalXCodeGenerator::AddLinkLibrary(cmXCodeObject* target,
const char* library,
cmTarget* dtarget)
@@ -1030,14 +1102,12 @@ void cmGlobalXCodeGenerator::AddLinkLibrary(cmXCodeObject* target,
// remove double quotes
libs = libs.substr(1, libs.size()-2);
libs += " ";
- libs +=
- m_CurrentLocalGenerator->ConvertToOutputForExisting(dir.c_str());
+ libs += this->ConvertToRelativeOutputPath(dir.c_str());
spath->SetString(libs.c_str());
}
else
{
- std::string libs =
- m_CurrentLocalGenerator->ConvertToOutputForExisting(dir.c_str());
+ std::string libs = this->ConvertToRelativeOutputPath(dir.c_str());
bset->AddAttribute("LIBRARY_SEARCH_PATHS",
this->CreateString(libs.c_str()));
}
@@ -1074,7 +1144,7 @@ void cmGlobalXCodeGenerator::AddLinkLibrary(cmXCodeObject* target,
ldflags->SetString(link.c_str());
}
-
+//----------------------------------------------------------------------------
std::string cmGlobalXCodeGenerator::GetTargetFullPath(cmTarget* target)
{
std::string libPath;
@@ -1102,7 +1172,7 @@ std::string cmGlobalXCodeGenerator::GetTargetFullPath(cmTarget* target)
return libPath;
}
-
+//----------------------------------------------------------------------------
void cmGlobalXCodeGenerator::AddDependAndLinkInformation(cmXCodeObject* target)
{
cmTarget* cmtarget = target->GetcmTarget();
@@ -1158,8 +1228,6 @@ void cmGlobalXCodeGenerator::AddDependAndLinkInformation(cmXCodeObject* target)
}
}
-// to force the location of a target
-// add this to build settings of target SYMROOT = /tmp/;
//----------------------------------------------------------------------------
void cmGlobalXCodeGenerator::CreateXCodeObjects(cmLocalGenerator* root,
@@ -1235,8 +1303,6 @@ void cmGlobalXCodeGenerator::CreateXCodeObjects(cmLocalGenerator* root,
m_RootObject->AddAttribute("hasScannedForEncodings",
this->CreateString("0"));
std::vector<cmXCodeObject*> targets;
- m_DoneAllBuild = false;
- m_DoneXCodeHack = false;
for(std::vector<cmLocalGenerator*>::iterator i = generators.begin();
i != generators.end(); ++i)
{
@@ -1412,3 +1478,59 @@ void cmGlobalXCodeGenerator::GetDocumentation(cmDocumentationEntry& entry)
entry.brief = "Generate XCode project files.";
entry.full = "";
}
+
+//----------------------------------------------------------------------------
+std::string cmGlobalXCodeGenerator::ConvertToRelativeOutputPath(const char* p)
+{
+ if ( !m_CurrentMakefile->IsOn("CMAKE_USE_RELATIVE_PATHS") )
+ {
+ return cmSystemTools::ConvertToOutputPath(p);
+ }
+ // NOTE, much of this was copied from
+ // cmLocalGenerator::ConvertToRelativeOutputPath
+ // fixes here should be made there as well.
+ //
+ // copy to a string class
+ std::string pathIn = p;
+ // check to see if the path is already relative, it is
+ // considered relative if one of the following is true
+ // - has no / in it at all
+ // - does not start with / or drive leter :
+ // - starts with a ".."
+ if(pathIn.find('/') == pathIn.npos ||
+ (pathIn[0] != '/' && pathIn[1] != ':') ||
+ pathIn.find("..") == 0)
+ {
+ return cmSystemTools::ConvertToOutputPath(p);
+ }
+ // Given that we are in m_CurrentOutputDirectory how to we
+ // get to pathIn with a relative path, store in ret
+ std::string ret =
+ cmSystemTools::RelativePath(m_OutputDir.c_str(), pathIn.c_str());
+
+ // If the path is 0 sized make it a .
+ // this happens when pathIn is the same as m_CurrentOutputDirectory
+ if(ret.size() == 0)
+ {
+ ret = ".";
+ }
+ // if there was a trailing / there still is one, and
+ // if there was not one, there still is not one
+ if(ret[ret.size()-1] == '/' &&
+ pathIn[pathIn.size()-1] != '/')
+ {
+ ret.erase(ret.size()-1, 1);
+ }
+ if(ret[ret.size()-1] != '/' &&
+ pathIn[pathIn.size()-1] == '/')
+ {
+ ret += "/";
+ }
+ // Now convert the relative path to an output path
+ ret = cmSystemTools::ConvertToOutputPath(ret.c_str());
+ // finally return the path
+ // at this point it should be relative and in the correct format
+ // for the native build system. (i.e. \ for windows and / for unix,
+ // and correct escaping/quoting of spaces in the path
+ return ret;
+}