diff options
author | Brad King <brad.king@kitware.com> | 2017-03-13 11:54:30 -0400 |
---|---|---|
committer | Brad King <brad.king@kitware.com> | 2017-03-21 10:02:34 -0400 |
commit | 075f6454092ae058add228eda8220a3680b2f9e4 (patch) | |
tree | c0bff4ce5eaf25b8e38d904f3cfb64ebfc13265b /Source | |
parent | 21c4ec4ffe1c40382f6b435ff49eade31e1137f2 (diff) | |
download | cmake-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.cxx | 11 | ||||
-rw-r--r-- | Source/cmGeneratorTarget.h | 2 | ||||
-rw-r--r-- | Source/cmGlobalVisualStudioGenerator.cxx | 68 | ||||
-rw-r--r-- | Source/cmLocalVisualStudio7Generator.cxx | 2 | ||||
-rw-r--r-- | Source/cmMakefileTargetGenerator.cxx | 37 | ||||
-rw-r--r-- | Source/cmNinjaNormalTargetGenerator.cxx | 20 | ||||
-rw-r--r-- | Source/cmNinjaTargetGenerator.cxx | 12 | ||||
-rw-r--r-- | Source/cmVisualStudio10TargetGenerator.cxx | 2 |
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(); |