Refactor WINDOWS_EXPORT_ALL_SYMBOLS implementation

Use `cmGeneratorTarget::ModuleDefinitionInfo` to combine the
implementation of `WINDOWS_EXPORT_ALL_SYMBOLS` with that of using a
`.def` file as a source.  Only one of these could be used within a
single target before anyway.
This commit is contained in:
Brad King 2017-03-09 15:56:30 -05:00
parent 25d261efa7
commit f36eaf6a6e
11 changed files with 90 additions and 137 deletions

View File

@ -1975,7 +1975,12 @@ void cmGeneratorTarget::ComputeModuleDefinitionInfo(
{
std::vector<cmSourceFile const*> sources;
this->GetModuleDefinitionSources(sources, config);
if (!sources.empty()) {
info.WindowsExportAllSymbols =
this->Makefile->IsOn("CMAKE_SUPPORT_WINDOWS_EXPORT_ALL_SYMBOLS") &&
this->GetPropertyAsBool("WINDOWS_EXPORT_ALL_SYMBOLS");
if (info.WindowsExportAllSymbols) {
info.DefFile = this->ObjectDirectory /* has slash */ + "exports.def";
} else if (!sources.empty()) {
info.DefFile = sources.front()->GetFullPath();
}
}

View File

@ -238,6 +238,7 @@ public:
struct ModuleDefinitionInfo
{
std::string DefFile;
bool WindowsExportAllSymbols;
};
ModuleDefinitionInfo const* GetModuleDefinitionInfo(
std::string const& config) const;

View File

@ -814,10 +814,14 @@ void cmGlobalVisualStudioGenerator::AddSymbolExportCommand(
cmGeneratorTarget* gt, std::vector<cmCustomCommand>& commands,
std::string const& configName)
{
cmGeneratorTarget::ModuleDefinitionInfo const* mdi =
gt->GetModuleDefinitionInfo(configName);
if (!mdi || !mdi->WindowsExportAllSymbols) {
return;
}
std::vector<std::string> outputs;
std::string deffile = gt->ObjectDirectory;
deffile += "/exportall.def";
outputs.push_back(deffile);
outputs.push_back(mdi->DefFile);
std::vector<std::string> empty;
std::vector<cmSourceFile const*> objectSources;
gt->GetObjectSources(objectSources, configName);
@ -835,7 +839,7 @@ void cmGlobalVisualStudioGenerator::AddSymbolExportCommand(
cmdl.push_back(cmakeCommand);
cmdl.push_back("-E");
cmdl.push_back("__create_def");
cmdl.push_back(deffile);
cmdl.push_back(mdi->DefFile);
std::string obj_dir_expanded = obj_dir;
cmSystemTools::ReplaceString(obj_dir_expanded, this->GetCMakeCFGIntDir(),
configName.c_str());

View File

@ -1004,13 +1004,6 @@ void cmLocalVisualStudio7Generator::OutputBuildTool(
linkOptions.AddFlag("ModuleDefinitionFile", defFile.c_str());
}
if ((target->GetType() == cmStateEnums::SHARED_LIBRARY ||
target->IsExecutableWithExports()) &&
this->Makefile->IsOn("CMAKE_SUPPORT_WINDOWS_EXPORT_ALL_SYMBOLS")) {
if (target->GetPropertyAsBool("WINDOWS_EXPORT_ALL_SYMBOLS")) {
linkOptions.AddFlag("ModuleDefinitionFile", "$(IntDir)/exportall.def");
}
}
switch (target->GetType()) {
case cmStateEnums::UNKNOWN_LIBRARY:
break;
@ -1823,17 +1816,15 @@ void cmLocalVisualStudio7Generator::OutputTargetRules(
tool = this->FortranProject ? "VFPreLinkEventTool" : "VCPreLinkEventTool";
event.Start(tool);
bool addedPrelink = false;
if ((target->GetType() == cmStateEnums::SHARED_LIBRARY ||
target->IsExecutableWithExports()) &&
this->Makefile->IsOn("CMAKE_SUPPORT_WINDOWS_EXPORT_ALL_SYMBOLS")) {
if (target->GetPropertyAsBool("WINDOWS_EXPORT_ALL_SYMBOLS")) {
addedPrelink = true;
std::vector<cmCustomCommand> commands = target->GetPreLinkCommands();
cmGlobalVisualStudioGenerator* gg =
static_cast<cmGlobalVisualStudioGenerator*>(this->GlobalGenerator);
gg->AddSymbolExportCommand(target, commands, configName);
event.Write(commands);
}
cmGeneratorTarget::ModuleDefinitionInfo const* mdi =
target->GetModuleDefinitionInfo(configName);
if (mdi && mdi->WindowsExportAllSymbols) {
addedPrelink = true;
std::vector<cmCustomCommand> commands = target->GetPreLinkCommands();
cmGlobalVisualStudioGenerator* gg =
static_cast<cmGlobalVisualStudioGenerator*>(this->GlobalGenerator);
gg->AddSymbolExportCommand(target, commands, configName);
event.Write(commands);
}
if (!addedPrelink) {
event.Write(target->GetPreLinkCommands());

View File

@ -556,10 +556,7 @@ void cmMakefileExecutableTargetGenerator::WriteExecutableRule(bool relink)
}
// maybe create .def file from list of objects
if (this->GeneratorTarget->IsExecutableWithExports() &&
this->Makefile->IsOn("CMAKE_SUPPORT_WINDOWS_EXPORT_ALL_SYMBOLS")) {
this->GenDefFile(real_link_commands, linkFlags);
}
this->GenDefFile(real_link_commands);
std::string manifests = this->GetManifests();

View File

@ -750,10 +750,7 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules(
}
// maybe create .def file from list of objects
if (this->GeneratorTarget->GetType() == cmStateEnums::SHARED_LIBRARY &&
this->Makefile->IsOn("CMAKE_SUPPORT_WINDOWS_EXPORT_ALL_SYMBOLS")) {
this->GenDefFile(real_link_commands, linkFlags);
}
this->GenDefFile(real_link_commands);
std::string manifests = this->GetManifests();

View File

@ -1416,7 +1416,7 @@ void cmMakefileTargetGenerator::AppendLinkDepends(
// Add a dependency on the link definitions file, if any.
cmGeneratorTarget::ModuleDefinitionInfo const* mdi =
this->GeneratorTarget->GetModuleDefinitionInfo(this->GetConfigName());
if (mdi && !mdi->DefFile.empty()) {
if (mdi && !mdi->WindowsExportAllSymbols && !mdi->DefFile.empty()) {
depends.push_back(mdi->DefFile);
}
@ -1720,49 +1720,39 @@ void cmMakefileTargetGenerator::AddIncludeFlags(std::string& flags,
}
void cmMakefileTargetGenerator::GenDefFile(
std::vector<std::string>& real_link_commands, std::string& linkFlags)
std::vector<std::string>& real_link_commands)
{
if (this->GeneratorTarget->GetPropertyAsBool("WINDOWS_EXPORT_ALL_SYMBOLS")) {
std::string name_of_def_file =
this->GeneratorTarget->GetSupportDirectory();
name_of_def_file += std::string("/") + this->GeneratorTarget->GetName();
name_of_def_file += ".def";
std::string cmd = cmSystemTools::GetCMakeCommand();
cmd = this->LocalGenerator->ConvertToOutputFormat(
cmd, cmOutputConverter::SHELL);
cmd += " -E __create_def ";
cmd += this->LocalGenerator->ConvertToOutputFormat(
this->LocalGenerator->MaybeConvertToRelativePath(
this->LocalGenerator->GetCurrentBinaryDirectory(), name_of_def_file),
cmOutputConverter::SHELL);
cmd += " ";
std::string objlist_file = name_of_def_file;
objlist_file += ".objs";
cmd += this->LocalGenerator->ConvertToOutputFormat(
this->LocalGenerator->MaybeConvertToRelativePath(
this->LocalGenerator->GetCurrentBinaryDirectory(), objlist_file),
cmOutputConverter::SHELL);
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")) {
fout << *i << "\n";
}
}
for (std::vector<std::string>::const_iterator i =
this->ExternalObjects.begin();
i != this->ExternalObjects.end(); ++i) {
cmGeneratorTarget::ModuleDefinitionInfo const* mdi =
this->GeneratorTarget->GetModuleDefinitionInfo(this->GetConfigName());
if (!mdi || !mdi->WindowsExportAllSymbols) {
return;
}
std::string cmd = cmSystemTools::GetCMakeCommand();
cmd =
this->LocalGenerator->ConvertToOutputFormat(cmd, cmOutputConverter::SHELL);
cmd += " -E __create_def ";
cmd += this->LocalGenerator->ConvertToOutputFormat(
this->LocalGenerator->MaybeConvertToRelativePath(
this->LocalGenerator->GetCurrentBinaryDirectory(), mdi->DefFile),
cmOutputConverter::SHELL);
cmd += " ";
std::string objlist_file = mdi->DefFile + ".objs";
cmd += this->LocalGenerator->ConvertToOutputFormat(
this->LocalGenerator->MaybeConvertToRelativePath(
this->LocalGenerator->GetCurrentBinaryDirectory(), objlist_file),
cmOutputConverter::SHELL);
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")) {
fout << *i << "\n";
}
// now add the def file link flag
linkFlags += " ";
linkFlags += this->Makefile->GetSafeDefinition("CMAKE_LINK_DEF_FILE_FLAG");
linkFlags += this->LocalGenerator->ConvertToOutputFormat(
this->LocalGenerator->MaybeConvertToRelativePath(
this->LocalGenerator->GetCurrentBinaryDirectory(), name_of_def_file),
cmOutputConverter::SHELL);
linkFlags += " ";
}
for (std::vector<std::string>::const_iterator i =
this->ExternalObjects.begin();
i != this->ExternalObjects.end(); ++i) {
fout << *i << "\n";
}
}

View File

@ -166,8 +166,7 @@ protected:
bool useWatcomQuote);
/** Add commands for generate def files */
void GenDefFile(std::vector<std::string>& real_link_commands,
std::string& linkFlags);
void GenDefFile(std::vector<std::string>& real_link_commands);
void AddIncludeFlags(std::string& flags,
const std::string& lang) CM_OVERRIDE;

View File

@ -860,19 +860,6 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement()
linkLineComputer.get(), this->GetConfigName(), vars["LINK_LIBRARIES"],
vars["FLAGS"], vars["LINK_FLAGS"], frameworkPath, linkPath, &genTarget);
if (this->GetMakefile()->IsOn("CMAKE_SUPPORT_WINDOWS_EXPORT_ALL_SYMBOLS") &&
(gt.GetType() == cmStateEnums::SHARED_LIBRARY ||
gt.IsExecutableWithExports())) {
if (gt.GetPropertyAsBool("WINDOWS_EXPORT_ALL_SYMBOLS")) {
std::string name_of_def_file = gt.GetSupportDirectory();
name_of_def_file += "/" + gt.GetName();
name_of_def_file += ".def ";
vars["LINK_FLAGS"] += " /DEF:";
vars["LINK_FLAGS"] += this->GetLocalGenerator()->ConvertToOutputFormat(
name_of_def_file, cmOutputConverter::SHELL);
}
}
// Add OS X version flags, if any.
if (this->GeneratorTarget->GetType() == cmStateEnums::SHARED_LIBRARY ||
this->GeneratorTarget->GetType() == cmStateEnums::MODULE_LIBRARY) {
@ -989,33 +976,27 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement()
}
// maybe create .def file from list of objects
if ((gt.GetType() == cmStateEnums::SHARED_LIBRARY ||
gt.IsExecutableWithExports()) &&
this->GetMakefile()->IsOn("CMAKE_SUPPORT_WINDOWS_EXPORT_ALL_SYMBOLS")) {
if (gt.GetPropertyAsBool("WINDOWS_EXPORT_ALL_SYMBOLS")) {
std::string cmakeCommand =
this->GetLocalGenerator()->ConvertToOutputFormat(
cmSystemTools::GetCMakeCommand(), cmOutputConverter::SHELL);
std::string name_of_def_file = gt.GetSupportDirectory();
name_of_def_file += "/" + gt.GetName();
name_of_def_file += ".def";
std::string cmd = cmakeCommand;
cmd += " -E __create_def ";
cmd += this->GetLocalGenerator()->ConvertToOutputFormat(
name_of_def_file, cmOutputConverter::SHELL);
cmd += " ";
cmNinjaDeps objs = this->GetObjects();
std::string obj_list_file = name_of_def_file;
obj_list_file += ".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";
}
cmGeneratorTarget::ModuleDefinitionInfo const* mdi =
gt.GetModuleDefinitionInfo(this->GetConfigName());
if (mdi && mdi->WindowsExportAllSymbols) {
std::string cmakeCommand =
this->GetLocalGenerator()->ConvertToOutputFormat(
cmSystemTools::GetCMakeCommand(), cmOutputConverter::SHELL);
std::string cmd = cmakeCommand;
cmd += " -E __create_def ";
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";
}
}
}

View File

@ -214,7 +214,7 @@ cmNinjaDeps cmNinjaTargetGenerator::ComputeLinkDeps() const
// Add a dependency on the link definitions file, if any.
cmGeneratorTarget::ModuleDefinitionInfo const* mdi =
this->GeneratorTarget->GetModuleDefinitionInfo(this->GetConfigName());
if (mdi && !mdi->DefFile.empty()) {
if (mdi && !mdi->WindowsExportAllSymbols && !mdi->DefFile.empty()) {
result.push_back(this->ConvertToNinjaPath(mdi->DefFile));
}

View File

@ -2923,15 +2923,6 @@ bool cmVisualStudio10TargetGenerator::ComputeLinkOptions(
"%(IgnoreSpecificDefaultLibraries)");
}
if ((this->GeneratorTarget->GetType() == cmStateEnums::SHARED_LIBRARY ||
this->GeneratorTarget->IsExecutableWithExports()) &&
this->Makefile->IsOn("CMAKE_SUPPORT_WINDOWS_EXPORT_ALL_SYMBOLS")) {
if (this->GeneratorTarget->GetPropertyAsBool(
"WINDOWS_EXPORT_ALL_SYMBOLS")) {
linkOptions.AddFlag("ModuleDefinitionFile", "$(IntDir)exportall.def");
}
}
// Hack to fix flag version selection in a common use case.
// FIXME: Select flag table based on toolset instead of VS version.
if (this->LocalGenerator->GetVersion() >=
@ -3169,18 +3160,15 @@ void cmVisualStudio10TargetGenerator::WriteEvents(
std::string const& configName)
{
bool addedPrelink = false;
if ((this->GeneratorTarget->GetType() == cmStateEnums::SHARED_LIBRARY ||
this->GeneratorTarget->IsExecutableWithExports()) &&
this->Makefile->IsOn("CMAKE_SUPPORT_WINDOWS_EXPORT_ALL_SYMBOLS")) {
if (this->GeneratorTarget->GetPropertyAsBool(
"WINDOWS_EXPORT_ALL_SYMBOLS")) {
addedPrelink = true;
std::vector<cmCustomCommand> commands =
this->GeneratorTarget->GetPreLinkCommands();
this->GlobalGenerator->AddSymbolExportCommand(this->GeneratorTarget,
commands, configName);
this->WriteEvent("PreLinkEvent", commands, configName);
}
cmGeneratorTarget::ModuleDefinitionInfo const* mdi =
this->GeneratorTarget->GetModuleDefinitionInfo(configName);
if (mdi && mdi->WindowsExportAllSymbols) {
addedPrelink = true;
std::vector<cmCustomCommand> commands =
this->GeneratorTarget->GetPreLinkCommands();
this->GlobalGenerator->AddSymbolExportCommand(this->GeneratorTarget,
commands, configName);
this->WriteEvent("PreLinkEvent", commands, configName);
}
if (!addedPrelink) {
this->WriteEvent("PreLinkEvent",