summaryrefslogtreecommitdiff
path: root/Source
diff options
context:
space:
mode:
authorBrad King <brad.king@kitware.com>2017-03-13 11:54:30 -0400
committerBrad King <brad.king@kitware.com>2017-03-21 10:02:34 -0400
commit075f6454092ae058add228eda8220a3680b2f9e4 (patch)
treec0bff4ce5eaf25b8e38d904f3cfb64ebfc13265b /Source
parent21c4ec4ffe1c40382f6b435ff49eade31e1137f2 (diff)
downloadcmake-075f6454092ae058add228eda8220a3680b2f9e4.tar.gz
Support WINDOWS_EXPORT_ALL_SYMBOLS with `.def` files
The `WINDOWS_EXPORT_ALL_SYMBOLS` target property exports all symbols found in object files explicitly given to the linker. However, the linker may also find additional symbols in dependencies and copy them into the linked binary (e.g. from `msvcrt.lib`). Provide a way to export an explicit list of such symbols by adding a `.def` file as a source file. Fixes: #16473
Diffstat (limited to 'Source')
-rw-r--r--Source/cmGeneratorTarget.cxx11
-rw-r--r--Source/cmGeneratorTarget.h2
-rw-r--r--Source/cmGlobalVisualStudioGenerator.cxx68
-rw-r--r--Source/cmLocalVisualStudio7Generator.cxx2
-rw-r--r--Source/cmMakefileTargetGenerator.cxx37
-rw-r--r--Source/cmNinjaNormalTargetGenerator.cxx20
-rw-r--r--Source/cmNinjaTargetGenerator.cxx12
-rw-r--r--Source/cmVisualStudio10TargetGenerator.cxx2
8 files changed, 97 insertions, 57 deletions
diff --git a/Source/cmGeneratorTarget.cxx b/Source/cmGeneratorTarget.cxx
index 29698cf913..e27424f812 100644
--- a/Source/cmGeneratorTarget.cxx
+++ b/Source/cmGeneratorTarget.cxx
@@ -1973,15 +1973,16 @@ cmGeneratorTarget::GetModuleDefinitionInfo(std::string const& config) const
void cmGeneratorTarget::ComputeModuleDefinitionInfo(
std::string const& config, ModuleDefinitionInfo& info) const
{
- std::vector<cmSourceFile const*> sources;
- this->GetModuleDefinitionSources(sources, config);
+ this->GetModuleDefinitionSources(info.Sources, config);
info.WindowsExportAllSymbols =
this->Makefile->IsOn("CMAKE_SUPPORT_WINDOWS_EXPORT_ALL_SYMBOLS") &&
this->GetPropertyAsBool("WINDOWS_EXPORT_ALL_SYMBOLS");
- if (info.WindowsExportAllSymbols) {
+ info.DefFileGenerated =
+ info.WindowsExportAllSymbols || info.Sources.size() > 1;
+ if (info.DefFileGenerated) {
info.DefFile = this->ObjectDirectory /* has slash */ + "exports.def";
- } else if (!sources.empty()) {
- info.DefFile = sources.front()->GetFullPath();
+ } else if (!info.Sources.empty()) {
+ info.DefFile = info.Sources.front()->GetFullPath();
}
}
diff --git a/Source/cmGeneratorTarget.h b/Source/cmGeneratorTarget.h
index 92285f3d32..68d6ef8d38 100644
--- a/Source/cmGeneratorTarget.h
+++ b/Source/cmGeneratorTarget.h
@@ -238,7 +238,9 @@ public:
struct ModuleDefinitionInfo
{
std::string DefFile;
+ bool DefFileGenerated;
bool WindowsExportAllSymbols;
+ std::vector<cmSourceFile const*> Sources;
};
ModuleDefinitionInfo const* GetModuleDefinitionInfo(
std::string const& config) const;
diff --git a/Source/cmGlobalVisualStudioGenerator.cxx b/Source/cmGlobalVisualStudioGenerator.cxx
index 4e7d92a767..d052f030a8 100644
--- a/Source/cmGlobalVisualStudioGenerator.cxx
+++ b/Source/cmGlobalVisualStudioGenerator.cxx
@@ -816,7 +816,7 @@ void cmGlobalVisualStudioGenerator::AddSymbolExportCommand(
{
cmGeneratorTarget::ModuleDefinitionInfo const* mdi =
gt->GetModuleDefinitionInfo(configName);
- if (!mdi || !mdi->WindowsExportAllSymbols) {
+ if (!mdi || !mdi->DefFileGenerated) {
return;
}
@@ -851,37 +851,47 @@ void cmGlobalVisualStudioGenerator::AddSymbolExportCommand(
cmSystemTools::Error("could not open ", objs_file.c_str());
return;
}
- std::vector<std::string> objs;
- for (std::vector<cmSourceFile const*>::const_iterator it =
- objectSources.begin();
- it != objectSources.end(); ++it) {
- // Find the object file name corresponding to this source file.
- std::map<cmSourceFile const*, std::string>::const_iterator map_it =
- mapping.find(*it);
- // It must exist because we populated the mapping just above.
- assert(!map_it->second.empty());
- std::string objFile = obj_dir + map_it->second;
- objs.push_back(objFile);
- }
- std::vector<cmSourceFile const*> externalObjectSources;
- gt->GetExternalObjects(externalObjectSources, configName);
- for (std::vector<cmSourceFile const*>::const_iterator it =
- externalObjectSources.begin();
- it != externalObjectSources.end(); ++it) {
- objs.push_back((*it)->GetFullPath());
- }
- gt->UseObjectLibraries(objs, configName);
- for (std::vector<std::string>::iterator it = objs.begin(); it != objs.end();
- ++it) {
- std::string objFile = *it;
- // replace $(ConfigurationName) in the object names
- cmSystemTools::ReplaceString(objFile, this->GetCMakeCFGIntDir(),
- configName.c_str());
- if (cmHasLiteralSuffix(objFile, ".obj")) {
- fout << objFile << "\n";
+ if (mdi->WindowsExportAllSymbols) {
+ std::vector<std::string> objs;
+ for (std::vector<cmSourceFile const*>::const_iterator it =
+ objectSources.begin();
+ it != objectSources.end(); ++it) {
+ // Find the object file name corresponding to this source file.
+ std::map<cmSourceFile const*, std::string>::const_iterator map_it =
+ mapping.find(*it);
+ // It must exist because we populated the mapping just above.
+ assert(!map_it->second.empty());
+ std::string objFile = obj_dir + map_it->second;
+ objs.push_back(objFile);
+ }
+ std::vector<cmSourceFile const*> externalObjectSources;
+ gt->GetExternalObjects(externalObjectSources, configName);
+ for (std::vector<cmSourceFile const*>::const_iterator it =
+ externalObjectSources.begin();
+ it != externalObjectSources.end(); ++it) {
+ objs.push_back((*it)->GetFullPath());
+ }
+
+ gt->UseObjectLibraries(objs, configName);
+ for (std::vector<std::string>::iterator it = objs.begin();
+ it != objs.end(); ++it) {
+ std::string objFile = *it;
+ // replace $(ConfigurationName) in the object names
+ cmSystemTools::ReplaceString(objFile, this->GetCMakeCFGIntDir(),
+ configName.c_str());
+ if (cmHasLiteralSuffix(objFile, ".obj")) {
+ fout << objFile << "\n";
+ }
}
}
+
+ for (std::vector<cmSourceFile const*>::const_iterator i =
+ mdi->Sources.begin();
+ i != mdi->Sources.end(); ++i) {
+ fout << (*i)->GetFullPath() << "\n";
+ }
+
cmCustomCommandLines commandLines;
commandLines.push_back(cmdl);
cmCustomCommand command(gt->Target->GetMakefile(), outputs, empty, empty,
diff --git a/Source/cmLocalVisualStudio7Generator.cxx b/Source/cmLocalVisualStudio7Generator.cxx
index 8026de9f0b..06cca2a246 100644
--- a/Source/cmLocalVisualStudio7Generator.cxx
+++ b/Source/cmLocalVisualStudio7Generator.cxx
@@ -1818,7 +1818,7 @@ void cmLocalVisualStudio7Generator::OutputTargetRules(
bool addedPrelink = false;
cmGeneratorTarget::ModuleDefinitionInfo const* mdi =
target->GetModuleDefinitionInfo(configName);
- if (mdi && mdi->WindowsExportAllSymbols) {
+ if (mdi && mdi->DefFileGenerated) {
addedPrelink = true;
std::vector<cmCustomCommand> commands = target->GetPreLinkCommands();
cmGlobalVisualStudioGenerator* gg =
diff --git a/Source/cmMakefileTargetGenerator.cxx b/Source/cmMakefileTargetGenerator.cxx
index 1fa8702750..ed380242aa 100644
--- a/Source/cmMakefileTargetGenerator.cxx
+++ b/Source/cmMakefileTargetGenerator.cxx
@@ -1414,10 +1414,14 @@ void cmMakefileTargetGenerator::AppendLinkDepends(
this->AppendTargetDepends(depends);
// Add a dependency on the link definitions file, if any.
- cmGeneratorTarget::ModuleDefinitionInfo const* mdi =
- this->GeneratorTarget->GetModuleDefinitionInfo(this->GetConfigName());
- if (mdi && !mdi->WindowsExportAllSymbols && !mdi->DefFile.empty()) {
- depends.push_back(mdi->DefFile);
+ if (cmGeneratorTarget::ModuleDefinitionInfo const* mdi =
+ this->GeneratorTarget->GetModuleDefinitionInfo(
+ this->GetConfigName())) {
+ for (std::vector<cmSourceFile const*>::const_iterator i =
+ mdi->Sources.begin();
+ i != mdi->Sources.end(); ++i) {
+ depends.push_back((*i)->GetFullPath());
+ }
}
// Add a dependency on user-specified manifest files, if any.
@@ -1724,7 +1728,7 @@ void cmMakefileTargetGenerator::GenDefFile(
{
cmGeneratorTarget::ModuleDefinitionInfo const* mdi =
this->GeneratorTarget->GetModuleDefinitionInfo(this->GetConfigName());
- if (!mdi || !mdi->WindowsExportAllSymbols) {
+ if (!mdi || !mdi->DefFileGenerated) {
return;
}
std::string cmd = cmSystemTools::GetCMakeCommand();
@@ -1744,15 +1748,24 @@ void cmMakefileTargetGenerator::GenDefFile(
real_link_commands.insert(real_link_commands.begin(), cmd);
// create a list of obj files for the -E __create_def to read
cmGeneratedFileStream fout(objlist_file.c_str());
- for (std::vector<std::string>::const_iterator i = this->Objects.begin();
- i != this->Objects.end(); ++i) {
- if (cmHasLiteralSuffix(*i, ".obj")) {
+
+ if (mdi->WindowsExportAllSymbols) {
+ for (std::vector<std::string>::const_iterator i = this->Objects.begin();
+ i != this->Objects.end(); ++i) {
+ if (cmHasLiteralSuffix(*i, ".obj")) {
+ fout << *i << "\n";
+ }
+ }
+ for (std::vector<std::string>::const_iterator i =
+ this->ExternalObjects.begin();
+ i != this->ExternalObjects.end(); ++i) {
fout << *i << "\n";
}
}
- for (std::vector<std::string>::const_iterator i =
- this->ExternalObjects.begin();
- i != this->ExternalObjects.end(); ++i) {
- fout << *i << "\n";
+
+ for (std::vector<cmSourceFile const*>::const_iterator i =
+ mdi->Sources.begin();
+ i != mdi->Sources.end(); ++i) {
+ fout << (*i)->GetFullPath() << "\n";
}
}
diff --git a/Source/cmNinjaNormalTargetGenerator.cxx b/Source/cmNinjaNormalTargetGenerator.cxx
index 300618ff44..cd1407df62 100644
--- a/Source/cmNinjaNormalTargetGenerator.cxx
+++ b/Source/cmNinjaNormalTargetGenerator.cxx
@@ -978,7 +978,7 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement()
// maybe create .def file from list of objects
cmGeneratorTarget::ModuleDefinitionInfo const* mdi =
gt.GetModuleDefinitionInfo(this->GetConfigName());
- if (mdi && mdi->WindowsExportAllSymbols) {
+ if (mdi && mdi->DefFileGenerated) {
std::string cmakeCommand =
this->GetLocalGenerator()->ConvertToOutputFormat(
cmSystemTools::GetCMakeCommand(), cmOutputConverter::SHELL);
@@ -987,18 +987,28 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement()
cmd += this->GetLocalGenerator()->ConvertToOutputFormat(
mdi->DefFile, cmOutputConverter::SHELL);
cmd += " ";
- cmNinjaDeps objs = this->GetObjects();
std::string obj_list_file = mdi->DefFile + ".objs";
cmd += this->GetLocalGenerator()->ConvertToOutputFormat(
obj_list_file, cmOutputConverter::SHELL);
preLinkCmdLines.push_back(cmd);
+
// create a list of obj files for the -E __create_def to read
cmGeneratedFileStream fout(obj_list_file.c_str());
- for (cmNinjaDeps::iterator i = objs.begin(); i != objs.end(); ++i) {
- if (cmHasLiteralSuffix(*i, ".obj")) {
- fout << *i << "\n";
+
+ if (mdi->WindowsExportAllSymbols) {
+ cmNinjaDeps objs = this->GetObjects();
+ for (cmNinjaDeps::iterator i = objs.begin(); i != objs.end(); ++i) {
+ if (cmHasLiteralSuffix(*i, ".obj")) {
+ fout << *i << "\n";
+ }
}
}
+
+ for (std::vector<cmSourceFile const*>::const_iterator i =
+ mdi->Sources.begin();
+ i != mdi->Sources.end(); ++i) {
+ fout << (*i)->GetFullPath() << "\n";
+ }
}
// If we have any PRE_LINK commands, we need to go back to CMAKE_BINARY_DIR
// for
diff --git a/Source/cmNinjaTargetGenerator.cxx b/Source/cmNinjaTargetGenerator.cxx
index 917383d352..5866950dae 100644
--- a/Source/cmNinjaTargetGenerator.cxx
+++ b/Source/cmNinjaTargetGenerator.cxx
@@ -212,10 +212,14 @@ cmNinjaDeps cmNinjaTargetGenerator::ComputeLinkDeps() const
std::transform(deps.begin(), deps.end(), result.begin(), MapToNinjaPath());
// Add a dependency on the link definitions file, if any.
- cmGeneratorTarget::ModuleDefinitionInfo const* mdi =
- this->GeneratorTarget->GetModuleDefinitionInfo(this->GetConfigName());
- if (mdi && !mdi->WindowsExportAllSymbols && !mdi->DefFile.empty()) {
- result.push_back(this->ConvertToNinjaPath(mdi->DefFile));
+ if (cmGeneratorTarget::ModuleDefinitionInfo const* mdi =
+ this->GeneratorTarget->GetModuleDefinitionInfo(
+ this->GetConfigName())) {
+ for (std::vector<cmSourceFile const*>::const_iterator i =
+ mdi->Sources.begin();
+ i != mdi->Sources.end(); ++i) {
+ result.push_back(this->ConvertToNinjaPath((*i)->GetFullPath()));
+ }
}
// Add a dependency on user-specified manifest files, if any.
diff --git a/Source/cmVisualStudio10TargetGenerator.cxx b/Source/cmVisualStudio10TargetGenerator.cxx
index 4aea6f8e65..68f4e1d1df 100644
--- a/Source/cmVisualStudio10TargetGenerator.cxx
+++ b/Source/cmVisualStudio10TargetGenerator.cxx
@@ -3162,7 +3162,7 @@ void cmVisualStudio10TargetGenerator::WriteEvents(
bool addedPrelink = false;
cmGeneratorTarget::ModuleDefinitionInfo const* mdi =
this->GeneratorTarget->GetModuleDefinitionInfo(configName);
- if (mdi && mdi->WindowsExportAllSymbols) {
+ if (mdi && mdi->DefFileGenerated) {
addedPrelink = true;
std::vector<cmCustomCommand> commands =
this->GeneratorTarget->GetPreLinkCommands();