diff options
| author | ruki <[email protected]> | 2023-11-01 20:17:23 -0500 |
|---|---|---|
| committer | GitHub <[email protected]> | 2023-11-01 20:17:23 -0500 |
| commit | 086e6dd7a5e8d0b821b25f9e42516c93bd6aa223 (patch) | |
| tree | 694aa686e55b60284d9cea074fddd6c3f3807f82 | |
| parent | d861249210eb0278b723ace984ba11e2929ee2a8 (diff) | |
| parent | ccf9c0fe4326e18cbca7495a6f947578d4e5a3f2 (diff) | |
Merge pull request #4349 from zeromake/master
feat: add check_sizeof
| -rw-r--r-- | xmake/core/project/option.lua | 27 | ||||
| -rw-r--r-- | xmake/includes/check/check_sizeof.lua | 148 | ||||
| -rw-r--r-- | xmake/includes/check/xmake.lua | 1 | ||||
| -rw-r--r-- | xmake/modules/lib/detect/check_cxsnippets.lua | 9 |
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 } |
