From 024d05adada5b9deaac84f0f4df8beed273c972a Mon Sep 17 00:00:00 2001 From: Brad King Date: Tue, 29 Sep 2009 16:39:07 -0400 Subject: [PATCH] Fix use of module .def files for MS tools We recognize .def source files and map them to the /DEF: option in the MSVC tools. Previously this worked only for shared libraries. This commit cleans up the implementation and makes it work for executables too. See issue #9613. --- Source/cmLocalVisualStudio7Generator.cxx | 28 +++++-------------- Source/cmLocalVisualStudio7Generator.h | 1 - .../cmMakefileExecutableTargetGenerator.cxx | 2 ++ Source/cmMakefileLibraryTargetGenerator.cxx | 26 ++--------------- Source/cmMakefileTargetGenerator.cxx | 28 +++++++++++++++++++ Source/cmMakefileTargetGenerator.h | 6 ++++ Source/cmVisualStudio10TargetGenerator.cxx | 5 ++++ 7 files changed, 51 insertions(+), 45 deletions(-) diff --git a/Source/cmLocalVisualStudio7Generator.cxx b/Source/cmLocalVisualStudio7Generator.cxx index 13ad50865..8639adb10 100644 --- a/Source/cmLocalVisualStudio7Generator.cxx +++ b/Source/cmLocalVisualStudio7Generator.cxx @@ -887,6 +887,12 @@ void cmLocalVisualStudio7Generator::OutputBuildTool(std::ostream& fout, Options linkOptions(this, this->Version, Options::Linker, cmLocalVisualStudio7GeneratorLinkFlagTable); linkOptions.Parse(extraLinkOptions.c_str()); + if(!this->ModuleDefinitionFile.empty()) + { + std::string defFile = + this->ConvertToXMLOutputPath(this->ModuleDefinitionFile.c_str()); + linkOptions.AddFlag("ModuleDefinitionFile", defFile.c_str()); + } switch(target.GetType()) { case cmTarget::STATIC_LIBRARY: @@ -960,7 +966,6 @@ void cmLocalVisualStudio7Generator::OutputBuildTool(std::ostream& fout, fout << "\t\t\t\tAdditionalLibraryDirectories=\""; this->OutputLibraryDirectories(fout, cli.GetDirectories()); fout << "\"\n"; - this->OutputModuleDefinitionFile(fout, target); temp = target.GetDirectory(configName); temp += "/"; temp += targetNamePDB; @@ -1080,26 +1085,6 @@ cmLocalVisualStudio7Generator fout << "\t\t\t\tVersion=\"" << major << "." << minor << "\"\n"; } -void cmLocalVisualStudio7Generator -::OutputModuleDefinitionFile(std::ostream& fout, - cmTarget &target) -{ - std::vector const& classes = target.GetSourceFiles(); - for(std::vector::const_iterator i = classes.begin(); - i != classes.end(); i++) - { - cmSourceFile* sf = *i; - if(cmSystemTools::UpperCase(sf->GetExtension()) == "DEF") - { - fout << "\t\t\t\tModuleDefinitionFile=\"" - << this->ConvertToXMLOutputPath(sf->GetFullPath().c_str()) - << "\"\n"; - return; - } - } - -} - //---------------------------------------------------------------------------- void cmLocalVisualStudio7GeneratorInternals @@ -1174,6 +1159,7 @@ void cmLocalVisualStudio7Generator::WriteVCProjFile(std::ostream& fout, std::vector sourceGroups = this->Makefile->GetSourceGroups(); // get the classes from the source lists then add them to the groups + this->ModuleDefinitionFile = ""; std::vectorconst & classes = target.GetSourceFiles(); for(std::vector::const_iterator i = classes.begin(); i != classes.end(); i++) diff --git a/Source/cmLocalVisualStudio7Generator.h b/Source/cmLocalVisualStudio7Generator.h index b5fc405b6..19f7b97f7 100644 --- a/Source/cmLocalVisualStudio7Generator.h +++ b/Source/cmLocalVisualStudio7Generator.h @@ -102,7 +102,6 @@ private: cmTarget& t, bool debug); void OutputLibraryDirectories(std::ostream& fout, std::vector const& dirs); - void OutputModuleDefinitionFile(std::ostream& fout, cmTarget &target); void WriteProjectStart(std::ostream& fout, const char *libName, cmTarget &tgt, std::vector &sgs); void WriteProjectStartFortran(std::ostream& fout, const char *libName, diff --git a/Source/cmMakefileExecutableTargetGenerator.cxx b/Source/cmMakefileExecutableTargetGenerator.cxx index 48df82ae8..c7213a66c 100644 --- a/Source/cmMakefileExecutableTargetGenerator.cxx +++ b/Source/cmMakefileExecutableTargetGenerator.cxx @@ -243,6 +243,8 @@ void cmMakefileExecutableTargetGenerator::WriteExecutableRule(bool relink) this->LocalGenerator->AppendFlags (linkFlags, this->Target->GetProperty(linkFlagsConfig.c_str())); + this->AddModuleDefinitionFlag(linkFlags); + // Construct a list of files associated with this executable that // may need to be cleaned. std::vector exeCleanFiles; diff --git a/Source/cmMakefileLibraryTargetGenerator.cxx b/Source/cmMakefileLibraryTargetGenerator.cxx index bf704d890..9162b4c52 100644 --- a/Source/cmMakefileLibraryTargetGenerator.cxx +++ b/Source/cmMakefileLibraryTargetGenerator.cxx @@ -146,27 +146,8 @@ void cmMakefileLibraryTargetGenerator::WriteSharedLibraryRules(bool relink) this->LocalGenerator->AddConfigVariableFlags (extraFlags, "CMAKE_SHARED_LINKER_FLAGS", this->ConfigName); - if(this->Makefile->IsOn("WIN32") && !(this->Makefile->IsOn("CYGWIN") - || this->Makefile->IsOn("MINGW"))) - { - const std::vector& sources = - this->Target->GetSourceFiles(); - for(std::vector::const_iterator i = sources.begin(); - i != sources.end(); ++i) - { - cmSourceFile* sf = *i; - if(sf->GetExtension() == "def") - { - extraFlags += " "; - extraFlags += - this->Makefile->GetSafeDefinition("CMAKE_LINK_DEF_FILE_FLAG"); - extraFlags += - this->Convert(sf->GetFullPath().c_str(), - cmLocalGenerator::START_OUTPUT, - cmLocalGenerator::SHELL); - } - } - } + this->AddModuleDefinitionFlag(extraFlags); + this->WriteLibraryRules(linkRuleVar.c_str(), extraFlags.c_str(), relink); } @@ -191,8 +172,8 @@ void cmMakefileLibraryTargetGenerator::WriteModuleLibraryRules(bool relink) (extraFlags, this->Target->GetProperty(linkFlagsConfig.c_str())); this->LocalGenerator->AddConfigVariableFlags (extraFlags, "CMAKE_MODULE_LINKER_FLAGS", this->ConfigName); + this->AddModuleDefinitionFlag(extraFlags); - // TODO: .def files should be supported here also. this->WriteLibraryRules(linkRuleVar.c_str(), extraFlags.c_str(), relink); } @@ -218,7 +199,6 @@ void cmMakefileLibraryTargetGenerator::WriteFrameworkRules(bool relink) this->LocalGenerator->AddConfigVariableFlags (extraFlags, "CMAKE_MACOSX_FRAMEWORK_LINKER_FLAGS", this->ConfigName); - // TODO: .def files should be supported here also. this->WriteLibraryRules(linkRuleVar.c_str(), extraFlags.c_str(), relink); } diff --git a/Source/cmMakefileTargetGenerator.cxx b/Source/cmMakefileTargetGenerator.cxx index 5a8c0aa2e..94e0833fc 100644 --- a/Source/cmMakefileTargetGenerator.cxx +++ b/Source/cmMakefileTargetGenerator.cxx @@ -170,6 +170,10 @@ void cmMakefileTargetGenerator::WriteTargetBuildRules() // This is an external object file. Just add it. this->ExternalObjects.push_back((*source)->GetFullPath()); } + else if(cmSystemTools::UpperCase((*source)->GetExtension()) == "DEF") + { + this->ModuleDefinitionFile = (*source)->GetFullPath(); + } else { // We only get here if a source file is not an external object @@ -1734,3 +1738,27 @@ void cmMakefileTargetGenerator::AddFortranFlags(std::string& flags) } } } + +//---------------------------------------------------------------------------- +void cmMakefileTargetGenerator::AddModuleDefinitionFlag(std::string& flags) +{ + if(this->ModuleDefinitionFile.empty()) + { + return; + } + + // TODO: Create a per-language flag variable. + const char* defFileFlag = + this->Makefile->GetDefinition("CMAKE_LINK_DEF_FILE_FLAG"); + if(!defFileFlag) + { + return; + } + + // Append the flag and value. + std::string flag = defFileFlag; + flag += this->Convert(this->ModuleDefinitionFile.c_str(), + cmLocalGenerator::START_OUTPUT, + cmLocalGenerator::SHELL); + this->LocalGenerator->AppendFlags(flags, flag.c_str()); +} diff --git a/Source/cmMakefileTargetGenerator.h b/Source/cmMakefileTargetGenerator.h index c36ec5990..6878e0643 100644 --- a/Source/cmMakefileTargetGenerator.h +++ b/Source/cmMakefileTargetGenerator.h @@ -186,6 +186,9 @@ protected: std::vector Objects; std::vector ExternalObjects; + // The windows module definition source file (.def), if any. + std::string ModuleDefinitionFile; + // Set of object file names that will be built in this directory. std::set ObjectFiles; @@ -214,6 +217,9 @@ protected: // Compute target-specific Fortran language flags. void AddFortranFlags(std::string& flags); + // Helper to add flag for windows .def file. + void AddModuleDefinitionFlag(std::string& flags); + //================================================================== // Convenience routines that do nothing more than forward to // implementaitons diff --git a/Source/cmVisualStudio10TargetGenerator.cxx b/Source/cmVisualStudio10TargetGenerator.cxx index b7991b6d1..e7a8784f0 100644 --- a/Source/cmVisualStudio10TargetGenerator.cxx +++ b/Source/cmVisualStudio10TargetGenerator.cxx @@ -1125,6 +1125,11 @@ void cmVisualStudio10TargetGenerator::WriteLinkOptions(std::string const& linkOptions.AddFlag("ImportLibrary", imLib.c_str()); linkOptions.AddFlag("ProgramDataBaseFileName", pdb.c_str()); linkOptions.Parse(flags.c_str()); + if(!this->ModuleDefinitionFile.empty()) + { + linkOptions.AddFlag("ModuleDefinitionFile", + this->ModuleDefinitionFile.c_str()); + } linkOptions.OutputAdditionalOptions(*this->BuildFileStream, " ", ""); linkOptions.OutputFlagMap(*this->BuildFileStream, " ");