Skip to content

Commit 786a34b

Browse files
authored
Refine specification of CMake C/C++ standard version requirement (#28126)
### Description <!-- Describe your changes. --> - Use `c_std_99` and `cxx_std_20` target compile features to specify minimum C/C++ standard versions for onnxruntime targets. - Update existing handling of `CMAKE_CXX_STANDARD/CMAKE_C_STANDARD` to error out if existing values don't meet the minimum version requirements. Ideally, we would only use the target compile feature mechanism, but these variables affect dependencies too and we should try to build everything with the same version (e.g., we need to do this for Abseil). - Patch the external `date` dependency to avoid overriding the project-wide setting of `CMAKE_CXX_STANDARD` to `17`. This causes an issue with non-vcpkg builds and is the motivation for this change. ### Motivation and Context <!-- - Why is this change required? What problem does it solve? - If it fixes an open issue, please link to the issue here. --> Fix C++20 build issue in non-vcpkg builds. Improve minimum language standard version handling.
1 parent c5e6bd8 commit 786a34b

4 files changed

Lines changed: 99 additions & 9 deletions

File tree

cmake/CMakeLists.txt

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -10,15 +10,7 @@ cmake_policy(SET CMP0104 OLD)
1010
# Project
1111
project(onnxruntime C CXX ASM)
1212

13-
# Set C/C++ standard versions
14-
if (NOT CMAKE_C_STANDARD)
15-
# Needed for Java
16-
set(CMAKE_C_STANDARD 99)
17-
endif()
18-
19-
if (NOT CMAKE_CXX_STANDARD)
20-
set(CMAKE_CXX_STANDARD 20)
21-
endif()
13+
include(onnxruntime_language_standard_versions.cmake)
2214

2315
# We don't use C++20 modules yet.
2416
# There are some known issues to address first:
@@ -1243,6 +1235,11 @@ function(onnxruntime_configure_target target_name)
12431235
target_link_options(${target_name} PRIVATE "$<$<LINK_LANGUAGE:CXX,C>:/CETCOMPAT>")
12441236
endif()
12451237

1238+
# Add compile features for minimum required language standard versions.
1239+
# Wrap in $<BUILD_INTERFACE:...> so the requirement is not exported to consumers of installed ORT targets.
1240+
target_compile_features(${target_name} PUBLIC
1241+
$<BUILD_INTERFACE:${onnxruntime_c_std_compile_feature}>
1242+
$<BUILD_INTERFACE:${onnxruntime_cxx_std_compile_feature}>)
12461243
endfunction()
12471244

12481245
function(onnxruntime_add_shared_library target_name)

cmake/external/onnxruntime_external_deps.cmake

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -274,6 +274,8 @@ onnxruntime_fetchcontent_declare(
274274
URL ${DEP_URL_date}
275275
URL_HASH SHA1=${DEP_SHA1_date}
276276
EXCLUDE_FROM_ALL
277+
PATCH_COMMAND
278+
${Patch_EXECUTABLE} --binary --ignore-whitespace -p1 < ${PROJECT_SOURCE_DIR}/patches/date/date.patch
277279
FIND_PACKAGE_ARGS 3...<4 NAMES date
278280
)
279281
onnxruntime_fetchcontent_makeavailable(date)
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
# Copyright (c) Microsoft Corporation. All rights reserved.
2+
# Licensed under the MIT License.
3+
4+
#
5+
# Minimum required language standard versions.
6+
#
7+
8+
set(onnxruntime_MINIMUM_C_STANDARD_VERSION 99)
9+
set(onnxruntime_MINIMUM_CXX_STANDARD_VERSION 20)
10+
11+
#
12+
# Handle CMAKE_<LANG>_STANDARD variables.
13+
#
14+
# We only set them if unset. Otherwise, enforce a minimum value.
15+
#
16+
# We care about the CMAKE_<LANG>_STANDARD variables because we typically want our dependencies to be built with the
17+
# same language standard versions as the rest of our code.
18+
# E.g., this is important for Abseil.
19+
#
20+
21+
# "Normalize" means make suitable for comparison.
22+
function(onnxruntime_normalize_language_standard_version
23+
language_standard_version_var_name
24+
version
25+
normalized_version_var_name)
26+
set(normalized_version ${version})
27+
28+
# Note: For CMAKE_C_STANDARD and CMAKE_CXX_STANDARD, we assume two-digit versions based on years.
29+
if("${language_standard_version_var_name}" STREQUAL "CMAKE_C_STANDARD")
30+
if("${version}" EQUAL "90" OR "${version}" EQUAL "99")
31+
set(base_year 1900)
32+
else()
33+
set(base_year 2000)
34+
endif()
35+
math(EXPR normalized_version "${base_year} + ${version}")
36+
elseif("${language_standard_version_var_name}" STREQUAL "CMAKE_CXX_STANDARD")
37+
if("${version}" EQUAL "98")
38+
set(base_year 1900)
39+
else()
40+
set(base_year 2000)
41+
endif()
42+
math(EXPR normalized_version "${base_year} + ${version}")
43+
endif()
44+
45+
set(${normalized_version_var_name} ${normalized_version} PARENT_SCOPE)
46+
endfunction()
47+
48+
function(onnxruntime_ensure_minimum_language_standard_version
49+
language_standard_version_var_name
50+
minimum_version)
51+
if(DEFINED ${language_standard_version_var_name})
52+
onnxruntime_normalize_language_standard_version(
53+
${language_standard_version_var_name} "${minimum_version}" normalized_minimum_version)
54+
onnxruntime_normalize_language_standard_version(
55+
${language_standard_version_var_name} "${${language_standard_version_var_name}}" normalized_version)
56+
57+
if(normalized_version VERSION_LESS normalized_minimum_version)
58+
message(FATAL_ERROR "${language_standard_version_var_name} must be at least ${minimum_version}. "
59+
"It is ${${language_standard_version_var_name}}.")
60+
endif()
61+
else()
62+
message(STATUS "Setting ${language_standard_version_var_name} to ${minimum_version}")
63+
set(${language_standard_version_var_name} ${minimum_version} PARENT_SCOPE)
64+
endif()
65+
endfunction()
66+
67+
onnxruntime_ensure_minimum_language_standard_version(CMAKE_C_STANDARD ${onnxruntime_MINIMUM_C_STANDARD_VERSION})
68+
onnxruntime_ensure_minimum_language_standard_version(CMAKE_CXX_STANDARD ${onnxruntime_MINIMUM_CXX_STANDARD_VERSION})
69+
70+
#
71+
# Define onnxruntime_<lang>_std_compile_feature variables specifying the <lang> standard version compile feature name.
72+
# These should be used by all onnxruntime targets via target_compile_features().
73+
#
74+
75+
set(onnxruntime_c_std_compile_feature c_std_${onnxruntime_MINIMUM_C_STANDARD_VERSION})
76+
set(onnxruntime_cxx_std_compile_feature cxx_std_${onnxruntime_MINIMUM_CXX_STANDARD_VERSION})

cmake/patches/date/date.patch

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
diff --git a/CMakeLists.txt b/CMakeLists.txt
2+
index 012512a..548ee4c 100644
3+
--- a/CMakeLists.txt
4+
+++ b/CMakeLists.txt
5+
@@ -24,8 +24,8 @@ include( GNUInstallDirs )
6+
7+
get_directory_property( has_parent PARENT_DIRECTORY )
8+
9+
-# Override by setting on CMake command line.
10+
-set( CMAKE_CXX_STANDARD 17 CACHE STRING "The C++ standard whose features are requested." )
11+
+# Don't explicitly set CMAKE_CXX_STANDARD as a cache variable.
12+
+# Cache variables are sticky and global. They may override values from other projects.
13+
14+
option( USE_SYSTEM_TZ_DB "Use the operating system's timezone database" OFF )
15+
option( MANUAL_TZ_DB "User will set TZ DB manually by invoking set_install in their code" OFF )

0 commit comments

Comments
 (0)