This is a mirror page, please see the original page:
https://xmake.io/#/manual/helper_interfacesAutomatic detection of auxiliary interface
In addition, the version of this interface after 2.2.5 provides some built-in helper functions, which can be imported directly using includes. See the specific built-in functions: Helper functions
We can use these interfaces to detect links, c/c++ type, includes and compiler features, and write macro definitions to config.h
Among them, we provide two types of interfaces, check_xxx
and configvar_check_xxx
. The interfaces prefixed with configvar_
will be written into the config.h.in template file specified by add_configfiles
after passing the test.
And check_xxx
only defines related macros to participate in compilation, but it will not be persisted in config.h.in
.
For related issues, see:
Note: Instead of introducing these interfaces separately via includes("check_links.lua")
,
for versions 2.8.5 and above, you can use the more convenient
includes("@builtin/check")
to bring in all the checking interfaces at once, but of course we can also bring in individual scripts on an as-needed basis:
includes("@builtin/check/check_links.lua")
The original introduction path, which does not distinguish whether it is a user path or not, is not easy to manage and maintain,
and is easily interfered by user configurations, so it will be gradually deprecated later.
Check links
We can check whether the specified links pass or not by trying to link.
includes("check_links.lua")
target("test")
set_kind("binary")
add_files("*.c")
add_configfiles("config.h.in")
configvar_check_links("HAS_PTHREAD", {"pthread", "m", "dl"})
config.h.in
${define HAS_PTHREAD}
config.h
#define HAS_PTHREAD 1
/* #undef HAS_PTHREAD */
Detect c/c++ type
We can also detect the existence of c/c++ types.
configvar_check_ctypes
is used to detect c code types, and configvar_check_cxxtypes
is used to detect c++ code types.
includes("check_ctypes.lua")
target("test")
set_kind("binary")
add_files("*.c")
add_configfiles("config.h.in")
configvar_check_ctypes("HAS_WCHAR", "wchar_t")
configvar_check_ctypes("HAS_WCHAR_AND_FLOAT", {"wchar_t", "float"})
config.h.in
${define HAS_WCHAR}
${define HAS_WCHAR_AND_FLOAT}
config.h
/* #undef HAS_WCHAR */
/* #undef HAS_WCHAR_AND_FLOAT */
Detect c/c++ functions
configvar_check_cfuncs
is used to detect c code functions, and configvar_check_cxxfuncs
is used to detect c++ code functions.
includes("check_cfuncs.lua")
target("test")
set_kind("binary")
add_files("*.c")
add_configfiles("config.h.in")
configvar_check_cfuncs("HAS_SETJMP", "setjmp", {includes = {"signal.h", "setjmp.h"}})
config.h.in
${define HAS_SETJMP}
config.h
#define HAS_SETJMP 1
/* #undef HAS_SETJMP */
Detect c/c++ header files
configvar_check_cincludes
is used to detect c code header files, and configvar_check_cxxincludes
is used to detect c++ code header files.
includes("check_cincludes.lua")
target("test")
set_kind("binary")
add_files("*.c")
add_configfiles("config.h.in")
configvar_check_cincludes("HAS_STRING_H", "string.h")
configvar_check_cincludes("HAS_STRING_AND_STDIO_H", {"string.h", "stdio.h"})
config.h.in
${define HAS_STRING_H}
${define HAS_STRING_AND_STDIO_H}
config.h
/* #undef HAS_STRING_H */
#define HAS_STRING_AND_STDIO_H 1
Detect c/c++ code snippets
configvar_check_csnippets
is used to detect c code snippets, and configvar_check_cxxsnippets
is used to detect c++ code snippets.
includes("check_csnippets.lua")
target("test")
set_kind("binary")
add_files("*.c")
add_configfiles("config.h.in")
configvar_check_csnippets("HAS_STATIC_ASSERT", "_Static_assert(1, \"\");")
config.h.in
${define HAS_STATIC_ASSERT}
config.h
#define HAS_STATIC_ASSERT 1
After v2.5.7, check_csnippets has been improved, adding tryrun
and output
parameters to try to run and capture output.
includes("check_csnippets.lua")
target("test")
set_kind("binary")
add_files("*.c")
add_configfiles("config.h.in")
check_csnippets("HAS_INT_4", "return (sizeof(int) == 4)? 0: -1;", {tryrun = true})
check_csnippets("INT_SIZE",'printf("%d", sizeof(int)); return 0;', {output = true, number = true})
configvar_check_csnippets("HAS_LONG_8", "return (sizeof(long) == 8)? 0: -1;", {tryrun = true})
configvar_check_csnippets("PTR_SIZE",'printf("%d", sizeof(void*)); return 0;', {output = true, number = true})
If capture output is enabled, ${define PTR_SIZE}
in config.h.in
will automatically generate #define PTR_SIZE 4
.
Among them, the number = true
setting can be forced as a number instead of a string value, otherwise it will be defined as #define PTR_SIZE "4"
by default
Detecting compiler features
includes("check_features.lua")
target("test")
set_kind("binary")
add_files("*.c")
add_configfiles("config.h.in")
configvar_check_features("HAS_CONSTEXPR", "cxx_constexpr")
configvar_check_features("HAS_CONSEXPR_AND_STATIC_ASSERT", {"cxx_constexpr", "c_static_assert"}, {languages = "c++11"})
config.h.in
${define HAS_CONSTEXPR}
${define HAS_CONSEXPR_AND_STATIC_ASSERT}
config.h
/* #undef HAS_CONSTEXPR */
#define HAS_CONSEXPR_AND_STATIC_ASSERT 1
List of all c compiler features:
Feature name |
---|
c_static_assert |
c_restrict |
c_variadic_macros |
c_function_prototypes |
List of all c++ compiler features:
Feature name |
---|
cxx_variable_templates |
cxx_relaxed_constexpr |
cxx_aggregate_default_initializers |
cxx_contextual_conversions |
cxx_attribute_deprecated |
cxx_decltype_auto |
cxx_digit_separators |
cxx_generic_lambdas |
cxx_lambda_init_captures |
cxx_binary_literals |
cxx_return_type_deduction |
cxx_decltype_incomplete_return_types |
cxx_reference_qualified_functions |
cxx_alignof |
cxx_attributes |
cxx_inheriting_constructors |
cxx_thread_local |
cxx_alias_templates |
cxx_delegating_constructors |
cxx_extended_friend_declarations |
cxx_final |
cxx_nonstatic_member_init |
cxx_override |
cxx_user_literals |
cxx_constexpr |
cxx_defaulted_move_initializers |
cxx_enum_forward_declarations |
cxx_noexcept |
cxx_nullptr |
cxx_range_for |
cxx_unrestricted_unions |
cxx_explicit_conversions |
cxx_lambdas |
cxx_local_type_template_args |
cxx_raw_string_literals |
cxx_auto_type |
cxx_defaulted_functions |
cxx_deleted_functions |
cxx_generalized_initializers |
cxx_inline_namespaces |
cxx_sizeof_member |
cxx_strong_enums |
cxx_trailing_return_types |
cxx_unicode_literals |
cxx_uniform_initialization |
cxx_variadic_templates |
cxx_decltype |
cxx_default_function_template_args |
cxx_long_long_type |
cxx_right_angle_brackets |
cxx_rvalue_references |
cxx_static_assert |
cxx_extern_templates |
cxx_func_identifier |
cxx_variadic_macros |
cxx_template_template_parameters |
v2.5.9 adds c++17 feature detection:
Feature name |
---|
cxx_aggregate_bases |
cxx_aligned_new |
cxx_capture_star_this |
cxx_constexpr |
cxx_deduction_guides |
cxx_enumerator_attributes |
cxx_fold_expressions |
cxx_guaranteed_copy_elision |
cxx_hex_float |
cxx_if_constexpr |
cxx_inheriting_constructors |
cxx_inline_variables |
cxx_namespace_attributes |
cxx_noexcept_function_type |
cxx_nontype_template_args |
cxx_nontype_template_parameter_auto |
cxx_range_based_for |
cxx_static_assert |
cxx_structured_bindings |
cxx_template_template_args |
cxx_variadic_using |
v2.5.9 adds c++20 feature detection:
Feature name |
---|
cxx_aggregate_paren_init |
cxx_char8_t |
cxx_concepts |
cxx_conditional_explicit |
cxx_consteval |
cxx_constexpr |
cxx_constexpr_dynamic_alloc |
cxx_constexpr_in_decltype |
cxx_constinit |
cxx_deduction_guides |
cxx_designated_initializers |
cxx_generic_lambdas |
cxx_impl_coroutine |
cxx_impl_destroying_delete |
cxx_impl_three_way_comparison |
cxx_init_captures |
cxx_modules |
cxx_nontype_template_args |
cxx_using_enum |
After 2.5.8, support for cstd and c++ std versions are added, related issues: #1715
configvar_check_features("HAS_CXX_STD_98", "cxx_std_98")
configvar_check_features("HAS_CXX_STD_11", "cxx_std_11", {languages = "c++11"})
configvar_check_features("HAS_CXX_STD_14", "cxx_std_14", {languages = "c++14"})
configvar_check_features("HAS_CXX_STD_17", "cxx_std_17", {languages = "c++17"})
configvar_check_features("HAS_CXX_STD_20", "cxx_std_20", {languages = "c++20"})
configvar_check_features("HAS_C_STD_89", "c_std_89")
configvar_check_features("HAS_C_STD_99", "c_std_99")
configvar_check_features("HAS_C_STD_11", "c_std_11", {languages = "c11"})
configvar_check_features("HAS_C_STD_17", "c_std_17", {languages = "c17"})
Detect built-in macro definitions
There are some built-in macro definitions in the compiler, such as __GNUC__
, etc. We can use the check_macros
and configvar_check_macros
auxiliary scripts to detect their existence.
Related issues: #1715
- Check whether the macro is defined
configvar_check_macros("HAS_GCC", "__GNUC__")
- The detection macro is not defined
configvar_check_macros("NO_GCC", "__GNUC__", {defined = false})
- Detect macro conditions
configvar_check_macros("HAS_CXX20", "__cplusplus >= 202002L", {languages = "c++20"})
Detect type size
In previous versions, type detection was possible with check_csnippets
and output = true
.
check_csnippets("INT_SIZE", 'printf("%d", sizeof(int)); return 0;', {output = true, number = true})
This way, however, extracts the type size information by trying to run the test code and then getting the run output.
This doesn't work for cross-compilation.
In version 2.8.5, we added the check_sizeof
helper interface, which allows you to extract type size information by parsing the binary file of the test program directly.
Since there is no need to run tests, this approach not only supports cross-compilation, but also greatly improves the efficiency of testing and is much easier to use.
includes("@builtin/check")
target("test")
set_kind("static")
add_files("*.cpp")
check_sizeof("LONG_SIZE", "long")
check_sizeof("STRING_SIZE", "std::string", {includes = "string"})
$ xmake f -c
checking for LONG_SIZE ... 8
checking for STRING_SIZE ... 24
Alternatively, I can check for it in the script field with target:check_sizeof
.
Detecting big-endian
After version 2.8.9, we added the check_bigendian
interface to determine if the current compilation target is in bigendian mode.
includes("@builtin/check")
target("test")
set_kind("static")
add_files("*.cpp")
check_bigendian("IS_BIG_ENDIAN")
If the test passes and it is currently in big endian mode, then IS_BIG_ENDIAN=1
is defined.