summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorruki <[email protected]>2017-07-10 21:34:02 +0800
committerruki <[email protected]>2017-07-10 21:34:02 +0800
commit03420ca44581f299a48935ca60af4824575cd9c1 (patch)
treeb4644e07c92e62b973d15f3f0d3e0ee41f95446e
parentdef23a930fc3780e54b2a8a6fc60854d2e193000 (diff)
add has_features and features for compiler
-rw-r--r--xmake/core/sandbox/modules/import/core/language/language.lua10
-rw-r--r--xmake/core/sandbox/modules/import/core/tool/compiler.lua138
-rw-r--r--xmake/core/sandbox/modules/import/core/tool/linker.lua26
-rw-r--r--xmake/core/tool/builder.lua22
-rw-r--r--xmake/core/tool/compiler.lua12
-rw-r--r--xmake/core/tool/linker.lua10
-rw-r--r--xmake/core/tool/tool.lua2
-rw-r--r--xmake/modules/core/tools/gcc.lua1
-rw-r--r--xmake/modules/detect/tools/gcc/features.lua7
-rw-r--r--xmake/modules/detect/tools/gcc/has_flag.lua14
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)?