summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorruki <[email protected]>2023-03-17 23:22:36 +0800
committerGitHub <[email protected]>2023-03-17 23:22:36 +0800
commit404a8a5feadef0c56f57895103ff6f9419cdfd41 (patch)
tree73160a76034e3325c952ea33a893a3edf9de6ae2
parent890b52a2b7311315862841b1f5c17fd01bbb7751 (diff)
parentf7bc68f09a8d20fcae1304c9ab70d7f9b7472de5 (diff)
Merge pull request #3521 from xmake-io/hasxxx
add has_xxx for target
-rw-r--r--xmake/core/package/package.lua85
-rw-r--r--xmake/core/project/option.lua3
-rw-r--r--xmake/core/project/target.lua141
-rw-r--r--xmake/core/sandbox/modules/import/core/tool/compiler.lua27
-rw-r--r--xmake/modules/lib/detect/has_features.lua20
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