diff options
author | Brad King <brad.king@kitware.com> | 2016-07-13 13:26:33 (GMT) |
---|---|---|
committer | CMake Topic Stage <kwrobot@kitware.com> | 2016-07-13 13:26:33 (GMT) |
commit | 40f24f0ec266c15f8e887cb7e2be957b23d32c6a (patch) | |
tree | ce34ee18e51424d6e5240bff92a27c09510fdcae | |
parent | 43875ca59ce4084bd1bd857e4d3e1c18b682a466 (diff) | |
parent | 9da725cb00d25c7d3f45e8ee8c943ec5241d6227 (diff) | |
download | CMake-40f24f0ec266c15f8e887cb7e2be957b23d32c6a.zip CMake-40f24f0ec266c15f8e887cb7e2be957b23d32c6a.tar.gz CMake-40f24f0ec266c15f8e887cb7e2be957b23d32c6a.tar.bz2 |
Merge topic 'windows-export-all-from-exe'
9da725cb Windows: Honor WINDOWS_EXPORT_ALL_SYMBOLS for executables with exports
2005b960 Makefile: Factor out WINDOWS_EXPORT_ALL_SYMBOLS helper
-rw-r--r-- | Help/prop_tgt/WINDOWS_EXPORT_ALL_SYMBOLS.rst | 5 | ||||
-rw-r--r-- | Help/release/dev/windows-export-all-from-exe.rst | 5 | ||||
-rw-r--r-- | Source/cmLocalVisualStudio7Generator.cxx | 6 | ||||
-rw-r--r-- | Source/cmMakefileExecutableTargetGenerator.cxx | 6 | ||||
-rw-r--r-- | Source/cmMakefileLibraryTargetGenerator.cxx | 43 | ||||
-rw-r--r-- | Source/cmMakefileTargetGenerator.cxx | 43 | ||||
-rw-r--r-- | Source/cmMakefileTargetGenerator.h | 4 | ||||
-rw-r--r-- | Source/cmNinjaNormalTargetGenerator.cxx | 6 | ||||
-rw-r--r-- | Source/cmTarget.cxx | 3 | ||||
-rw-r--r-- | Source/cmVisualStudio10TargetGenerator.cxx | 6 | ||||
-rw-r--r-- | Tests/RunCMake/AutoExportDll/AutoExport.cmake | 6 | ||||
-rw-r--r-- | Tests/RunCMake/AutoExportDll/hello2.c | 8 | ||||
-rw-r--r-- | Tests/RunCMake/AutoExportDll/say.cxx | 8 |
13 files changed, 98 insertions, 51 deletions
diff --git a/Help/prop_tgt/WINDOWS_EXPORT_ALL_SYMBOLS.rst b/Help/prop_tgt/WINDOWS_EXPORT_ALL_SYMBOLS.rst index 3f48af8..06c3e6d 100644 --- a/Help/prop_tgt/WINDOWS_EXPORT_ALL_SYMBOLS.rst +++ b/Help/prop_tgt/WINDOWS_EXPORT_ALL_SYMBOLS.rst @@ -5,8 +5,9 @@ This property is implemented only for MS-compatible tools on Windows. Enable this boolean property to automatically create a module definition (``.def``) file with all global symbols found in the input ``.obj`` files -for a ``SHARED`` library on Windows. The module definition file will be -passed to the linker causing all symbols to be exported from the ``.dll``. +for a ``SHARED`` library (or executable with :prop_tgt:`ENABLE_EXPORTS`) +on Windows. The module definition file will be passed to the linker +causing all symbols to be exported from the ``.dll``. For global *data* symbols, ``__declspec(dllimport)`` must still be used when compiling against the code in the ``.dll``. All other function symbols will be automatically exported and imported by callers. This simplifies porting diff --git a/Help/release/dev/windows-export-all-from-exe.rst b/Help/release/dev/windows-export-all-from-exe.rst new file mode 100644 index 0000000..48c16ec --- /dev/null +++ b/Help/release/dev/windows-export-all-from-exe.rst @@ -0,0 +1,5 @@ +windows-export-all-from-exe +--------------------------- + +* The :prop_tgt:`WINDOWS_EXPORT_ALL_SYMBOLS` target property now applies + to executable targets with the :prop_tgt:`ENABLE_EXPORTS` property set. diff --git a/Source/cmLocalVisualStudio7Generator.cxx b/Source/cmLocalVisualStudio7Generator.cxx index c38e99c..e72abe9 100644 --- a/Source/cmLocalVisualStudio7Generator.cxx +++ b/Source/cmLocalVisualStudio7Generator.cxx @@ -1013,7 +1013,8 @@ void cmLocalVisualStudio7Generator::OutputBuildTool( linkOptions.AddFlag("ModuleDefinitionFile", defFile.c_str()); } - if (target->GetType() == cmState::SHARED_LIBRARY && + if ((target->GetType() == cmState::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"); @@ -1836,7 +1837,8 @@ void cmLocalVisualStudio7Generator::OutputTargetRules( tool = this->FortranProject ? "VFPreLinkEventTool" : "VCPreLinkEventTool"; event.Start(tool); bool addedPrelink = false; - if (target->GetType() == cmState::SHARED_LIBRARY && + if ((target->GetType() == cmState::SHARED_LIBRARY || + target->IsExecutableWithExports()) && this->Makefile->IsOn("CMAKE_SUPPORT_WINDOWS_EXPORT_ALL_SYMBOLS")) { if (target->GetPropertyAsBool("WINDOWS_EXPORT_ALL_SYMBOLS")) { addedPrelink = true; diff --git a/Source/cmMakefileExecutableTargetGenerator.cxx b/Source/cmMakefileExecutableTargetGenerator.cxx index 9a37a33..8730ccd 100644 --- a/Source/cmMakefileExecutableTargetGenerator.cxx +++ b/Source/cmMakefileExecutableTargetGenerator.cxx @@ -318,6 +318,12 @@ void cmMakefileExecutableTargetGenerator::WriteExecutableRule(bool relink) this->CreateObjectLists(useLinkScript, false, useResponseFileForObjects, buildObjs, depends, useWatcomQuote); + // 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); + } + std::string manifests = this->GetManifests(); cmLocalGenerator::RuleVariables vars; diff --git a/Source/cmMakefileLibraryTargetGenerator.cxx b/Source/cmMakefileLibraryTargetGenerator.cxx index 380fd7d..7de2db0 100644 --- a/Source/cmMakefileLibraryTargetGenerator.cxx +++ b/Source/cmMakefileLibraryTargetGenerator.cxx @@ -521,48 +521,7 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules( // maybe create .def file from list of objects if (this->GeneratorTarget->GetType() == cmState::SHARED_LIBRARY && this->Makefile->IsOn("CMAKE_SUPPORT_WINDOWS_EXPORT_ALL_SYMBOLS")) { - 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->Convert(cmd, cmOutputConverter::NONE, - cmOutputConverter::SHELL); - cmd += " -E __create_def "; - cmd += this->Convert(name_of_def_file, cmOutputConverter::START_OUTPUT, - cmOutputConverter::SHELL); - cmd += " "; - std::string objlist_file = name_of_def_file; - objlist_file += ".objs"; - cmd += this->Convert(objlist_file, cmOutputConverter::START_OUTPUT, - cmOutputConverter::SHELL); - real_link_commands.push_back(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) { - fout << *i << "\n"; - } - // now add the def file link flag - linkFlags += " "; - linkFlags += - this->Makefile->GetSafeDefinition("CMAKE_LINK_DEF_FILE_FLAG"); - linkFlags += - this->Convert(name_of_def_file, cmOutputConverter::START_OUTPUT, - cmOutputConverter::SHELL); - linkFlags += " "; - } + this->GenDefFile(real_link_commands, linkFlags); } std::string manifests = this->GetManifests(); diff --git a/Source/cmMakefileTargetGenerator.cxx b/Source/cmMakefileTargetGenerator.cxx index 2f9c4da..00b1219 100644 --- a/Source/cmMakefileTargetGenerator.cxx +++ b/Source/cmMakefileTargetGenerator.cxx @@ -1595,3 +1595,46 @@ void cmMakefileTargetGenerator::AddIncludeFlags(std::string& flags, this->LocalGenerator->AppendFlags(flags, includeFlags); } } + +void cmMakefileTargetGenerator::GenDefFile( + std::vector<std::string>& real_link_commands, std::string& linkFlags) +{ + 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->Convert(cmd, cmOutputConverter::NONE, cmOutputConverter::SHELL); + cmd += " -E __create_def "; + cmd += this->Convert(name_of_def_file, cmOutputConverter::START_OUTPUT, + cmOutputConverter::SHELL); + cmd += " "; + std::string objlist_file = name_of_def_file; + objlist_file += ".objs"; + cmd += this->Convert(objlist_file, cmOutputConverter::START_OUTPUT, + 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) { + fout << *i << "\n"; + } + // now add the def file link flag + linkFlags += " "; + linkFlags += this->Makefile->GetSafeDefinition("CMAKE_LINK_DEF_FILE_FLAG"); + linkFlags += + this->Convert(name_of_def_file, cmOutputConverter::START_OUTPUT, + cmOutputConverter::SHELL); + linkFlags += " "; + } +} diff --git a/Source/cmMakefileTargetGenerator.h b/Source/cmMakefileTargetGenerator.h index 7749d8b..4284549 100644 --- a/Source/cmMakefileTargetGenerator.h +++ b/Source/cmMakefileTargetGenerator.h @@ -162,6 +162,10 @@ protected: std::vector<std::string>& makefile_depends, bool useWatcomQuote); + /** Add commands for generate def files */ + void GenDefFile(std::vector<std::string>& real_link_commands, + std::string& linkFlags); + void AddIncludeFlags(std::string& flags, const std::string& lang) CM_OVERRIDE; diff --git a/Source/cmNinjaNormalTargetGenerator.cxx b/Source/cmNinjaNormalTargetGenerator.cxx index 77d3901..81a1618 100644 --- a/Source/cmNinjaNormalTargetGenerator.cxx +++ b/Source/cmNinjaNormalTargetGenerator.cxx @@ -472,7 +472,8 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement() vars["FLAGS"], vars["LINK_FLAGS"], frameworkPath, linkPath, &genTarget, useWatcomQuote); if (this->GetMakefile()->IsOn("CMAKE_SUPPORT_WINDOWS_EXPORT_ALL_SYMBOLS") && - gt.GetType() == cmState::SHARED_LIBRARY) { + (gt.GetType() == cmState::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(); @@ -599,7 +600,8 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement() } // maybe create .def file from list of objects - if (gt.GetType() == cmState::SHARED_LIBRARY && + if ((gt.GetType() == cmState::SHARED_LIBRARY || + gt.IsExecutableWithExports()) && this->GetMakefile()->IsOn("CMAKE_SUPPORT_WINDOWS_EXPORT_ALL_SYMBOLS")) { if (gt.GetPropertyAsBool("WINDOWS_EXPORT_ALL_SYMBOLS")) { std::string cmakeCommand = diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx index ceebf93..8476538 100644 --- a/Source/cmTarget.cxx +++ b/Source/cmTarget.cxx @@ -253,7 +253,8 @@ void cmTarget::SetMakefile(cmMakefile* mf) this->TargetTypeValue == cmState::MODULE_LIBRARY) { this->SetProperty("POSITION_INDEPENDENT_CODE", "True"); } - if (this->TargetTypeValue == cmState::SHARED_LIBRARY) { + if (this->TargetTypeValue == cmState::SHARED_LIBRARY || + this->TargetTypeValue == cmState::EXECUTABLE) { this->SetPropertyDefault("WINDOWS_EXPORT_ALL_SYMBOLS", CM_NULLPTR); } diff --git a/Source/cmVisualStudio10TargetGenerator.cxx b/Source/cmVisualStudio10TargetGenerator.cxx index 13e7c89..50da41b 100644 --- a/Source/cmVisualStudio10TargetGenerator.cxx +++ b/Source/cmVisualStudio10TargetGenerator.cxx @@ -2343,7 +2343,8 @@ bool cmVisualStudio10TargetGenerator::ComputeLinkOptions( "%(IgnoreSpecificDefaultLibraries)"); } - if (this->GeneratorTarget->GetType() == cmState::SHARED_LIBRARY && + if ((this->GeneratorTarget->GetType() == cmState::SHARED_LIBRARY || + this->GeneratorTarget->IsExecutableWithExports()) && this->Makefile->IsOn("CMAKE_SUPPORT_WINDOWS_EXPORT_ALL_SYMBOLS")) { if (this->GeneratorTarget->GetPropertyAsBool( "WINDOWS_EXPORT_ALL_SYMBOLS")) { @@ -2506,7 +2507,8 @@ void cmVisualStudio10TargetGenerator::WriteEvents( std::string const& configName) { bool addedPrelink = false; - if (this->GeneratorTarget->GetType() == cmState::SHARED_LIBRARY && + if ((this->GeneratorTarget->GetType() == cmState::SHARED_LIBRARY || + this->GeneratorTarget->IsExecutableWithExports()) && this->Makefile->IsOn("CMAKE_SUPPORT_WINDOWS_EXPORT_ALL_SYMBOLS")) { if (this->GeneratorTarget->GetPropertyAsBool( "WINDOWS_EXPORT_ALL_SYMBOLS")) { diff --git a/Tests/RunCMake/AutoExportDll/AutoExport.cmake b/Tests/RunCMake/AutoExportDll/AutoExport.cmake index 3b2b2c5..bdddb38 100644 --- a/Tests/RunCMake/AutoExportDll/AutoExport.cmake +++ b/Tests/RunCMake/AutoExportDll/AutoExport.cmake @@ -3,5 +3,11 @@ set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS TRUE) set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${autoexport_BINARY_DIR}/bin) add_subdirectory(sub) add_library(autoexport SHARED hello.cxx world.cxx foo.c) + add_executable(say say.cxx) +if(MSVC) + set_target_properties(say PROPERTIES ENABLE_EXPORTS ON) + add_library(autoexport_for_exec SHARED hello2.c) + target_link_libraries(autoexport_for_exec say) +endif() target_link_libraries(say autoexport autoexport2) diff --git a/Tests/RunCMake/AutoExportDll/hello2.c b/Tests/RunCMake/AutoExportDll/hello2.c new file mode 100644 index 0000000..d4d6b72 --- /dev/null +++ b/Tests/RunCMake/AutoExportDll/hello2.c @@ -0,0 +1,8 @@ +#include <stdio.h> + +extern int own_auto_export_function(int i); + +void hello2() +{ + printf("hello exec:%i", own_auto_export_function(41)); +} diff --git a/Tests/RunCMake/AutoExportDll/say.cxx b/Tests/RunCMake/AutoExportDll/say.cxx index 0178688..9ca8d31 100644 --- a/Tests/RunCMake/AutoExportDll/say.cxx +++ b/Tests/RunCMake/AutoExportDll/say.cxx @@ -18,6 +18,14 @@ int bar(); void hello(); void world(); +// test exports for executable target +extern "C" { +int own_auto_export_function(int i) +{ + return i + 1; +} +} + int main() { // test static data (needs declspec to work) |