diff options
| author | Carbene Hu <[email protected]> | 2024-03-17 14:59:02 +0800 |
|---|---|---|
| committer | Carbene Hu <[email protected]> | 2024-03-17 14:59:02 +0800 |
| commit | 097a6d25fe308683161920f3cd9292063cddab14 (patch) | |
| tree | 115b697afc1b19a5d67207ed41a0ffb581fe1424 | |
| parent | 9eb1a7489b99e05c65c62ccb651c65c02dc9b216 (diff) | |
feat: Add check_bigendian #4843
| -rw-r--r-- | tests/apis/check_xxx/config.h.in | 1 | ||||
| -rw-r--r-- | tests/apis/check_xxx/xmake.lua | 2 | ||||
| -rw-r--r-- | xmake/core/project/target.lua | 12 | ||||
| -rw-r--r-- | xmake/includes/check/check_bigendian.lua | 137 | ||||
| -rw-r--r-- | xmake/includes/check/xmake.lua | 1 | ||||
| -rw-r--r-- | xmake/modules/lib/detect/check_bigendian.lua | 71 |
6 files changed, 224 insertions, 0 deletions
diff --git a/tests/apis/check_xxx/config.h.in b/tests/apis/check_xxx/config.h.in index 9dedbaf96..d2f70893b 100644 --- a/tests/apis/check_xxx/config.h.in +++ b/tests/apis/check_xxx/config.h.in @@ -19,6 +19,7 @@ ${define HAS_C_STD_11} ${define HAS_C_STD_17} ${define HAS_GCC} ${define HAS_CXX20} +${define IS_BIG_ENDIAN} ${define NO_GCC} ${define PTR_SIZE} ${define HAVE_VISIBILITY} diff --git a/tests/apis/check_xxx/xmake.lua b/tests/apis/check_xxx/xmake.lua index fdef4b472..a72b575ae 100644 --- a/tests/apis/check_xxx/xmake.lua +++ b/tests/apis/check_xxx/xmake.lua @@ -6,6 +6,7 @@ target("foo") add_includedirs("$(buildir)") add_configfiles("config.h.in") + check_bigendian("IS_BIG_ENDIAN") check_ctypes("HAS_WCHAR", "wchar_t") check_cincludes("HAS_STRING_H", "string.h") check_csnippets("HAS_INT_4", "return (sizeof(int) == 4)? 0 : -1;", {tryrun = true}) @@ -20,6 +21,7 @@ target("foo") check_csnippets("INT_SIZE", 'printf("%d", sizeof(int)); return 0;', {output = true, number = true}) check_sizeof("LONG_SIZE", "long") check_sizeof("STRING_SIZE", "std::string", {includes = "string"}) + configvar_check_bigendian("IS_BIG_ENDIAN") configvar_check_cincludes("HAS_STRING_AND_STDIO_H", {"string.h", "stdio.h"}) configvar_check_ctypes("HAS_WCHAR_AND_FLOAT", {"wchar_t", "float"}) configvar_check_links("HAS_PTHREAD", {"pthread", "m", "dl"}) diff --git a/xmake/core/project/target.lua b/xmake/core/project/target.lua index 2c2fafdc3..8757c63e2 100644 --- a/xmake/core/project/target.lua +++ b/xmake/core/project/target.lua @@ -2600,6 +2600,18 @@ function _instance:check_sizeof(typename, opt) return sandbox_module.import("lib.detect.check_sizeof", {anonymous = true})(typename, opt) end +-- check the endianness of compiler +-- +-- @param opt the argument options, e.g. {includes = "xxx.h", configs = {defines = ""}} +-- +-- @return the type size +-- +function _instance:check_bigendian(opt) + opt = opt or {} + opt.target = self:_checked_target() + return sandbox_module.import("lib.detect.check_bigendian", {anonymous = true})(opt) +end + -- check the given c snippets? -- -- @param snippets the snippets diff --git a/xmake/includes/check/check_bigendian.lua b/xmake/includes/check/check_bigendian.lua new file mode 100644 index 000000000..63b9d6f4a --- /dev/null +++ b/xmake/includes/check/check_bigendian.lua @@ -0,0 +1,137 @@ +--!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) 2024, TBOOX Open Source Group. +-- +-- @author CarbeneHu +-- @file check_bigendian.lua +-- + +-- check compiler byteorder(big-endian/little-endian) add to macro definition +-- +-- from https://github.com/xmake-io/xmake/issues/4843 +-- +-- e.g. +-- +-- check_bigendian("IS_BIG_ENDIAN") => IS_BIG_ENDIAN=0 +-- +-- configvar_check_bigendian("IS_BIG_ENDIAN") => #define IS_BIG_ENDIAN 0 +-- + +local check_bigendian_template = [[ +#include <inttypes.h> +/* A 16 bit integer is required. */ +typedef uint16_t byteorder_int16_t; + +/* On a little endian machine, these 16bit ints will give "THIS IS LITTLE ENDIAN." + On a big endian machine the characters will be exchanged pairwise. */ +const byteorder_int16_t info_little[] = {0x4854, 0x5349, 0x4920, 0x2053, 0x494c, 0x5454, 0x454c, 0x4520, 0x444e, 0x4149, 0x2e4e, 0x0000}; + +/* on a big endian machine, these 16bit ints will give "THIS IS BIG ENDIAN." + On a little endian machine the characters will be exchanged pairwise. */ +const byteorder_int16_t info_big[] = {0x5448, 0x4953, 0x2049, 0x5320, 0x4249, 0x4720, 0x454e, 0x4449, 0x414e, 0x2e2e, 0x0000}; + +int main(int argc, char *argv[]) +{ + int require = 0; + require += info_little[argc]; + require += info_big[argc]; + (void)argv; + return require; +}]] + +local function _byteorder_binary_match(content) + local match = content:match("THIS IS BIG ENDIAN") + return match and true or false +end + +function check_bigendian(definition, opt) + opt = opt or {} + local optname = opt.name or ("__" .. definition) + interp_save_scope() + option(optname) + set_showmenu(false) + add_cxxsnippets(definition, check_bigendian_template, {binary_match = _byteorder_binary_match}) + if opt.links then + add_links(opt.links) + end + if opt.includes then + add_cxxincludes(opt.includes) + end + if opt.languages then + set_languages(opt.languages) + end + if opt.cflags then + add_cflags(opt.cflags) + end + if opt.cxflags then + add_cxflags(opt.cxflags) + end + if opt.defines then + add_defines(opt.defines) + end + if opt.warnings then + set_warnings(opt.warnings) + end + after_check(function(option) + option:add("defines", definition .. "=" .. (option:value() and 1 or 0)) + end) + option_end() + interp_restore_scope() + add_options(optname) +end + +function configvar_check_bigendian(definition, opt) + opt = opt or {} + local optname = opt.name or ("__" .. definition) + local defname, defval = table.unpack(definition:split('=')) + interp_save_scope() + option(optname) + set_showmenu(false) + add_cxxsnippets(definition, check_bigendian_template, {binary_match = _byteorder_binary_match}) + if opt.default == nil then + set_configvar(defname, defval or 1, { quote = false }) + end + if opt.links then + add_links(opt.links) + end + if opt.includes then + add_cxxincludes(opt.includes) + end + if opt.languages then + set_languages(opt.languages) + end + if opt.cflags then + add_cflags(opt.cflags) + end + if opt.cxflags then + add_cxflags(opt.cxflags) + end + if opt.defines then + add_defines(opt.defines) + end + if opt.warnings then + set_warnings(opt.warnings) + end + after_check(function(option) + option:set("configvar", defname, option:value() and 1 or 0, { quote = false }) + end) + option_end() + interp_restore_scope() + if opt.default == nil then + add_options(optname) + else + set_configvar(defname, has_config(optname) and (defval or 1) or opt.default, { quote = false }) + end +end diff --git a/xmake/includes/check/xmake.lua b/xmake/includes/check/xmake.lua index e24639dbb..b9fd19b73 100644 --- a/xmake/includes/check/xmake.lua +++ b/xmake/includes/check/xmake.lua @@ -18,6 +18,7 @@ -- @file xmake.lua -- +includes("@builtin/check/check_bigendian.lua") includes("@builtin/check/check_cflags.lua") includes("@builtin/check/check_cfuncs.lua") includes("@builtin/check/check_cincludes.lua") diff --git a/xmake/modules/lib/detect/check_bigendian.lua b/xmake/modules/lib/detect/check_bigendian.lua new file mode 100644 index 000000000..13b0f96b1 --- /dev/null +++ b/xmake/modules/lib/detect/check_bigendian.lua @@ -0,0 +1,71 @@ +--!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, TBOOX Open Source Group. +-- +-- @author CarbeneHu +-- @file check_bigendian.lua +-- + +-- imports +import("lib.detect.check_cxxsnippets") + +local check_bigendian_template = [[ +#include <inttypes.h> +/* A 16 bit integer is required. */ +typedef uint16_t byteorder_int16_t; + +/* On a little endian machine, these 16bit ints will give "THIS IS LITTLE ENDIAN." + On a big endian machine the characters will be exchanged pairwise. */ +const byteorder_int16_t info_little[] = {0x4854, 0x5349, 0x4920, 0x2053, 0x494c, 0x5454, 0x454c, 0x4520, 0x444e, 0x4149, 0x2e4e, 0x0000}; + +/* on a big endian machine, these 16bit ints will give "THIS IS BIG ENDIAN." + On a little endian machine the characters will be exchanged pairwise. */ +const byteorder_int16_t info_big[] = {0x5448, 0x4953, 0x2049, 0x5320, 0x4249, 0x4720, 0x454e, 0x4449, 0x414e, 0x2e2e, 0x0000}; + +int main(int argc, char *argv[]) +{ + int require = 0; + require += info_little[argc]; + require += info_big[argc]; + (void)argv; + return require; +}]] + +local function _byteorder_binary_match(content) + local match = content:match("THIS IS BIG ENDIAN") + return match and true or false +end + +-- check the endianness of the compiler +-- +-- @param opt the argument options +-- e.g. +-- { verbose = false, target = [target|option], includes = "stdio.h" +-- , configs = {defines = "xx", cxflags = ""}} +-- +-- @return Boolean value whether the compiler is big-endian +-- +-- @code +-- local is_bigendian = check_bigendian() +-- @endcode +-- +function main(typename, opt) + local snippets = check_bigendian_template + local ok, is_bigendian = check_cxxsnippets(snippets, table.join(table.wrap(opt), {binary_match = _byteorder_binary_match})) + if ok then + return is_bigendian + end +end + |
