OpenWatcom: Allow specifying the runtime library

Add a `CMAKE_WATCOM_RUNTIME_LIBRARY` variable to control the
runtime library selection.  Add policy CMP0136 to switch to
in place of the old hard-coded default flags.

Fixes: #23178
pipelines/280515^2
Cameron Cawley 2021-10-18 23:20:07 +01:00 committed by Brad King
parent 849ad97d95
commit 33da5824ac
19 changed files with 299 additions and 6 deletions

View File

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

View File

@ -58,6 +58,7 @@ Policies Introduced by CMake 3.24
.. toctree::
: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>
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>

View File

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

View File

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

49
Help/policy/CMP0136.rst Normal file
View File

@ -0,0 +1,49 @@
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`` 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

View File

@ -0,0 +1,18 @@
``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.
``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.
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.

View File

@ -0,0 +1,33 @@
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`` 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.

View File

@ -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`.

View File

@ -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`` 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.

View File

@ -14,11 +14,20 @@ set(CMAKE_SHARED_LIBRARY_C_FLAGS "-bd") # ... while this is a space separated st
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(NOT CMAKE_C_STANDARD_INCLUDE_DIRECTORIES)
@ -32,4 +41,9 @@ endif()
macro(__windows_open_watcom lang)
set(CMAKE_${lang}_CREATE_WIN32_EXE "system nt_win")
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()

View File

@ -228,6 +228,8 @@ std::string const kCMAKE_TRY_COMPILE_OSX_ARCHITECTURES =
std::string const kCMAKE_TRY_COMPILE_PLATFORM_VARIABLES =
"CMAKE_TRY_COMPILE_PLATFORM_VARIABLES";
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 */
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");
}
/* 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. */
if (this->Makefile->GetPolicyStatus(cmPolicies::CMP0104) !=
cmPolicies::NEW &&
@ -902,6 +911,7 @@ int cmCoreTryCompile::TryCompileCode(std::vector<std::string> const& argv,
vars.insert(kCMAKE_SYSROOT_LINK);
vars.insert(kCMAKE_WARN_DEPRECATED);
vars.emplace("CMAKE_MSVC_RUNTIME_LIBRARY"_s);
vars.emplace("CMAKE_WATCOM_RUNTIME_LIBRARY"_s);
if (cmValue varListStr = this->Makefile->GetDefinition(
kCMAKE_TRY_COMPILE_PLATFORM_VARIABLES)) {

View File

@ -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(

View File

@ -408,7 +408,10 @@ class cmMakefile;
SELECT(POLICY, CMP0135, \
"ExternalProject ignores timestamps in archives by default for the " \
"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_FOR_EACH_POLICY_ID(POLICY) \

View File

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

View File

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

View File

@ -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)

View File

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

View File

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

View File

@ -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