Automatic 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](https://github.com/xmake- io/xmake/tree/master/xmake/includes)
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 1Detect 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 1After 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 1List 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 ... 24Alternatively, 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.