1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
|
--!A cross-platform build utility based on Lua
--
-- Licensed under the Apache License, Version 2.0 (the "License");
-- you may not use this file except in compliance with the License.
-- You may obtain a copy of the License at
--
-- http://www.apache.org/licenses/LICENSE-2.0
--
-- Unless required by applicable law or agreed to in writing, software
-- distributed under the License is distributed on an "AS IS" BASIS,
-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-- See the License for the specific language governing permissions and
-- limitations under the License.
--
-- Copyright (C) 2015-present, Xmake Open Source Community.
--
-- @author ruki
-- @file cxxfeatures.lua
--
-- set features
function _set(feature, condition)
_g.features = _g.features or {}
_g.features[feature] = condition
end
-- get features
--
-- http://gcc.gnu.org/projects/cxx0x.html
-- http://gcc.gnu.org/projects/cxx1y.html
-- https://gcc.gnu.org/projects/cxx-status.html
--
-- porting from Modules/Compiler/GNU-CXX-FeatureTests.cmake
--
function main()
-- init conditions
-- gcc -x c++ -std=c++20 -dM -E - < /dev/null | grep __cplusplus
local gcc_minver = "(__GNUC__ * 100 + __GNUC_MINOR__) >= 404"
local gcc90_cxx20 = "(__GNUC__ * 100 + __GNUC_MINOR__) >= 900 && __cplusplus >= 202002L"
local gcc70_cxx17 = "(__GNUC__ * 100 + __GNUC_MINOR__) >= 700 && __cplusplus >= 201703L"
local gcc50_cxx14 = "(__GNUC__ * 100 + __GNUC_MINOR__) >= 500 && __cplusplus >= 201402L"
local gcc49_cxx14 = "(__GNUC__ * 100 + __GNUC_MINOR__) >= 409 && __cplusplus > 201103L"
local gcc481_cxx11 = "((__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) >= 40801) && __cplusplus >= 201103L"
local gcc48_cxx11 = "(__GNUC__ * 100 + __GNUC_MINOR__) >= 408 && __cplusplus >= 201103L"
local gcc47_cxx11 = "(__GNUC__ * 100 + __GNUC_MINOR__) >= 407 && __cplusplus >= 201103L"
local gcc_cxx0x_defined = "(__cplusplus >= 201103L || (defined(__GXX_EXPERIMENTAL_CXX0X__) && __GXX_EXPERIMENTAL_CXX0X__))"
local gcc46_cxx11 = "(__GNUC__ * 100 + __GNUC_MINOR__) >= 406 && " .. gcc_cxx0x_defined
local gcc45_cxx11 = "(__GNUC__ * 100 + __GNUC_MINOR__) >= 405 && " .. gcc_cxx0x_defined
local gcc44_cxx11 = "(__GNUC__ * 100 + __GNUC_MINOR__) >= 404 && " .. gcc_cxx0x_defined
local gcc43_cxx11 = gcc_minver .. " && " .. gcc_cxx0x_defined
-- set language standard supports
_set("cxx_std_98", gcc_minver)
_set("cxx_std_11", gcc43_cxx11)
_set("cxx_std_14", gcc49_cxx14)
_set("cxx_std_17", gcc70_cxx17)
_set("cxx_std_20", gcc90_cxx20)
-- set features
_set("cxx_variable_templates", gcc50_cxx14)
_set("cxx_relaxed_constexpr", gcc50_cxx14)
_set("cxx_aggregate_default_initializers", gcc50_cxx14)
-- GNU 4.9 in c++14 mode sets __cplusplus to 201300L, so don't test for the
-- correct value of it below.
-- https://patchwork.ozlabs.org/patch/382470/
_set("cxx_contextual_conversions", gcc49_cxx14)
_set("cxx_attribute_deprecated", gcc49_cxx14)
_set("cxx_decltype_auto", gcc49_cxx14)
_set("cxx_digit_separators", gcc49_cxx14)
_set("cxx_generic_lambdas", gcc49_cxx14)
_set("cxx_lambda_init_captures", gcc49_cxx14)
-- GNU 4.3 supports binary literals as an extension, but may warn about
-- use of extensions prior to GNU 4.9
-- http://stackoverflow.com/questions/16334024/difference-between-gcc-binary-literals-and-c14-ones
_set("cxx_binary_literals", gcc49_cxx14)
-- The feature below is documented as available in GNU 4.8 (by implementing an
-- earlier draft of the standard paper), but that version of the compiler
-- does not set __cplusplus to a value greater than 201103L until GNU 4.9:
-- http://gcc.gnu.org/onlinedocs/gcc-4.8.2/cpp/Standard-Predefined-Macros.html#Standard-Predefined-Macros
-- http://gcc.gnu.org/onlinedocs/gcc-4.9.0/cpp/Standard-Predefined-Macros.html#Standard-Predefined-Macros
-- So, CMake only reports availability for it with GNU 4.9 or later.
_set("cxx_return_type_deduction", gcc49_cxx14)
-- Introduced in GCC 4.8.1
_set("cxx_decltype_incomplete_return_types", gcc481_cxx11)
_set("cxx_reference_qualified_functions", gcc481_cxx11)
-- The alignof feature works with GNU 4.7 and -std=c++11, but it is documented
-- as available with GNU 4.8, so treat that as true.
_set("cxx_alignas", gcc48_cxx11)
_set("cxx_alignof", gcc48_cxx11)
_set("cxx_attributes", gcc48_cxx11)
_set("cxx_inheriting_constructors", gcc48_cxx11)
_set("cxx_thread_local", gcc48_cxx11)
_set("cxx_alias_templates", gcc47_cxx11)
_set("cxx_delegating_constructors", gcc47_cxx11)
_set("cxx_extended_friend_declarations", gcc47_cxx11)
_set("cxx_final", gcc47_cxx11)
_set("cxx_nonstatic_member_init", gcc47_cxx11)
_set("cxx_override", gcc47_cxx11)
_set("cxx_user_literals", gcc47_cxx11)
-- NOTE: C++11 was ratified in September 2011. GNU 4.7 is the first minor
-- release following that (March 2012), and the first minor release to
-- support -std=c++11. Prior to that, support for C++11 features is technically
-- experiemental and possibly incomplete (see for example the note below about
-- cxx_variadic_template_template_parameters)
-- GNU does not define __cplusplus correctly before version 4.7.
-- https://gcc.gnu.org/bugzilla/show_bug.cgi?id=1773
-- __GXX_EXPERIMENTAL_CXX0X__ is defined in prior versions, but may not be
-- defined in the future.
_set("cxx_constexpr", gcc46_cxx11)
_set("cxx_defaulted_move_initializers", gcc46_cxx11)
_set("cxx_enum_forward_declarations", gcc46_cxx11)
_set("cxx_noexcept", gcc46_cxx11)
_set("cxx_nullptr", gcc46_cxx11)
_set("cxx_range_for", gcc46_cxx11)
_set("cxx_unrestricted_unions", gcc46_cxx11)
_set("cxx_explicit_conversions", gcc45_cxx11)
_set("cxx_lambdas", gcc45_cxx11)
_set("cxx_local_type_template_args", gcc45_cxx11)
_set("cxx_raw_string_literals", gcc45_cxx11)
_set("cxx_auto_type", gcc44_cxx11)
_set("cxx_defaulted_functions", gcc44_cxx11)
_set("cxx_deleted_functions", gcc44_cxx11)
_set("cxx_generalized_initializers", gcc44_cxx11)
_set("cxx_inline_namespaces", gcc44_cxx11)
_set("cxx_sizeof_member", gcc44_cxx11)
_set("cxx_strong_enums", gcc44_cxx11)
_set("cxx_trailing_return_types", gcc44_cxx11)
_set("cxx_unicode_literals", gcc44_cxx11)
_set("cxx_uniform_initialization", gcc44_cxx11)
_set("cxx_variadic_templates", gcc44_cxx11)
-- TODO: If features are ever recorded for GNU 4.3, there should possibly
-- be a new feature added like cxx_variadic_template_template_parameters,
-- which is implemented by GNU 4.4, but not 4.3. cxx_variadic_templates is
-- actually implemented by GNU 4.3, but variadic template template parameters
-- 'completes' it, so that is the version we record as having the variadic
-- templates capability in CMake. See
-- http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2555.pdf
-- TODO: Should be supported by GNU 4.3
_set("cxx_decltype", gcc43_cxx11)
_set("cxx_default_function_template_args", gcc43_cxx11)
_set("cxx_long_long_type", gcc43_cxx11)
_set("cxx_right_angle_brackets", gcc43_cxx11)
_set("cxx_rvalue_references", gcc43_cxx11)
_set("cxx_static_assert", gcc43_cxx11)
-- TODO: Should be supported since GNU 3.4?
_set("cxx_extern_templates", gcc_minver .. " && " .. gcc_cxx0x_defined)
-- TODO: Should be supported forever?
_set("cxx_func_identifier", gcc_minver .. " && " .. gcc_cxx0x_defined)
_set("cxx_variadic_macros", gcc_minver .. " && " .. gcc_cxx0x_defined)
_set("cxx_template_template_parameters", gcc_minver .. " && __cplusplus")
-- c++17 language features with predefined macros
-- https://en.cppreference.com/w/cpp/feature_test
local features_cxx17 = {
"__cpp_aggregate_bases",
"__cpp_aligned_new",
"__cpp_capture_star_this",
"__cpp_constexpr",
"__cpp_deduction_guides",
"__cpp_enumerator_attributes",
"__cpp_fold_expressions",
"__cpp_guaranteed_copy_elision",
"__cpp_hex_float",
"__cpp_if_constexpr",
"__cpp_inheriting_constructors",
"__cpp_inline_variables",
"__cpp_namespace_attributes",
"__cpp_noexcept_function_type",
"__cpp_nontype_template_args",
"__cpp_nontype_template_parameter_auto",
"__cpp_range_based_for",
"__cpp_static_assert",
"__cpp_structured_bindings",
"__cpp_template_template_args",
"__cpp_variadic_using"}
for _, feature in ipairs(features_cxx17) do
_set((feature:gsub("__cpp", "cxx")), "__cplusplus && defined(" .. feature .. ")")
end
-- c++20 language features with predefined macros
-- https://en.cppreference.com/w/cpp/feature_test
local features_cxx20 = {
"__cpp_aggregate_paren_init",
"__cpp_char8_t",
"__cpp_concepts",
"__cpp_conditional_explicit",
"__cpp_consteval",
"__cpp_constexpr",
"__cpp_constexpr_dynamic_alloc",
"__cpp_constexpr_in_decltype",
"__cpp_constinit",
"__cpp_deduction_guides",
"__cpp_designated_initializers",
"__cpp_generic_lambdas",
"__cpp_impl_coroutine",
"__cpp_impl_destroying_delete",
"__cpp_impl_three_way_comparison",
"__cpp_init_captures",
"__cpp_modules",
"__cpp_nontype_template_args",
"__cpp_using_enum"}
for _, feature in ipairs(features_cxx20) do
_set((feature:gsub("__cpp", "cxx")), "__cplusplus && defined(" .. feature .. ")")
end
-- get features
return _g.features
end
|