diff options
| author | ruki <[email protected]> | 2023-03-17 23:22:36 +0800 |
|---|---|---|
| committer | GitHub <[email protected]> | 2023-03-17 23:22:36 +0800 |
| commit | 404a8a5feadef0c56f57895103ff6f9419cdfd41 (patch) | |
| tree | 73160a76034e3325c952ea33a893a3edf9de6ae2 | |
| parent | 890b52a2b7311315862841b1f5c17fd01bbb7751 (diff) | |
| parent | f7bc68f09a8d20fcae1304c9ab70d7f9b7472de5 (diff) | |
Merge pull request #3521 from xmake-io/hasxxx
add has_xxx for target
| -rw-r--r-- | xmake/core/package/package.lua | 85 | ||||
| -rw-r--r-- | xmake/core/project/option.lua | 3 | ||||
| -rw-r--r-- | xmake/core/project/target.lua | 141 | ||||
| -rw-r--r-- | xmake/core/sandbox/modules/import/core/tool/compiler.lua | 27 | ||||
| -rw-r--r-- | xmake/modules/lib/detect/has_features.lua | 20 |
5 files changed, 230 insertions, 46 deletions
diff --git a/xmake/core/package/package.lua b/xmake/core/package/package.lua index a7171c1d1..cfc60f696 100644 --- a/xmake/core/package/package.lua +++ b/xmake/core/package/package.lua @@ -36,6 +36,7 @@ local scopeinfo = require("base/scopeinfo") local interpreter = require("base/interpreter") local memcache = require("cache/memcache") local toolchain = require("tool/toolchain") +local compiler = require("tool/compiler") local sandbox = require("sandbox/sandbox") local config = require("project/config") local policy = require("project/policy") @@ -59,6 +60,16 @@ function _instance.new(name, info, opt) return instance end +-- get memcache +function _instance:_memcache() + local cache = self._MEMCACHE + if not cache then + cache = memcache.cache("core.package.package." .. tostring(self)) + self._MEMCACHE = cache + end + return cache +end + -- get the package name function _instance:name() return self._NAME @@ -1110,6 +1121,23 @@ function _instance:toolconfig(name) end end +-- get the target compiler +function _instance:compiler(sourcekind) + local compilerinst = self:_memcache():get("compiler") + if not compilerinst then + if not sourcekind then + os.raise("please pass sourcekind to the first argument of package:compiler(), e.g. cc, cxx, as") + end + local instance, errors = compiler.load(sourcekind, self) + if not instance then + os.raise(errors) + end + compilerinst = instance + self:_memcache():set("compiler", compilerinst) + end + return compilerinst +end + -- has the given tool for the current package? -- -- e.g. @@ -2060,7 +2088,7 @@ end -- has the given c funcs? -- -- @param funcs the funcs --- @param opt the argument options, e.g. { includes = ""} +-- @param opt the argument options, e.g. {includes = "xxx.h", configs = {defines = ""}} -- -- @return true or false, errors -- @@ -2074,7 +2102,7 @@ end -- has the given c++ funcs? -- -- @param funcs the funcs --- @param opt the argument options, e.g. {includes = ""} +-- @param opt the argument options, e.g. {includes = "xxx.h", configs = {defines = ""}} -- -- @return true or false, errors -- @@ -2087,8 +2115,8 @@ end -- has the given c types? -- --- @param types the types --- @param opt the argument options, e.g. { defines = ""} +-- @param types the types +-- @param opt the argument options, e.g. {configs = {defines = ""}} -- -- @return true or false, errors -- @@ -2101,8 +2129,8 @@ end -- has the given c++ types? -- --- @param types the types --- @param opt the argument options, e.g. { defines = ""} +-- @param types the types +-- @param opt the argument options, e.g. {configs = {defines = ""}} -- -- @return true or false, errors -- @@ -2116,7 +2144,7 @@ end -- has the given c includes? -- -- @param includes the includes --- @param opt the argument options, e.g. { defines = ""} +-- @param opt the argument options, e.g. {configs = {defines = ""}} -- -- @return true or false, errors -- @@ -2130,7 +2158,7 @@ end -- has the given c++ includes? -- -- @param includes the includes --- @param opt the argument options, e.g. { defines = ""} +-- @param opt the argument options, e.g. {configs = {defines = ""}} -- -- @return true or false, errors -- @@ -2141,10 +2169,47 @@ function _instance:has_cxxincludes(includes, opt) return sandbox_module.import("lib.detect.has_cxxincludes", {anonymous = true})(includes, opt) end +-- has the given c flags? +-- +-- @param flags the flags +-- @param opt the argument options, e.g. { flagskey = "xxx" } +-- +-- @return true or false, errors +-- +function _instance:has_cflags(flags, opt) + local compinst = self:compiler("cc") + return compinst:has_flags(flags, "cflags", opt) +end + +-- has the given c++ flags? +-- +-- @param flags the flags +-- @param opt the argument options, e.g. { flagskey = "xxx" } +-- +-- @return true or false, errors +-- +function _instance:has_cxxflags(flags, opt) + local compinst = self:compiler("cxx") + return compinst:has_flags(flags, "cxxflags", opt) +end + +-- has the given features? +-- +-- @param features the features, e.g. {"c_static_assert", "cxx_constexpr"} +-- @param opt the argument options, e.g. {flags = ""} +-- +-- @return true or false, errors +-- +function _instance:has_features(features, opt) + opt = opt or {} + opt.target = self + return sandbox_module.import("core.tool.compiler", {anonymous = true}).has_features(features, opt) +end + -- check the given c snippets? -- -- @param snippets the snippets --- @param opt the argument options, e.g. { includes = ""} +-- @param opt the argument options, e.g. {includes = "xxx.h", configs = {defines = ""}} -- -- @return true or false, errors -- @@ -2158,7 +2223,7 @@ end -- check the given c++ snippets? -- -- @param snippets the snippets --- @param opt the argument options, e.g. { includes = ""} +-- @param opt the argument options, e.g. {includes = "xxx.h", configs = {defines = ""}} -- -- @return true or false, errors -- diff --git a/xmake/core/project/option.lua b/xmake/core/project/option.lua index dcb94aa55..73e3a8f1f 100644 --- a/xmake/core/project/option.lua +++ b/xmake/core/project/option.lua @@ -209,8 +209,7 @@ function _instance:_do_check_features() -- all features are supported? features = table.wrap(features) - local features_supported = self._core_tool_compiler.has_features(features, {target = self}) - if features_supported and #features_supported == #features then + if self._core_tool_compiler.has_features(features, {target = self}) then passed = 1 end diff --git a/xmake/core/project/target.lua b/xmake/core/project/target.lua index 79c5f0546..dae799f9e 100644 --- a/xmake/core/project/target.lua +++ b/xmake/core/project/target.lua @@ -2252,6 +2252,147 @@ function _instance:has_tool(toolkind, ...) end end +-- has the given c funcs? +-- +-- @param funcs the funcs +-- @param opt the argument options, e.g. {includes = "xxx.h", configs = {defines = ""}} +-- +-- @return true or false, errors +-- +function _instance:has_cfuncs(funcs, opt) + opt = opt or {} + opt.target = self + return sandbox_module.import("lib.detect.has_cfuncs", {anonymous = true})(funcs, opt) +end + +-- has the given c++ funcs? +-- +-- @param funcs the funcs +-- @param opt the argument options, e.g. {includes = "xxx.h", configs = {defines = ""}} +-- +-- @return true or false, errors +-- +function _instance:has_cxxfuncs(funcs, opt) + opt = opt or {} + opt.target = self + return sandbox_module.import("lib.detect.has_cxxfuncs", {anonymous = true})(funcs, opt) +end + +-- has the given c types? +-- +-- @param types the types +-- @param opt the argument options, e.g. {configs = {defines = ""}} +-- +-- @return true or false, errors +-- +function _instance:has_ctypes(types, opt) + opt = opt or {} + opt.target = self + return sandbox_module.import("lib.detect.has_ctypes", {anonymous = true})(types, opt) +end + +-- has the given c++ types? +-- +-- @param types the types +-- @param opt the argument options, e.g. {configs = {defines = ""}} +-- +-- @return true or false, errors +-- +function _instance:has_cxxtypes(types, opt) + opt = opt or {} + opt.target = self + return sandbox_module.import("lib.detect.has_cxxtypes", {anonymous = true})(types, opt) +end + +-- has the given c includes? +-- +-- @param includes the includes +-- @param opt the argument options, e.g. {configs = {defines = ""}} +-- +-- @return true or false, errors +-- +function _instance:has_cincludes(includes, opt) + opt = opt or {} + opt.target = self + return sandbox_module.import("lib.detect.has_cincludes", {anonymous = true})(includes, opt) +end + +-- has the given c++ includes? +-- +-- @param includes the includes +-- @param opt the argument options, e.g. {configs = {defines = ""}} +-- +-- @return true or false, errors +-- +function _instance:has_cxxincludes(includes, opt) + opt = opt or {} + opt.target = self + return sandbox_module.import("lib.detect.has_cxxincludes", {anonymous = true})(includes, opt) +end + +-- has the given c flags? +-- +-- @param flags the flags +-- @param opt the argument options, e.g. { flagskey = "xxx" } +-- +-- @return true or false, errors +-- +function _instance:has_cflags(flags, opt) + local compinst = self:compiler("cc") + return compinst:has_flags(flags, "cflags", opt) +end + +-- has the given c++ flags? +-- +-- @param flags the flags +-- @param opt the argument options, e.g. { flagskey = "xxx" } +-- +-- @return true or false, errors +-- +function _instance:has_cxxflags(flags, opt) + local compinst = self:compiler("cxx") + return compinst:has_flags(flags, "cxxflags", opt) +end + +-- has the given features? +-- +-- @param features the features, e.g. {"c_static_assert", "cxx_constexpr"} +-- @param opt the argument options, e.g. {flags = ""} +-- +-- @return true or false, errors +-- +function _instance:has_features(features, opt) + opt = opt or {} + opt.target = self + return sandbox_module.import("core.tool.compiler", {anonymous = true}).has_features(features, opt) +end + +-- check the given c snippets? +-- +-- @param snippets the snippets +-- @param opt the argument options, e.g. {includes = "xxx.h", configs = {defines = ""}} +-- +-- @return true or false, errors +-- +function _instance:check_csnippets(snippets, opt) + opt = opt or {} + opt.target = self + return sandbox_module.import("lib.detect.check_csnippets", {anonymous = true})(snippets, opt) +end + +-- check the given c++ snippets? +-- +-- @param snippets the snippets +-- @param opt the argument options, e.g. {includes = "xxx.h", configs = {defines = ""}} +-- +-- @return true or false, errors +-- +function _instance:check_cxxsnippets(snippets, opt) + opt = opt or {} + opt.target = self + return sandbox_module.import("lib.detect.check_cxxsnippets", {anonymous = true})(snippets, opt) +end + -- get project function target._project() return target._PROJECT diff --git a/xmake/core/sandbox/modules/import/core/tool/compiler.lua b/xmake/core/sandbox/modules/import/core/tool/compiler.lua index 4545a0a14..aae2201ce 100644 --- a/xmake/core/sandbox/modules/import/core/tool/compiler.lua +++ b/xmake/core/sandbox/modules/import/core/tool/compiler.lua @@ -226,7 +226,7 @@ end -- @param opt the argument options (contain all the compiler attributes of target), -- e.g. {target = ..., targetkind = "static", cxflags = "", defines = "", includedirs = "", ...} -- --- @return the supported features or nil +-- @return the true or false -- function sandbox_core_tool_compiler.has_features(features, opt) @@ -236,14 +236,10 @@ function sandbox_core_tool_compiler.has_features(features, opt) return end - -- init options - opt = opt or {} - - -- get the language kinds - local langkinds = language.langkinds() - -- classify features by the source kind + opt = opt or {} local features_by_kind = {} + local langkinds = language.langkinds() for _, feature in ipairs(table.wrap(features)) do -- get language kind @@ -260,29 +256,18 @@ function sandbox_core_tool_compiler.has_features(features, opt) end -- has features for each compiler? - local results = nil for sourcekind, features in pairs(features_by_kind) do - - -- get the compiler instance local instance = sandbox_core_tool_compiler.load(sourcekind, opt) - - -- get flags local flags = instance:compflags(opt) - - -- has features? local ok, results_or_errors = sandbox.load(sandbox_core_tool_compiler._has_features, instance:name(), features, {flags = flags, program = instance:program(), envs = instance:runenvs()}) if not ok then raise(results_or_errors) end - - -- save results - if results_or_errors then - results = table.join(results or {}, results_or_errors) + if not results_or_errors then + return false end end - - -- ok? - return results + return true end -- has the given flags? diff --git a/xmake/modules/lib/detect/has_features.lua b/xmake/modules/lib/detect/has_features.lua index 80dbc2ec7..2b879dd1e 100644 --- a/xmake/modules/lib/detect/has_features.lua +++ b/xmake/modules/lib/detect/has_features.lua @@ -28,7 +28,7 @@ import("lib.detect.features", {alias = "get_features"}) -- @param features the features -- @param opt the argument options, e.g. {verbose = false, flags = {}, program = ""}} -- --- @return the supported features or nil +-- @return true or false -- -- @code -- local features = has_features("clang", "cxx_constexpr") @@ -37,20 +37,14 @@ import("lib.detect.features", {alias = "get_features"}) -- @endcode -- function main(name, features, opt) - - -- init options opt = opt or {} - - -- get all features - local all = get_features(name, opt) or {} - - -- get results - local results = nil + local allfeatures = get_features(name, opt) or {} + local passed = 0 + features = table.wrap(features) for _, feature in ipairs(features) do - if all[feature] then - results = results or {} - table.insert(results, feature) + if allfeatures[feature] then + passed = passed + 1 end end - return results + return passed == #features end |
