Bladeren bron

MSVC: Define _WINDLL consistently for shared libraries

Visual Studio defines this automatically for `.dll` targets.
For consistency, define it when compiling for the MSVC ABI
with other generators.  Add policy CMP0203 for compatibility.

Fixes: #27253
AJIOB 1 maand geleden
bovenliggende
commit
83bbde5449
43 gewijzigde bestanden met toevoegingen van 268 en 45 verwijderingen
  1. 1 0
      Help/manual/cmake-policies.7.rst
  2. 28 0
      Help/policy/CMP0203.rst
  3. 6 0
      Help/release/dev/define-windll.rst
  4. 1 0
      Modules/Platform/Windows-Clang.cmake
  5. 2 0
      Modules/Platform/Windows-MSVC.cmake
  6. 1 0
      Modules/Platform/Windows-NVIDIA-CUDA.cmake
  7. 30 0
      Source/cmGeneratorTarget.cxx
  8. 7 0
      Source/cmGeneratorTarget.h
  9. 4 0
      Source/cmGlobalXCodeGenerator.cxx
  10. 4 0
      Source/cmLocalGenerator.cxx
  11. 2 0
      Source/cmLocalVisualStudio7Generator.cxx
  12. 5 1
      Source/cmPolicies.h
  13. 4 0
      Source/cmVisualStudio10TargetGenerator.cxx
  14. 10 0
      Tests/RunCMake/CMakeLists.txt
  15. 1 0
      Tests/RunCMake/FileAPI/RunCMakeTest.cmake
  16. 1 0
      Tests/RunCMake/FileAPI/check_index.py
  17. 12 0
      Tests/RunCMake/FileAPI/codemodel-v2-check.py
  18. 13 13
      Tests/RunCMake/FileAPI/codemodel-v2-data/directories/top.json
  19. 3 3
      Tests/RunCMake/FileAPI/codemodel-v2-data/targets/c_exe.json
  20. 2 2
      Tests/RunCMake/FileAPI/codemodel-v2-data/targets/c_lib.json
  21. 3 3
      Tests/RunCMake/FileAPI/codemodel-v2-data/targets/c_shared_exe.json
  22. 9 5
      Tests/RunCMake/FileAPI/codemodel-v2-data/targets/c_shared_lib.json
  23. 3 3
      Tests/RunCMake/FileAPI/codemodel-v2-data/targets/c_static_exe.json
  24. 2 2
      Tests/RunCMake/FileAPI/codemodel-v2-data/targets/c_static_lib.json
  25. 1 1
      Tests/RunCMake/FileAPI/codemodel-v2-data/targets/c_subdir.json
  26. 1 1
      Tests/RunCMake/FileAPI/codemodel-v2-data/targets/cxx_exe.json
  27. 7 3
      Tests/RunCMake/FileAPI/codemodel-v2-data/targets/cxx_shared_lib.json
  28. 3 3
      Tests/RunCMake/FileAPI/codemodel-v2-data/targets/interface_exe.json
  29. 1 1
      Tests/RunCMake/FileAPI/codemodel-v2-data/targets/interface_lib.json
  30. 4 0
      Tests/RunCMake/FileAPI/codemodel-v2-data/targets/shared_framework.json
  31. 2 0
      Tests/RunCMake/FileAPI/codemodel-v2.cmake
  32. 8 4
      Tests/RunCMake/PrecompileHeaders/PchReuseFromObjLib.cmake
  33. 3 0
      Tests/RunCMake/SharedLibraryDefines/C.cmake
  34. 3 0
      Tests/RunCMake/SharedLibraryDefines/CMakeLists.txt
  35. 3 0
      Tests/RunCMake/SharedLibraryDefines/CUDA.cmake
  36. 3 0
      Tests/RunCMake/SharedLibraryDefines/CXX.cmake
  37. 20 0
      Tests/RunCMake/SharedLibraryDefines/RunCMakeTest.cmake
  38. 1 0
      Tests/RunCMake/SharedLibraryDefines/checker.c
  39. 1 0
      Tests/RunCMake/SharedLibraryDefines/checker.cu
  40. 1 0
      Tests/RunCMake/SharedLibraryDefines/checker.cxx
  41. 19 0
      Tests/RunCMake/SharedLibraryDefines/checker.h
  42. 32 0
      Tests/RunCMake/SharedLibraryDefines/common.cmake
  43. 1 0
      Tests/RunCMake/TargetPolicies/PolicyList-stderr.txt

+ 1 - 0
Help/manual/cmake-policies.7.rst

@@ -98,6 +98,7 @@ Policies Introduced by CMake 4.2
 .. toctree::
    :maxdepth: 1
 
+   CMP0203: _WINDLL is defined for shared libraries targeting the MSVC ABI. </policy/CMP0203>
    CMP0202: PDB file names always include their target's per-config POSTFIX. </policy/CMP0202>
    CMP0201: The Python::NumPy target does not depend on the Python::Module target. </policy/CMP0201>
    CMP0200: Location and configuration selection for imported targets is more consistent. </policy/CMP0200>

+ 28 - 0
Help/policy/CMP0203.rst

@@ -0,0 +1,28 @@
+CMP0203
+-------
+
+.. versionadded:: 4.2
+
+``_WINDLL`` is defined for shared libraries targeting the MSVC ABI.
+
+In CMake 4.1 and below, :ref:`Visual Studio Generators` compile sources in
+shared libraries with ``_WINDLL`` defined due to behavior of Visual Studio
+itself.  The preprocessor definition is not modeled by CMake and is therefore
+not added by other generators, such as :generator:`Ninja`.
+
+CMake 4.2 and above, when targeting the MSVC ABI, prefer to compile sources
+in shared libraries with ``_WINDLL`` defined by all generators.
+This policy provides compatibility with projects that have not been updated
+to be aware of the definition.  Its setting is recorded by each target as
+it is created, and affects compilation of sources in that target.
+
+The ``OLD`` behavior for this policy does not model the ``_WINDLL``
+preprocessor definition in CMake itself.  The ``NEW`` behavior for this
+policy adds the ``_WINDLL`` preprocessor definition to sources in shared
+libraries when targeting the MSVC ABI.
+
+.. |INTRODUCED_IN_CMAKE_VERSION| replace:: 4.2
+.. |WARNS_OR_DOES_NOT_WARN| replace:: does *not* warn
+.. include:: include/STANDARD_ADVICE.rst
+
+.. include:: include/DEPRECATED.rst

+ 6 - 0
Help/release/dev/define-windll.rst

@@ -0,0 +1,6 @@
+define-windll
+-------------
+
+* For builds targeting the MSVC ABI, all generators now add the ``_WINDLL``
+  preprocessor definition when compiling sources in shared libraries.
+  See policy :policy:`CMP0203`.

+ 1 - 0
Modules/Platform/Windows-Clang.cmake

@@ -59,6 +59,7 @@ macro(__windows_compiler_clang_gnu lang)
   set(CMAKE_${lang}_LINK_OPTIONS_NO_PIE "")
   set(CMAKE_SHARED_LIBRARY_${lang}_FLAGS "")
   set(CMAKE_SHARED_LIBRARY_CREATE_${lang}_FLAGS "-shared")
+  set(CMAKE_${lang}_SHARED_LIBRARY_COMPILE_DEFINITIONS "_WINDLL")
 
   # linker selection
   set(CMAKE_${lang}_USING_LINKER_DEFAULT "-fuse-ld=lld-link")

+ 2 - 0
Modules/Platform/Windows-MSVC.cmake

@@ -398,8 +398,10 @@ macro(__windows_compiler_msvc lang)
   endif()
   set(CMAKE_SHARED_LIBRARY_CREATE_${lang}_FLAGS "")
   if(CMAKE_SYSTEM_NAME STREQUAL "WindowsKernelModeDriver")
+    set(CMAKE_${lang}_SHARED_LIBRARY_COMPILE_DEFINITIONS "")
     set(_DLL_DRIVER "-driver")
   else()
+    set(CMAKE_${lang}_SHARED_LIBRARY_COMPILE_DEFINITIONS "_WINDLL")
     set(_DLL_DRIVER "/dll")
   endif()
   set(CMAKE_${lang}_CREATE_SHARED_LIBRARY

+ 1 - 0
Modules/Platform/Windows-NVIDIA-CUDA.cmake

@@ -15,6 +15,7 @@ set(_CMAKE_VS_LINK_DLL "<CMAKE_COMMAND> -E vs_link_dll --intdir=<OBJECT_DIR> --r
 set(_CMAKE_VS_LINK_EXE "<CMAKE_COMMAND> -E vs_link_exe --intdir=<OBJECT_DIR> --rc=<CMAKE_RC_COMPILER> --mt=<CMAKE_MT> --manifests <MANIFESTS> -- ")
 set(CMAKE_CUDA_CREATE_SHARED_LIBRARY
   "${_CMAKE_VS_LINK_DLL}<CMAKE_LINKER> ${CMAKE_CL_NOLOGO} <OBJECTS> ${CMAKE_START_TEMP_FILE} /out:<TARGET> /implib:<TARGET_IMPLIB> /pdb:<TARGET_PDB> /dll /version:<TARGET_VERSION_MAJOR>.<TARGET_VERSION_MINOR>${_PLATFORM_LINK_FLAGS} <LINK_FLAGS> <LINK_LIBRARIES>${__IMPLICIT_LINKS} ${CMAKE_END_TEMP_FILE}")
+set(CMAKE_CUDA_SHARED_LIBRARY_COMPILE_DEFINITIONS "_WINDLL")
 
 set(CMAKE_CUDA_CREATE_SHARED_MODULE ${CMAKE_CUDA_CREATE_SHARED_LIBRARY})
 set(CMAKE_CUDA_CREATE_STATIC_LIBRARY  "<CMAKE_AR> ${CMAKE_CL_NOLOGO}${_PLATFORM_ARCHIVE_FLAGS} <LINK_FLAGS> /out:<TARGET> <OBJECTS> ")

+ 30 - 0
Source/cmGeneratorTarget.cxx

@@ -1844,6 +1844,36 @@ std::string const* cmGeneratorTarget::GetExportMacro() const
   return nullptr;
 }
 
+cmList const& cmGeneratorTarget::GetSharedLibraryCompileDefs(
+  std::string const& config) const
+{
+  {
+    auto it = this->SharedLibraryCompileDefs.find(config);
+    if (it != this->SharedLibraryCompileDefs.end()) {
+      return it->second;
+    }
+  }
+
+  auto emplaceResult =
+    this->SharedLibraryCompileDefs.emplace(config, cmList{});
+  auto& defs = emplaceResult.first->second;
+  if (this->GetType() != cmStateEnums::SHARED_LIBRARY &&
+      this->GetType() != cmStateEnums::MODULE_LIBRARY) {
+    return defs;
+  }
+
+  if (this->GetPolicyStatusCMP0203() != cmPolicies::NEW) {
+    return defs;
+  }
+
+  auto linkerLang = this->GetLinkerLanguage(config);
+  auto definitionVar =
+    cmStrCat("CMAKE_", linkerLang, "_SHARED_LIBRARY_COMPILE_DEFINITIONS");
+  defs = this->Makefile->GetSafeDefinition(definitionVar);
+
+  return defs;
+}
+
 cmGeneratorTarget::NameComponents const&
 cmGeneratorTarget::GetFullNameComponents(
   std::string const& config, cmStateEnums::ArtifactType artifact) const

+ 7 - 0
Source/cmGeneratorTarget.h

@@ -20,6 +20,7 @@
 
 #include "cmAlgorithms.h"
 #include "cmLinkItem.h"
+#include "cmList.h"
 #include "cmListFileCache.h"
 #include "cmObjectLocation.h"
 #include "cmPolicies.h"
@@ -382,6 +383,11 @@ public:
       If no macro should be defined null is returned.  */
   std::string const* GetExportMacro() const;
 
+  /** Get the list of preprocessor definitions, that should be defined
+      when building sources in this target.
+      If no macro should be defined the empty list is returned.  */
+  cmList const& GetSharedLibraryCompileDefs(std::string const& config) const;
+
   /** Get the soname of the target.  Allowed only for a shared library.  */
   std::string GetSOName(std::string const& config,
                         cmStateEnums::ArtifactType artifact =
@@ -1167,6 +1173,7 @@ private:
   mutable std::map<std::string, std::vector<std::string>> SystemIncludesCache;
 
   mutable std::string ExportMacro;
+  mutable std::unordered_map<std::string, cmList> SharedLibraryCompileDefs;
 
   void ConstructSourceFileFlags() const;
   mutable bool SourceFileFlagsConstructed = false;

+ 4 - 0
Source/cmGlobalXCodeGenerator.cxx

@@ -2604,6 +2604,10 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmGeneratorTarget* gtgt,
     // Add the export symbol definition for shared library objects.
     this->AppendDefines(ppDefs, exportMacro->c_str());
   }
+  for (auto const& sharedLibCompileDef :
+       gtgt->GetSharedLibraryCompileDefs(configName)) {
+    this->AppendDefines(ppDefs, sharedLibCompileDef.c_str());
+  }
   std::vector<std::string> targetDefines;
   if (!langForPreprocessorDefinitions.empty()) {
     gtgt->GetCompileDefinitions(targetDefines, configName,

+ 4 - 0
Source/cmLocalGenerator.cxx

@@ -1859,6 +1859,10 @@ std::set<BT<std::string>> cmLocalGenerator::GetTargetDefines(
   if (std::string const* exportMacro = target->GetExportMacro()) {
     this->AppendDefines(defines, *exportMacro);
   }
+  for (auto const& sharedLibCompileDef :
+       target->GetSharedLibraryCompileDefs(config)) {
+    this->AppendDefines(defines, sharedLibCompileDef);
+  }
 
   // Add preprocessor definitions for this target and configuration.
   std::vector<BT<std::string>> targetDefines =

+ 2 - 0
Source/cmLocalVisualStudio7Generator.cxx

@@ -768,6 +768,8 @@ void cmLocalVisualStudio7Generator::WriteConfiguration(
   if (std::string const* exportMacro = target->GetExportMacro()) {
     targetOptions.AddDefine(*exportMacro);
   }
+  // No need to add the SharedLibraryCompileDefs define here:
+  // it is added by VisualStudio itself
 
   // The intermediate directory name consists of a directory for the
   // target and a subdirectory for the configuration name.

+ 5 - 1
Source/cmPolicies.h

@@ -607,6 +607,9 @@ class cmMakefile;
          4, 2, 0, WARN)                                                       \
   SELECT(POLICY, CMP0202,                                                     \
          "PDB file names always include their target's per-config POSTFIX.",  \
+         4, 2, 0, WARN)                                                       \
+  SELECT(POLICY, CMP0203,                                                     \
+         "_WINDLL is defined for shared libraries targeting the MSVC ABI.",   \
          4, 2, 0, WARN)
 
 #define CM_SELECT_ID(F, A1, A2, A3, A4, A5, A6) F(A1)
@@ -658,7 +661,8 @@ class cmMakefile;
   F(CMP0195)                                                                  \
   F(CMP0199)                                                                  \
   F(CMP0200)                                                                  \
-  F(CMP0202)
+  F(CMP0202)                                                                  \
+  F(CMP0203)
 
 #define CM_FOR_EACH_CUSTOM_COMMAND_POLICY(F)                                  \
   F(CMP0116)                                                                  \

+ 4 - 0
Source/cmVisualStudio10TargetGenerator.cxx

@@ -3605,6 +3605,8 @@ bool cmVisualStudio10TargetGenerator::ComputeClOptions(
         this->GeneratorTarget->GetExportMacro()) {
     clOptions.AddDefine(*exportMacro);
   }
+  // No need to add the SharedLibraryCompileDefs define here:
+  // it is added by VisualStudio itself
 
   if (this->MSTools) {
     // If we have the VS_WINRT_COMPONENT set then force Compile as WinRT
@@ -3990,6 +3992,8 @@ bool cmVisualStudio10TargetGenerator::ComputeCudaOptions(
         this->GeneratorTarget->GetExportMacro()) {
     cudaOptions.AddDefine(*exportMacro);
   }
+  // No need to add the SharedLibraryCompileDefs define here:
+  // it is added by VisualStudio itself
 
   // Get includes for this target
   cudaOptions.AddIncludes(this->GetIncludes(configName, "CUDA"));

+ 10 - 0
Tests/RunCMake/CMakeLists.txt

@@ -424,6 +424,7 @@ if(CMAKE_USE_SYSTEM_JSONCPP)
 endif()
 add_RunCMake_test(FileAPI -DPython_EXECUTABLE=${Python_EXECUTABLE}
                           -DCMAKE_CXX_COMPILER_ID=${CMAKE_CXX_COMPILER_ID}
+                          -DCMAKE_CXX_SIMULATE_ID=${CMAKE_CXX_SIMULATE_ID}
                           -DCMake_TEST_JSON_SCHEMA=${CMake_TEST_JSON_SCHEMA})
 if(CMAKE_GENERATOR MATCHES "Make|Ninja|FASTBuild")
   add_RunCMake_test(Instrumentation)
@@ -1436,3 +1437,12 @@ if(CMake_TEST_Emscripten_TOOLCHAINS)
   add_RunCMake_test(Emscripten -DCMake_TEST_Emscripten_TOOLCHAINS=${CMake_TEST_Emscripten_TOOLCHAINS})
   set_property(TEST RunCMake.Emscripten APPEND PROPERTY LABELS "Emscripten")
 endif()
+
+if (CMAKE_C_COMPILER_ID STREQUAL "MSVC" OR CMAKE_C_SIMULATE_ID STREQUAL "MSVC")
+  add_RunCMake_test(SharedLibraryDefines
+    -DCMAKE_C_COMPILER_ID=${CMAKE_C_COMPILER_ID}
+    -DCMAKE_C_SIMULATE_ID=${CMAKE_C_SIMULATE_ID}
+    -DCMake_TEST_CUDA=${CMake_TEST_CUDA}
+  )
+  set_property(TEST RunCMake.SharedLibraryDefines APPEND PROPERTY LABELS "CUDA")
+endif()

+ 1 - 0
Tests/RunCMake/FileAPI/RunCMakeTest.cmake

@@ -112,6 +112,7 @@ function(check_python case prefix)
       --build-dir "${RunCMake_TEST_BINARY_DIR}"
       --reply-index "${index}"
       --cxx-compiler-id "${CMAKE_CXX_COMPILER_ID}"
+      --cxx-simulate-id "${CMAKE_CXX_SIMULATE_ID}"
     RESULT_VARIABLE result
     OUTPUT_VARIABLE output
     ERROR_VARIABLE output

+ 1 - 0
Tests/RunCMake/FileAPI/check_index.py

@@ -163,6 +163,7 @@ parser = argparse.ArgumentParser()
 parser.add_argument("--build-dir")
 parser.add_argument("--reply-index")
 parser.add_argument("--cxx-compiler-id")
+parser.add_argument("--cxx-simulate-id")
 args = parser.parse_args()
 
 reply_dir = os.path.dirname(args.reply_index)

+ 12 - 0
Tests/RunCMake/FileAPI/codemodel-v2-check.py

@@ -941,6 +941,18 @@ def gen_check_build_system_targets(c, g, inSource):
                 e["sources"] = precompile_header_data["sources"]
                 e["sourceGroups"] = precompile_header_data["sourceGroups"]
 
+    if args.cxx_compiler_id != 'MSVC' and args.cxx_simulate_id != 'MSVC':
+        for e in expected:
+            if not e["compileGroups"]:
+                continue
+
+            for group in e["compileGroups"]:
+                if not group["defines"]:
+                    continue
+
+                # _WINDLL is expected for compilers targeting the MSVC ABI, but not for others.
+                group["defines"] = [d for d in group["defines"] if d and d["define"] != "_WINDLL"]
+
     if os.path.exists(os.path.join(reply_dir, "..", "..", "..", "..", "cxx", "cxx_std_11.txt")):
         for e in expected:
             if e["name"] == "cxx_standard_compile_feature_exe":

+ 13 - 13
Tests/RunCMake/FileAPI/codemodel-v2-data/directories/top.json

@@ -54,7 +54,7 @@
             "backtrace": [
                 {
                     "file": "^codemodel-v2\\.cmake$",
-                    "line": 48,
+                    "line": 50,
                     "command": "install",
                     "hasParent": true
                 },
@@ -99,7 +99,7 @@
             "backtrace": [
                 {
                     "file": "^codemodel-v2\\.cmake$",
-                    "line": 51,
+                    "line": 53,
                     "command": "install",
                     "hasParent": true
                 },
@@ -147,7 +147,7 @@
             "backtrace": [
                 {
                     "file": "^codemodel-v2\\.cmake$",
-                    "line": 51,
+                    "line": 53,
                     "command": "install",
                     "hasParent": true
                 },
@@ -192,7 +192,7 @@
             "backtrace": [
                 {
                     "file": "^codemodel-v2\\.cmake$",
-                    "line": 51,
+                    "line": 53,
                     "command": "install",
                     "hasParent": true
                 },
@@ -236,7 +236,7 @@
             "backtrace": [
                 {
                     "file": "^codemodel-v2\\.cmake$",
-                    "line": 51,
+                    "line": 53,
                     "command": "install",
                     "hasParent": true
                 },
@@ -280,7 +280,7 @@
             "backtrace": [
                 {
                     "file": "^codemodel-v2\\.cmake$",
-                    "line": 56,
+                    "line": 58,
                     "command": "install",
                     "hasParent": true
                 },
@@ -327,7 +327,7 @@
             "backtrace": [
                 {
                     "file": "^codemodel-v2\\.cmake$",
-                    "line": 58,
+                    "line": 60,
                     "command": "install",
                     "hasParent": true
                 },
@@ -372,7 +372,7 @@
             "backtrace": [
                 {
                     "file": "^codemodel-v2\\.cmake$",
-                    "line": 59,
+                    "line": 61,
                     "command": "install",
                     "hasParent": true
                 },
@@ -421,7 +421,7 @@
             "backtrace": [
                 {
                     "file": "^codemodel-v2\\.cmake$",
-                    "line": 60,
+                    "line": 62,
                     "command": "install",
                     "hasParent": true
                 },
@@ -473,7 +473,7 @@
             "backtrace": [
                 {
                     "file": "^codemodel-v2\\.cmake$",
-                    "line": 61,
+                    "line": 63,
                     "command": "install",
                     "hasParent": true
                 },
@@ -522,7 +522,7 @@
             "backtrace": [
                 {
                     "file": "^codemodel-v2\\.cmake$",
-                    "line": 62,
+                    "line": 64,
                     "command": "install",
                     "hasParent": true
                 },
@@ -564,7 +564,7 @@
             "backtrace": [
                 {
                     "file": "^codemodel-v2\\.cmake$",
-                    "line": 63,
+                    "line": 65,
                     "command": "install",
                     "hasParent": true
                 },
@@ -606,7 +606,7 @@
             "backtrace": [
                 {
                     "file": "^codemodel-v2\\.cmake$",
-                    "line": 64,
+                    "line": 66,
                     "command": "install",
                     "hasParent": true
                 },

+ 3 - 3
Tests/RunCMake/FileAPI/codemodel-v2-data/targets/c_exe.json

@@ -19,7 +19,7 @@
             "backtrace": [
                 {
                     "file": "^codemodel-v2\\.cmake$",
-                    "line": 10,
+                    "line": 12,
                     "command": "add_executable",
                     "hasParent": true
                 },
@@ -67,7 +67,7 @@
     "backtrace": [
         {
             "file": "^codemodel-v2\\.cmake$",
-            "line": 10,
+            "line": 12,
             "command": "add_executable",
             "hasParent": true
         },
@@ -117,7 +117,7 @@
             "backtrace": [
                 {
                     "file": "^codemodel-v2\\.cmake$",
-                    "line": 11,
+                    "line": 13,
                     "command": "target_link_libraries",
                     "hasParent": true
                 },

+ 2 - 2
Tests/RunCMake/FileAPI/codemodel-v2-data/targets/c_lib.json

@@ -19,7 +19,7 @@
             "backtrace": [
                 {
                     "file": "^codemodel-v2\\.cmake$",
-                    "line": 9,
+                    "line": 11,
                     "command": "add_library",
                     "hasParent": true
                 },
@@ -67,7 +67,7 @@
     "backtrace": [
         {
             "file": "^codemodel-v2\\.cmake$",
-            "line": 9,
+            "line": 11,
             "command": "add_library",
             "hasParent": true
         },

+ 3 - 3
Tests/RunCMake/FileAPI/codemodel-v2-data/targets/c_shared_exe.json

@@ -19,7 +19,7 @@
             "backtrace": [
                 {
                     "file": "^codemodel-v2\\.cmake$",
-                    "line": 15,
+                    "line": 17,
                     "command": "add_executable",
                     "hasParent": true
                 },
@@ -67,7 +67,7 @@
     "backtrace": [
         {
             "file": "^codemodel-v2\\.cmake$",
-            "line": 15,
+            "line": 17,
             "command": "add_executable",
             "hasParent": true
         },
@@ -117,7 +117,7 @@
             "backtrace": [
                 {
                     "file": "^codemodel-v2\\.cmake$",
-                    "line": 16,
+                    "line": 18,
                     "command": "target_link_libraries",
                     "hasParent": true
                 },

+ 9 - 5
Tests/RunCMake/FileAPI/codemodel-v2-data/targets/c_shared_lib.json

@@ -19,7 +19,7 @@
             "backtrace": [
                 {
                     "file": "^codemodel-v2\\.cmake$",
-                    "line": 14,
+                    "line": 16,
                     "command": "add_library",
                     "hasParent": true
                 },
@@ -61,6 +61,10 @@
             "includes": null,
             "frameworks": null,
             "defines": [
+                {
+                    "define": "_WINDLL",
+                    "backtrace": null
+                },
                 {
                     "define": "c_shared_lib_EXPORTS",
                     "backtrace": null
@@ -72,7 +76,7 @@
     "backtrace": [
         {
             "file": "^codemodel-v2\\.cmake$",
-            "line": 14,
+            "line": 16,
             "command": "add_library",
             "hasParent": true
         },
@@ -121,7 +125,7 @@
                 "backtrace": [
                     {
                         "file": "^codemodel-v2\\.cmake$",
-                        "line": 51,
+                        "line": 53,
                         "command": "install",
                         "hasParent": true
                     },
@@ -151,7 +155,7 @@
                 "backtrace": [
                     {
                         "file": "^codemodel-v2\\.cmake$",
-                        "line": 51,
+                        "line": 53,
                         "command": "install",
                         "hasParent": true
                     },
@@ -181,7 +185,7 @@
                 "backtrace": [
                     {
                         "file": "^codemodel-v2\\.cmake$",
-                        "line": 56,
+                        "line": 58,
                         "command": "install",
                         "hasParent": true
                     },

+ 3 - 3
Tests/RunCMake/FileAPI/codemodel-v2-data/targets/c_static_exe.json

@@ -19,7 +19,7 @@
             "backtrace": [
                 {
                     "file": "^codemodel-v2\\.cmake$",
-                    "line": 19,
+                    "line": 21,
                     "command": "add_executable",
                     "hasParent": true
                 },
@@ -67,7 +67,7 @@
     "backtrace": [
         {
             "file": "^codemodel-v2\\.cmake$",
-            "line": 19,
+            "line": 21,
             "command": "add_executable",
             "hasParent": true
         },
@@ -117,7 +117,7 @@
             "backtrace": [
                 {
                     "file": "^codemodel-v2\\.cmake$",
-                    "line": 20,
+                    "line": 22,
                     "command": "target_link_libraries",
                     "hasParent": true
                 },

+ 2 - 2
Tests/RunCMake/FileAPI/codemodel-v2-data/targets/c_static_lib.json

@@ -19,7 +19,7 @@
             "backtrace": [
                 {
                     "file": "^codemodel-v2\\.cmake$",
-                    "line": 18,
+                    "line": 20,
                     "command": "add_library",
                     "hasParent": true
                 },
@@ -67,7 +67,7 @@
     "backtrace": [
         {
             "file": "^codemodel-v2\\.cmake$",
-            "line": 18,
+            "line": 20,
             "command": "add_library",
             "hasParent": true
         },

+ 1 - 1
Tests/RunCMake/FileAPI/codemodel-v2-data/targets/c_subdir.json

@@ -92,7 +92,7 @@
     "backtrace": [
         {
             "file": "^codemodel-v2\\.cmake$",
-            "line": 22,
+            "line": 24,
             "command": "add_library",
             "hasParent": true
         },

+ 1 - 1
Tests/RunCMake/FileAPI/codemodel-v2-data/targets/cxx_exe.json

@@ -142,7 +142,7 @@
                 "backtrace": [
                     {
                         "file": "^codemodel-v2\\.cmake$",
-                        "line": 48,
+                        "line": 50,
                         "command": "install",
                         "hasParent": true
                     },

+ 7 - 3
Tests/RunCMake/FileAPI/codemodel-v2-data/targets/cxx_shared_lib.json

@@ -49,6 +49,10 @@
             "includes": null,
             "frameworks": null,
             "defines": [
+                {
+                    "define": "_WINDLL",
+                    "backtrace": null
+                },
                 {
                     "define": "cxx_shared_lib_EXPORTS",
                     "backtrace": null
@@ -97,7 +101,7 @@
                 "backtrace": [
                     {
                         "file": "^codemodel-v2\\.cmake$",
-                        "line": 51,
+                        "line": 53,
                         "command": "install",
                         "hasParent": true
                     },
@@ -127,7 +131,7 @@
                 "backtrace": [
                     {
                         "file": "^codemodel-v2\\.cmake$",
-                        "line": 51,
+                        "line": 53,
                         "command": "install",
                         "hasParent": true
                     },
@@ -157,7 +161,7 @@
                 "backtrace": [
                     {
                         "file": "^codemodel-v2\\.cmake$",
-                        "line": 56,
+                        "line": 58,
                         "command": "install",
                         "hasParent": true
                     },

+ 3 - 3
Tests/RunCMake/FileAPI/codemodel-v2-data/targets/interface_exe.json

@@ -31,7 +31,7 @@
                 },
                 {
                     "file": "^codemodel-v2\\.cmake$",
-                    "line": 7,
+                    "line": 9,
                     "command": "include",
                     "hasParent": true
                 },
@@ -94,7 +94,7 @@
                         },
                         {
                             "file": "^codemodel-v2\\.cmake$",
-                            "line": 7,
+                            "line": 9,
                             "command": "include",
                             "hasParent": true
                         },
@@ -137,7 +137,7 @@
         },
         {
             "file": "^codemodel-v2\\.cmake$",
-            "line": 7,
+            "line": 9,
             "command": "include",
             "hasParent": true
         },

+ 1 - 1
Tests/RunCMake/FileAPI/codemodel-v2-data/targets/interface_lib.json

@@ -27,7 +27,7 @@
         },
         {
             "file": "^codemodel-v2\\.cmake$",
-            "line": 7,
+            "line": 9,
             "command": "include",
             "hasParent": true
         },

+ 4 - 0
Tests/RunCMake/FileAPI/codemodel-v2-data/targets/shared_framework.json

@@ -49,6 +49,10 @@
             "includes": null,
             "frameworks": null,
             "defines": [
+                {
+                    "define": "_WINDLL",
+                    "backtrace": null
+                },
                 {
                     "define": "shared_framework_EXPORTS",
                     "backtrace": null

+ 2 - 0
Tests/RunCMake/FileAPI/codemodel-v2.cmake

@@ -2,6 +2,8 @@ set(CMAKE_INTERMEDIATE_DIR_STRATEGY FULL CACHE STRING "" FORCE)
 
 enable_language(C)
 
+cmake_policy(SET CMP0203 NEW)
+
 set(CMAKE_AIX_SHARED_LIBRARY_ARCHIVE 0)
 
 include("${CMAKE_CURRENT_LIST_DIR}/include_test.cmake")

+ 8 - 4
Tests/RunCMake/PrecompileHeaders/PchReuseFromObjLib.cmake

@@ -3,6 +3,8 @@ set(CMAKE_INTERMEDIATE_DIR_STRATEGY FULL CACHE STRING "" FORCE)
 enable_language(C)
 enable_language(CXX)
 
+cmake_policy(SET CMP0203 NEW)
+
 set(CMAKE_PCH_WARN_INVALID OFF)
 
 if(CMAKE_CXX_COMPILE_OPTIONS_USE_PCH)
@@ -42,6 +44,12 @@ add_library(pch-generator OBJECT ${CMAKE_BINARY_DIR}/pch.cxx)
 set_property(TARGET pch-generator PROPERTY POSITION_INDEPENDENT_CODE ON)
 target_precompile_headers(pch-generator PRIVATE ${CMAKE_BINARY_DIR}/string.hxx)
 
+if(CMAKE_C_COMPILER_ID STREQUAL "MSVC" OR CMAKE_C_SIMULATE_ID STREQUAL "MSVC")
+  # CMP0203 NEW behavior defines _WINDLL in sources of SHARED libraries.
+  # This PCH will be consumed by a SHARED library below.
+  target_compile_definitions(pch-generator PRIVATE _WINDLL)
+endif()
+
 target_include_directories(pch-generator PRIVATE ${CMAKE_BINARY_DIR}/CONFIG)
 
 ######################################################################
@@ -104,10 +112,6 @@ function(add_library_and_executable type)
       #define WIN32_BUILD_SHARED
     ]=])
     target_include_directories(message_${type} PRIVATE ${CMAKE_BINARY_DIR}/SHARED)
-
-    # Workaround for VS2008, the compiler fails with
-    # c1xx : fatal error C1083: Cannot open source file: '_WINDLL': No such file or directory
-    file(WRITE ${CMAKE_BINARY_DIR}/_WINDLL "/*empty*/\n")
   else()
     target_include_directories(message_${type} PRIVATE ${CMAKE_BINARY_DIR}/CONFIG)
   endif()

+ 3 - 0
Tests/RunCMake/SharedLibraryDefines/C.cmake

@@ -0,0 +1,3 @@
+set(language C)
+set(extension "c")
+include(common.cmake)

+ 3 - 0
Tests/RunCMake/SharedLibraryDefines/CMakeLists.txt

@@ -0,0 +1,3 @@
+cmake_minimum_required(VERSION 4.0)
+project(${RunCMake_TEST} NONE)
+include(${RunCMake_TEST}.cmake)

+ 3 - 0
Tests/RunCMake/SharedLibraryDefines/CUDA.cmake

@@ -0,0 +1,3 @@
+set(language CUDA)
+set(extension "cu")
+include(common.cmake)

+ 3 - 0
Tests/RunCMake/SharedLibraryDefines/CXX.cmake

@@ -0,0 +1,3 @@
+set(language CXX)
+set(extension "cxx")
+include(common.cmake)

+ 20 - 0
Tests/RunCMake/SharedLibraryDefines/RunCMakeTest.cmake

@@ -0,0 +1,20 @@
+include(RunCMake)
+
+function(configure_and_build case)
+  set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/${case}-build)
+  run_cmake(${case})
+  set(RunCMake_TEST_NO_CLEAN 1)
+  if (RunCMake_GENERATOR_IS_MULTI_CONFIG)
+    run_cmake_command(${case}-build-Debug ${CMAKE_COMMAND} --build . --config Debug)
+    run_cmake_command(${case}-build-Release ${CMAKE_COMMAND} --build . --config Release)
+  else()
+    run_cmake_command(${case}-build ${CMAKE_COMMAND} --build .)
+  endif()
+endfunction()
+
+configure_and_build(C)
+configure_and_build(CXX)
+
+if(CMake_TEST_CUDA)
+  configure_and_build(CUDA)
+endif()

+ 1 - 0
Tests/RunCMake/SharedLibraryDefines/checker.c

@@ -0,0 +1 @@
+#include "checker.h"

+ 1 - 0
Tests/RunCMake/SharedLibraryDefines/checker.cu

@@ -0,0 +1 @@
+#include "checker.h"

+ 1 - 0
Tests/RunCMake/SharedLibraryDefines/checker.cxx

@@ -0,0 +1 @@
+#include "checker.h"

+ 19 - 0
Tests/RunCMake/SharedLibraryDefines/checker.h

@@ -0,0 +1,19 @@
+#pragma once
+
+#ifdef MUST_HAVE_DEFINE
+#  ifndef _WINDLL
+#    error "_WINDLL is not defined, but it should be"
+#  endif
+#  if _WINDLL != 1
+#    error "_WINDLL is not defined as 1, but it should be"
+#  endif
+#else
+#  ifdef _WINDLL
+#    error "_WINDLL is defined, but it should not be"
+#  endif
+#endif
+
+int FUNCTION()
+{
+  return 0;
+}

+ 32 - 0
Tests/RunCMake/SharedLibraryDefines/common.cmake

@@ -0,0 +1,32 @@
+enable_language(${language})
+
+function(sharedLibraryDefs_addTests policy_value)
+  block(SCOPE_FOR POLICIES)
+    if (NOT "${policy_value}" STREQUAL "WARN")
+      # WARN is the default value - no need to set it
+      cmake_policy(SET CMP0203 "${policy_value}")
+    endif()
+
+    add_executable(${language}-CMP0203_${policy_value} checker.${extension})
+    target_compile_definitions(${language}-CMP0203_${policy_value} PRIVATE "FUNCTION=main")
+
+    add_library(${language}-CMP0203_${policy_value}_shared SHARED checker.${extension})
+    target_compile_definitions(${language}-CMP0203_${policy_value}_shared PRIVATE "FUNCTION=test")
+
+    add_library(${language}-CMP0203_${policy_value}_static STATIC checker.${extension})
+    target_compile_definitions(${language}-CMP0203_${policy_value}_static PRIVATE "FUNCTION=test")
+  endblock()
+endfunction()
+
+sharedLibraryDefs_addTests(OLD)
+sharedLibraryDefs_addTests(WARN)
+
+if (CMAKE_GENERATOR MATCHES "Visual Studio")
+  # Visual Studio always defines `_WINDLL`
+  target_compile_definitions(${language}-CMP0203_OLD_shared PRIVATE "MUST_HAVE_DEFINE")
+  target_compile_definitions(${language}-CMP0203_WARN_shared PRIVATE "MUST_HAVE_DEFINE")
+endif()
+
+sharedLibraryDefs_addTests(NEW)
+
+target_compile_definitions(${language}-CMP0203_NEW_shared PRIVATE "MUST_HAVE_DEFINE")

+ 1 - 0
Tests/RunCMake/TargetPolicies/PolicyList-stderr.txt

@@ -50,6 +50,7 @@
    \* CMP0199
    \* CMP0200
    \* CMP0202
+   \* CMP0203
 
 Call Stack \(most recent call first\):
   CMakeLists.txt:3 \(include\)