summaryrefslogtreecommitdiffstats
path: root/Source
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
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')
-rw-r--r--Source/CTest/cmCTestBuildAndTestHandler.cxx2
-rw-r--r--Source/cmFileCommand.cxx11
-rw-r--r--Source/cmGlobalGenerator.h2
-rw-r--r--Source/cmGlobalVisualStudio6Generator.cxx7
-rw-r--r--Source/cmGlobalVisualStudio71Generator.cxx5
-rw-r--r--Source/cmGlobalVisualStudio7Generator.cxx11
-rw-r--r--Source/cmGlobalVisualStudio7Generator.h4
-rw-r--r--Source/cmGlobalXCodeGenerator.cxx648
-rw-r--r--Source/cmGlobalXCodeGenerator.h7
-rw-r--r--Source/cmLinkLibrariesCommand.cxx15
-rw-r--r--Source/cmLocalGenerator.cxx587
-rw-r--r--Source/cmLocalGenerator.h26
-rw-r--r--Source/cmLocalUnixMakefileGenerator3.cxx104
-rw-r--r--Source/cmLocalUnixMakefileGenerator3.h4
-rw-r--r--Source/cmLocalVisualStudio6Generator.cxx77
-rw-r--r--Source/cmLocalVisualStudio7Generator.cxx227
-rw-r--r--Source/cmLocalVisualStudio7Generator.h7
-rw-r--r--Source/cmMakefile.cxx17
-rw-r--r--Source/cmOrderLinkDirectories.cxx53
-rw-r--r--Source/cmOrderLinkDirectories.h11
-rw-r--r--Source/cmTarget.cxx310
-rw-r--r--Source/cmTarget.h57
-rw-r--r--Source/cmTargetLinkLibrariesCommand.cxx45
-rw-r--r--Source/cmTargetLinkLibrariesCommand.h6
-rw-r--r--Source/cmXCodeObject.h14
25 files changed, 1195 insertions, 1062 deletions
diff --git a/Source/CTest/cmCTestBuildAndTestHandler.cxx b/Source/CTest/cmCTestBuildAndTestHandler.cxx
index cf1dfeb..5220fc8 100644
--- a/Source/CTest/cmCTestBuildAndTestHandler.cxx
+++ b/Source/CTest/cmCTestBuildAndTestHandler.cxx
@@ -72,7 +72,7 @@ int cmCTestBuildAndTestHandler::RunCMake(std::string* outstring, cmOStringStream
}
if ( m_CTest->GetConfigType().size() > 0 )
{
- std::string btype = "-DBUILD_TYPE:STRING=" + m_CTest->GetConfigType();
+ std::string btype = "-DCMAKE_BUILD_TYPE:STRING=" + m_CTest->GetConfigType();
args.push_back(btype);
}
diff --git a/Source/cmFileCommand.cxx b/Source/cmFileCommand.cxx
index 4a06cb4..fee585f 100644
--- a/Source/cmFileCommand.cxx
+++ b/Source/cmFileCommand.cxx
@@ -288,12 +288,6 @@ bool cmFileCommand::HandleInstallCommand(
build_type += 2;
}
- const char* debug_postfix
- = m_Makefile->GetDefinition("CMAKE_DEBUG_POSTFIX");
- if(!debug_postfix)
- {
- debug_postfix = "";
- }
const char* destdir = cmSystemTools::GetEnv("DESTDIR");
std::string extra_dir = "";
@@ -505,11 +499,6 @@ bool cmFileCommand::HandleInstallCommand(
case cmTarget::MODULE_LIBRARY:
case cmTarget::STATIC_LIBRARY:
case cmTarget::SHARED_LIBRARY:
- if ( debug )
- {
- fname = fnamewe + debug_postfix + ext;
- destfile = destfilewe + debug_postfix + ext;
- }
{
// Handle shared library versioning
const char* lib_version = 0;
diff --git a/Source/cmGlobalGenerator.h b/Source/cmGlobalGenerator.h
index f5ef449..d11f8fb 100644
--- a/Source/cmGlobalGenerator.h
+++ b/Source/cmGlobalGenerator.h
@@ -156,7 +156,7 @@ protected:
void ConfigureRelativePaths();
void SetupTests();
-
+
bool m_ForceUnixPaths;
cmStdString m_FindMakeProgramFile;
cmStdString m_ConfiguredFilesPath;
diff --git a/Source/cmGlobalVisualStudio6Generator.cxx b/Source/cmGlobalVisualStudio6Generator.cxx
index 07f171d..11dbff2 100644
--- a/Source/cmGlobalVisualStudio6Generator.cxx
+++ b/Source/cmGlobalVisualStudio6Generator.cxx
@@ -394,11 +394,8 @@ void cmGlobalVisualStudio6Generator::WriteProject(std::ostream& fout,
if(j->first != dspname)
{
// is the library part of this DSW ? If so add dependency
- std::string libPath = j->first + "_CMAKE_PATH";
- const char* cacheValue
- = m_CMakeInstance->GetCacheDefinition(libPath.c_str());
- if(cacheValue && *cacheValue)
- {
+ if(this->FindTarget(0, j->first.c_str()))
+ {
fout << "Begin Project Dependency\n";
fout << "Project_Dep_Name " << j->first.c_str() << "\n";
fout << "End Project Dependency\n";
diff --git a/Source/cmGlobalVisualStudio71Generator.cxx b/Source/cmGlobalVisualStudio71Generator.cxx
index bba2ae5..a5e14aa 100644
--- a/Source/cmGlobalVisualStudio71Generator.cxx
+++ b/Source/cmGlobalVisualStudio71Generator.cxx
@@ -264,10 +264,7 @@ cmGlobalVisualStudio71Generator
if(j->first != dspname)
{
// is the library part of this SLN ? If so add dependency
- std::string libPath = j->first + "_CMAKE_PATH";
- const char* cacheValue
- = m_CMakeInstance->GetCacheDefinition(libPath.c_str());
- if(cacheValue && *cacheValue)
+ if(this->FindTarget(m_CurrentProject.c_str(), j->first.c_str()))
{
fout << "\t\t{" << this->GetGUID(j->first.c_str()) << "} = {"
<< this->GetGUID(j->first.c_str()) << "}\n";
diff --git a/Source/cmGlobalVisualStudio7Generator.cxx b/Source/cmGlobalVisualStudio7Generator.cxx
index e2d8d6b..a5d5735 100644
--- a/Source/cmGlobalVisualStudio7Generator.cxx
+++ b/Source/cmGlobalVisualStudio7Generator.cxx
@@ -238,6 +238,7 @@ void cmGlobalVisualStudio7Generator::OutputSLNFile(cmLocalGenerator* root,
{
return;
}
+ m_CurrentProject = root->GetMakefile()->GetProjectName();
std::string fname = root->GetMakefile()->GetStartOutputDirectory();
fname += "/";
fname += root->GetMakefile()->GetProjectName();
@@ -547,10 +548,7 @@ cmGlobalVisualStudio7Generator
if(j->first != dspname)
{
// is the library part of this SLN ? If so add dependency
- std::string libPath = j->first + "_CMAKE_PATH";
- const char* cacheValue
- = m_CMakeInstance->GetCacheDefinition(libPath.c_str());
- if(cacheValue && *cacheValue)
+ if(this->FindTarget(m_CurrentProject.c_str(), j->first.c_str()))
{
std::string guid = this->GetGUID(j->first.c_str());
if(guid.size() == 0)
@@ -561,9 +559,8 @@ cmGlobalVisualStudio7Generator
m += j->first.c_str();
cmSystemTools::Error(m.c_str());
}
-
- fout << "\t\t{" << this->GetGUID(dspname) << "}." << depcount << " = {"
- << guid << "}\n";
+ fout << "\t\t{" << this->GetGUID(dspname) << "}."
+ << depcount << " = {" << guid << "}\n";
depcount++;
}
}
diff --git a/Source/cmGlobalVisualStudio7Generator.h b/Source/cmGlobalVisualStudio7Generator.h
index 2af47f7..eb55bd2 100644
--- a/Source/cmGlobalVisualStudio7Generator.h
+++ b/Source/cmGlobalVisualStudio7Generator.h
@@ -102,6 +102,10 @@ protected:
std::vector<std::string> m_Configurations;
std::map<cmStdString, cmStdString> m_GUIDMap;
+
+ // Set during OutputSLNFile with the name of the current project.
+ // There is one SLN file per project.
+ std::string m_CurrentProject;
};
#define CMAKE_CHECK_BUILD_SYSTEM_TARGET "ZERO_CHECK"
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();
diff --git a/Source/cmGlobalXCodeGenerator.h b/Source/cmGlobalXCodeGenerator.h
index 4a519aa..9cea343 100644
--- a/Source/cmGlobalXCodeGenerator.h
+++ b/Source/cmGlobalXCodeGenerator.h
@@ -104,7 +104,7 @@ private:
void AppendOrAddBuildSetting(cmXCodeObject* settings, const char* attr,
const char* value);
void AppendBuildSettingAttribute(cmXCodeObject* target, const char* attr,
- const char* value);
+ const char* value, const char* configName);
cmXCodeObject* CreateUtilityTarget(cmTarget& target);
void AddDependAndLinkInformation(cmXCodeObject* target);
void CreateBuildSettings(cmTarget& target,
@@ -128,11 +128,8 @@ private:
void CreateXCodeTargets(cmLocalGenerator* gen, std::vector<cmXCodeObject*>&);
void AddDependTarget(cmXCodeObject* target,
cmXCodeObject* dependTarget);
- void AddLinkLibrary(cmXCodeObject* target,
- const char* lib, cmTarget* dtarget = 0);
void ConfigureOutputPaths();
void CreateXCodeDependHackTarget(std::vector<cmXCodeObject*>& targets);
- std::string GetTargetFullPath(cmTarget*);
bool SpecialTargetEmitted(std::string const& tname);
void AddExtraTargets(cmLocalGenerator* root,
std::vector<cmLocalGenerator*>& gens);
@@ -142,7 +139,6 @@ private:
const std::vector<cmCustomCommand>&);
void CreateReRunCMakeFile(cmLocalGenerator* root);
protected:
- std::string AddConfigDir(const char* d);
int m_XcodeVersion;
std::vector<cmXCodeObject*> m_XCodeObjects;
@@ -152,6 +148,7 @@ private:
cmXCodeObject* m_SourcesGroupChildren;
cmMakefile* m_CurrentMakefile;
cmLocalGenerator* m_CurrentLocalGenerator;
+ std::vector<std::string> m_CurrentConfigurationTypes;
std::string m_CurrentReRunCMakeMakefile;
std::string m_CurrentXCodeHackMakefile;
std::string m_CurrentProject;
diff --git a/Source/cmLinkLibrariesCommand.cxx b/Source/cmLinkLibrariesCommand.cxx
index c34cd3c..ec51212 100644
--- a/Source/cmLinkLibrariesCommand.cxx
+++ b/Source/cmLinkLibrariesCommand.cxx
@@ -54,21 +54,6 @@ bool cmLinkLibrariesCommand::InitialPass(std::vector<std::string> const& args)
{
m_Makefile->AddLinkLibrary(i->c_str());
}
-
- const char* ldir = m_Makefile->GetDefinition("LIBRARY_OUTPUT_PATH");
- if (cmSystemTools::IsOff(ldir))
- {
- std::string libPath = *i + "_CMAKE_PATH";
- const char* dir = m_Makefile->GetDefinition(libPath.c_str());
- if( dir && *dir )
- {
- m_Makefile->AddLinkDirectory( dir );
- }
- }
- else
- {
- m_Makefile->AddLinkDirectory( ldir );
- }
}
return true;
diff --git a/Source/cmLocalGenerator.cxx b/Source/cmLocalGenerator.cxx
index 214ab6b..28e32c8 100644
--- a/Source/cmLocalGenerator.cxx
+++ b/Source/cmLocalGenerator.cxx
@@ -293,12 +293,29 @@ void cmLocalGenerator::GenerateInstallRules()
<< "ENDIF(NOT CMAKE_INSTALL_PREFIX)" << std::endl
<< std::endl;
- const char* cmakeDebugPosfix = m_Makefile->GetDefinition("CMAKE_DEBUG_POSTFIX");
- if ( cmakeDebugPosfix )
+ std::vector<std::string> configurationTypes;
+ if(const char* types = m_Makefile->GetDefinition("CMAKE_CONFIGURATION_TYPES"))
{
- fout << "SET(CMAKE_DEBUG_POSTFIX \"" << cmakeDebugPosfix << "\")"
- << std::endl << std::endl;
+ cmSystemTools::ExpandListArgument(types, configurationTypes);
}
+ const char* config = 0;
+ if(configurationTypes.empty())
+ {
+ config = m_Makefile->GetDefinition("CMAKE_BUILD_TYPE");
+ }
+
+ fout <<
+ "# Set the install configuration name.\n"
+ "IF(NOT CMAKE_INSTALL_CONFIG_NAME)\n"
+ " IF(BUILD_TYPE)\n"
+ " STRING(REGEX REPLACE \"^[^A-Za-z0-9_]+\" \"\"\n"
+ " CMAKE_INSTALL_CONFIG_NAME \"${BUILD_TYPE}\")\n"
+ " ELSE(BUILD_TYPE)\n"
+ " SET(CMAKE_INSTALL_CONFIG_NAME Release)\n"
+ " ENDIF(BUILD_TYPE)\n"
+ " MESSAGE(STATUS \"Install configuration: \\\"${CMAKE_INSTALL_CONFIG_NAME}\\\"\")\n"
+ "ENDIF(NOT CMAKE_INSTALL_CONFIG_NAME)\n"
+ "\n";
std::string libOutPath = "";
if (m_Makefile->GetDefinition("LIBRARY_OUTPUT_PATH"))
@@ -349,116 +366,123 @@ void cmLocalGenerator::GenerateInstallRules()
}
if (l->second.GetInstallPath() != "")
{
- destination = "${CMAKE_INSTALL_PREFIX}/" + l->second.GetInstallPath();
+ destination = "${CMAKE_INSTALL_PREFIX}" + l->second.GetInstallPath();
cmSystemTools::ConvertToUnixSlashes(destination);
const char* dest = destination.c_str();
int type = l->second.GetType();
-
-
std::string fname;
+ std::string props;
+ const char* properties = 0;
const char* files;
+
+ this->PrepareInstallReference(fout, l->second, configurationTypes);
+
// now install the target
switch (type)
{
- case cmTarget::STATIC_LIBRARY:
- case cmTarget::MODULE_LIBRARY:
- fname = libOutPath;
- fname += l->second.GetFullName();
- files = fname.c_str();
- this->AddInstallRule(fout, dest, type, files);
- break;
- case cmTarget::SHARED_LIBRARY:
- {
- // Special code to handle DLL
- fname = libOutPath;
- fname += l->second.GetFullName();
- std::string ext = cmSystemTools::GetFilenameExtension(fname);
- ext = cmSystemTools::LowerCase(ext);
- if ( ext == ".dll" )
+ case cmTarget::SHARED_LIBRARY:
{
- std::string libname = libOutPath;
- libname += cmSystemTools::GetFilenameWithoutExtension(fname);
- libname += ".lib";
- files = libname.c_str();
- this->AddInstallRule(fout, dest, cmTarget::STATIC_LIBRARY, files, true);
- std::string dlldest = "${CMAKE_INSTALL_PREFIX}/" + l->second.GetRuntimeInstallPath();
- files = fname.c_str();
- this->AddInstallRule(fout, dlldest.c_str(), type, files);
- }
- else
- {
- files = fname.c_str();
- std::string properties;
- const char* lib_version = l->second.GetProperty("VERSION");
- const char* lib_soversion = l->second.GetProperty("SOVERSION");
- if(!m_Makefile->GetDefinition("CMAKE_SHARED_LIBRARY_SONAME_C_FLAG"))
- {
- // Versioning is supported only for shared libraries and modules,
- // and then only when the platform supports an soname flag.
- lib_version = 0;
- lib_soversion = 0;
- }
- if ( lib_version )
+ // Special code to handle DLL
+ fname = l->second.GetFullName();
+ std::string ext = cmSystemTools::GetFilenameLastExtension(fname);
+ ext = cmSystemTools::LowerCase(ext);
+ if ( ext == ".dll" )
{
- properties += " VERSION ";
- properties += lib_version;
+ // Install the .lib separately.
+ std::string libname = libOutPath;
+ libname += this->GetInstallReference(l->second, config,
+ configurationTypes,
+ true);
+ files = libname.c_str();
+ this->AddInstallRule(fout, dest, cmTarget::STATIC_LIBRARY, files, true);
+
+ // Change the destination to the .dll destination.
+ destination = "${CMAKE_INSTALL_PREFIX}" + l->second.GetRuntimeInstallPath();
+ dest = destination.c_str();
}
- if ( lib_soversion )
+ else
{
- properties += " SOVERSION ";
- properties += lib_soversion;
+ // Add shared library installation properties.
+ const char* lib_version = l->second.GetProperty("VERSION");
+ const char* lib_soversion = l->second.GetProperty("SOVERSION");
+ if(!m_Makefile->GetDefinition("CMAKE_SHARED_LIBRARY_SONAME_C_FLAG"))
+ {
+ // Versioning is supported only for shared libraries and modules,
+ // and then only when the platform supports an soname flag.
+ lib_version = 0;
+ lib_soversion = 0;
+ }
+ if ( lib_version )
+ {
+ props += " VERSION ";
+ props += lib_version;
+ }
+ if ( lib_soversion )
+ {
+ props += " SOVERSION ";
+ props += lib_soversion;
+ }
+ properties = props.c_str();
}
- this->AddInstallRule(fout, dest, type, files, false, properties.c_str());
}
- }
- break;
- case cmTarget::EXECUTABLE:
- {
- std::string properties;
-#if defined(_WIN32) && !defined(__CYGWIN__)
- const char* exe_version = 0;
-#else
- const char* exe_version = l->second.GetProperty("VERSION");
-#endif
- if(exe_version)
- {
- properties += " VERSION ";
- properties += exe_version;
- }
- if(l->second.GetPropertyAsBool("MACOSX_BUNDLE"))
+ /* No "break;" because we want to install the library here. */
+ case cmTarget::STATIC_LIBRARY:
+ case cmTarget::MODULE_LIBRARY:
{
- fname = exeOutPath;
- fname += l->second.GetFullName();
- std::string plist = fname;
- plist += ".app/Contents/Info.plist";
- fname += ".app/Contents/MacOS/";
- fname += l->second.GetName();
+ fname = libOutPath;
+ fname += this->GetInstallReference(l->second, config,
+ configurationTypes);
files = fname.c_str();
- std::string bdest = dest;
- bdest += "/";
- bdest += l->second.GetName();
- std::string pdest = bdest;
- pdest += ".app/Contents";
- bdest += ".app/Contents/MacOS";
- // first install the actual executable
- this->AddInstallRule(fout, bdest.c_str(), type, files,
- false, properties.c_str());
- files = plist.c_str();
- // now install the Info.plist file
- this->AddInstallRule(fout, pdest.c_str(),
- cmTarget::INSTALL_FILES, files);
+ this->AddInstallRule(fout, dest, type, files, false, properties);
}
- else
+ break;
+ case cmTarget::EXECUTABLE:
{
+#if defined(_WIN32) && !defined(__CYGWIN__)
+ const char* exe_version = 0;
+#else
+ const char* exe_version = l->second.GetProperty("VERSION");
+#endif
+ if(exe_version)
+ {
+ props += " VERSION ";
+ props += exe_version;
+ properties = props.c_str();
+ }
+ std::string exeName =
+ this->GetInstallReference(l->second, config, configurationTypes);
fname = exeOutPath;
- fname += l->second.GetFullName();
- files = fname.c_str();
- this->AddInstallRule(fout, dest, type, files, false,
- properties.c_str());
+ fname += exeName;
+ if(l->second.GetPropertyAsBool("MACOSX_BUNDLE"))
+ {
+ std::string plist = fname;
+ plist += ".app/Contents/Info.plist";
+ fname += ".app/Contents/MacOS/";
+ fname += exeName;
+ files = fname.c_str();
+ std::string bdest = dest;
+ bdest += "/";
+ bdest += exeName;
+ std::string pdest = bdest;
+ pdest += ".app/Contents";
+ bdest += ".app/Contents/MacOS";
+ // first install the actual executable
+ this->AddInstallRule(fout, bdest.c_str(), type, files,
+ false, properties);
+ files = plist.c_str();
+ // now install the Info.plist file
+ this->AddInstallRule(fout, pdest.c_str(),
+ cmTarget::INSTALL_FILES, files);
+ }
+ else
+ {
+ files = fname.c_str();
+ this->AddInstallRule(fout, dest, type, files, false,
+ properties);
+ }
}
- }
- break;
- case cmTarget::INSTALL_FILES:
+ break;
+ case cmTarget::INSTALL_FILES:
{
std::string sourcePath = m_Makefile->GetCurrentDirectory();
std::string binaryPath = m_Makefile->GetCurrentOutputDirectory();
@@ -482,8 +506,8 @@ void cmLocalGenerator::GenerateInstallRules()
this->AddInstallRule(fout, dest, type, files);
}
}
- break;
- case cmTarget::INSTALL_PROGRAMS:
+ break;
+ case cmTarget::INSTALL_PROGRAMS:
{
std::string sourcePath = m_Makefile->GetCurrentDirectory();
std::string binaryPath = m_Makefile->GetCurrentOutputDirectory();
@@ -506,10 +530,10 @@ void cmLocalGenerator::GenerateInstallRules()
this->AddInstallRule(fout, dest, type, files);
}
}
- break;
- case cmTarget::UTILITY:
- default:
- break;
+ break;
+ case cmTarget::UTILITY:
+ default:
+ break;
}
}
if ( postinstall )
@@ -687,7 +711,6 @@ void cmLocalGenerator::AddBuildTargetRule(const char* llang, cmTarget& target)
0, // object
flags.c_str(), // flags
0, // objects quoted
- 0, // target base name
0, // target so name,
linkFlags.c_str() // link flags
);
@@ -775,7 +798,6 @@ cmLocalGenerator::ExpandRuleVariable(std::string const& variable,
const char* object,
const char* flags,
const char* objectsquoted,
- const char* targetBase,
const char* targetSOName,
const char* linkFlags)
{
@@ -839,33 +861,19 @@ cmLocalGenerator::ExpandRuleVariable(std::string const& variable,
{
return target;
}
- }
- if(targetBase)
- {
- if(variable == "TARGET_BASE.lib" || variable == "TARGET_BASE.dll")
+ if(variable == "TARGET_BASE")
{
- // special case for quoted paths with spaces
- // if you see <TARGET_BASE>.lib then put the .lib inside
- // the quotes, same for .dll
- if((strlen(targetBase) > 1) && targetBase[0] == '\"')
+ // Strip the last extension off the target name.
+ std::string targetBase = target;
+ std::string::size_type pos = targetBase.rfind(".");
+ if(pos != targetBase.npos)
{
- std::string base = targetBase;
- base[base.size()-1] = '.';
- std::string baseLib = base + "lib\"";
- std::string baseDll = base + "dll\"";
- if(variable == "TARGET_BASE.lib" )
- {
- return baseLib;
- }
- if(variable == "TARGET_BASE.dll" )
- {
- return baseDll;
- }
+ return targetBase.substr(0, pos);
+ }
+ else
+ {
+ return targetBase;
}
- }
- if(variable == "TARGET_BASE")
- {
- return targetBase;
}
}
if(targetSOName)
@@ -950,7 +958,6 @@ cmLocalGenerator::ExpandRuleVariables(std::string& s,
const char* object,
const char* flags,
const char* objectsquoted,
- const char* targetBase,
const char* targetSOName,
const char* linkFlags)
{
@@ -987,7 +994,7 @@ cmLocalGenerator::ExpandRuleVariables(std::string& s,
target, linkLibs,
source, object, flags,
objectsquoted,
- targetBase, targetSOName,
+ targetSOName,
linkFlags);
expandedInput += s.substr(pos, start-pos);
expandedInput += replace;
@@ -1300,7 +1307,8 @@ void cmLocalGenerator::OutputLinkLibraries(std::ostream& fout,
std::string runtimeSep;
std::vector<std::string> runtimeDirs;
- std::string buildType = m_Makefile->GetSafeDefinition("CMAKE_BUILD_TYPE");
+ const char* config = m_Makefile->GetDefinition("CMAKE_BUILD_TYPE");
+ std::string buildType = config?config:"";
buildType = cmSystemTools::UpperCase(buildType);
cmTarget::LinkLibraryType cmakeBuildType = cmTarget::GENERAL;
if(buildType == "DEBUG")
@@ -1350,42 +1358,17 @@ void cmLocalGenerator::OutputLinkLibraries(std::ostream& fout,
linkLibs = m_Makefile->GetSafeDefinition(linkFlagsVar.c_str());
linkLibs += " ";
}
-
- cmOrderLinkDirectories orderLibs;
- std::string ext =
- m_Makefile->GetSafeDefinition("CMAKE_STATIC_LIBRARY_SUFFIX");
- if(ext.size())
- {
- orderLibs.AddLinkExtension(ext.c_str());
- }
- ext =
- m_Makefile->GetSafeDefinition("CMAKE_STATIC_LIBRARY_PREFIX");
- if(ext.size())
- {
- orderLibs.SetLinkPrefix(ext.c_str());
- }
- ext =
- m_Makefile->GetSafeDefinition("CMAKE_SHARED_LIBRARY_SUFFIX");
- if(ext.size())
- {
- orderLibs.AddLinkExtension(ext.c_str());
- }
- ext =
- m_Makefile->GetSafeDefinition("CMAKE_LINK_LIBRARY_SUFFIX");
- if(ext.size())
+
+ // Compute the link library and directory information.
+ std::vector<cmStdString> libNames;
+ std::vector<cmStdString> libDirs;
+ this->ComputeLinkInformation(tgt, config, libNames, libDirs);
+
+ // Append the library search path flags.
+ for(std::vector<cmStdString>::const_iterator libDir = libDirs.begin();
+ libDir != libDirs.end(); ++libDir)
{
- orderLibs.AddLinkExtension(ext.c_str());
- }
- // compute the correct order for -L paths
- orderLibs.SetLinkInformation(tgt, cmakeBuildType, targetLibrary);
- orderLibs.DetermineLibraryPathOrder();
- std::vector<cmStdString> libdirs;
- std::vector<cmStdString> linkItems;
- orderLibs.GetLinkerInformation(libdirs, linkItems);
- for(std::vector<cmStdString>::const_iterator libDir = libdirs.begin();
- libDir != libdirs.end(); ++libDir)
- {
- std::string libpath = this->ConvertToOutputForExisting(libDir->c_str());
+ std::string libpath = this->ConvertToOutputForExisting(libDir->c_str());
if(emitted.insert(libpath).second)
{
std::string fullLibPath;
@@ -1413,34 +1396,14 @@ void cmLocalGenerator::OutputLinkLibraries(std::ostream& fout,
}
}
- std::string linkSuffix =
- m_Makefile->GetSafeDefinition("CMAKE_LINK_LIBRARY_SUFFIX");
- std::string regexp = ".*\\";
- regexp += linkSuffix;
- regexp += "$";
- cmsys::RegularExpression hasSuffix(regexp.c_str());
- std::string librariesLinked;
- for(std::vector<cmStdString>::iterator lib = linkItems.begin();
- lib != linkItems.end(); ++lib)
- {
- cmStdString& linkItem = *lib;
- // check to see if the link item has a -l already
- cmsys::RegularExpression reg("^([ \t]*\\-[lLWRBF])|([ \t]*\\-framework)|(\\${)|([ \t]*\\-pthread)|([ \t]*`)");
- if(!reg.find(linkItem))
- {
- librariesLinked += libLinkFlag;
- }
- librariesLinked += linkItem;
-
- if(linkSuffix.size() && !hasSuffix.find(linkItem))
- {
- librariesLinked += linkSuffix;
- }
- librariesLinked += " ";
+ // Append the link libraries.
+ for(std::vector<cmStdString>::iterator lib = libNames.begin();
+ lib != libNames.end(); ++lib)
+ {
+ linkLibs += *lib;
+ linkLibs += " ";
}
- linkLibs += librariesLinked;
-
fout << linkLibs;
if(outputRuntime && runtimeDirs.size()>0)
@@ -1470,6 +1433,191 @@ void cmLocalGenerator::OutputLinkLibraries(std::ostream& fout,
}
}
+//----------------------------------------------------------------------------
+void
+cmLocalGenerator::ComputeLinkInformation(cmTarget& target,
+ const char* config,
+ std::vector<cmStdString>& outLibs,
+ std::vector<cmStdString>& outDirs,
+ std::vector<cmStdString>* fullPathLibs)
+{
+ // Compute which library configuration to link.
+ cmTarget::LinkLibraryType linkType = cmTarget::OPTIMIZED;
+ if(config && cmSystemTools::UpperCase(config) == "DEBUG")
+ {
+ linkType = cmTarget::DEBUG;
+ }
+
+ // Get the list of libraries against which this target wants to link.
+ std::vector<std::string> linkLibraries;
+ const cmTarget::LinkLibraries& inLibs = target.GetLinkLibraries();
+ for(cmTarget::LinkLibraries::const_iterator j = inLibs.begin();
+ j != inLibs.end(); ++j)
+ {
+ // For backwards compatibility variables may have been expanded
+ // inside library names. Clean up the resulting name.
+ std::string lib = j->first;
+ std::string::size_type pos = lib.find_first_not_of(" \t\r\n");
+ if(pos != lib.npos)
+ {
+ lib = lib.substr(pos, lib.npos);
+ }
+ pos = lib.find_last_not_of(" \t\r\n");
+ if(pos != lib.npos)
+ {
+ lib = lib.substr(0, pos);
+ }
+ if(lib.empty())
+ {
+ continue;
+ }
+
+ // Link to a library if it is not the same target and is meant for
+ // this configuration type.
+ if((target.GetType() == cmTarget::EXECUTABLE ||
+ j->first != target.GetName()) &&
+ (j->second == cmTarget::GENERAL || j->second == linkType))
+ {
+ // Compute the proper name to use to link this library.
+ cmTarget* tgt = m_GlobalGenerator->FindTarget(0, j->first.c_str());
+ if(tgt)
+ {
+ // This is a CMake target. Ask the target for its real name.
+ linkLibraries.push_back(tgt->GetFullName(config));
+ if(fullPathLibs)
+ {
+ fullPathLibs->push_back(tgt->GetFullPath(config));
+ }
+ }
+ else
+ {
+ // This is not a CMake target. Use the name given.
+ linkLibraries.push_back(j->first);
+ }
+ }
+ }
+
+ // Get the list of directories the target wants to search for libraries.
+ const std::vector<std::string>&
+ linkDirectories = target.GetLinkDirectories();
+
+ // Compute the link directory order needed to link the libraries.
+ cmOrderLinkDirectories orderLibs;
+ orderLibs.SetLinkPrefix(
+ m_Makefile->GetDefinition("CMAKE_STATIC_LIBRARY_PREFIX"));
+ orderLibs.AddLinkExtension(
+ m_Makefile->GetDefinition("CMAKE_STATIC_LIBRARY_SUFFIX"));
+ orderLibs.AddLinkExtension(
+ m_Makefile->GetDefinition("CMAKE_SHARED_LIBRARY_SUFFIX"));
+ orderLibs.AddLinkExtension(
+ m_Makefile->GetDefinition("CMAKE_LINK_LIBRARY_SUFFIX"));
+ orderLibs.SetLinkInformation(target.GetName(),
+ linkLibraries,
+ linkDirectories);
+ orderLibs.DetermineLibraryPathOrder();
+ std::vector<cmStdString> orderedLibs;
+ orderLibs.GetLinkerInformation(outDirs, orderedLibs);
+ if(fullPathLibs)
+ {
+ orderLibs.GetFullPathLibraries(*fullPathLibs);
+ }
+
+ // Make sure libraries are linked with the proper syntax.
+ std::string libLinkFlag =
+ m_Makefile->GetSafeDefinition("CMAKE_LINK_LIBRARY_FLAG");
+ std::string libLinkSuffix =
+ m_Makefile->GetSafeDefinition("CMAKE_LINK_LIBRARY_SUFFIX");
+ for(std::vector<cmStdString>::iterator l = orderedLibs.begin();
+ l != orderedLibs.end(); ++l)
+ {
+ std::string lib = *l;
+ if(lib[0] == '-' || lib[0] == '$' || lib[0] == '`')
+ {
+ // The library is linked with special syntax by the user.
+ outLibs.push_back(lib);
+ }
+ else
+ {
+ // Generate the proper link syntax.
+ lib = libLinkFlag;
+ lib += *l;
+ lib += libLinkSuffix;
+ outLibs.push_back(lib);
+ }
+ }
+}
+
+//----------------------------------------------------------------------------
+std::string
+cmLocalGenerator::GetInstallReference(cmTarget& target, const char* config,
+ std::vector<std::string> const& configs,
+ bool implib /* = false*/)
+{
+ if(configs.empty())
+ {
+ std::string ref = target.GetFullName(config);
+ if(implib)
+ {
+ ref = cmSystemTools::GetFilenameWithoutLastExtension(ref);
+ ref += ".lib";
+ }
+ return ref;
+ }
+ else
+ {
+ std::string ref = "${";
+ ref += target.GetName();
+ if(implib)
+ {
+ ref += "_LIBNAME_";
+ }
+ else
+ {
+ ref += "_NAME_";
+ }
+ ref += "${CMAKE_INSTALL_CONFIG_NAME}}";
+ return ref;
+ }
+}
+
+//----------------------------------------------------------------------------
+void
+cmLocalGenerator
+::PrepareInstallReference(std::ostream& fout, cmTarget& target,
+ std::vector<std::string> const& configs)
+{
+ // If the target name may vary with the configuration type then
+ // store all possible names ahead of time in variables.
+ cmTarget::TargetType type = target.GetType();
+ if(type == cmTarget::SHARED_LIBRARY ||
+ type == cmTarget::STATIC_LIBRARY ||
+ type == cmTarget::MODULE_LIBRARY ||
+ type == cmTarget::EXECUTABLE)
+ {
+ std::string fname;
+ for(std::vector<std::string>::const_iterator i = configs.begin();
+ i != configs.end(); ++i)
+ {
+ // Set a variable with the target name for this
+ // configuration.
+ fname = target.GetFullName(i->c_str());
+ fout << "SET(" << target.GetName() << "_NAME_" << *i
+ << " \"" << fname << "\")\n";
+
+#ifdef _WIN32
+ // If the target is a .dll then add the corresponding .lib
+ // name in its own variable.
+ if(type == cmTarget::SHARED_LIBRARY)
+ {
+ fname = cmSystemTools::GetFilenameWithoutExtension(fname);
+ fname += ".lib";
+ fout << "SET(" << target.GetName() << "_LIBNAME_" << *i
+ << " \"" << fname << "\")\n";
+ }
+#endif
+ }
+ }
+}
//----------------------------------------------------------------------------
void cmLocalGenerator::AddLanguageFlags(std::string& flags,
@@ -1483,6 +1631,65 @@ void cmLocalGenerator::AddLanguageFlags(std::string& flags,
}
//----------------------------------------------------------------------------
+std::string cmLocalGenerator::GetRealDependency(const char* inName,
+ const char* config,
+ bool* inLocal)
+{
+ // Older CMake code may specify the dependency using the target
+ // output file rather than the target name. Such code would have
+ // been written before there was support for target properties that
+ // modify the name so stripping down to just the file name should
+ // produce the target name in this case.
+ std::string name = cmSystemTools::GetFilenameName(inName);
+ if(cmSystemTools::GetFilenameLastExtension(name) == ".exe")
+ {
+ name = cmSystemTools::GetFilenameWithoutLastExtension(name);
+ }
+
+ // Look for a CMake target in the current makefile.
+ cmTarget* target = m_Makefile->FindTarget(name.c_str());
+
+ // If no target was found in the current makefile search globally.
+ bool local = target?true:false;
+ if(inLocal)
+ {
+ *inLocal = local;
+ }
+ if(!local)
+ {
+ target = m_GlobalGenerator->FindTarget(0, name.c_str());
+ }
+
+ // If a target was found then get its real location.
+ if(target)
+ {
+ switch (target->GetType())
+ {
+ case cmTarget::EXECUTABLE:
+ case cmTarget::STATIC_LIBRARY:
+ case cmTarget::SHARED_LIBRARY:
+ case cmTarget::MODULE_LIBRARY:
+ {
+ // Get the location of the target's output file and depend on it.
+ if(const char* location = target->GetLocation(config))
+ {
+ return location;
+ }
+ }
+ break;
+ case cmTarget::UTILITY:
+ case cmTarget::INSTALL_FILES:
+ case cmTarget::INSTALL_PROGRAMS:
+ break;
+ }
+ }
+
+ // The name was not that of a CMake target. The dependency should
+ // use the name as given.
+ return inName;
+}
+
+//----------------------------------------------------------------------------
void cmLocalGenerator::AddSharedFlags(std::string& flags,
const char* lang,
bool shared)
diff --git a/Source/cmLocalGenerator.h b/Source/cmLocalGenerator.h
index 11b3e22..72fe169 100644
--- a/Source/cmLocalGenerator.h
+++ b/Source/cmLocalGenerator.h
@@ -134,6 +134,16 @@ public:
///! Get the include flags for the current makefile and language
const char* GetIncludeFlags(const char* lang);
+ /** Translate a dependency as given in CMake code to the name to
+ appear in a generated build file. If the given name is that of
+ a CMake target it will be transformed to the real output
+ location of that target for the given configuration. Otherwise
+ the original name will be returned. If the local argument is
+ given it is set to indicate whethr the name is of a utility
+ target available in the same makefile. */
+ std::string GetRealDependency(const char* name, const char* config,
+ bool* local=0);
+
///! for existing files convert to output path and short path if spaces
std::string ConvertToOutputForExisting(const char* p);
@@ -145,6 +155,13 @@ public:
/** Called from command-line hook to scan dependencies. */
virtual bool ScanDependencies(std::vector<std::string> const& /* args */) {return true;};
+ /** Compute the list of link libraries and directories for the given
+ target and configuration. */
+ void ComputeLinkInformation(cmTarget& target, const char* config,
+ std::vector<cmStdString>& outLibs,
+ std::vector<cmStdString>& outDirs,
+ std::vector<cmStdString>* fullPathLibs=0);
+
protected:
/** Construct a script from the given list of command lines. */
std::string ConstructScript(const cmCustomCommandLines& commandLines,
@@ -159,6 +176,13 @@ protected:
///! put all the libraries for a target on into the given stream
virtual void OutputLinkLibraries(std::ostream&, const char* name,cmTarget &);
+ /** Compute the string to use to refer to a target in an install
+ file. */
+ std::string GetInstallReference(cmTarget& target, const char* config,
+ std::vector<std::string> const& configs,
+ bool implib = false);
+ void PrepareInstallReference(std::ostream& fout, cmTarget& target,
+ std::vector<std::string> const& configs);
/** Get the include flags for the current makefile and language. */
void GetIncludeDirectories(std::vector<std::string>& dirs);
@@ -173,7 +197,6 @@ protected:
const char* object =0,
const char* flags = 0,
const char* objectsquoted = 0,
- const char* targetBase = 0,
const char* targetSOName = 0,
const char* linkFlags = 0);
// Expand rule variables in a single string
@@ -186,7 +209,6 @@ protected:
const char* object,
const char* flags,
const char* objectsquoted,
- const char* targetBase,
const char* targetSOName,
const char* linkFlags);
diff --git a/Source/cmLocalUnixMakefileGenerator3.cxx b/Source/cmLocalUnixMakefileGenerator3.cxx
index b8d080a..e4d6b69 100644
--- a/Source/cmLocalUnixMakefileGenerator3.cxx
+++ b/Source/cmLocalUnixMakefileGenerator3.cxx
@@ -111,6 +111,18 @@ void cmLocalUnixMakefileGenerator3::ConfigureOutputPaths()
m_ExecutableOutputPath = exeOut;
this->FormatOutputPath(m_ExecutableOutputPath, "EXECUTABLE");
}
+
+ // Store the configuration name that will be generated.
+ if(const char* config = m_Makefile->GetDefinition("CMAKE_BUILD_TYPE"))
+ {
+ // Use the build type given by the user.
+ m_ConfigurationName = config;
+ }
+ else
+ {
+ // No configuration type given.
+ m_ConfigurationName = "";
+ }
}
//----------------------------------------------------------------------------
@@ -1358,7 +1370,8 @@ cmLocalUnixMakefileGenerator3
// Get the name of the executable to generate.
std::string targetName;
std::string targetNameReal;
- target.GetExecutableNames(targetName, targetNameReal);
+ target.GetExecutableNames(targetName, targetNameReal,
+ m_ConfigurationName.c_str());
// Construct the full path version of the names.
std::string outpath = m_ExecutableOutputPath;
@@ -1460,7 +1473,8 @@ cmLocalUnixMakefileGenerator3
{
std::string cleanName;
std::string cleanRealName;
- target.GetExecutableCleanNames(cleanName, cleanRealName);
+ target.GetExecutableCleanNames(cleanName, cleanRealName,
+ m_ConfigurationName.c_str());
std::string cleanFullName = outpath + cleanName;
std::string cleanFullRealName = outpath + cleanRealName;
exeCleanFiles.push_back
@@ -1540,7 +1554,6 @@ cmLocalUnixMakefileGenerator3
flags.c_str(),
0,
0,
- 0,
linkFlags.c_str());
}
@@ -1738,9 +1751,8 @@ cmLocalUnixMakefileGenerator3
std::string targetName;
std::string targetNameSO;
std::string targetNameReal;
- std::string targetNameBase;
- target.GetLibraryNames(targetName, targetNameSO,
- targetNameReal, targetNameBase);
+ target.GetLibraryNames(targetName, targetNameSO, targetNameReal,
+ m_ConfigurationName.c_str());
// Construct the full path version of the names.
std::string outpath = m_LibraryOutputPath;
@@ -1752,7 +1764,6 @@ cmLocalUnixMakefileGenerator3
std::string targetFullPath = outpath + targetName;
std::string targetFullPathSO = outpath + targetNameSO;
std::string targetFullPathReal = outpath + targetNameReal;
- std::string targetFullPathBase = outpath + targetNameBase;
// Construct the output path version of the names for use in command
// arguments.
@@ -1762,8 +1773,6 @@ cmLocalUnixMakefileGenerator3
this->Convert(targetFullPathSO.c_str(),START_OUTPUT,MAKEFILE);
std::string targetOutPathReal =
this->Convert(targetFullPathReal.c_str(),START_OUTPUT,MAKEFILE);
- std::string targetOutPathBase =
- this->Convert(targetFullPathBase.c_str(),START_OUTPUT,MAKEFILE);
// Add the link message.
std::string buildEcho = "Linking ";
@@ -1793,7 +1802,8 @@ cmLocalUnixMakefileGenerator3
target.GetLibraryCleanNames(cleanStaticName,
cleanSharedName,
cleanSharedSOName,
- cleanSharedRealName);
+ cleanSharedRealName,
+ m_ConfigurationName.c_str());
std::string cleanFullStaticName = outpath + cleanStaticName;
std::string cleanFullSharedName = outpath + cleanSharedName;
std::string cleanFullSharedSOName = outpath + cleanSharedSOName;
@@ -1885,7 +1895,6 @@ cmLocalUnixMakefileGenerator3
targetOutPathReal.c_str(),
linklibs.str().c_str(),
0, 0, 0, buildObjs.c_str(),
- targetOutPathBase.c_str(),
targetNameSO.c_str(),
linkFlags.c_str());
}
@@ -2289,67 +2298,38 @@ cmLocalUnixMakefileGenerator3
//----------------------------------------------------------------------------
void
cmLocalUnixMakefileGenerator3
-::AppendAnyDepend(std::vector<std::string>& depends, const char* name,
- bool assume_unknown_is_file)
+::AppendAnyDepend(std::vector<std::string>& depends, const char* name)
{
// There are a few cases for the name of the target:
// - CMake target.
// - Full path to a file: depend on it.
- // - Other format (like -lm): do nothing unless assume_unknown_is_file is true.
-
- // Look for a CMake target in the current makefile.
- cmTarget* target = m_Makefile->FindTarget(name);
-
- // If no target was found in the current makefile search globally.
- bool local = target?true:false;
- if(!local)
- {
- target = m_GlobalGenerator->FindTarget(0, name);
- }
+ // - Other format (like -lm): no file on which to depend, do nothing.
- // If a target was found then depend on it.
- if(target)
+ // Lookup the real name of the dependency in case it is a CMake target.
+ bool local;
+ std::string dep = this->GetRealDependency(name,
+ m_ConfigurationName.c_str(),
+ &local);
+ if(dep == name)
{
- switch (target->GetType())
+ if(local)
{
- case cmTarget::EXECUTABLE:
- case cmTarget::STATIC_LIBRARY:
- case cmTarget::SHARED_LIBRARY:
- case cmTarget::MODULE_LIBRARY:
- {
- // Get the location of the target's output file and depend on it.
- if(const char* location = target->GetProperty("LOCATION"))
- {
- depends.push_back(location);
- }
- }
- break;
- case cmTarget::UTILITY:
- {
- if(local)
- {
- // This is a utility target in the current makefile. Just
- // depend on it directly.
- depends.push_back(name);
- }
- }
- break;
- case cmTarget::INSTALL_FILES:
- case cmTarget::INSTALL_PROGRAMS:
- // Do not depend on install targets.
- break;
+ // The dependency is on a CMake utility target in the current
+ // makefile. Just depend on it directly.
+ depends.push_back(name);
+ }
+ else if(cmSystemTools::FileIsFullPath(name))
+ {
+ // This is a path to a file. Just trust the listfile author
+ // that it will be present or there is a rule to build it.
+ depends.push_back(cmSystemTools::CollapseFullPath(name));
}
}
- else if(cmSystemTools::FileIsFullPath(name))
- {
- // This is a path to a file. Just trust the listfile author that
- // it will be present or there is a rule to build it.
- depends.push_back(cmSystemTools::CollapseFullPath(name));
- }
- else if(assume_unknown_is_file)
+ else
{
- // Just assume this is a file or make target that will be present.
- depends.push_back(name);
+ // The dependency is on a CMake target and has been transformed to
+ // the target's location on disk.
+ depends.push_back(dep);
}
}
diff --git a/Source/cmLocalUnixMakefileGenerator3.h b/Source/cmLocalUnixMakefileGenerator3.h
index 5dfd86e..cf383c3 100644
--- a/Source/cmLocalUnixMakefileGenerator3.h
+++ b/Source/cmLocalUnixMakefileGenerator3.h
@@ -327,8 +327,7 @@ protected:
const char* GetSourceFileLanguage(const cmSourceFile& source);
std::string ConvertToQuotedOutputPath(const char* p);
- void AppendAnyDepend(std::vector<std::string>& depends, const char* name,
- bool assume_unknown_is_file=false);
+ void AppendAnyDepend(std::vector<std::string>& depends, const char* name);
void AppendRuleDepend(std::vector<std::string>& depends,
const char* ruleFileName);
void AppendCustomDepends(std::vector<std::string>& depends,
@@ -363,6 +362,7 @@ private:
std::string m_MakeSilentFlag;
std::string m_ExecutableOutputPath;
std::string m_LibraryOutputPath;
+ std::string m_ConfigurationName;
bool m_DefineWindowsNULL;
bool m_UnixCD;
bool m_PassMakeflags;
diff --git a/Source/cmLocalVisualStudio6Generator.cxx b/Source/cmLocalVisualStudio6Generator.cxx
index 1e41a33..054a782 100644
--- a/Source/cmLocalVisualStudio6Generator.cxx
+++ b/Source/cmLocalVisualStudio6Generator.cxx
@@ -553,40 +553,10 @@ void cmLocalVisualStudio6Generator::WriteCustomRule(std::ostream& fout,
for(std::vector<std::string>::const_iterator d = depends.begin();
d != depends.end(); ++d)
{
- std::string dep = cmSystemTools::GetFilenameName(*d);
- if (cmSystemTools::GetFilenameLastExtension(dep) == ".exe")
- {
- dep = cmSystemTools::GetFilenameWithoutLastExtension(dep);
- }
- std::string libPath = dep + "_CMAKE_PATH";
- const char* cacheValue = m_Makefile->GetDefinition(libPath.c_str());
- if (cacheValue && *cacheValue)
- {
- std::string exePath = "";
- if (m_Makefile->GetDefinition("EXECUTABLE_OUTPUT_PATH"))
- {
- exePath = m_Makefile->GetDefinition("EXECUTABLE_OUTPUT_PATH");
- }
- if(exePath.size())
- {
- libPath = exePath;
- }
- else
- {
- libPath = cacheValue;
- }
- libPath += "/";
- libPath += "$(INTDIR)/";
- libPath += dep;
- libPath += ".exe";
- fout << "\\\n\t" <<
- this->ConvertToOptionallyRelativeOutputPath(libPath.c_str());
- }
- else
- {
- fout << "\\\n\t" <<
- this->ConvertToOptionallyRelativeOutputPath(d->c_str());
- }
+ // Lookup the real name of the dependency in case it is a CMake target.
+ std::string dep = this->GetRealDependency(d->c_str(), i->c_str());
+ fout << "\\\n\t" <<
+ this->ConvertToOptionallyRelativeOutputPath(dep.c_str());
}
fout << "\n";
@@ -950,7 +920,6 @@ void cmLocalVisualStudio6Generator
libMultiLineOptionsForDebug += " \n";
}
}
-
// find link libraries
const cmTarget::LinkLibraries& libs = target.GetLinkLibraries();
cmTarget::LinkLibraries::const_iterator j;
@@ -958,35 +927,41 @@ void cmLocalVisualStudio6Generator
{
// add libraries to executables and dlls (but never include
// a library in a library, bad recursion)
+ // NEVER LINK STATIC LIBRARIES TO OTHER STATIC LIBRARIES
if ((target.GetType() != cmTarget::SHARED_LIBRARY
&& target.GetType() != cmTarget::STATIC_LIBRARY
&& target.GetType() != cmTarget::MODULE_LIBRARY) ||
(target.GetType()==cmTarget::SHARED_LIBRARY && libName != j->first) ||
(target.GetType()==cmTarget::MODULE_LIBRARY && libName != j->first))
{
- std::string lib = j->first;
- std::string libDebug = j->first;
- std::string libPath = j->first + "_CMAKE_PATH";
- const char* cacheValue
- = m_GlobalGenerator->GetCMakeInstance()->GetCacheDefinition(
- libPath.c_str());
- if ( cacheValue && *cacheValue && m_Makefile->GetDefinition("CMAKE_DEBUG_POSTFIX") )
- {
- libDebug += m_Makefile->GetDefinition("CMAKE_DEBUG_POSTFIX");
- }
- if(j->first.find(".lib") == std::string::npos)
+ // Compute the proper name to use to link this library.
+ std::string lib;
+ std::string libDebug;
+ cmTarget* tgt = m_GlobalGenerator->FindTarget(0, j->first.c_str());
+ if(tgt)
{
+ lib = cmSystemTools::GetFilenameWithoutExtension(tgt->GetFullName().c_str());
+ libDebug = cmSystemTools::GetFilenameWithoutExtension(tgt->GetFullName("Debug").c_str());
lib += ".lib";
libDebug += ".lib";
}
+ else
+ {
+ lib = j->first.c_str();
+ libDebug = j->first.c_str();
+ if(j->first.find(".lib") == std::string::npos)
+ {
+ lib += ".lib";
+ libDebug += ".lib";
+ }
+ }
lib = this->ConvertToOptionallyRelativeOutputPath(lib.c_str());
libDebug = this->ConvertToOptionallyRelativeOutputPath(libDebug.c_str());
-
+
if (j->second == cmTarget::GENERAL)
{
libOptions += " ";
libOptions += lib;
-
libMultiLineOptions += "# ADD LINK32 ";
libMultiLineOptions += lib;
libMultiLineOptions += "\n";
@@ -1016,6 +991,12 @@ void cmLocalVisualStudio6Generator
}
std::string outputName = "(OUTPUT_NAME is for executables only)";
std::string extraLinkOptions;
+ // TODO: Fix construction of library/executable name through
+ // cmTarget. OUTPUT_LIBNAMEDEBUG_POSTFIX should be replaced by the
+ // library's debug configuration name. OUTPUT_LIBNAME should be
+ // replaced by the non-debug configuration name. This generator
+ // should just be re-written to not use template files and just
+ // generate the code. Setting up these substitutions is a pain.
if(target.GetType() == cmTarget::EXECUTABLE)
{
extraLinkOptions =
diff --git a/Source/cmLocalVisualStudio7Generator.cxx b/Source/cmLocalVisualStudio7Generator.cxx
index bb969aa..8578588 100644
--- a/Source/cmLocalVisualStudio7Generator.cxx
+++ b/Source/cmLocalVisualStudio7Generator.cxx
@@ -92,6 +92,10 @@ void cmLocalVisualStudio7Generator::OutputVCProjFile()
// clear project names
m_CreatedProjectNames.clear();
+#if 1
+ // TODO: This block should be moved to a central location for all
+ // generators. It is duplicated in every generator.
+
// Call TraceVSDependencies on all targets
cmTargets &tgts = m_Makefile->GetTargets();
for(cmTargets::iterator l = tgts.begin();
@@ -168,6 +172,7 @@ void cmLocalVisualStudio7Generator::OutputVCProjFile()
}
}
}
+#endif
for(cmTargets::iterator l = tgts.begin();
l != tgts.end(); l++)
{
@@ -446,12 +451,6 @@ void cmLocalVisualStudio7Generator::WriteConfiguration(std::ostream& fout,
std::string programDatabase;
const char* pre = "WIN32,_DEBUG,_WINDOWS";
- std::string debugPostfix = "";
- bool debug = !strcmp(configName,"Debug");
- if (debug && m_Makefile->GetDefinition("CMAKE_DEBUG_POSTFIX"))
- {
- debugPostfix = m_Makefile->GetDefinition("CMAKE_DEBUG_POSTFIX");
- }
// fill the flagMap for Debug, Release, MinSizeRel, and RelWithDebInfo
// also set the flags, and pre-defined macros
if(strcmp(configName, "Debug") == 0)
@@ -462,7 +461,7 @@ void cmLocalVisualStudio7Generator::WriteConfiguration(std::ostream& fout,
flags += flagsDebug;
pre = "WIN32,_DEBUG,_WINDOWS";
std::string libpath = m_LibraryOutputPath +
- "$(OutDir)/" + libName + debugPostfix + ".pdb";
+ "$(OutDir)/" + libName + ".pdb";
programDatabase = "\t\t\t\tProgramDatabaseFileName=\"";
programDatabase += libpath;
programDatabase += "\"";
@@ -492,7 +491,7 @@ void cmLocalVisualStudio7Generator::WriteConfiguration(std::ostream& fout,
pre = "WIN32,_WINDOWS";
flags += flagsDebugRel;
std::string libpath = m_LibraryOutputPath +
- "$(OutDir)/" + libName + debugPostfix + ".pdb";
+ "$(OutDir)/" + libName + ".pdb";
programDatabase = "\t\t\t\tProgramDatabaseFileName=\"";
programDatabase += libpath;
programDatabase += "\"";
@@ -665,15 +664,9 @@ void cmLocalVisualStudio7Generator::OutputBuildTool(std::ostream& fout,
const char* configName,
const char *libName,
cmTarget &target)
-{
+{
+ std::string targetFullName = target.GetFullName(configName);
std::string temp;
- std::string debugPostfix = "";
- bool debug = !strcmp(configName,"Debug");
- if (debug && m_Makefile->GetDefinition("CMAKE_DEBUG_POSTFIX"))
- {
- debugPostfix = m_Makefile->GetDefinition("CMAKE_DEBUG_POSTFIX");
- }
-
std::string extraLinkOptions;
if(target.GetType() == cmTarget::EXECUTABLE)
{
@@ -704,8 +697,8 @@ void cmLocalVisualStudio7Generator::OutputBuildTool(std::ostream& fout,
{
case cmTarget::STATIC_LIBRARY:
{
- std::string libpath = m_LibraryOutputPath +
- "$(OutDir)/" + libName + debugPostfix + ".lib";
+ std::string libpath = m_LibraryOutputPath +
+ "$(OutDir)/" + targetFullName;
fout << "\t\t\t<Tool\n"
<< "\t\t\t\tName=\"VCLibrarianTool\"\n";
if(const char* libflags = target.GetProperty("STATIC_LIBRARY_FLAGS"))
@@ -719,6 +712,11 @@ void cmLocalVisualStudio7Generator::OutputBuildTool(std::ostream& fout,
case cmTarget::SHARED_LIBRARY:
case cmTarget::MODULE_LIBRARY:
{
+ // Compute the link library and directory information.
+ std::vector<cmStdString> linkLibs;
+ std::vector<cmStdString> linkDirs;
+ this->ComputeLinkInformation(target, configName, linkLibs, linkDirs);
+
fout << "\t\t\t<Tool\n"
<< "\t\t\t\tName=\"VCLinkerTool\"\n"
<< "\t\t\t\tAdditionalOptions=\"/MACHINE:I386";
@@ -729,14 +727,12 @@ void cmLocalVisualStudio7Generator::OutputBuildTool(std::ostream& fout,
}
fout << "\"\n"
<< "\t\t\t\tAdditionalDependencies=\" odbc32.lib odbccp32.lib ";
- this->OutputLibraries(fout, configName, libName, target);
+ this->OutputLibraries(fout, linkLibs);
fout << "\"\n";
temp = m_LibraryOutputPath;
temp += configName;
temp += "/";
- temp += libName;
- temp += debugPostfix;
- temp += ".dll";
+ temp += targetFullName;
fout << "\t\t\t\tOutputFile=\""
<< this->ConvertToXMLOutputPathSingle(temp.c_str()) << "\"\n";
for(std::map<cmStdString, cmStdString>::iterator i = flagMap.begin();
@@ -745,13 +741,12 @@ void cmLocalVisualStudio7Generator::OutputBuildTool(std::ostream& fout,
fout << "\t\t\t\t" << i->first << "=\"" << i->second << "\"\n";
}
fout << "\t\t\t\tAdditionalLibraryDirectories=\"";
- this->OutputLibraryDirectories(fout, configName, libName, target);
+ this->OutputLibraryDirectories(fout, linkDirs);
fout << "\"\n";
this->OutputModuleDefinitionFile(fout, target);
temp = m_LibraryOutputPath;
temp += "$(OutDir)/";
temp += libName;
- temp += debugPostfix;
temp += ".pdb";
fout << "\t\t\t\tProgramDatabaseFile=\"" <<
this->ConvertToXMLOutputPathSingle(temp.c_str()) << "\"\n";
@@ -778,15 +773,18 @@ void cmLocalVisualStudio7Generator::OutputBuildTool(std::ostream& fout,
temp = m_LibraryOutputPath;
temp += configName;
temp += "/";
- temp += libName;
- temp += debugPostfix;
+ temp += cmSystemTools::GetFilenameWithoutLastExtension(targetFullName.c_str());
temp += ".lib";
fout << "\t\t\t\tImportLibrary=\"" << this->ConvertToXMLOutputPathSingle(temp.c_str()) << "\"/>\n";
}
break;
case cmTarget::EXECUTABLE:
{
-
+ // Compute the link library and directory information.
+ std::vector<cmStdString> linkLibs;
+ std::vector<cmStdString> linkDirs;
+ this->ComputeLinkInformation(target, configName, linkLibs, linkDirs);
+
fout << "\t\t\t<Tool\n"
<< "\t\t\t\tName=\"VCLinkerTool\"\n"
<< "\t\t\t\tAdditionalOptions=\"/MACHINE:I386";
@@ -799,23 +797,12 @@ void cmLocalVisualStudio7Generator::OutputBuildTool(std::ostream& fout,
<< "\t\t\t\tAdditionalDependencies=\""
<< m_Makefile->GetRequiredDefinition("CMAKE_STANDARD_LIBRARIES")
<< " ";
- this->OutputLibraries(fout, configName, libName, target);
+ this->OutputLibraries(fout, linkLibs);
fout << "\"\n";
temp = m_ExecutableOutputPath;
temp += configName;
temp += "/";
-
- // do we have a different executable name?
- if (target.GetProperty("OUTPUT_NAME"))
- {
- temp += target.GetProperty("OUTPUT_NAME");
- }
- else
- {
- temp += libName;
- }
-
- temp += ".exe";
+ temp += targetFullName;
fout << "\t\t\t\tOutputFile=\"" << this->ConvertToXMLOutputPathSingle(temp.c_str()) << "\"\n";
for(std::map<cmStdString, cmStdString>::iterator i = flagMap.begin();
i != flagMap.end(); ++i)
@@ -823,7 +810,7 @@ void cmLocalVisualStudio7Generator::OutputBuildTool(std::ostream& fout,
fout << "\t\t\t\t" << i->first << "=\"" << i->second << "\"\n";
}
fout << "\t\t\t\tAdditionalLibraryDirectories=\"";
- this->OutputLibraryDirectories(fout, configName, libName, target);
+ this->OutputLibraryDirectories(fout, linkDirs);
fout << "\"\n";
fout << "\t\t\t\tProgramDatabaseFile=\"" << m_LibraryOutputPath
<< "$(OutDir)\\" << libName << ".pdb\"\n";
@@ -881,108 +868,45 @@ void cmLocalVisualStudio7Generator::OutputModuleDefinitionFile(std::ostream& fou
}
-void cmLocalVisualStudio7Generator::OutputLibraryDirectories(std::ostream& fout,
- const char*,
- const char*,
- cmTarget &tgt)
-{
- bool hasone = false;
- if(m_LibraryOutputPath.size())
- {
- hasone = true;
- std::string temp = m_LibraryOutputPath;
- temp += "$(OutDir)";
-
- fout << this->ConvertToXMLOutputPath(temp.c_str()) << "," <<
- this->ConvertToXMLOutputPath(m_LibraryOutputPath.c_str());
- }
- if(m_ExecutableOutputPath.size() &&
- (m_LibraryOutputPath != m_ExecutableOutputPath))
+//----------------------------------------------------------------------------
+void
+cmLocalVisualStudio7Generator
+::OutputLibraries(std::ostream& fout,
+ std::vector<cmStdString> const& libs)
+{
+ for(std::vector<cmStdString>::const_iterator l = libs.begin();
+ l != libs.end(); ++l)
{
- if (hasone)
- {
- fout << ",";
- }
- hasone = true;
- std::string temp = m_ExecutableOutputPath;
- temp += "$(OutDir)";
- fout << this->ConvertToXMLOutputPath(temp.c_str()) << "," <<
- this->ConvertToXMLOutputPath(m_ExecutableOutputPath.c_str());
- }
-
- std::set<std::string> pathEmitted;
- std::vector<std::string>::const_iterator i;
- const std::vector<std::string>& libdirs = tgt.GetLinkDirectories();
- for(i = libdirs.begin(); i != libdirs.end(); ++i)
- {
- std::string lpath = *i;
- if(lpath[lpath.size()-1] != '/')
- {
- lpath += "/";
- }
- if(pathEmitted.insert(lpath).second)
- {
- if(hasone)
- {
- fout << ",";
- }
- std::string lpathi = lpath + "$(OutDir)";
- fout << this->ConvertToXMLOutputPath(lpathi.c_str()) << "," <<
- this->ConvertToXMLOutputPath(lpath.c_str());
- hasone = true;
- }
+ fout << this->ConvertToXMLOutputPath(l->c_str()) << " ";
}
}
-void cmLocalVisualStudio7Generator::OutputLibraries(std::ostream& fout,
- const char* configName,
- const char* libName,
- cmTarget &target)
+//----------------------------------------------------------------------------
+void
+cmLocalVisualStudio7Generator
+::OutputLibraryDirectories(std::ostream& fout,
+ std::vector<cmStdString> const& dirs)
{
- const cmTarget::LinkLibraries& libs = target.GetLinkLibraries();
- cmTarget::LinkLibraries::const_iterator j;
- for(j = libs.begin(); j != libs.end(); ++j)
- {
- if(j->first != libName)
+ const char* comma = "";
+ for(std::vector<cmStdString>::const_iterator d = dirs.begin();
+ d != dirs.end(); ++d)
+ {
+ std::string dir = *d;
+ if(!dir.empty())
{
- std::string lib = j->first;
- std::string debugPostfix = "";
- // if this is a library we are building then watch for a debugPostfix
- if (!strcmp(configName,"Debug"))
- {
- std::string libPath = j->first + "_CMAKE_PATH";
- const char* cacheValue
- = m_GlobalGenerator->GetCMakeInstance()->GetCacheDefinition(libPath.c_str());
- if(cacheValue && *cacheValue && m_Makefile->GetDefinition("CMAKE_DEBUG_POSTFIX"))
- {
- debugPostfix = m_Makefile->GetDefinition("CMAKE_DEBUG_POSTFIX");
- }
- }
- // chop off the last 4 chars of the library string
-
- std::string lowerCaseLibExt = j->first;
- if(lowerCaseLibExt.size() > 4)
- {
- lowerCaseLibExt = j->first.substr(j->first.size()-4, 4);
- }
- // lower case the extension
- lowerCaseLibExt = cmSystemTools::LowerCase(lowerCaseLibExt);
- // now check to see if it was a .lib, if not then add a .lib
- if(lowerCaseLibExt != ".lib")
+ if(dir[dir.size()-1] != '/')
{
- lib += debugPostfix + ".lib";
- }
- lib = this->ConvertToXMLOutputPath(lib.c_str());
- if (j->second == cmTarget::GENERAL
- || (j->second == cmTarget::DEBUG && strcmp(configName, "Debug") == 0)
- || (j->second == cmTarget::OPTIMIZED && strcmp(configName, "Debug") != 0))
- {
- fout << lib << " ";
+ dir += "/";
}
+ dir += "$(OutDir)";
+ fout << comma << this->ConvertToXMLOutputPath(dir.c_str())
+ << "," << this->ConvertToXMLOutputPath(d->c_str());
+ comma = ",";
}
}
}
+//----------------------------------------------------------------------------
void cmLocalVisualStudio7Generator::OutputDefineFlags(const char* flags,
std::ostream& fout)
{
@@ -1250,42 +1174,11 @@ WriteCustomRule(std::ostream& fout,
std::string temp;
for(std::vector<std::string>::const_iterator d = depends.begin();
d != depends.end(); ++d)
- {
- std::string dep = cmSystemTools::GetFilenameName(*d);
- if (cmSystemTools::GetFilenameLastExtension(dep) == ".exe")
- {
- dep = cmSystemTools::GetFilenameWithoutLastExtension(dep);
- }
- // check to see if the dependency is another target built by cmake
- std::string libPath = dep + "_CMAKE_PATH";
- const char* cacheValue = m_Makefile->GetDefinition(libPath.c_str());
- if (cacheValue && *cacheValue)
- {
- std::string exePath = "";
- if (m_Makefile->GetDefinition("EXECUTABLE_OUTPUT_PATH"))
- {
- exePath = m_Makefile->GetDefinition("EXECUTABLE_OUTPUT_PATH");
- }
- if(exePath.size())
- {
- libPath = exePath;
- }
- else
- {
- libPath = cacheValue;
- }
- libPath += "/";
- libPath += "$(OutDir)/";
- libPath += dep;
- libPath += ".exe";
- fout << this->ConvertToXMLOutputPath(libPath.c_str())
- << ";";
- }
- else
- {
- fout << this->ConvertToXMLOutputPath(d->c_str())
- << ";";
- }
+ {
+ // Lookup the real name of the dependency in case it is a CMake target.
+ std::string dep = this->GetRealDependency(d->c_str(), i->c_str());
+ fout << this->ConvertToXMLOutputPath(dep.c_str())
+ << ";";
}
fout << "\"\n";
fout << "\t\t\t\t\tOutputs=\"";
diff --git a/Source/cmLocalVisualStudio7Generator.h b/Source/cmLocalVisualStudio7Generator.h
index 1e20619..36dafa6 100644
--- a/Source/cmLocalVisualStudio7Generator.h
+++ b/Source/cmLocalVisualStudio7Generator.h
@@ -90,12 +90,9 @@ private:
void OutputBuildTool(std::ostream& fout, const char* configName,
const char* libname, cmTarget& t);
void OutputLibraries(std::ostream& fout,
- const char* configName,
- const char* libName,
- cmTarget &target);
+ std::vector<cmStdString> const& libs);
void OutputLibraryDirectories(std::ostream& fout,
- const char* configName,
- const char* libName, cmTarget &target);
+ std::vector<cmStdString> const& dirs);
void OutputModuleDefinitionFile(std::ostream& fout, cmTarget &target);
void WriteProjectStart(std::ostream& fout, const char *libName,
cmTarget &tgt, std::vector<cmSourceGroup> &sgs);
diff --git a/Source/cmMakefile.cxx b/Source/cmMakefile.cxx
index dc4c2ea..58dbab1 100644
--- a/Source/cmMakefile.cxx
+++ b/Source/cmMakefile.cxx
@@ -457,7 +457,6 @@ void cmMakefile::ConfigureFinalPass()
{
cmSystemTools::Error("You have requested backwards compatibility with CMake version 1.2 or earlier. This version of CMake only supports backwards compatibility with CMake 1.4 or later. For compatibility with 1.2 or earlier please use CMake 2.0");
}
-
for (cmTargets::iterator l = m_Targets.begin();
l != m_Targets.end(); l++)
{
@@ -1090,14 +1089,6 @@ void cmMakefile::AddLibrary(const char* lname, int shared,
target.SetMakefile(this);
this->AddGlobalLinkInformation(lname, target);
m_Targets.insert(cmTargets::value_type(lname,target));
-
- // Add an entry into the cache
- std::string libPath = lname;
- libPath += "_CMAKE_PATH";
- this->GetCacheManager()->
- AddCacheEntry(libPath.c_str(),
- this->GetCurrentOutputDirectory(),
- "Path to a library", cmCacheManager::INTERNAL);
}
cmTarget* cmMakefile::AddExecutable(const char *exeName,
@@ -1111,14 +1102,6 @@ cmTarget* cmMakefile::AddExecutable(const char *exeName,
this->AddGlobalLinkInformation(exeName, target);
cmTargets::iterator it =
m_Targets.insert(cmTargets::value_type(exeName,target)).first;
-
- // Add an entry into the cache
- std::string exePath = exeName;
- exePath += "_CMAKE_PATH";
- this->GetCacheManager()->
- AddCacheEntry(exePath.c_str(),
- this->GetCurrentOutputDirectory(),
- "Path to an executable", cmCacheManager::INTERNAL);
return &it->second;
}
diff --git a/Source/cmOrderLinkDirectories.cxx b/Source/cmOrderLinkDirectories.cxx
index bfcd073..b3362ef 100644
--- a/Source/cmOrderLinkDirectories.cxx
+++ b/Source/cmOrderLinkDirectories.cxx
@@ -221,50 +221,29 @@ void cmOrderLinkDirectories::OrderPaths(std::vector<cmStdString>&
}
//-------------------------------------------------------------------
-void cmOrderLinkDirectories::SetLinkInformation(cmTarget& target,
- cmTarget::LinkLibraryType
- linktype,
- const char* targetLibrary)
+void cmOrderLinkDirectories::SetLinkInformation(
+ const char* targetName,
+ const std::vector<std::string>& linkLibraries,
+ const std::vector<std::string>& linkDirectories
+ )
{
- m_TargetName = target.GetName();
- // collect the search paths from the target into paths set
- const std::vector<std::string>& searchPaths = target.GetLinkDirectories();
+ // Save the target name.
+ m_TargetName = targetName;
+
+ // Merge the link directory search path given into our path set.
std::vector<cmStdString> empty;
- for(std::vector<std::string>::const_iterator p = searchPaths.begin();
- p != searchPaths.end(); ++p)
+ for(std::vector<std::string>::const_iterator p = linkDirectories.begin();
+ p != linkDirectories.end(); ++p)
{
m_DirectoryToAfterList[*p] = empty;
m_LinkPathSet.insert(*p);
}
- // collect the link items from the target and put it into libs
- const cmTarget::LinkLibraries& tlibs = target.GetLinkLibraries();
- std::vector<cmStdString> libs;
- for(cmTarget::LinkLibraries::const_iterator lib = tlibs.begin();
- lib != tlibs.end(); ++lib)
+
+ // Append the link library list into our raw list.
+ for(std::vector<std::string>::const_iterator l = linkLibraries.begin();
+ l != linkLibraries.end(); ++l)
{
- // skip zero size library entries, this may happen
- // if a variable expands to nothing.
- if (lib->first.size() == 0)
- {
- continue;
- }
- // Don't link the library against itself!
- if(targetLibrary && (lib->first == targetLibrary) &&
- target.GetType() != cmTarget::EXECUTABLE)
- {
- continue;
- }
- // use the correct lib for the current configuration
- if (lib->second == cmTarget::DEBUG && linktype != cmTarget::DEBUG)
- {
- continue;
- }
- if (lib->second == cmTarget::OPTIMIZED &&
- (linktype != cmTarget::OPTIMIZED && linktype != cmTarget::GENERAL))
- {
- continue;
- }
- m_RawLinkItems.push_back(lib->first);
+ m_RawLinkItems.push_back(*l);
}
}
diff --git a/Source/cmOrderLinkDirectories.h b/Source/cmOrderLinkDirectories.h
index 49830b5..88f6e16 100644
--- a/Source/cmOrderLinkDirectories.h
+++ b/Source/cmOrderLinkDirectories.h
@@ -49,8 +49,9 @@ class cmOrderLinkDirectories
public:
cmOrderLinkDirectories();
///! set link information from the target
- void SetLinkInformation(cmTarget&, cmTarget::LinkLibraryType,
- const char* targetLibrary);
+ void SetLinkInformation(const char* targetName,
+ const std::vector<std::string>& linkLibraries,
+ const std::vector<std::string>& linkDirectories);
///! Compute the best order for -L paths from GetLinkLibraries
bool DetermineLibraryPathOrder();
///! Get the results from DetermineLibraryPathOrder
@@ -65,12 +66,18 @@ public:
// CMAKE_LINK_LIBRARY_SUFFIX
void AddLinkExtension(const char* e)
{
+ if(e && *e)
+ {
m_LinkExtensions.push_back(e);
+ }
}
// should be set from CMAKE_STATIC_LIBRARY_PREFIX
void SetLinkPrefix(const char* s)
{
+ if(s)
+ {
m_LinkPrefix = s;
+ }
}
// Return any warnings if the exist
std::string GetWarnings();
diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx
index 3480794..c5471b8 100644
--- a/Source/cmTarget.cxx
+++ b/Source/cmTarget.cxx
@@ -24,6 +24,13 @@
#include <queue>
#include <stdlib.h> // required for atof
+//----------------------------------------------------------------------------
+cmTarget::cmTarget()
+{
+ m_Makefile = 0;
+ m_LinkLibrariesAnalyzed = false;
+ m_LinkDirectoriesComputed = false;
+}
void cmTarget::SetType(TargetType type, const char* name)
{
@@ -171,9 +178,7 @@ void cmTarget::TraceVSDependencies(std::string projFile,
dep = cmSystemTools::GetFilenameWithoutLastExtension(dep);
}
// watch for target dependencies,
- std::string libPath = dep + "_CMAKE_PATH";
- const char* cacheValue = makefile->GetDefinition(libPath.c_str());
- if (cacheValue && *cacheValue)
+ if(m_Makefile->GetLocalGenerator()->GetGlobalGenerator()->FindTarget(0, dep.c_str()))
{
// add the depend as a utility on the target
this->AddUtility(dep.c_str());
@@ -271,14 +276,71 @@ void cmTarget::MergeLinkLibraries( cmMakefile& mf,
m_PrevLinkedLibraries = libs;
}
+//----------------------------------------------------------------------------
void cmTarget::AddLinkDirectory(const char* d)
{
// Make sure we don't add unnecessary search directories.
- if( std::find( m_LinkDirectories.begin(), m_LinkDirectories.end(), d )
- == m_LinkDirectories.end() )
- m_LinkDirectories.push_back( d );
+ if(std::find(m_ExplicitLinkDirectories.begin(),
+ m_ExplicitLinkDirectories.end(), d)
+ == m_ExplicitLinkDirectories.end() )
+ {
+ m_ExplicitLinkDirectories.push_back( d );
+ m_LinkDirectoriesComputed = false;
+ }
}
+//----------------------------------------------------------------------------
+const std::vector<std::string>& cmTarget::GetLinkDirectories()
+{
+ // Make sure all library dependencies have been analyzed.
+ if(!m_LinkLibrariesAnalyzed && !m_LinkLibraries.empty())
+ {
+ cmSystemTools::Error(
+ "cmTarget::GetLinkDirectories called before cmTarget::AnalyzeLibDependencies on target ",
+ m_Name.c_str());
+ }
+
+ // Make sure the complete set of link directories has been computed.
+ if(!m_LinkDirectoriesComputed)
+ {
+ // Compute the full set of link directories including the
+ // locations of targets that have been linked in. Start with the
+ // link directories given explicitly.
+ m_LinkDirectories = m_ExplicitLinkDirectories;
+ for(LinkLibraries::iterator ll = m_LinkLibraries.begin();
+ ll != m_LinkLibraries.end(); ++ll)
+ {
+ // If this library is a CMake target then add its location as a
+ // link directory.
+ std::string lib = ll->first;
+ cmTarget* tgt = 0;
+ if(m_Makefile && m_Makefile->GetLocalGenerator() &&
+ m_Makefile->GetLocalGenerator()->GetGlobalGenerator())
+ {
+ tgt = (m_Makefile->GetLocalGenerator()->GetGlobalGenerator()
+ ->FindTarget(0, lib.c_str()));
+ }
+ if(tgt)
+ {
+ // Add the directory only if it is not already present. This
+ // is an N^2 algorithm for adding the directories, but N
+ // should not get very big.
+ const char* libpath = tgt->GetDirectory();
+ if(std::find(m_LinkDirectories.begin(), m_LinkDirectories.end(),
+ libpath) == m_LinkDirectories.end())
+ {
+ m_LinkDirectories.push_back(libpath);
+ }
+ }
+ }
+
+ // The complete set of link directories has now been computed.
+ m_LinkDirectoriesComputed = true;
+ }
+
+ // Return the complete set of link directories.
+ return m_LinkDirectories;
+}
void cmTarget::ClearDependencyInformation( cmMakefile& mf, const char* target )
{
@@ -498,11 +560,6 @@ cmTarget::AnalyzeLibDependencies( const cmMakefile& mf )
// The dependency map.
DependencyMap dep_map;
- // If LIBRARY_OUTPUT_PATH is not set, then we must add search paths
- // for all the new libraries added by the dependency analysis.
- const char* libOutPath = mf.GetDefinition("LIBRARY_OUTPUT_PATH");
- bool addLibDirs = (libOutPath==0 || strcmp(libOutPath,"")==0);
-
// 1. Build the dependency graph
//
for(LinkLibraries::reverse_iterator lib = m_LinkLibraries.rbegin();
@@ -541,30 +598,11 @@ cmTarget::AnalyzeLibDependencies( const cmMakefile& mf )
}
}
-
// 4. Add the new libraries to the link line.
//
for( std::vector<std::string>::reverse_iterator k = newLinkLibraries.rbegin();
k != newLinkLibraries.rend(); ++k )
{
- if( addLibDirs )
- {
- // who the hell knows what this is, I think that K contains the
- // name of a library but ... Ken
- // k contains the same stuff that are on the LINK_LIBRARIES
- // commands. Normally, they would just be library names. -- Amitha.
- std::string libPathStr = *k + "_CMAKE_PATH";
- const char* libpath = mf.GetDefinition( libPathStr.c_str() );
- if( libpath )
- {
- // Don't add a link directory that is already present.
- if(std::find(m_LinkDirectories.begin(),
- m_LinkDirectories.end(), libpath) == m_LinkDirectories.end())
- {
- m_LinkDirectories.push_back(libpath);
- }
- }
- }
std::string linkType = *k;
linkType += "_LINK_TYPE";
cmTarget::LinkLibraryType llt = cmTarget::GENERAL;
@@ -582,6 +620,7 @@ cmTarget::AnalyzeLibDependencies( const cmMakefile& mf )
}
m_LinkLibraries.push_back( std::make_pair(*k,llt) );
}
+ m_LinkLibrariesAnalyzed = true;
}
@@ -724,6 +763,45 @@ void cmTarget::SetProperty(const char* prop, const char* value)
m_Properties[prop] = value;
}
+const char* cmTarget::GetDirectory()
+{
+ switch( this->GetType() )
+ {
+ case cmTarget::STATIC_LIBRARY:
+ case cmTarget::MODULE_LIBRARY:
+ case cmTarget::SHARED_LIBRARY:
+ m_Directory = m_Makefile->GetSafeDefinition("LIBRARY_OUTPUT_PATH");
+ break;
+ case cmTarget::EXECUTABLE:
+ m_Directory = m_Makefile->GetSafeDefinition("EXECUTABLE_OUTPUT_PATH");
+ break;
+ default:
+ return 0;
+ }
+ if(m_Directory.empty())
+ {
+ m_Directory = m_Makefile->GetStartOutputDirectory();
+ }
+ return m_Directory.c_str();
+}
+
+const char* cmTarget::GetLocation(const char* config)
+{
+ m_Location = this->GetDirectory();
+ if(!m_Location.empty())
+ {
+ m_Location += "/";
+ }
+ const char* cfgid = m_Makefile->GetDefinition("CMAKE_CFG_INTDIR");
+ if(cfgid && strcmp(cfgid, ".") != 0)
+ {
+ m_Location += cfgid;
+ m_Location += "/";
+ }
+ m_Location += this->GetFullName(config);
+ return m_Location.c_str();
+}
+
void cmTarget::UpdateLocation()
{
// make sure we have a makefile
@@ -908,12 +986,12 @@ const char* cmTarget::GetCreateRuleVariable()
return "";
}
-const char* cmTarget::GetSuffixVariable()
+const char* cmTarget::GetSuffixVariable()
{
return this->GetSuffixVariableInternal(this->GetType());
}
-const char* cmTarget::GetSuffixVariableInternal(TargetType type)
+const char* cmTarget::GetSuffixVariableInternal(TargetType type)
{
switch(type)
{
@@ -958,15 +1036,81 @@ const char* cmTarget::GetPrefixVariableInternal(TargetType type)
return "";
}
-std::string cmTarget::GetFullName()
+//----------------------------------------------------------------------------
+std::string cmTarget::GetFullName(const char* config)
+{
+ return this->GetFullNameInternal(this->GetType(), config);
+}
+
+//----------------------------------------------------------------------------
+void cmTarget::GetFullName(std::string& prefix, std::string& base,
+ std::string& suffix, const char* config)
+{
+ this->GetFullNameInternal(this->GetType(), config, prefix, base, suffix);
+}
+
+//----------------------------------------------------------------------------
+std::string cmTarget::GetFullPath(const char* config)
+{
+ // Start with the output directory for the target.
+ std::string fpath = this->GetDirectory();
+ fpath += "/";
+
+ // Add the configuration's subdirectory. This may need to be replaced with
+ // a call into the generator found through m_Makefile so that each
+ // generator can map configuration names to output directories its own way.
+ if(config)
+ {
+ fpath += config;
+ fpath += "/";
+ }
+
+ // Add the full name of the target.
+ fpath += this->GetFullName(config);
+ return fpath;
+}
+
+//----------------------------------------------------------------------------
+std::string cmTarget::GetFullNameInternal(TargetType type, const char* config)
{
- return this->GetFullNameInternal(this->GetType());
+ std::string prefix;
+ std::string base;
+ std::string suffix;
+ this->GetFullNameInternal(type, config, prefix, base, suffix);
+ return prefix+base+suffix;
}
-std::string cmTarget::GetFullNameInternal(TargetType type)
+//----------------------------------------------------------------------------
+void cmTarget::GetFullNameInternal(TargetType type,
+ const char* config,
+ std::string& outPrefix,
+ std::string& outBase,
+ std::string& outSuffix)
{
+ // Use just the target name for non-main target types.
+ if(type != cmTarget::STATIC_LIBRARY &&
+ type != cmTarget::SHARED_LIBRARY &&
+ type != cmTarget::MODULE_LIBRARY &&
+ type != cmTarget::EXECUTABLE)
+ {
+ outPrefix = "";
+ outBase = this->GetName();
+ outSuffix = "";
+ return;
+ }
+
+ // Compute the full name for main target types.
const char* targetPrefix = this->GetProperty("PREFIX");
const char* targetSuffix = this->GetProperty("SUFFIX");
+ const char* configPostfix = 0;
+ if(config && *config && type != cmTarget::EXECUTABLE)
+ {
+ std::string configVar = "CMAKE_";
+ configVar += config;
+ configVar += "_POSTFIX";
+ configVar = cmSystemTools::UpperCase(configVar);
+ configPostfix = m_Makefile->GetDefinition(configVar.c_str());
+ }
const char* prefixVar = this->GetPrefixVariableInternal(type);
const char* suffixVar = this->GetSuffixVariableInternal(type);
const char* ll =
@@ -999,91 +1143,48 @@ std::string cmTarget::GetFullNameInternal(TargetType type)
}
// Begin the final name with the prefix.
- std::string name = targetPrefix?targetPrefix:"";
+ outPrefix = targetPrefix?targetPrefix:"";
// Append the target name or property-specified name. Support this
// only for executable targets.
const char* outname = this->GetProperty("OUTPUT_NAME");
if(outname && type == cmTarget::EXECUTABLE)
{
- name += outname;
+ outBase = outname;
}
else
{
- name += this->GetName();
+ outBase = this->GetName();
}
- // Append the suffix.
- name += targetSuffix?targetSuffix:"";
-
- // Return the final name.
- return name;
-}
-
-std::string cmTarget::GetBaseName()
-{
- return this->GetBaseNameInternal(this->GetType());
-}
+ // Append the per-configuration postfix.
+ outBase += configPostfix?configPostfix:"";
-std::string
-cmTarget::GetBaseNameInternal(TargetType type)
-{
- std::string pathPrefix = "";
-#ifdef __APPLE__
- if(this->GetPropertyAsBool("MACOSX_BUNDLE"))
- {
- pathPrefix = this->GetName();
- pathPrefix += ".app/Contents/MacOS/";
- }
-#endif
- const char* targetPrefix = this->GetProperty("PREFIX");
- const char* prefixVar = this->GetPrefixVariableInternal(type);
- // if there is no prefix on the target use the cmake definition
- if(!targetPrefix && prefixVar)
- {
- // first check for a language specific suffix var
- const char* ll =
- this->GetLinkerLanguage(
- m_Makefile->GetLocalGenerator()->GetGlobalGenerator());
- if(ll)
- {
- std::string langPrefix = prefixVar + std::string("_") + ll;
- targetPrefix = m_Makefile->GetDefinition(langPrefix.c_str());
- }
- // if there not a language specific suffix then use the general one
- if(!targetPrefix)
- {
- targetPrefix = m_Makefile->GetSafeDefinition(prefixVar);
- }
- }
- std::string name = pathPrefix;
- name += targetPrefix?targetPrefix:"";
- name += this->GetName();
- return name;
+ // Append the suffix.
+ outSuffix = targetSuffix?targetSuffix:"";
}
void cmTarget::GetLibraryNames(std::string& name,
std::string& soName,
std::string& realName,
- std::string& baseName)
+ const char* config)
{
// Get the names based on the real type of the library.
- this->GetLibraryNamesInternal(name, soName, realName, this->GetType());
-
- // The library name without extension.
- baseName = this->GetBaseName();
+ this->GetLibraryNamesInternal(name, soName, realName, this->GetType(),
+ config);
}
void cmTarget::GetLibraryCleanNames(std::string& staticName,
std::string& sharedName,
std::string& sharedSOName,
- std::string& sharedRealName)
+ std::string& sharedRealName,
+ const char* config)
{
// Get the name as if this were a static library.
std::string soName;
std::string realName;
this->GetLibraryNamesInternal(staticName, soName, realName,
- cmTarget::STATIC_LIBRARY);
+ cmTarget::STATIC_LIBRARY, config);
// Get the names as if this were a shared library.
if(this->GetType() == cmTarget::STATIC_LIBRARY)
@@ -1094,20 +1195,23 @@ void cmTarget::GetLibraryCleanNames(std::string& staticName,
// type will never be MODULE. Either way the only names that
// might have to be cleaned are the shared library names.
this->GetLibraryNamesInternal(sharedName, sharedSOName,
- sharedRealName, cmTarget::SHARED_LIBRARY);
+ sharedRealName, cmTarget::SHARED_LIBRARY,
+ config);
}
else
{
// Use the name of the real type of the library (shared or module).
this->GetLibraryNamesInternal(sharedName, sharedSOName,
- sharedRealName, this->GetType());
+ sharedRealName, this->GetType(),
+ config);
}
}
void cmTarget::GetLibraryNamesInternal(std::string& name,
std::string& soName,
std::string& realName,
- TargetType type)
+ TargetType type,
+ const char* config)
{
// Construct the name of the soname flag variable for this language.
const char* ll =
@@ -1140,7 +1244,7 @@ void cmTarget::GetLibraryNamesInternal(std::string& name,
}
// The library name.
- name = this->GetFullNameInternal(type);
+ name = this->GetFullNameInternal(type, config);
// The library's soname.
soName = name;
@@ -1165,22 +1269,26 @@ void cmTarget::GetLibraryNamesInternal(std::string& name,
}
void cmTarget::GetExecutableNames(std::string& name,
- std::string& realName)
+ std::string& realName,
+ const char* config)
{
// Get the names based on the real type of the executable.
- this->GetExecutableNamesInternal(name, realName, this->GetType());
+ this->GetExecutableNamesInternal(name, realName, this->GetType(), config);
}
void cmTarget::GetExecutableCleanNames(std::string& name,
- std::string& realName)
+ std::string& realName,
+ const char* config)
{
// Get the name and versioned name of this executable.
- this->GetExecutableNamesInternal(name, realName, cmTarget::EXECUTABLE);
+ this->GetExecutableNamesInternal(name, realName, cmTarget::EXECUTABLE,
+ config);
}
void cmTarget::GetExecutableNamesInternal(std::string& name,
std::string& realName,
- TargetType type)
+ TargetType type,
+ const char* config)
{
// This versioning is supported only for executables and then only
// when the platform supports symbolic links.
@@ -1196,7 +1304,7 @@ void cmTarget::GetExecutableNamesInternal(std::string& name,
#endif
// The executable name.
- name = this->GetFullNameInternal(type);
+ name = this->GetFullNameInternal(type, config);
// The executable's real name on disk.
realName = name;
diff --git a/Source/cmTarget.h b/Source/cmTarget.h
index 630367d..790ab39 100644
--- a/Source/cmTarget.h
+++ b/Source/cmTarget.h
@@ -32,6 +32,7 @@ class cmGlobalGenerator;
class cmTarget
{
public:
+ cmTarget();
enum TargetType { EXECUTABLE, STATIC_LIBRARY,
SHARED_LIBRARY, MODULE_LIBRARY, UTILITY, INSTALL_FILES,
INSTALL_PROGRAMS };
@@ -111,9 +112,8 @@ public:
void MergeLinkLibraries( cmMakefile& mf, const char* selfname, const LinkLibraries& libs );
- const std::vector<std::string>& GetLinkDirectories()
- {return m_LinkDirectories;}
-
+ const std::vector<std::string>& GetLinkDirectories();
+
void AddLinkDirectory(const char* d);
/**
@@ -151,6 +151,9 @@ public:
const char *GetProperty(const char *prop);
bool GetPropertyAsBool(const char *prop);
+ const char* GetDirectory();
+ const char* GetLocation(const char* config);
+
/**
* Trace through the source files in this target and add al source files
* that they depend on, used by the visual studio generators
@@ -170,18 +173,19 @@ public:
/** Get the full name of the target according to the settings in its
makefile. */
- std::string GetFullName();
+ std::string GetFullName(const char* config=0);
+ void GetFullName(std::string& prefix, std::string& base, std::string& suffix,
+ const char* config=0);
- /** Get the base name (no suffix) of the target according to the
- settings in its makefile. */
- std::string GetBaseName();
+ /** Get the full path to the target according to the settings in its
+ makefile and the configuration type. */
+ std::string GetFullPath(const char* config=0);
/** Get the names of the library needed to generate a build rule
that takes into account shared library version numbers. This
should be called only on a library target. */
- void GetLibraryNames(std::string& name,
- std::string& soName, std::string& realName,
- std::string& baseName);
+ void GetLibraryNames(std::string& name, std::string& soName,
+ std::string& realName, const char* config);
/** Get the names of the library used to remove existing copies of
the library from the build tree either before linking or during
@@ -190,18 +194,21 @@ public:
void GetLibraryCleanNames(std::string& staticName,
std::string& sharedName,
std::string& sharedSOName,
- std::string& sharedRealName);
+ std::string& sharedRealName,
+ const char* config);
/** Get the names of the executable needed to generate a build rule
that takes into account executable version numbers. This should
be called only on an executable target. */
- void GetExecutableNames(std::string& name, std::string& realName);
+ void GetExecutableNames(std::string& name, std::string& realName,
+ const char* config);
/** Get the names of the executable used to remove existing copies
of the executable from the build tree either before linking or
during a clean step. This should be called only on an
executable target. */
- void GetExecutableCleanNames(std::string& name, std::string& realName);
+ void GetExecutableCleanNames(std::string& name, std::string& realName,
+ const char* config);
private:
/**
* A list of direct dependencies. Use in conjunction with DependencyMap.
@@ -258,15 +265,19 @@ private:
const char* GetSuffixVariableInternal(TargetType type);
const char* GetPrefixVariableInternal(TargetType type);
- std::string GetFullNameInternal(TargetType type);
- std::string GetBaseNameInternal(TargetType type);
+ std::string GetFullNameInternal(TargetType type, const char* config);
+ void GetFullNameInternal(TargetType type, const char* config,
+ std::string& outPrefix, std::string& outBase,
+ std::string& outSuffix);
void GetLibraryNamesInternal(std::string& name,
std::string& soName,
std::string& realName,
- TargetType type);
+ TargetType type,
+ const char* config);
void GetExecutableNamesInternal(std::string& name,
std::string& realName,
- TargetType type);
+ TargetType type,
+ const char* config);
// update the value of the LOCATION var
void UpdateLocation();
@@ -281,16 +292,22 @@ private:
std::vector<cmSourceFile*> m_SourceFiles;
LinkLibraries m_LinkLibraries;
LinkLibraries m_PrevLinkedLibraries;
+ bool m_LinkLibrariesAnalyzed;
+ bool m_LinkDirectoriesComputed;
std::vector<std::string> m_Frameworks;
std::vector<std::string> m_LinkDirectories;
+ std::vector<std::string> m_ExplicitLinkDirectories;
std::string m_InstallPath;
std::string m_RuntimeInstallPath;
+ std::string m_Directory;
+ std::string m_Location;
std::set<cmStdString> m_Utilities;
bool m_RecordDependencies;
std::map<cmStdString,cmStdString> m_Properties;
-
- // the Makefile that owns this target
- cmMakefile *m_Makefile;
+
+ // The cmMakefile instance that owns this target. This should
+ // always be set.
+ cmMakefile* m_Makefile;
};
typedef std::map<cmStdString,cmTarget> cmTargets;
diff --git a/Source/cmTargetLinkLibrariesCommand.cxx b/Source/cmTargetLinkLibrariesCommand.cxx
index b917781..9b35c95 100644
--- a/Source/cmTargetLinkLibrariesCommand.cxx
+++ b/Source/cmTargetLinkLibrariesCommand.cxx
@@ -66,51 +66,6 @@ bool cmTargetLinkLibrariesCommand::InitialPass(std::vector<std::string> const& a
m_Makefile->AddLinkLibraryForTarget(args[0].c_str(),i->c_str(),
cmTarget::GENERAL);
}
- // if this is a library that cmake knows about, and LIBRARY_OUTPUT_PATH
- // is not set, then add the link directory
- const char* ldir = m_Makefile->GetDefinition("LIBRARY_OUTPUT_PATH");
- if (cmSystemTools::IsOff(ldir))
- {
- std::string libPath = *i + "_CMAKE_PATH";
-
- const char* dir = m_Makefile->GetDefinition(libPath.c_str());
- if( dir && *dir )
- {
- m_Makefile->AddLinkDirectoryForTarget(args[0].c_str(), dir );
- }
- else
- {
- m_HasLocation.push_back(*i);
- }
- }
- else
- {
- m_Makefile->AddLinkDirectoryForTarget(args[0].c_str(), ldir );
- }
}
return true;
}
-
-void cmTargetLinkLibrariesCommand::FinalPass()
-{
- std::vector<std::string>::size_type cc;
- std::string libPath;
- if ( !m_Makefile->GetDefinition("CMAKE_IGNORE_DEPENDENCIES_ORDERING") )
- {
- for ( cc = 0; cc < m_HasLocation.size(); cc ++ )
- {
- libPath = m_HasLocation[cc] + "_CMAKE_PATH";
- const char* dir = m_Makefile->GetDefinition(libPath.c_str());
- if ( dir && *dir )
- {
- std::string str = "Library " + m_HasLocation[cc] +
- " is defined using ADD_LIBRARY after the library is used "
- "using TARGET_LINK_LIBRARIES for the target " + m_TargetName +
- ". This breaks CMake's dependency "
- "handling. Please fix the CMakeLists.txt file.";
- this->SetError(str.c_str());
- cmSystemTools::Message(str.c_str(), "CMake Error");
- }
- }
- }
-}
diff --git a/Source/cmTargetLinkLibrariesCommand.h b/Source/cmTargetLinkLibrariesCommand.h
index 52d744a..2e1b0d4 100644
--- a/Source/cmTargetLinkLibrariesCommand.h
+++ b/Source/cmTargetLinkLibrariesCommand.h
@@ -44,11 +44,6 @@ public:
virtual bool InitialPass(std::vector<std::string> const& args);
/**
- * Verify that the ordering in CMake is correct.
- */
- virtual void FinalPass();
-
- /**
* The name of the command as specified in CMakeList.txt.
*/
virtual const char* GetName() { return "TARGET_LINK_LIBRARIES";}
@@ -79,7 +74,6 @@ public:
cmTypeMacro(cmTargetLinkLibrariesCommand, cmCommand);
private:
- std::vector<std::string> m_HasLocation;
std::string m_TargetName;
};
diff --git a/Source/cmXCodeObject.h b/Source/cmXCodeObject.h
index 5e6a9e1..11a7088 100644
--- a/Source/cmXCodeObject.h
+++ b/Source/cmXCodeObject.h
@@ -18,6 +18,7 @@ public:
PBXAggregateTarget,XCBuildConfiguration,XCConfigurationList,
None
};
+ class StringVec: public std::vector<cmStdString> {};
static const char* PBXTypeNames[];
virtual ~cmXCodeObject();
cmXCodeObject(PBXType ptype, Type type);
@@ -110,11 +111,16 @@ public:
}
void CopyAttributes(cmXCodeObject* );
- void AddDependLibrary(const char* l)
+ void AddDependLibrary(const char* configName,
+ const char* l)
{
- m_DependLibraries.push_back(l);
+ if(!configName)
+ {
+ configName = "";
+ }
+ m_DependLibraries[configName].push_back(l);
}
- std::vector<cmStdString> const& GetDependLibraries()
+ std::map<cmStdString, StringVec> const& GetDependLibraries()
{
return m_DependLibraries;
}
@@ -131,7 +137,7 @@ protected:
cmXCodeObject* m_Object;
cmXCodeObject* m_PBXTargetDependency;
std::vector<cmXCodeObject*> m_List;
- std::vector<cmStdString> m_DependLibraries;
+ std::map<cmStdString, StringVec> m_DependLibraries;
std::map<cmStdString, cmXCodeObject*> m_ObjectAttributes;
};
#endif