Commit be2c45f2 authored by Brad King's avatar Brad King 💬 Committed by Kitware Robot
Browse files

Merge topic 'prepare-per-config-objects'

ca697bfc cmGeneratorTarget: Drop obj libs from GetConfigCommonSourceFiles
e44a8d2c Xcode: Refactor loop over all sources
97cc29c7 VS: Teach generators how to mark per-config source files
2f6f6f0c Xcode: Use config-specific object library files on link lines
888c8af6 VS: List config-specific object library files on link lines
40aa6c05

 cmGeneratorTarget: Add method to collect all sources for all configs

Acked-by: Kitware Robot's avatarKitware Robot <kwrobot@kitware.com>
Merge-request: !701
parents c003f1b9 ca697bfc
......@@ -949,6 +949,19 @@ void cmGeneratorTarget::GetSourceFiles(std::vector<cmSourceFile*>& files,
}
}
void cmGeneratorTarget::GetSourceFilesWithoutObjectLibraries(
std::vector<cmSourceFile*>& files, const std::string& config) const
{
KindedSources const& kinded = this->GetKindedSources(config);
files.reserve(kinded.Sources.size());
for (std::vector<SourceAndKind>::const_iterator si = kinded.Sources.begin();
si != kinded.Sources.end(); ++si) {
if (si->Source->GetObjectLibrary().empty()) {
files.push_back(si->Source);
}
}
}
cmGeneratorTarget::KindedSources const& cmGeneratorTarget::GetKindedSources(
std::string const& config) const
{
......@@ -1069,6 +1082,43 @@ void cmGeneratorTarget::ComputeKindedSources(KindedSources& files,
}
}
std::vector<cmGeneratorTarget::AllConfigSource> const&
cmGeneratorTarget::GetAllConfigSources() const
{
if (this->AllConfigSources.empty()) {
this->ComputeAllConfigSources();
}
return this->AllConfigSources;
}
void cmGeneratorTarget::ComputeAllConfigSources() const
{
std::vector<std::string> configs;
this->Makefile->GetConfigurations(configs);
std::map<cmSourceFile const*, size_t> index;
for (size_t ci = 0; ci < configs.size(); ++ci) {
KindedSources const& sources = this->GetKindedSources(configs[ci]);
for (std::vector<cmGeneratorTarget::SourceAndKind>::const_iterator si =
sources.Sources.begin();
si != sources.Sources.end(); ++si) {
std::map<cmSourceFile const*, size_t>::iterator mi =
index.find(si->Source);
if (mi == index.end()) {
AllConfigSource acs;
acs.Source = si->Source;
acs.Kind = si->Kind;
this->AllConfigSources.push_back(acs);
std::map<cmSourceFile const*, size_t>::value_type entry(
si->Source, this->AllConfigSources.size() - 1);
mi = index.insert(entry).first;
}
this->AllConfigSources[mi->second].Configs.push_back(ci);
}
}
}
std::string cmGeneratorTarget::GetCompilePDBName(
const std::string& config) const
{
......@@ -4900,11 +4950,11 @@ bool cmGeneratorTarget::GetConfigCommonSourceFiles(
std::vector<std::string>::const_iterator it = configs.begin();
const std::string& firstConfig = *it;
this->GetSourceFiles(files, firstConfig);
this->GetSourceFilesWithoutObjectLibraries(files, firstConfig);
for (; it != configs.end(); ++it) {
std::vector<cmSourceFile*> configFiles;
this->GetSourceFiles(configFiles, *it);
this->GetSourceFilesWithoutObjectLibraries(configFiles, *it);
if (configFiles != files) {
std::string firstConfigFiles;
const char* sep = "";
......
......@@ -12,6 +12,7 @@
#include <map>
#include <set>
#include <stddef.h>
#include <string>
#include <utility>
#include <vector>
......@@ -69,6 +70,8 @@ public:
bool GetPropertyAsBool(const std::string& prop) const;
void GetSourceFiles(std::vector<cmSourceFile*>& files,
const std::string& config) const;
void GetSourceFilesWithoutObjectLibraries(std::vector<cmSourceFile*>& files,
const std::string& config) const;
/** Source file kinds (classifications).
Generators use this to decide how to treat a source file. */
......@@ -107,6 +110,17 @@ public:
/** Get all sources needed for a configuration with kinds assigned. */
KindedSources const& GetKindedSources(std::string const& config) const;
struct AllConfigSource
{
cmSourceFile const* Source;
cmGeneratorTarget::SourceKind Kind;
std::vector<size_t> Configs;
};
/** Get all sources needed for all configurations with kinds and
per-source configurations assigned. */
std::vector<AllConfigSource> const& GetAllConfigSources() const;
void GetObjectSources(std::vector<cmSourceFile const*>&,
const std::string& config) const;
const std::string& GetObjectName(cmSourceFile const* file);
......@@ -338,6 +352,9 @@ public:
std::string GetFullNameImported(const std::string& config,
bool implib) const;
/** Get source files common to all configurations and diagnose cases
with per-config sources. Excludes sources added by a TARGET_OBJECTS
generator expression. */
bool GetConfigCommonSourceFiles(std::vector<cmSourceFile*>& files) const;
bool HaveBuildTreeRPATH(const std::string& config) const;
......@@ -731,6 +748,9 @@ private:
void ComputeKindedSources(KindedSources& files,
std::string const& config) const;
mutable std::vector<AllConfigSource> AllConfigSources;
void ComputeAllConfigSources() const;
std::vector<TargetPropertyEntry*> IncludeDirectoriesEntries;
std::vector<TargetPropertyEntry*> CompileOptionsEntries;
std::vector<TargetPropertyEntry*> CompileFeaturesEntries;
......
......@@ -651,11 +651,6 @@ std::string GetGroupMapKeyFromPath(cmGeneratorTarget* target,
return key;
}
std::string GetGroupMapKey(cmGeneratorTarget* target, cmSourceFile* sf)
{
return GetGroupMapKeyFromPath(target, sf->GetFullPath());
}
cmXCodeObject* cmGlobalXCodeGenerator::CreateXCodeSourceFileFromPath(
const std::string& fullpath, cmGeneratorTarget* target,
const std::string& lang, cmSourceFile* sf)
......@@ -2673,7 +2668,7 @@ void cmGlobalXCodeGenerator::AddDependAndLinkInformation(cmXCodeObject* target)
std::string linkObjs;
const char* sep = "";
std::vector<cmSourceFile const*> objs;
gt->GetExternalObjects(objs, "");
gt->GetExternalObjects(objs, configName);
for (std::vector<cmSourceFile const*>::const_iterator oi = objs.begin();
oi != objs.end(); ++oi) {
if ((*oi)->GetObjectLibrary().empty()) {
......@@ -2788,42 +2783,26 @@ bool cmGlobalXCodeGenerator::CreateGroups(
gtgt->AddSource(plist);
}
std::vector<cmSourceFile*> classes;
if (!gtgt->GetConfigCommonSourceFiles(classes)) {
return false;
}
std::vector<cmGeneratorTarget::AllConfigSource> const& sources =
gtgt->GetAllConfigSources();
// Put cmSourceFile instances in proper groups:
for (std::vector<cmSourceFile*>::const_iterator s = classes.begin();
s != classes.end(); s++) {
cmSourceFile* sf = *s;
for (std::vector<cmGeneratorTarget::AllConfigSource>::const_iterator si =
sources.begin();
si != sources.end(); ++si) {
cmSourceFile const* sf = si->Source;
if (this->XcodeVersion >= 50 && !sf->GetObjectLibrary().empty()) {
// Object library files go on the link line instead.
continue;
}
// Add the file to the list of sources.
std::string const& source = sf->GetFullPath();
cmSourceGroup* sourceGroup =
mf->FindSourceGroup(source.c_str(), sourceGroups);
cmXCodeObject* pbxgroup = this->CreateOrGetPBXGroup(gtgt, sourceGroup);
std::string key = GetGroupMapKey(gtgt, sf);
std::string key = GetGroupMapKeyFromPath(gtgt, source);
this->GroupMap[key] = pbxgroup;
}
if (this->XcodeVersion < 50) {
// Put OBJECT_LIBRARY objects in proper groups:
std::vector<cmSourceFile const*> objs;
gtgt->GetExternalObjects(objs, "");
for (std::vector<cmSourceFile const*>::const_iterator oi =
objs.begin();
oi != objs.end(); ++oi) {
if ((*oi)->GetObjectLibrary().empty()) {
continue;
}
std::string const& source = (*oi)->GetFullPath();
cmSourceGroup* sourceGroup =
mf->FindSourceGroup(source.c_str(), sourceGroups);
cmXCodeObject* pbxgroup =
this->CreateOrGetPBXGroup(gtgt, sourceGroup);
std::string key = GetGroupMapKeyFromPath(gtgt, source);
this->GroupMap[key] = pbxgroup;
}
}
}
}
return true;
......
......@@ -30,7 +30,7 @@ public:
typedef cmComputeLinkInformation::ItemVector ItemVector;
void OutputLibraries(std::ostream& fout, ItemVector const& libs);
void OutputObjects(std::ostream& fout, cmGeneratorTarget* t,
const char* isep = 0);
std::string const& config, const char* isep = 0);
private:
cmLocalVisualStudio7Generator* LocalGenerator;
......@@ -1043,7 +1043,7 @@ void cmLocalVisualStudio7Generator::OutputBuildTool(
if (this->GetVersion() < cmGlobalVisualStudioGenerator::VS8 ||
this->FortranProject) {
std::ostringstream libdeps;
this->Internal->OutputObjects(libdeps, target);
this->Internal->OutputObjects(libdeps, target, configName);
if (!libdeps.str().empty()) {
fout << "\t\t\t\tAdditionalDependencies=\"" << libdeps.str()
<< "\"\n";
......@@ -1096,7 +1096,7 @@ void cmLocalVisualStudio7Generator::OutputBuildTool(
<< this->Makefile->GetSafeDefinition(standardLibsVar.c_str());
if (this->GetVersion() < cmGlobalVisualStudioGenerator::VS8 ||
this->FortranProject) {
this->Internal->OutputObjects(fout, target, " ");
this->Internal->OutputObjects(fout, target, configName, " ");
}
fout << " ";
this->Internal->OutputLibraries(fout, cli.GetItems());
......@@ -1181,7 +1181,7 @@ void cmLocalVisualStudio7Generator::OutputBuildTool(
<< this->Makefile->GetSafeDefinition(standardLibsVar.c_str());
if (this->GetVersion() < cmGlobalVisualStudioGenerator::VS8 ||
this->FortranProject) {
this->Internal->OutputObjects(fout, target, " ");
this->Internal->OutputObjects(fout, target, configName, " ");
}
fout << " ";
this->Internal->OutputLibraries(fout, cli.GetItems());
......@@ -1300,21 +1300,20 @@ void cmLocalVisualStudio7GeneratorInternals::OutputLibraries(
}
void cmLocalVisualStudio7GeneratorInternals::OutputObjects(
std::ostream& fout, cmGeneratorTarget* gt, const char* isep)
std::ostream& fout, cmGeneratorTarget* gt, std::string const& configName,
const char* isep)
{
// VS < 8 does not support per-config source locations so we
// list object library content on the link line instead.
cmLocalVisualStudio7Generator* lg = this->LocalGenerator;
std::string currentBinDir = lg->GetCurrentBinaryDirectory();
std::vector<cmSourceFile*> sources;
if (!gt->GetConfigCommonSourceFiles(sources)) {
return;
}
std::vector<cmSourceFile const*> objs;
gt->GetExternalObjects(objs, configName);
const char* sep = isep ? isep : "";
for (std::vector<cmSourceFile*>::const_iterator i = sources.begin();
i != sources.end(); i++) {
for (std::vector<cmSourceFile const*>::const_iterator i = objs.begin();
i != objs.end(); ++i) {
if (!(*i)->GetObjectLibrary().empty()) {
std::string const& objFile = (*i)->GetFullPath();
std::string rel = lg->ConvertToRelativePath(currentBinDir, objFile);
......@@ -1369,14 +1368,14 @@ void cmLocalVisualStudio7Generator::WriteVCProjFile(std::ostream& fout,
// We may be modifying the source groups temporarily, so make a copy.
std::vector<cmSourceGroup> sourceGroups = this->Makefile->GetSourceGroups();
// get the classes from the source lists then add them to the groups
std::vector<cmSourceFile*> classes;
if (!target->GetConfigCommonSourceFiles(classes)) {
return;
}
for (std::vector<cmSourceFile*>::const_iterator i = classes.begin();
i != classes.end(); i++) {
if (!(*i)->GetObjectLibrary().empty()) {
std::vector<cmGeneratorTarget::AllConfigSource> const& sources =
target->GetAllConfigSources();
std::map<cmSourceFile const*, size_t> sourcesIndex;
for (size_t si = 0; si < sources.size(); ++si) {
cmSourceFile const* sf = sources[si].Source;
sourcesIndex[sf] = si;
if (!sf->GetObjectLibrary().empty()) {
if (this->GetVersion() < cmGlobalVisualStudioGenerator::VS8 ||
this->FortranProject) {
// VS < 8 does not support per-config source locations so we
......@@ -1386,10 +1385,10 @@ void cmLocalVisualStudio7Generator::WriteVCProjFile(std::ostream& fout,
}
}
// Add the file to the list of sources.
std::string source = (*i)->GetFullPath();
std::string const source = sf->GetFullPath();
cmSourceGroup* sourceGroup =
this->Makefile->FindSourceGroup(source.c_str(), sourceGroups);
sourceGroup->AssignSource(*i);
sourceGroup->AssignSource(sf);
}
// open the project
......@@ -1402,7 +1401,7 @@ void cmLocalVisualStudio7Generator::WriteVCProjFile(std::ostream& fout,
// Loop through every source group.
for (unsigned int i = 0; i < sourceGroups.size(); ++i) {
cmSourceGroup sg = sourceGroups[i];
this->WriteGroup(&sg, target, fout, libName, configs);
this->WriteGroup(&sg, target, fout, libName, configs, sourcesIndex);
}
fout << "\t</Files>\n";
......@@ -1424,25 +1423,28 @@ struct cmLVS7GFileConfig
class cmLocalVisualStudio7GeneratorFCInfo
{
public:
cmLocalVisualStudio7GeneratorFCInfo(cmLocalVisualStudio7Generator* lg,
cmGeneratorTarget* target,
cmSourceFile const& sf,
std::vector<std::string> const& configs);
cmLocalVisualStudio7GeneratorFCInfo(
cmLocalVisualStudio7Generator* lg, cmGeneratorTarget* target,
cmGeneratorTarget::AllConfigSource const& acs,
std::vector<std::string> const& configs);
std::map<std::string, cmLVS7GFileConfig> FileConfigMap;
};
cmLocalVisualStudio7GeneratorFCInfo::cmLocalVisualStudio7GeneratorFCInfo(
cmLocalVisualStudio7Generator* lg, cmGeneratorTarget* gt,
cmSourceFile const& sf, std::vector<std::string> const& configs)
cmGeneratorTarget::AllConfigSource const& acs,
std::vector<std::string> const& configs)
{
cmSourceFile const& sf = *acs.Source;
std::string objectName;
if (gt->HasExplicitObjectName(&sf)) {
objectName = gt->GetObjectName(&sf);
}
// Compute per-source, per-config information.
size_t ci = 0;
for (std::vector<std::string>::const_iterator i = configs.begin();
i != configs.end(); ++i) {
i != configs.end(); ++i, ++ci) {
std::string configUpper = cmSystemTools::UpperCase(*i);
cmLVS7GFileConfig fc;
bool needfc = false;
......@@ -1508,7 +1510,9 @@ cmLocalVisualStudio7GeneratorFCInfo::cmLocalVisualStudio7GeneratorFCInfo(
}
// If HEADER_FILE_ONLY is set, we must suppress this generation in
// the project file
fc.ExcludedFromBuild = (sf.GetPropertyAsBool("HEADER_FILE_ONLY"));
fc.ExcludedFromBuild = sf.GetPropertyAsBool("HEADER_FILE_ONLY") ||
std::find(acs.Configs.begin(), acs.Configs.end(), ci) ==
acs.Configs.end();
if (fc.ExcludedFromBuild) {
needfc = true;
}
......@@ -1563,7 +1567,8 @@ std::string cmLocalVisualStudio7Generator::ComputeLongestObjectDirectory(
bool cmLocalVisualStudio7Generator::WriteGroup(
const cmSourceGroup* sg, cmGeneratorTarget* target, std::ostream& fout,
const std::string& libName, std::vector<std::string> const& configs)
const std::string& libName, std::vector<std::string> const& configs,
std::map<cmSourceFile const*, size_t> const& sourcesIndex)
{
cmGlobalVisualStudio7Generator* gg =
static_cast<cmGlobalVisualStudio7Generator*>(this->GlobalGenerator);
......@@ -1574,7 +1579,8 @@ bool cmLocalVisualStudio7Generator::WriteGroup(
bool hasChildrenWithSources = false;
std::ostringstream tmpOut;
for (unsigned int i = 0; i < children.size(); ++i) {
if (this->WriteGroup(&children[i], target, tmpOut, libName, configs)) {
if (this->WriteGroup(&children[i], target, tmpOut, libName, configs,
sourcesIndex)) {
hasChildrenWithSources = true;
}
}
......@@ -1590,15 +1596,26 @@ bool cmLocalVisualStudio7Generator::WriteGroup(
this->WriteVCProjBeginGroup(fout, name.c_str(), "");
}
std::vector<cmGeneratorTarget::AllConfigSource> const& sources =
target->GetAllConfigSources();
// Loop through each source in the source group.
for (std::vector<const cmSourceFile*>::const_iterator sf =
sourceFiles.begin();
sf != sourceFiles.end(); ++sf) {
std::string source = (*sf)->GetFullPath();
FCInfo fcinfo(this, target, *(*sf), configs);
if (source != libName || target->GetType() == cmStateEnums::UTILITY ||
target->GetType() == cmStateEnums::GLOBAL_TARGET) {
// Look up the source kind and configs.
std::map<cmSourceFile const*, size_t>::const_iterator map_it =
sourcesIndex.find(*sf);
// The map entry must exist because we populated it earlier.
assert(map_it != sourcesIndex.end());
cmGeneratorTarget::AllConfigSource const& acs = sources[map_it->second];
FCInfo fcinfo(this, target, acs, configs);
fout << "\t\t\t<File\n";
std::string d = this->ConvertToXMLOutputPathSingle(source.c_str());
// Tell MS-Dev what the source is. If the compiler knows how to
......@@ -1638,6 +1655,9 @@ bool cmLocalVisualStudio7Generator::WriteGroup(
lang == "ASM_MASM") {
aCompilerTool = "MASM";
}
if (acs.Kind == cmGeneratorTarget::SourceKindExternalObject) {
aCompilerTool = "VCCustomBuildTool";
}
for (std::map<std::string, cmLVS7GFileConfig>::const_iterator fci =
fcinfo.FileConfigMap.begin();
fci != fcinfo.FileConfigMap.end(); ++fci) {
......
......@@ -119,7 +119,8 @@ private:
bool WriteGroup(const cmSourceGroup* sg, cmGeneratorTarget* target,
std::ostream& fout, const std::string& libName,
std::vector<std::string> const& configs);
std::vector<std::string> const& configs,
std::map<cmSourceFile const*, size_t> const& sourcesIndex);
friend class cmLocalVisualStudio7GeneratorFCInfo;
friend class cmLocalVisualStudio7GeneratorInternals;
......
......@@ -1241,16 +1241,15 @@ void cmVisualStudio10TargetGenerator::WriteGroups()
// collect up group information
std::vector<cmSourceGroup> sourceGroups = this->Makefile->GetSourceGroups();
std::vector<cmSourceFile*> classes;
if (!this->GeneratorTarget->GetConfigCommonSourceFiles(classes)) {
return;
}
std::vector<cmGeneratorTarget::AllConfigSource> const& sources =
this->GeneratorTarget->GetAllConfigSources();
std::set<cmSourceGroup*> groupsUsed;
for (std::vector<cmSourceFile*>::const_iterator s = classes.begin();
s != classes.end(); s++) {
cmSourceFile* sf = *s;
std::string const& source = sf->GetFullPath();
for (std::vector<cmGeneratorTarget::AllConfigSource>::const_iterator si =
sources.begin();
si != sources.end(); ++si) {
std::string const& source = si->Source->GetFullPath();
cmSourceGroup* sourceGroup =
this->Makefile->FindSourceGroup(source.c_str(), sourceGroups);
groupsUsed.insert(sourceGroup);
......@@ -1734,12 +1733,17 @@ void cmVisualStudio10TargetGenerator::WriteAllSources()
}
this->WriteString("<ItemGroup>\n", 1);
cmGeneratorTarget::KindedSources const& sources =
this->GeneratorTarget->GetKindedSources("");
std::vector<size_t> all_configs;
for (size_t ci = 0; ci < this->Configurations.size(); ++ci) {
all_configs.push_back(ci);
}
std::vector<cmGeneratorTarget::AllConfigSource> const& sources =
this->GeneratorTarget->GetAllConfigSources();
for (std::vector<cmGeneratorTarget::SourceAndKind>::const_iterator si =
sources.Sources.begin();
si != sources.Sources.end(); ++si) {
for (std::vector<cmGeneratorTarget::AllConfigSource>::const_iterator si =
sources.begin();
si != sources.end(); ++si) {
std::string tool;
switch (si->Kind) {
case cmGeneratorTarget::SourceKindAppManifest:
......@@ -1810,14 +1814,35 @@ void cmVisualStudio10TargetGenerator::WriteAllSources()
}
if (!tool.empty()) {
// Compute set of configurations to exclude, if any.
std::vector<size_t> const& include_configs = si->Configs;
std::vector<size_t> exclude_configs;
std::set_difference(all_configs.begin(), all_configs.end(),
include_configs.begin(), include_configs.end(),
std::back_inserter(exclude_configs));
if (si->Kind == cmGeneratorTarget::SourceKindObjectSource) {
// FIXME: refactor generation to avoid tracking XML syntax state.
this->WriteSource(tool, si->Source, " ");
if (this->OutputSourceSpecificFlags(si->Source)) {
bool have_nested = this->OutputSourceSpecificFlags(si->Source);
if (!exclude_configs.empty()) {
if (!have_nested) {
(*this->BuildFileStream) << ">\n";
}
this->WriteExcludeFromBuild(exclude_configs);
have_nested = true;
}
if (have_nested) {
this->WriteString("</", 2);
(*this->BuildFileStream) << tool << ">\n";
} else {
(*this->BuildFileStream) << " />\n";
}
} else if (!exclude_configs.empty()) {
this->WriteSource(tool, si->Source, ">\n");
this->WriteExcludeFromBuild(exclude_configs);
this->WriteString("</", 2);
(*this->BuildFileStream) << tool << ">\n";
} else {
this->WriteSource(tool, si->Source);
}
......@@ -2001,6 +2026,19 @@ bool cmVisualStudio10TargetGenerator::OutputSourceSpecificFlags(
return hasFlags;
}
void cmVisualStudio10TargetGenerator::WriteExcludeFromBuild(
std::vector<size_t> const& exclude_configs)
{
for (std::vector<size_t>::const_iterator ci = exclude_configs.begin();
ci != exclude_configs.end(); ++ci) {
this->WriteString("", 3);
(*this->BuildFileStream)
<< "<ExcludedFromBuild Condition=\"'$(Configuration)|$(Platform)'=='"
<< cmVS10EscapeXML(this->Configurations[*ci]) << "|"
<< cmVS10EscapeXML(this->Platform) << "'\">true</ExcludedFromBuild>\n";
}
}
void cmVisualStudio10TargetGenerator::WritePathAndIncrementalLinkOptions()
{
cmStateEnums::TargetType ttype = this->GeneratorTarget->GetType();
......
......@@ -62,6 +62,7 @@ private:
void WriteNsightTegraConfigurationValues(std::string const& config);
void WriteSource(std::string const& tool, cmSourceFile const* sf,
const char* end = 0);
void WriteExcludeFromBuild(std::vector<size_t> const& exclude_configs);
void WriteAllSources();
void WriteDotNetReferences();
void WriteDotNetReference(std::string const& ref, std::string const& hint);
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment