Browse Source

VS: Restore subsystem link flag for DLLs

In commit 99d09ec45a (VS: Suppress MSBuild default link flags not
specified by project or user, 2025-06-17, v4.1.0-rc1~6^2) we removed our
default `-subsystem:...` link flag from `SHARED` and `MODULE` libraries
in Visual Studio generators for consistency with command-line generators.
However, unlike other flag suppressions for #27004, this change did not
just suppress MSBuild defaults, but actually changed flags the generator
was previously adding itself.

For the linker subsystem flag, consistency across generators should
perhaps achieved by adding the flag in other generators instead of
removing it from Visual Studio generators.  Restore the previous
behavior pending further investigation.

Issue: #27466
Fixes: #27464
Brad King 1 month ago
parent
commit
91b9db90e5

+ 22 - 25
Source/cmVisualStudio10TargetGenerator.cxx

@@ -4576,35 +4576,32 @@ bool cmVisualStudio10TargetGenerator::ComputeLinkOptions(
   }
 
   if (this->MSTools) {
-    if (this->GeneratorTarget->GetType() == cmStateEnums::EXECUTABLE) {
-      // Specify an entry point for executables.
-      if (this->GeneratorTarget->IsWin32Executable(config)) {
-        if (this->GlobalGenerator->TargetsWindowsCE()) {
-          linkOptions.AddFlag("SubSystem", "WindowsCE");
-          if (this->GeneratorTarget->GetType() == cmStateEnums::EXECUTABLE) {
-            if (this->ClOptions[config]->UsingUnicode()) {
-              linkOptions.AddFlag("EntryPointSymbol", "wWinMainCRTStartup");
-            } else {
-              linkOptions.AddFlag("EntryPointSymbol", "WinMainCRTStartup");
-            }
+    if (this->GeneratorTarget->IsWin32Executable(config)) {
+      if (this->GlobalGenerator->TargetsWindowsCE()) {
+        linkOptions.AddFlag("SubSystem", "WindowsCE");
+        if (this->GeneratorTarget->GetType() == cmStateEnums::EXECUTABLE) {
+          if (this->ClOptions[config]->UsingUnicode()) {
+            linkOptions.AddFlag("EntryPointSymbol", "wWinMainCRTStartup");
+          } else {
+            linkOptions.AddFlag("EntryPointSymbol", "WinMainCRTStartup");
           }
-        } else {
-          linkOptions.AddFlag("SubSystem", "Windows");
         }
       } else {
-        if (this->GlobalGenerator->TargetsWindowsCE()) {
-          linkOptions.AddFlag("SubSystem", "WindowsCE");
-          if (this->GeneratorTarget->GetType() == cmStateEnums::EXECUTABLE) {
-            if (this->ClOptions[config]->UsingUnicode()) {
-              linkOptions.AddFlag("EntryPointSymbol", "mainWCRTStartup");
-            } else {
-              linkOptions.AddFlag("EntryPointSymbol", "mainACRTStartup");
-            }
-          }
-        } else {
-          linkOptions.AddFlag("SubSystem", "Console");
-        };
+        linkOptions.AddFlag("SubSystem", "Windows");
       }
+    } else {
+      if (this->GlobalGenerator->TargetsWindowsCE()) {
+        linkOptions.AddFlag("SubSystem", "WindowsCE");
+        if (this->GeneratorTarget->GetType() == cmStateEnums::EXECUTABLE) {
+          if (this->ClOptions[config]->UsingUnicode()) {
+            linkOptions.AddFlag("EntryPointSymbol", "mainWCRTStartup");
+          } else {
+            linkOptions.AddFlag("EntryPointSymbol", "mainACRTStartup");
+          }
+        }
+      } else {
+        linkOptions.AddFlag("SubSystem", "Console");
+      };
     }
 
     if (cmValue stackVal = this->Makefile->GetDefinition(

+ 12 - 24
Tests/RunCMake/VS10Project/VsDefaultFlags-check.cmake

@@ -38,12 +38,12 @@ macro(VsDefaultCompilerFlags_check tgt)
   endif()
 endmacro()
 
-macro(VsDefaultLinkerFlags_check tgt needs_subsystem_console)
+macro(VsDefaultLinkerFlags_check tgt)
   set(HAVE_DataExecutionPrevention 0)
   set(HAVE_ImageHasSafeExceptionHandlers 0)
   set(HAVE_LinkErrorReporting 0)
   set(HAVE_RandomizedBaseAddress 0)
-  set(HAVE_SubSystem 0)
+  set(HAVE_SubSystem_Empty 0)
   set(HAVE_SubSystem_Console 0)
 
   file(STRINGS "${vcProjectFile}" lines)
@@ -61,7 +61,7 @@ macro(VsDefaultLinkerFlags_check tgt needs_subsystem_console)
       set(HAVE_RandomizedBaseAddress 1)
     endif()
     if(line MATCHES "^ *<SubSystem></SubSystem>")
-      set(HAVE_SubSystem 1)
+      set(HAVE_SubSystem_Empty 1)
     endif()
     if(line MATCHES "^ *<SubSystem>Console</SubSystem>")
       set(HAVE_SubSystem_Console 1)
@@ -88,33 +88,21 @@ macro(VsDefaultLinkerFlags_check tgt needs_subsystem_console)
     return()
   endif()
 
-  if(${needs_subsystem_console})
-    if(HAVE_SubSystem)
-      set(RunCMake_TEST_FAILED "Project file ${tgt}.vcxproj has a <SubSystem> property.")
-      return()
-    endif()
-
-    if(NOT HAVE_SubSystem_Console)
-      set(RunCMake_TEST_FAILED "Project file ${tgt}.vcxproj does not have a <SubSystem> property with 'Console' value.")
-      return()
-    endif()
-  else()
-    if(NOT HAVE_SubSystem)
-      set(RunCMake_TEST_FAILED "Project file ${tgt}.vcxproj does not have a <SubSystem> property.")
-      return()
-    endif()
+  if(HAVE_SubSystem_Empty)
+    set(RunCMake_TEST_FAILED "Project file ${tgt}.vcxproj has a <SubSystem> property.")
+    return()
+  endif()
 
-    if(HAVE_SubSystem_Console)
-      set(RunCMake_TEST_FAILED "Project file ${tgt}.vcxproj has a <SubSystem> property with 'Console' value.")
-      return()
-    endif()
+  if(NOT HAVE_SubSystem_Console)
+    set(RunCMake_TEST_FAILED "Project file ${tgt}.vcxproj does not have a <SubSystem> property with 'Console' value.")
+    return()
   endif()
 endmacro()
 
 VsDefaultCompilerFlags_check(emptyStatic)
 
 VsDefaultCompilerFlags_check(emptyShared)
-VsDefaultLinkerFlags_check(emptyShared OFF)
+VsDefaultLinkerFlags_check(emptyShared)
 
 VsDefaultCompilerFlags_check(main)
-VsDefaultLinkerFlags_check(main ON)
+VsDefaultLinkerFlags_check(main)