diff options
| author | ruki <[email protected]> | 2017-07-10 21:34:02 +0800 |
|---|---|---|
| committer | ruki <[email protected]> | 2017-07-10 21:34:02 +0800 |
| commit | 03420ca44581f299a48935ca60af4824575cd9c1 (patch) | |
| tree | b4644e07c92e62b973d15f3f0d3e0ee41f95446e | |
| parent | def23a930fc3780e54b2a8a6fc60854d2e193000 (diff) | |
add has_features and features for compiler
| -rw-r--r-- | xmake/core/sandbox/modules/import/core/language/language.lua | 10 | ||||
| -rw-r--r-- | xmake/core/sandbox/modules/import/core/tool/compiler.lua | 138 | ||||
| -rw-r--r-- | xmake/core/sandbox/modules/import/core/tool/linker.lua | 26 | ||||
| -rw-r--r-- | xmake/core/tool/builder.lua | 22 | ||||
| -rw-r--r-- | xmake/core/tool/compiler.lua | 12 | ||||
| -rw-r--r-- | xmake/core/tool/linker.lua | 10 | ||||
| -rw-r--r-- | xmake/core/tool/tool.lua | 2 | ||||
| -rw-r--r-- | xmake/modules/core/tools/gcc.lua | 1 | ||||
| -rw-r--r-- | xmake/modules/detect/tools/gcc/features.lua | 7 | ||||
| -rw-r--r-- | xmake/modules/detect/tools/gcc/has_flag.lua | 14 |
10 files changed, 203 insertions, 39 deletions
diff --git a/xmake/core/sandbox/modules/import/core/language/language.lua b/xmake/core/sandbox/modules/import/core/language/language.lua index 98494d6e5..392f76d81 100644 --- a/xmake/core/sandbox/modules/import/core/language/language.lua +++ b/xmake/core/sandbox/modules/import/core/language/language.lua @@ -31,36 +31,26 @@ local raise = require("sandbox/modules/raise") -- get the source extensions of all languages function sandbox_core_language.extensions() - - -- get it return language.extensions() end -- get the target kinds of all languages function sandbox_core_language.targetkinds() - - -- get it return language.targetkinds() end -- get the source kinds of all languages function sandbox_core_language.sourcekinds() - - -- get it return language.sourcekinds() end -- get the source flags of all languages function sandbox_core_language.sourceflags() - - -- get it return language.sourceflags() end -- get the linker kinds of all languages function sandbox_core_language.linkerkinds() - - -- get it return language.linkerkinds() end diff --git a/xmake/core/sandbox/modules/import/core/tool/compiler.lua b/xmake/core/sandbox/modules/import/core/tool/compiler.lua index a6ebc45f6..3aa7c0577 100644 --- a/xmake/core/sandbox/modules/import/core/tool/compiler.lua +++ b/xmake/core/sandbox/modules/import/core/tool/compiler.lua @@ -26,11 +26,13 @@ local sandbox_core_tool_compiler = sandbox_core_tool_compiler or {} -- load modules -local platform = require("platform/platform") -local language = require("language/language") -local compiler = require("tool/compiler") -local raise = require("sandbox/modules/raise") -local assert = require("sandbox/modules/assert") +local platform = require("platform/platform") +local language = require("language/language") +local compiler = require("tool/compiler") +local raise = require("sandbox/modules/raise") +local assert = require("sandbox/modules/assert") +local import = require("sandbox/modules/import") +local sandbox = require("sandbox/sandbox") -- get the feature of compiler function sandbox_core_tool_compiler.feature(sourcekind, name) @@ -93,6 +95,13 @@ function sandbox_core_tool_compiler.compile(sourcefiles, objectfile, opt) end -- make compiling flags +-- +-- @param sourcefiles the source files +-- @param opt the argument options (contain all the compiler attributes of target), +-- .e.g {target = ..., targetkind = "static", cxflags = "", defines = "", includedirs = "", ...} +-- +-- @return flags string, flags list +-- function sandbox_core_tool_compiler.compflags(sourcefiles, opt) -- get source kind if only one source file @@ -152,6 +161,125 @@ function sandbox_core_tool_compiler.build(sourcefiles, targetfile, opt) end end +-- get all compiler features +-- +-- @param sourcekind the source kind, .e.g cc, cxx, mm, mxx, sc +-- @param opt the argument options (contain all the compiler attributes of target), +-- .e.g {target = ..., targetkind = "static", cxflags = "", defines = "", includedirs = "", ...} +-- +-- @return the features +-- +function sandbox_core_tool_compiler.features(sourcekind, opt) + + -- get the compiler instance + local instance, errors = compiler.load(sourcekind) + if not instance then + raise(errors) + end + + -- import "lib.detect.features" + sandbox_core_tool_compiler._features = sandbox_core_tool_compiler._features or import("lib.detect.features") + if sandbox_core_tool_compiler._features then + + -- get flags + local _, flags = instance:compflags(opt) + + -- get features + local ok, results_or_errors = sandbox.load(sandbox_core_tool_compiler._features, instance:name(), {flags = flags, program = instance:program()}) + if not ok then + raise(results_or_errors) + end + + -- return features + return results_or_errors + end + + -- no features + return {} +end + +-- has the given features? +-- +-- @param features the features, .e.g {"c_static_assert", "cxx_constexpr"} +-- @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 +-- +function sandbox_core_tool_compiler.has_features(features, opt) + + -- init maps for c, objc + local kinds = {c = "cc", m = "mm"} + + -- import "lib.detect.has_features" + sandbox_core_tool_compiler._has_features = sandbox_core_tool_compiler._has_features or import("lib.detect.has_features") + if not sandbox_core_tool_compiler._has_features then + return + end + + -- classify features by kind + local features_by_kind = {} + for _, feature in ipairs(table.wrap(features)) do + + -- get feature kind + local kind = feature:match("^(%w-)_") + assert(kind, "unknown kind for the feature: %s", feature) + + -- fix kind for c, objc + kind = kinds[kind] or kind + + -- add feature + features_by_kind[kind] = features_by_kind[kind] or {} + table.insert(features_by_kind[kind], feature) + end + + -- has features for each compiler? + local results = nil + for kind, features in pairs(features_by_kind) do + + -- get the compiler instance + local instance, errors = compiler.load(kind) + if not instance then + raise(errors) + end + + -- 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()}) + if not ok then + raise(results_or_errors) + end + + -- save results + if results_or_errors then + results = table.join(results or {}, results_or_errors) + end + end + + -- ok? + return results +end + +-- has the given flags? +-- +-- @param sourcekind the source kind +-- @param flags the flags +-- +-- @return the supported flags or nil +-- +function sandbox_core_tool_compiler.has_flags(sourcekind, flags) + + -- get the compiler instance + local instance, errors = compiler.load(sourcekind) + if not instance then + raise(errors) + end + + -- has flags? + return instance:has_flags(flags) +end -- return module return sandbox_core_tool_compiler diff --git a/xmake/core/sandbox/modules/import/core/tool/linker.lua b/xmake/core/sandbox/modules/import/core/tool/linker.lua index 7b95d8b7c..f25b1f779 100644 --- a/xmake/core/sandbox/modules/import/core/tool/linker.lua +++ b/xmake/core/sandbox/modules/import/core/tool/linker.lua @@ -44,6 +44,12 @@ function sandbox_core_tool_linker.linkcmd(targetkind, sourcekinds, objectfiles, end -- make link flags for the given target +-- +-- @param targetkind the target kind +-- @param sourcekinds the source kinds +-- @param opt the argument options (contain all the linker attributes of target), +-- .e.g {target = ..., targetkind = "static", cxflags = "", defines = "", includedirs = "", ...} +-- function sandbox_core_tool_linker.linkflags(targetkind, sourcekinds, opt) -- get the linker instance @@ -72,5 +78,25 @@ function sandbox_core_tool_linker.link(targetkind, sourcekinds, objectfiles, tar end end +-- has the given flags? +-- +-- @param targetkind the target kind +-- @param sourcekinds the source kinds +-- @param flags the flags +-- +-- @return the supported flags or nil +-- +function sandbox_core_tool_linker.has_flags(targetkind, sourcekinds, flags) + + -- get the linker instance + local instance, errors = linker.load(targetkind, sourcekinds) + if not instance then + raise(errors) + end + + -- has flags? + return instance:has_flags(flags) +end + -- return module return sandbox_core_tool_linker diff --git a/xmake/core/tool/builder.lua b/xmake/core/tool/builder.lua index 9143fcbee..f66ad811e 100644 --- a/xmake/core/tool/builder.lua +++ b/xmake/core/tool/builder.lua @@ -26,17 +26,17 @@ local builder = builder or {} -- load modules -local io = require("base/io") -local path = require("base/path") -local utils = require("base/utils") -local table = require("base/table") -local string = require("base/string") -local option = require("base/option") -local tool = require("tool/tool") -local config = require("project/config") -local sandbox = require("sandbox/sandbox") -local language = require("language/language") -local platform = require("platform/platform") +local io = require("base/io") +local path = require("base/path") +local utils = require("base/utils") +local table = require("base/table") +local string = require("base/string") +local option = require("base/option") +local tool = require("tool/tool") +local config = require("project/config") +local sandbox = require("sandbox/sandbox") +local language = require("language/language") +local platform = require("platform/platform") -- get the tool of builder function builder:_tool() diff --git a/xmake/core/tool/compiler.lua b/xmake/core/tool/compiler.lua index 622ed946b..b3f58c512 100644 --- a/xmake/core/tool/compiler.lua +++ b/xmake/core/tool/compiler.lua @@ -184,6 +184,12 @@ function compiler:compcmd(sourcefiles, objectfile, opt) end -- get the compling flags +-- +-- @param opt the argument options (contain all the compiler attributes of target), +-- .e.g {target = ..., targetkind = "static", cxflags = "", defines = "", includedirs = "", ...} +-- +-- @return flags string, flags list +-- function compiler:compflags(opt) -- init options @@ -192,10 +198,10 @@ function compiler:compflags(opt) -- get target local target = opt.target - -- get the target key + -- make the key local key = nil - if target then - key = tostring(target) + for _, arg in pairs(opt) do + key = (key or "") .. tostring(arg) end -- get it directly from cache dirst diff --git a/xmake/core/tool/linker.lua b/xmake/core/tool/linker.lua index e1d091edb..133620d3d 100644 --- a/xmake/core/tool/linker.lua +++ b/xmake/core/tool/linker.lua @@ -188,6 +188,10 @@ function linker:linkcmd(objectfiles, targetfile, opt) end -- get the link flags +-- +-- @param opt the argument options (contain all the linker attributes of target), +-- .e.g {target = ..., targetkind = "static", ldflags = "", links = "", linkdirs = "", ...} +-- function linker:linkflags(opt) -- init options @@ -196,10 +200,10 @@ function linker:linkflags(opt) -- get target local target = opt.target - -- get the target key + -- make the key local key = nil - if target then - key = tostring(target) + for _, arg in pairs(opt) do + key = (key or "") .. tostring(arg) end -- get it directly from cache dirst diff --git a/xmake/core/tool/tool.lua b/xmake/core/tool/tool.lua index 67c95cc24..639306bc8 100644 --- a/xmake/core/tool/tool.lua +++ b/xmake/core/tool/tool.lua @@ -92,7 +92,7 @@ function _instance:has_flags(flag) self._has_flags = self._has_flags or import("lib.detect.has_flags") -- has flags? - return self._has_flags(self:name(), flag, {program = self:program()}) + return self._has_flags(self:name(), flag, {program = self:program(), toolkind = self:kind()}) end -- load the given tool from the given kind diff --git a/xmake/modules/core/tools/gcc.lua b/xmake/modules/core/tools/gcc.lua index 4071ba100..1bfcb6db9 100644 --- a/xmake/modules/core/tools/gcc.lua +++ b/xmake/modules/core/tools/gcc.lua @@ -64,7 +64,6 @@ function init(self) -- strip , ["-s"] = "-s" , ["-S"] = "-S" - } -- init features diff --git a/xmake/modules/detect/tools/gcc/features.lua b/xmake/modules/detect/tools/gcc/features.lua index 5047cb36c..da65e87a2 100644 --- a/xmake/modules/detect/tools/gcc/features.lua +++ b/xmake/modules/detect/tools/gcc/features.lua @@ -25,6 +25,7 @@ -- imports import("cfeatures") import("cxxfeatures") +import("core.language.language") -- get macro defines function _get_macro_defines(snippets, extension, opt) @@ -62,11 +63,11 @@ function _set_feature(feature, condition) local kind = feature:match("^(%w-)_") assert(kind, "unknown kind for the feature: %s", feature) - -- init language extensions - _g.extensions = _g.extensions or {c = ".c", cxx = ".cpp", objc = ".m", objcxx = ".mm"} + -- init maps for c, objc + local kinds = {c = "cc", m = "mm"} -- get extension - local extension = _g.extensions[kind] + local extension = table.wrap(language.sourcekinds()[kinds[kind] or kind])[1] assert(extension, "not supported kind for the feature: %s", feature) -- make snippet diff --git a/xmake/modules/detect/tools/gcc/has_flag.lua b/xmake/modules/detect/tools/gcc/has_flag.lua index abd0f5955..a8268f75b 100644 --- a/xmake/modules/detect/tools/gcc/has_flag.lua +++ b/xmake/modules/detect/tools/gcc/has_flag.lua @@ -24,6 +24,7 @@ -- imports import("lib.detect.cache") +import("core.language.language") -- is linker? function _islinker(flag, opt) @@ -83,8 +84,11 @@ function _check_try_running(flag, opt, islinker) -- check flag for linker if islinker then + -- get extension + local extension = table.wrap(language.sourcekinds()[opt.toolkind or "cc"])[1] or ".c" + -- make an stub source file - local sourcefile = path.join(os.tmpdir(), "detect", "gcc_has_flag.c") + local sourcefile = path.join(os.tmpdir(), "detect", "gcc_has_flag" .. extension) if not os.isfile(sourcefile) then io.writefile(sourcefile, "int main(int argc, char** argv)\n{return 0;}") end @@ -92,9 +96,15 @@ function _check_try_running(flag, opt, islinker) -- check it return try { function () os.runv(opt.program, {flag, "-o", os.nuldev(), sourcefile}); return true end } end + + -- get language + local lang = "c" + if opt.toolkind and (opt.toolkind == "cxx" or opt.toolkind == "mxx") then + lang = "c++" + end -- check flag for compiler - return try { function () os.runv(opt.program, {flag, "-S", "-o", os.nuldev(), "-xc", os.nuldev()}); return true end } + return try { function () os.runv(opt.program, {flag, "-S", "-o", os.nuldev(), "-x" .. lang, os.nuldev()}); return true end } end -- has_flag(flag)? |
