Selaa lähdekoodia

Windows: Honor WINDOWS_EXPORT_ALL_SYMBOLS for executables with exports

For executables with ENABLE_EXPORTS set, export all symbols when
instructed to do so by WINDOWS_EXPORT_ALL_SYMBOLS.
Yury Zhuravlev 9 vuotta sitten
vanhempi
sitoutus
9da725cb00

+ 3 - 2
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

+ 5 - 0
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.

+ 4 - 2
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;

+ 6 - 0
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;

+ 4 - 2
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 =

+ 2 - 1
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);
   }
 

+ 4 - 2
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")) {

+ 6 - 0
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)

+ 8 - 0
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));
+}

+ 8 - 0
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)