summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorruki <[email protected]>2024-03-17 19:21:09 +0800
committerGitHub <[email protected]>2024-03-17 19:21:09 +0800
commit9bf5a9a16757f49569cfc7138cf96c5530c20b0b (patch)
tree115b697afc1b19a5d67207ed41a0ffb581fe1424
parent9eb1a7489b99e05c65c62ccb651c65c02dc9b216 (diff)
parent097a6d25fe308683161920f3cd9292063cddab14 (diff)
Merge pull request #4847 from Hyiker/dev
feat: Add check_bigendian #4843
-rw-r--r--tests/apis/check_xxx/config.h.in1
-rw-r--r--tests/apis/check_xxx/xmake.lua2
-rw-r--r--xmake/core/project/target.lua12
-rw-r--r--xmake/includes/check/check_bigendian.lua137
-rw-r--r--xmake/includes/check/xmake.lua1
-rw-r--r--xmake/modules/lib/detect/check_bigendian.lua71
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
+