summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorruki <[email protected]>2023-11-01 20:17:23 -0500
committerGitHub <[email protected]>2023-11-01 20:17:23 -0500
commit086e6dd7a5e8d0b821b25f9e42516c93bd6aa223 (patch)
tree694aa686e55b60284d9cea074fddd6c3f3807f82
parentd861249210eb0278b723ace984ba11e2929ee2a8 (diff)
parentccf9c0fe4326e18cbca7495a6f947578d4e5a3f2 (diff)
Merge pull request #4349 from zeromake/master
feat: add check_sizeof
-rw-r--r--xmake/core/project/option.lua27
-rw-r--r--xmake/includes/check/check_sizeof.lua148
-rw-r--r--xmake/includes/check/xmake.lua1
-rw-r--r--xmake/modules/lib/detect/check_cxsnippets.lua9
4 files changed, 184 insertions, 1 deletions
diff --git a/xmake/core/project/option.lua b/xmake/core/project/option.lua
index 73e3a8f1f..4b808bec3 100644
--- a/xmake/core/project/option.lua
+++ b/xmake/core/project/option.lua
@@ -113,12 +113,17 @@ function _instance:_do_check_cxsnippets(snippets)
local snippets_build = {}
local snippets_tryrun = {}
local snippets_output = {}
+ local snippets_binaryfind = {}
+ local snippet_binaryfind = nil
if snippets then
for name, snippet in pairs(snippets) do
if self:extraconf(kind .. "snippets", name, "output") then
snippets_output[name] = snippet
elseif self:extraconf(kind .. "snippets", name, "tryrun") then
snippets_tryrun[name] = snippet
+ elseif self:extraconf(kind .. "snippets", name, "binaryfind") then
+ snippets_binaryfind[name] = snippet
+ snippet_binaryfind = self:extraconf(kind .. "snippets", name, "binaryfind")
else
snippets_build[name] = snippet
end
@@ -173,6 +178,28 @@ function _instance:_do_check_cxsnippets(snippets)
end
end
+ -- check snippets (run with binaryfind)
+ if #table.keys(snippets_binaryfind) > 0 then
+ local ok, results_or_errors, output = sandbox.load(self._check_cxsnippets, snippets_binaryfind, {
+ target = self,
+ sourcekind = sourcekind,
+ types = types,
+ funcs = funcs,
+ includes = includes,
+ binaryfind = snippet_binaryfind})
+ if not ok then
+ return false, -1, results_or_errors
+ end
+ -- passed or no passed?
+ if results_or_errors then
+ passed = 1
+ result_output = output
+ else
+ passed = -1
+ break
+ end
+ end
+
-- check snippets (build only)
if passed == 0 or #table.keys(snippets_build) > 0 then
local ok, results_or_errors = sandbox.load(self._check_cxsnippets, snippets_build, {
diff --git a/xmake/includes/check/check_sizeof.lua b/xmake/includes/check/check_sizeof.lua
new file mode 100644
index 000000000..c4921fbf9
--- /dev/null
+++ b/xmake/includes/check/check_sizeof.lua
@@ -0,0 +1,148 @@
+--!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) 2023, TBOOX Open Source Group.
+--
+-- @author zeromake
+-- @file check_sizeof.lua
+--
+
+-- check c sizeof(type) add to macro definition support cross compile
+--
+-- from https://github.com/xmake-io/xmake/issues/4345
+--
+-- e.g.
+--
+-- check_sizeof("SIZEOF_LONG", "long") => SIZEOF_LONG=4
+--
+-- configvar_check_sizeof("SIZEOF_LONG", "long") => #define SIZEOF_LONG 4
+--
+local binary_match = 'INFO:size%[(%d+)%]'
+
+local check_sizeof_template = [[
+#define SIZE (sizeof(${TYPE}))
+static char info_size[] = {'I', 'N', 'F', 'O', ':', 's','i','z','e','[',
+ ('0' + ((SIZE / 10000)%10)),
+ ('0' + ((SIZE / 1000)%10)),
+ ('0' + ((SIZE / 100)%10)),
+ ('0' + ((SIZE / 10)%10)),
+ ('0' + (SIZE % 10)),
+ ']',
+ '\0'};
+
+int main(int argc, char *argv[]) {
+ int require = 0;
+ require += info_size[argc];
+ (void)argv;
+ return require;
+}]]
+
+function check_sizeof(definition, typename, opt)
+ opt = opt or {}
+ if opt.number == nil then
+ opt.number = true
+ end
+ local optname = opt.name or ("__" .. definition)
+ local snippet = opt.snippet or ""
+ interp_save_scope()
+ option(optname)
+ set_showmenu(false)
+ add_csnippets(definition, check_sizeof_template:gsub('${TYPE}', typename), {binaryfind = binary_match})
+ if opt.links then
+ add_links(opt.links)
+ end
+ if opt.includes then
+ add_cincludes(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)
+ if option:value() then
+ if opt.number then
+ option:add("defines", definition .. "=" .. tonumber(option:value()))
+ elseif opt.quote == false then
+ option:add("defines", definition .. "=" .. option:value())
+ else
+ option:add("defines", definition .. "=\"" .. option:value() .. "\"")
+ end
+ end
+ end)
+ option_end()
+ interp_restore_scope()
+ add_options(optname)
+end
+
+
+function configvar_check_sizeof(definition, typename, opt)
+ opt = opt or {}
+ if opt.number == nil then
+ opt.number = true
+ end
+ local optname = opt.name or ("__" .. definition)
+ local defname, defval = table.unpack(definition:split('='))
+ interp_save_scope()
+ option(optname)
+ set_showmenu(false)
+ add_csnippets(definition, check_sizeof_template:gsub('${TYPE}', typename), {binaryfind = binary_match})
+ if opt.default == nil then
+ set_configvar(defname, defval or 1, {quote = opt.quote})
+ end
+ if opt.links then
+ add_links(opt.links)
+ end
+ if opt.includes then
+ add_cincludes(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)
+ if option:value() then
+ option:set("configvar", defname, opt.number and tonumber(option:value()) or option:value(), {quote = opt.quote})
+ end
+ 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 = true})
+ end
+end
+
diff --git a/xmake/includes/check/xmake.lua b/xmake/includes/check/xmake.lua
index 467d232f6..e24639dbb 100644
--- a/xmake/includes/check/xmake.lua
+++ b/xmake/includes/check/xmake.lua
@@ -32,3 +32,4 @@ includes("@builtin/check/check_features.lua")
includes("@builtin/check/check_links.lua")
includes("@builtin/check/check_macros.lua")
includes("@builtin/check/check_syslinks.lua")
+includes("@builtin/check/check_sizeof.lua")
diff --git a/xmake/modules/lib/detect/check_cxsnippets.lua b/xmake/modules/lib/detect/check_cxsnippets.lua
index bbcb15e23..912345909 100644
--- a/xmake/modules/lib/detect/check_cxsnippets.lua
+++ b/xmake/modules/lib/detect/check_cxsnippets.lua
@@ -240,7 +240,7 @@ function main(snippets, opt)
cprint("${dim}> %s", compiler.compcmd(sourcefile, objectfile, opt))
end
compiler.compile(sourcefile, objectfile, opt)
- if #links > 0 or opt.tryrun then
+ if #links > 0 or opt.tryrun or opt.binaryfind then
if option.get("diagnosis") then
cprint("${dim}> %s", linker.linkcmd("binary", {"cc", "cxx"}, objectfile, binaryfile, opt))
end
@@ -257,6 +257,13 @@ function main(snippets, opt)
os.vrun(binaryfile)
end
end
+ if opt.binaryfind then
+ local content = io.readfile(binaryfile, {encoding = "binary"})
+ local match = content:match(opt.binaryfind)
+ if match then
+ return true, match
+ end
+ end
return true
end,
catch { function (errs) errors = errs end }