浏览代码

Merge topic 'watcom-runtime-library-v2'

6a2b016bbd OpenWatcom: Support CMAKE_WATCOM_RUNTIME_LIBRARY with Linux and OS/2 builds
33da5824ac OpenWatcom: Allow specifying the runtime library

Acked-by: Kitware Robot <[email protected]>
Acked-by: buildbot <[email protected]>
Merge-request: !7184
Brad King 3 年之前
父节点
当前提交
54c3563e95

+ 1 - 0
Help/command/try_compile.rst

@@ -150,6 +150,7 @@ Other Behavior Settings
   * :variable:`CMAKE_LINK_SEARCH_END_STATIC`
   * :variable:`CMAKE_LINK_SEARCH_END_STATIC`
   * :variable:`CMAKE_MSVC_RUNTIME_LIBRARY`
   * :variable:`CMAKE_MSVC_RUNTIME_LIBRARY`
   * :variable:`CMAKE_POSITION_INDEPENDENT_CODE`
   * :variable:`CMAKE_POSITION_INDEPENDENT_CODE`
+  * :variable:`CMAKE_WATCOM_RUNTIME_LIBRARY`
 
 
   If :policy:`CMP0056` is set to ``NEW``, then
   If :policy:`CMP0056` is set to ``NEW``, then
   :variable:`CMAKE_EXE_LINKER_FLAGS` is passed in as well.
   :variable:`CMAKE_EXE_LINKER_FLAGS` is passed in as well.

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

@@ -58,6 +58,7 @@ Policies Introduced by CMake 3.24
 .. toctree::
 .. toctree::
    :maxdepth: 1
    :maxdepth: 1
 
 
+   CMP0136: Watcom runtime library flags are selected by an abstraction. </policy/CMP0136>
    CMP0135: ExternalProject ignores timestamps in archives by default for the URL download method. </policy/CMP0135>
    CMP0135: ExternalProject ignores timestamps in archives by default for the URL download method. </policy/CMP0135>
    CMP0134: Fallback to \"HOST\" Windows registry view when \"TARGET\" view is not usable. </policy/CMP0134>
    CMP0134: Fallback to \"HOST\" Windows registry view when \"TARGET\" view is not usable. </policy/CMP0134>
    CMP0133: The CPack module disables SLA by default in the CPack DragNDrop Generator. </policy/CMP0133>
    CMP0133: The CPack module disables SLA by default in the CPack DragNDrop Generator. </policy/CMP0133>

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

@@ -423,6 +423,7 @@ Properties on Targets
    /prop_tgt/VS_WINRT_COMPONENT
    /prop_tgt/VS_WINRT_COMPONENT
    /prop_tgt/VS_WINRT_EXTENSIONS
    /prop_tgt/VS_WINRT_EXTENSIONS
    /prop_tgt/VS_WINRT_REFERENCES
    /prop_tgt/VS_WINRT_REFERENCES
+   /prop_tgt/WATCOM_RUNTIME_LIBRARY
    /prop_tgt/WIN32_EXECUTABLE
    /prop_tgt/WIN32_EXECUTABLE
    /prop_tgt/WINDOWS_EXPORT_ALL_SYMBOLS
    /prop_tgt/WINDOWS_EXPORT_ALL_SYMBOLS
    /prop_tgt/XCODE_ATTRIBUTE_an-attribute
    /prop_tgt/XCODE_ATTRIBUTE_an-attribute

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

@@ -521,6 +521,7 @@ Variables that Control the Build
    /variable/CMAKE_VS_SDK_REFERENCE_DIRECTORIES
    /variable/CMAKE_VS_SDK_REFERENCE_DIRECTORIES
    /variable/CMAKE_VS_SDK_SOURCE_DIRECTORIES
    /variable/CMAKE_VS_SDK_SOURCE_DIRECTORIES
    /variable/CMAKE_VS_WINRT_BY_DEFAULT
    /variable/CMAKE_VS_WINRT_BY_DEFAULT
+   /variable/CMAKE_WATCOM_RUNTIME_LIBRARY
    /variable/CMAKE_WIN32_EXECUTABLE
    /variable/CMAKE_WIN32_EXECUTABLE
    /variable/CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS
    /variable/CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS
    /variable/CMAKE_XCODE_ATTRIBUTE_an-attribute
    /variable/CMAKE_XCODE_ATTRIBUTE_an-attribute

+ 50 - 0
Help/policy/CMP0136.rst

@@ -0,0 +1,50 @@
+CMP0136
+-------
+
+.. versionadded:: 3.24
+
+Watcom runtime library flags are selected by an abstraction.
+
+Compilers targeting the Watcom ABI have flags to select the Watcom runtime
+library.
+
+In CMake 3.23 and below, Watcom runtime library selection flags are added to
+the default :variable:`CMAKE_<LANG>_FLAGS_<CONFIG>` cache entries by CMake
+automatically.  This allows users to edit their cache entries to adjust the
+flags.  However, the presence of such default flags is problematic for
+projects that want to choose a different runtime library programmatically.
+In particular, it requires string editing of the
+:variable:`CMAKE_<LANG>_FLAGS_<CONFIG>` variables with knowledge of the
+CMake builtin defaults so they can be replaced.
+
+CMake 3.24 and above prefer to leave the Watcom runtime library selection flags
+out of the default :variable:`CMAKE_<LANG>_FLAGS_<CONFIG>` values and instead
+offer a first-class abstraction.  The :variable:`CMAKE_WATCOM_RUNTIME_LIBRARY`
+variable and :prop_tgt:`WATCOM_RUNTIME_LIBRARY` target property may be set to
+select the Watcom runtime library.  If they are not set then CMake uses the
+default value ``MultiThreadedDLL`` on Windows and ``SingleThreaded`` on other
+platforms, which is equivalent to the original flags.
+
+This policy provides compatibility with projects that have not been updated
+to be aware of the abstraction.  The policy setting takes effect as of the
+first :command:`project` or :command:`enable_language` command that enables
+a language whose compiler targets the Watcom ABI.
+
+.. note::
+
+  Once the policy has taken effect at the top of a project, that choice
+  must be used throughout the tree.  In projects that have nested projects
+  in subdirectories, be sure to convert everything together.
+
+The ``OLD`` behavior for this policy is to place Watcom runtime library
+flags in the default :variable:`CMAKE_<LANG>_FLAGS_<CONFIG>` cache
+entries and ignore the :variable:`CMAKE_WATCOM_RUNTIME_LIBRARY` abstraction.
+The ``NEW`` behavior for this policy is to *not* place Watcom runtime
+library flags in the default cache entries and use the abstraction instead.
+
+This policy was introduced in CMake version 3.24.  Use the
+:command:`cmake_policy` command to set it to ``OLD`` or ``NEW`` explicitly.
+Unlike many policies, CMake version |release| does *not* warn
+when this policy is not set and simply uses ``OLD`` behavior.
+
+.. include:: DEPRECATED.txt

+ 20 - 0
Help/prop_tgt/WATCOM_RUNTIME_LIBRARY-VALUES.txt

@@ -0,0 +1,20 @@
+``SingleThreaded``
+  Compile without additional flags to use a single-threaded
+  statically-linked runtime library.
+``SingleThreadedDLL``
+  Compile with ``-br`` or equivalent flag(s) to use a single-threaded
+  dynamically-linked runtime library. This is not available for Linux
+  targets.
+``MultiThreaded``
+  Compile with ``-bm`` or equivalent flag(s) to use a multi-threaded
+  statically-linked runtime library.
+``MultiThreadedDLL``
+  Compile with ``-bm -br`` or equivalent flag(s) to use a multi-threaded
+  dynamically-linked runtime library. This is not available for Linux
+  targets.
+
+The value is ignored on non-Watcom compilers but an unsupported value will
+be rejected as an error when using a compiler targeting the Watcom ABI.
+
+The value may also be the empty string (``""``) in which case no runtime
+library selection flag will be added explicitly by CMake.

+ 34 - 0
Help/prop_tgt/WATCOM_RUNTIME_LIBRARY.rst

@@ -0,0 +1,34 @@
+WATCOM_RUNTIME_LIBRARY
+----------------------
+
+.. versionadded:: 3.24
+
+Select the Watcom runtime library for use by compilers targeting the Watcom ABI.
+
+The allowed values are:
+
+.. include:: WATCOM_RUNTIME_LIBRARY-VALUES.txt
+
+Use :manual:`generator expressions <cmake-generator-expressions(7)>` to
+support per-configuration specification.
+
+For example, the code:
+
+.. code-block:: cmake
+
+  add_executable(foo foo.c)
+  set_property(TARGET foo PROPERTY
+    WATCOM_RUNTIME_LIBRARY "MultiThreaded")
+
+selects for the target ``foo`` a multi-threaded statically-linked runtime
+library.
+
+If this property is not set then CMake uses the default value
+``MultiThreadedDLL`` on Windows and ``SingleThreaded`` on other
+platforms to select a Watcom runtime library.
+
+.. note::
+
+  This property has effect only when policy :policy:`CMP0136` is set to ``NEW``
+  prior to the first :command:`project` or :command:`enable_language` command
+  that enables a language using a compiler targeting the Watcom ABI.

+ 7 - 0
Help/release/dev/watcom-runtime-library.rst

@@ -0,0 +1,7 @@
+watcom-runtime-library
+----------------------
+
+* The :variable:`CMAKE_WATCOM_RUNTIME_LIBRARY` variable and
+  :prop_tgt:`WATCOM_RUNTIME_LIBRARY` target property were introduced to
+  select the runtime library used by compilers targeting the Watcom ABI.
+  See policy :policy:`CMP0136`.

+ 36 - 0
Help/variable/CMAKE_WATCOM_RUNTIME_LIBRARY.rst

@@ -0,0 +1,36 @@
+CMAKE_WATCOM_RUNTIME_LIBRARY
+----------------------------
+
+.. versionadded:: 3.24
+
+Select the Watcom runtime library for use by compilers targeting the Watcom ABI.
+This variable is used to initialize the :prop_tgt:`WATCOM_RUNTIME_LIBRARY`
+property on all targets as they are created.  It is also propagated by
+calls to the :command:`try_compile` command into the test project.
+
+The allowed values are:
+
+.. include:: ../prop_tgt/WATCOM_RUNTIME_LIBRARY-VALUES.txt
+
+Use :manual:`generator expressions <cmake-generator-expressions(7)>` to
+support per-configuration specification.
+
+For example, the code:
+
+.. code-block:: cmake
+
+  set(CMAKE_WATCOM_RUNTIME_LIBRARY "MultiThreaded")
+
+selects for all following targets a multi-threaded statically-linked runtime
+library.
+
+If this variable is not set then the :prop_tgt:`WATCOM_RUNTIME_LIBRARY` target
+property will not be set automatically.  If that property is not set then
+CMake uses the default value ``MultiThreadedDLL`` on Windows and
+``SingleThreaded`` on other platforms to select a Watcom runtime library.
+
+.. note::
+
+  This variable has effect only when policy :policy:`CMP0136` is set to ``NEW``
+  prior to the first :command:`project` or :command:`enable_language` command
+  that enables a language using a compiler targeting the Watcom ABI.

+ 1 - 0
Modules/Platform/Linux-OpenWatcom-C.cmake

@@ -1 +1,2 @@
 include(Platform/Linux-OpenWatcom)
 include(Platform/Linux-OpenWatcom)
+__linux_open_watcom(C)

+ 1 - 0
Modules/Platform/Linux-OpenWatcom-CXX.cmake

@@ -1 +1,2 @@
 include(Platform/Linux-OpenWatcom)
 include(Platform/Linux-OpenWatcom)
+__linux_open_watcom(CXX)

+ 13 - 0
Modules/Platform/Linux-OpenWatcom.cmake

@@ -10,6 +10,14 @@ string(APPEND CMAKE_EXE_LINKER_FLAGS_INIT " system linux opt noextension")
 string(APPEND CMAKE_MODULE_LINKER_FLAGS_INIT " system linux")
 string(APPEND CMAKE_MODULE_LINKER_FLAGS_INIT " system linux")
 string(APPEND CMAKE_SHARED_LINKER_FLAGS_INIT " system linux")
 string(APPEND CMAKE_SHARED_LINKER_FLAGS_INIT " system linux")
 
 
+cmake_policy(GET CMP0136 __LINUX_WATCOM_CMP0136)
+if(__LINUX_WATCOM_CMP0136 STREQUAL "NEW")
+  set(CMAKE_WATCOM_RUNTIME_LIBRARY_DEFAULT "SingleThreaded")
+else()
+  set(CMAKE_WATCOM_RUNTIME_LIBRARY_DEFAULT "")
+endif()
+unset(__LINUX_WATCOM_CMP0136)
+
 # single/multi-threaded                 /-bm
 # single/multi-threaded                 /-bm
 # default is setup for single-threaded libraries
 # default is setup for single-threaded libraries
 string(APPEND CMAKE_C_FLAGS_INIT " -bt=linux")
 string(APPEND CMAKE_C_FLAGS_INIT " -bt=linux")
@@ -23,3 +31,8 @@ if(CMAKE_CROSSCOMPILING)
     set(CMAKE_CXX_STANDARD_INCLUDE_DIRECTORIES $ENV{WATCOM}/lh)
     set(CMAKE_CXX_STANDARD_INCLUDE_DIRECTORIES $ENV{WATCOM}/lh)
   endif()
   endif()
 endif()
 endif()
+
+macro(__linux_open_watcom lang)
+  set(CMAKE_${lang}_COMPILE_OPTIONS_WATCOM_RUNTIME_LIBRARY_SingleThreaded         "")
+  set(CMAKE_${lang}_COMPILE_OPTIONS_WATCOM_RUNTIME_LIBRARY_MultiThreaded          -bm)
+endmacro()

+ 1 - 0
Modules/Platform/OS2-OpenWatcom-C.cmake

@@ -1 +1,2 @@
 include(Platform/OS2-OpenWatcom)
 include(Platform/OS2-OpenWatcom)
+__os2_open_watcom(C)

+ 1 - 0
Modules/Platform/OS2-OpenWatcom-CXX.cmake

@@ -1 +1,2 @@
 include(Platform/OS2-OpenWatcom)
 include(Platform/OS2-OpenWatcom)
+__os2_open_watcom(CXX)

+ 15 - 0
Modules/Platform/OS2-OpenWatcom.cmake

@@ -16,6 +16,14 @@ endif()
 set(CMAKE_C_COMPILE_OPTIONS_DLL "-bd") # Note: This variable is a ';' separated list
 set(CMAKE_C_COMPILE_OPTIONS_DLL "-bd") # Note: This variable is a ';' separated list
 set(CMAKE_SHARED_LIBRARY_C_FLAGS "-bd") # ... while this is a space separated string.
 set(CMAKE_SHARED_LIBRARY_C_FLAGS "-bd") # ... while this is a space separated string.
 
 
+cmake_policy(GET CMP0136 __OS2_WATCOM_CMP0136)
+if(__OS2_WATCOM_CMP0136 STREQUAL "NEW")
+  set(CMAKE_WATCOM_RUNTIME_LIBRARY_DEFAULT "SingleThreaded")
+else()
+  set(CMAKE_WATCOM_RUNTIME_LIBRARY_DEFAULT "")
+endif()
+unset(__OS2_WATCOM_CMP0136)
+
 string(APPEND CMAKE_C_FLAGS_INIT " -bt=os2")
 string(APPEND CMAKE_C_FLAGS_INIT " -bt=os2")
 string(APPEND CMAKE_CXX_FLAGS_INIT " -bt=os2 -xs")
 string(APPEND CMAKE_CXX_FLAGS_INIT " -bt=os2 -xs")
 
 
@@ -33,3 +41,10 @@ if(NOT CMAKE_CXX_STANDARD_INCLUDE_DIRECTORIES)
     set(CMAKE_CXX_STANDARD_INCLUDE_DIRECTORIES $ENV{WATCOM}/h $ENV{WATCOM}/h/os2)
     set(CMAKE_CXX_STANDARD_INCLUDE_DIRECTORIES $ENV{WATCOM}/h $ENV{WATCOM}/h/os2)
   endif()
   endif()
 endif()
 endif()
+
+macro(__os2_open_watcom lang)
+  set(CMAKE_${lang}_COMPILE_OPTIONS_WATCOM_RUNTIME_LIBRARY_SingleThreaded         "")
+  set(CMAKE_${lang}_COMPILE_OPTIONS_WATCOM_RUNTIME_LIBRARY_SingleThreadedDLL      -br)
+  set(CMAKE_${lang}_COMPILE_OPTIONS_WATCOM_RUNTIME_LIBRARY_MultiThreaded          -bm)
+  set(CMAKE_${lang}_COMPILE_OPTIONS_WATCOM_RUNTIME_LIBRARY_MultiThreadedDLL       -bm -br)
+endmacro()

+ 19 - 5
Modules/Platform/Windows-OpenWatcom.cmake

@@ -14,11 +14,20 @@ set(CMAKE_SHARED_LIBRARY_C_FLAGS "-bd") # ... while this is a space separated st
 
 
 set(CMAKE_RC_COMPILER "rc" )
 set(CMAKE_RC_COMPILER "rc" )
 
 
-# single/multi-threaded                 /-bm
-# static/DLL run-time libraries         /-br
-# default is setup for multi-threaded + DLL run-time libraries
-string(APPEND CMAKE_C_FLAGS_INIT " -bt=nt -dWIN32 -br -bm")
-string(APPEND CMAKE_CXX_FLAGS_INIT " -bt=nt -xs -dWIN32 -br -bm")
+cmake_policy(GET CMP0136 __WINDOWS_WATCOM_CMP0136)
+if(__WINDOWS_WATCOM_CMP0136 STREQUAL "NEW")
+  set(CMAKE_WATCOM_RUNTIME_LIBRARY_DEFAULT "MultiThreadedDLL")
+  set(_br_bm "")
+else()
+  set(CMAKE_WATCOM_RUNTIME_LIBRARY_DEFAULT "")
+  set(_br_bm "-br -bm")
+endif()
+
+string(APPEND CMAKE_C_FLAGS_INIT " -bt=nt -dWIN32 ${_br_bm}")
+string(APPEND CMAKE_CXX_FLAGS_INIT " -bt=nt -xs -dWIN32 ${_br_bm}")
+
+unset(__WINDOWS_WATCOM_CMP0136)
+unset(_br_bm)
 
 
 if(CMAKE_CROSSCOMPILING)
 if(CMAKE_CROSSCOMPILING)
   if(NOT CMAKE_C_STANDARD_INCLUDE_DIRECTORIES)
   if(NOT CMAKE_C_STANDARD_INCLUDE_DIRECTORIES)
@@ -32,4 +41,9 @@ endif()
 macro(__windows_open_watcom lang)
 macro(__windows_open_watcom lang)
   set(CMAKE_${lang}_CREATE_WIN32_EXE "system nt_win")
   set(CMAKE_${lang}_CREATE_WIN32_EXE "system nt_win")
   set(CMAKE_${lang}_CREATE_CONSOLE_EXE "system nt")
   set(CMAKE_${lang}_CREATE_CONSOLE_EXE "system nt")
+
+  set(CMAKE_${lang}_COMPILE_OPTIONS_WATCOM_RUNTIME_LIBRARY_SingleThreaded         "")
+  set(CMAKE_${lang}_COMPILE_OPTIONS_WATCOM_RUNTIME_LIBRARY_SingleThreadedDLL      -br)
+  set(CMAKE_${lang}_COMPILE_OPTIONS_WATCOM_RUNTIME_LIBRARY_MultiThreaded          -bm)
+  set(CMAKE_${lang}_COMPILE_OPTIONS_WATCOM_RUNTIME_LIBRARY_MultiThreadedDLL       -bm -br)
 endmacro()
 endmacro()

+ 10 - 0
Source/cmCoreTryCompile.cxx

@@ -228,6 +228,8 @@ std::string const kCMAKE_TRY_COMPILE_OSX_ARCHITECTURES =
 std::string const kCMAKE_TRY_COMPILE_PLATFORM_VARIABLES =
 std::string const kCMAKE_TRY_COMPILE_PLATFORM_VARIABLES =
   "CMAKE_TRY_COMPILE_PLATFORM_VARIABLES";
   "CMAKE_TRY_COMPILE_PLATFORM_VARIABLES";
 std::string const kCMAKE_WARN_DEPRECATED = "CMAKE_WARN_DEPRECATED";
 std::string const kCMAKE_WARN_DEPRECATED = "CMAKE_WARN_DEPRECATED";
+std::string const kCMAKE_WATCOM_RUNTIME_LIBRARY_DEFAULT =
+  "CMAKE_WATCOM_RUNTIME_LIBRARY_DEFAULT";
 
 
 /* GHS Multi platform variables */
 /* GHS Multi platform variables */
 std::set<std::string> const ghs_platform_vars{
 std::set<std::string> const ghs_platform_vars{
@@ -555,6 +557,13 @@ int cmCoreTryCompile::TryCompileCode(std::vector<std::string> const& argv,
               !msvcRuntimeLibraryDefault->empty() ? "NEW" : "OLD");
               !msvcRuntimeLibraryDefault->empty() ? "NEW" : "OLD");
     }
     }
 
 
+    /* Set Watcom runtime library policy to match our selection.  */
+    if (cmValue watcomRuntimeLibraryDefault = this->Makefile->GetDefinition(
+          kCMAKE_WATCOM_RUNTIME_LIBRARY_DEFAULT)) {
+      fprintf(fout, "cmake_policy(SET CMP0136 %s)\n",
+              !watcomRuntimeLibraryDefault->empty() ? "NEW" : "OLD");
+    }
+
     /* Set CUDA architectures policy to match outer project.  */
     /* Set CUDA architectures policy to match outer project.  */
     if (this->Makefile->GetPolicyStatus(cmPolicies::CMP0104) !=
     if (this->Makefile->GetPolicyStatus(cmPolicies::CMP0104) !=
           cmPolicies::NEW &&
           cmPolicies::NEW &&
@@ -902,6 +911,7 @@ int cmCoreTryCompile::TryCompileCode(std::vector<std::string> const& argv,
     vars.insert(kCMAKE_SYSROOT_LINK);
     vars.insert(kCMAKE_SYSROOT_LINK);
     vars.insert(kCMAKE_WARN_DEPRECATED);
     vars.insert(kCMAKE_WARN_DEPRECATED);
     vars.emplace("CMAKE_MSVC_RUNTIME_LIBRARY"_s);
     vars.emplace("CMAKE_MSVC_RUNTIME_LIBRARY"_s);
+    vars.emplace("CMAKE_WATCOM_RUNTIME_LIBRARY"_s);
 
 
     if (cmValue varListStr = this->Makefile->GetDefinition(
     if (cmValue varListStr = this->Makefile->GetDefinition(
           kCMAKE_TRY_COMPILE_PLATFORM_VARIABLES)) {
           kCMAKE_TRY_COMPILE_PLATFORM_VARIABLES)) {

+ 32 - 0
Source/cmLocalGenerator.cxx

@@ -1994,6 +1994,38 @@ void cmLocalGenerator::AddLanguageFlags(std::string& flags,
       }
       }
     }
     }
   }
   }
+
+  // Add Watcom runtime library flags.  This is activated by the presence
+  // of a default selection whether or not it is overridden by a property.
+  cmValue watcomRuntimeLibraryDefault =
+    this->Makefile->GetDefinition("CMAKE_WATCOM_RUNTIME_LIBRARY_DEFAULT");
+  if (cmNonempty(watcomRuntimeLibraryDefault)) {
+    cmValue watcomRuntimeLibraryValue =
+      target->GetProperty("WATCOM_RUNTIME_LIBRARY");
+    if (!watcomRuntimeLibraryValue) {
+      watcomRuntimeLibraryValue = watcomRuntimeLibraryDefault;
+    }
+    std::string const watcomRuntimeLibrary = cmGeneratorExpression::Evaluate(
+      *watcomRuntimeLibraryValue, this, config, target);
+    if (!watcomRuntimeLibrary.empty()) {
+      if (cmValue watcomRuntimeLibraryOptions = this->Makefile->GetDefinition(
+            "CMAKE_" + lang + "_COMPILE_OPTIONS_WATCOM_RUNTIME_LIBRARY_" +
+            watcomRuntimeLibrary)) {
+        this->AppendCompileOptions(flags, *watcomRuntimeLibraryOptions);
+      } else if ((this->Makefile->GetSafeDefinition(
+                    "CMAKE_" + lang + "_COMPILER_ID") == "OpenWatcom" ||
+                  this->Makefile->GetSafeDefinition(
+                    "CMAKE_" + lang + "_SIMULATE_ID") == "OpenWatcom") &&
+                 !cmSystemTools::GetErrorOccuredFlag()) {
+        // The compiler uses the Watcom ABI so it needs a known runtime
+        // library.
+        this->IssueMessage(MessageType::FATAL_ERROR,
+                           "WATCOM_RUNTIME_LIBRARY value '" +
+                             watcomRuntimeLibrary + "' not known for this " +
+                             lang + " compiler.");
+      }
+    }
+  }
 }
 }
 
 
 void cmLocalGenerator::AddLanguageFlagsForLinking(
 void cmLocalGenerator::AddLanguageFlagsForLinking(

+ 4 - 1
Source/cmPolicies.h

@@ -408,7 +408,10 @@ class cmMakefile;
   SELECT(POLICY, CMP0135,                                                     \
   SELECT(POLICY, CMP0135,                                                     \
          "ExternalProject ignores timestamps in archives by default for the " \
          "ExternalProject ignores timestamps in archives by default for the " \
          "URL download method",                                               \
          "URL download method",                                               \
-         3, 24, 0, cmPolicies::WARN)
+         3, 24, 0, cmPolicies::WARN)                                          \
+  SELECT(POLICY, CMP0136,                                                     \
+         "Watcom runtime library flags are selected by an abstraction.", 3,   \
+         24, 0, cmPolicies::WARN)
 
 
 #define CM_SELECT_ID(F, A1, A2, A3, A4, A5, A6) F(A1)
 #define CM_SELECT_ID(F, A1, A2, A3, A4, A5, A6) F(A1)
 #define CM_FOR_EACH_POLICY_ID(POLICY)                                         \
 #define CM_FOR_EACH_POLICY_ID(POLICY)                                         \

+ 1 - 0
Source/cmTarget.cxx

@@ -543,6 +543,7 @@ cmTarget::cmTarget(std::string const& name, cmStateEnums::TargetType type,
     initProp("LINK_DEPENDS_NO_SHARED");
     initProp("LINK_DEPENDS_NO_SHARED");
     initProp("LINK_INTERFACE_LIBRARIES");
     initProp("LINK_INTERFACE_LIBRARIES");
     initProp("MSVC_RUNTIME_LIBRARY");
     initProp("MSVC_RUNTIME_LIBRARY");
+    initProp("WATCOM_RUNTIME_LIBRARY");
     initProp("WIN32_EXECUTABLE");
     initProp("WIN32_EXECUTABLE");
     initProp("MACOSX_BUNDLE");
     initProp("MACOSX_BUNDLE");
     initProp("MACOSX_RPATH");
     initProp("MACOSX_RPATH");

+ 4 - 0
Tests/CMakeLists.txt

@@ -2077,6 +2077,10 @@ if(BUILD_TESTING)
     ADD_TEST_MACRO(ModuleDefinition example_exe)
     ADD_TEST_MACRO(ModuleDefinition example_exe)
   endif()
   endif()
 
 
+  if (CMAKE_C_COMPILER_ID MATCHES "Watcom" AND WIN32)
+    ADD_TEST_MACRO(WatcomRuntimeLibrary)
+  endif()
+
   ADD_TEST_MACRO(CheckCompilerRelatedVariables CheckCompilerRelatedVariables)
   ADD_TEST_MACRO(CheckCompilerRelatedVariables CheckCompilerRelatedVariables)
 
 
   if("${CMAKE_GENERATOR}" MATCHES "Makefile" OR
   if("${CMAKE_GENERATOR}" MATCHES "Makefile" OR

+ 49 - 0
Tests/WatcomRuntimeLibrary/CMakeLists.txt

@@ -0,0 +1,49 @@
+cmake_minimum_required(VERSION 3.23)
+cmake_policy(SET CMP0136 NEW)
+project(WatcomRuntimeLibrary)
+
+function(verify_combinations threads lang src)
+  set(verify_def_MultiThreaded -DVERIFY_MT)
+  set(verify_def_DLL -DVERIFY_DLL)
+  foreach(dll "" DLL)
+    # Construct the name of this runtime library combination.
+    set(rtl "${threads}${dll}")
+
+    # Test that try_compile builds with this RTL.
+    set(CMAKE_WATCOM_RUNTIME_LIBRARY "${rtl}")
+    set(CMAKE_TRY_COMPILE_TARGET_TYPE "STATIC_LIBRARY")
+    try_compile(${rtl}_COMPILES
+      ${CMAKE_CURRENT_BINARY_DIR}/try_compile/${rtl}
+      ${CMAKE_CURRENT_SOURCE_DIR}/${src}
+      COMPILE_DEFINITIONS ${verify_def_${threads}} ${verify_def_${dll}}
+      OUTPUT_VARIABLE ${rtl}_OUTPUT
+      )
+    if(${rtl}_COMPILES)
+      message(STATUS "try_compile with ${rtl} worked")
+    else()
+      string(REPLACE "\n" "\n  " ${rtl}_OUTPUT "  ${${rtl}_OUTPUT}")
+      message(SEND_ERROR "try_compile with ${rtl} failed:\n${${rtl}_OUTPUT}")
+    endif()
+
+    # Test that targets build with this RTL.
+    set(CMAKE_WATCOM_RUNTIME_LIBRARY "$<$<BOOL:$<TARGET_PROPERTY:BOOL_TRUE>>:${rtl}>$<$<BOOL:$<TARGET_PROPERTY:BOOL_FALSE>>:BadContent>")
+    add_library(${rtl}-${lang} ${src})
+    set_property(TARGET ${rtl}-${lang} PROPERTY BOOL_TRUE TRUE)
+    target_compile_definitions(${rtl}-${lang} PRIVATE ${verify_def_${threads}} ${verify_def_${dll}})
+  endforeach()
+endfunction()
+
+function(verify lang src)
+  add_library(default-${lang} ${src})
+  target_compile_definitions(default-${lang} PRIVATE VERIFY_MT VERIFY_DLL)
+
+  verify_combinations(SingleThreaded ${lang} ${src})
+  verify_combinations(MultiThreaded ${lang} ${src})
+
+  # Test known  default behavior when no flag is given.
+  set(CMAKE_WATCOM_RUNTIME_LIBRARY "")
+  add_library(empty-${lang} ${src})
+endfunction()
+
+verify(C verify.c)
+verify(CXX verify.cxx)

+ 1 - 0
Tests/WatcomRuntimeLibrary/verify.c

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

+ 1 - 0
Tests/WatcomRuntimeLibrary/verify.cxx

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

+ 31 - 0
Tests/WatcomRuntimeLibrary/verify.h

@@ -0,0 +1,31 @@
+#ifdef VERIFY_DLL
+#  ifndef _DLL
+#    error "_DLL not defined by DLL runtime library selection"
+#  endif
+#  ifndef __SW_BR
+#    error "__SW_BR not defined by DLL runtime library selection"
+#  endif
+#else
+#  ifdef _DLL
+#    error "_DLL defined by non-DLL runtime library selection"
+#  endif
+#  ifdef __SW_BR
+#    error "__SW_BR defined by non-DLL runtime library selection"
+#  endif
+#endif
+
+#ifdef VERIFY_MT
+#  ifndef _MT
+#    error "_MT not defined by multi-threaded runtime library selection"
+#  endif
+#  ifndef __SW_BM
+#    error "__SW_BM not defined by multi-threaded runtime library selection"
+#  endif
+#else
+#  ifdef _MT
+#    error "_MT defined by single-threaded runtime library selection"
+#  endif
+#  ifdef __SW_BM
+#    error "__SW_BM defined by single-threaded runtime library selection"
+#  endif
+#endif