summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorruki <[email protected]>2017-05-11 21:04:06 +0800
committerruki <[email protected]>2017-05-11 21:04:06 +0800
commit149d26d8fefd4d3dbba882131b926f4a852e336c (patch)
tree15523cfe09041fcd33828e78992a0482c3eb9966
parentd986e3d5022914db01e4dec834de1368ab9147d4 (diff)
add add_csnippet and add_cxxsnippet into option
-rw-r--r--CHANGELOG.md8
-rw-r--r--xmake/core/language/language.lua9
-rw-r--r--xmake/core/project/option.lua173
-rw-r--r--xmake/languages/c++/api.lua6
4 files changed, 86 insertions, 110 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 7e843ab8f..40f08593d 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -2,6 +2,10 @@
## master (unreleased)
+### New features
+
+* [#83](https://github.com/tboox/xmake/issues/83): Add `add_csnippet` and `add_cxxsnippet` into `option` for detecting some compiler features.
+
## v2.1.4
### New features
@@ -272,6 +276,10 @@
## master (开发中)
+### 新特性
+
+* [#83](https://github.com/tboox/xmake/issues/83): 添加 `add_csnippet`,`add_cxxsnippet`到`option`来检测一些编译器特性
+
## v2.1.4
### 新特性
diff --git a/xmake/core/language/language.lua b/xmake/core/language/language.lua
index faaa1bb57..278d59a3e 100644
--- a/xmake/core/language/language.lua
+++ b/xmake/core/language/language.lua
@@ -412,13 +412,14 @@ function language.apis()
end
-- merge apis for each language
- local apis = {values = {}, pathes = {}, custom = {}}
+ local apis = {values = {}, pathes = {}, custom = {}, dictionary = {}}
for name, instance in pairs(languages) do
local instance_apis = instance:get("apis")
if instance_apis then
- table.join2(apis.values, table.wrap(instance_apis.values))
- table.join2(apis.pathes, table.wrap(instance_apis.pathes))
- table.join2(apis.custom, table.wrap(instance_apis.custom))
+ table.join2(apis.values, table.wrap(instance_apis.values))
+ table.join2(apis.pathes, table.wrap(instance_apis.pathes))
+ table.join2(apis.custom, table.wrap(instance_apis.custom))
+ table.join2(apis.dictionary, table.wrap(instance_apis.dictionary))
end
end
apis.values = table.unique(apis.values)
diff --git a/xmake/core/project/option.lua b/xmake/core/project/option.lua
index 23f0772ad..e4e408d90 100644
--- a/xmake/core/project/option.lua
+++ b/xmake/core/project/option.lua
@@ -160,11 +160,11 @@ function option:_check_function(checkcode, srcpath, objpath)
return instance:compile(srcpath, objpath, nil, self)
end
--- check typedef
-function option:_check_typedef(typedef, srcpath, objpath)
+-- check type
+function option:_check_type(typename, srcpath, objpath)
-- check
- assert(typedef)
+ assert(typename)
-- open the checking source file
local srcfile = io.open(srcpath, "w")
@@ -198,7 +198,7 @@ function option:_check_typedef(typedef, srcpath, objpath)
srcfile:print("{")
-- make interfaces
- srcfile:print(" typedef %s __type_xxx;", typedef)
+ srcfile:print(" typedef %s __type_xxx;", typename)
-- make the main function tailer
srcfile:print(" return 0;")
@@ -211,6 +211,30 @@ function option:_check_typedef(typedef, srcpath, objpath)
return instance:compile(srcpath, objpath, nil, self)
end
+-- check snippet
+function option:_check_snippet(snippet, srcpath, objpath)
+
+ -- check
+ assert(snippet)
+
+ -- get source kind
+ local sourcekind = language.sourcekind_of(srcpath)
+
+ -- load the compiler instance
+ local instance = compiler.load(sourcekind)
+ if not instance then
+ return false
+ end
+
+ -- write snippet to source file
+ if not io.writefile(srcpath, snippet) then
+ return false
+ end
+
+ -- attempt to compile it
+ return instance:compile(srcpath, objpath, nil, self)
+end
+
-- check option for checking links
function option:_check_links(cfile, objectfile, targetfile)
@@ -248,27 +272,27 @@ function option:_check_links(cfile, objectfile, targetfile)
return ok
end
--- check option for checking cincludes
-function option:_check_cincludes(cfile, objectfile)
+-- check option for checking includes
+function option:_check_includes(kind, file, objectfile)
-- done
- for _, cinclude in ipairs(table.wrap(self:get("cincludes"))) do
+ for _, include in ipairs(table.wrap(self:get(kind .. "includes"))) do
- -- this cinclude has been checked?
- option._CHECKED_CINCLUDES = option._CHECKED_CINCLUDES or {}
- if option._CHECKED_CINCLUDES[cinclude] then return true end
+ -- this include has been checked?
+ option._CHECKED_INCLUDES = option._CHECKED_INCLUDES or {}
+ if option._CHECKED_INCLUDES[include] then return true end
- -- check cinclude
- local ok, errors = self:_check_include(cinclude, cfile, objectfile)
+ -- check include
+ local ok, errors = self:_check_include(include, file, objectfile)
-- trace
- utils.cprint("checking for the c include %s ... %s", cinclude, utils.ifelse(ok, "${green}ok", "${red}no"))
+ utils.cprint("checking for the %s include %s ... %s", kind, include, utils.ifelse(ok, "${green}ok", "${red}no"))
if not ok and option_.get("verbose") then
utils.cprint("${red}" .. (errors or ""))
end
-- cache the result
- option._CHECKED_CINCLUDES[cinclude] = ok
+ option._CHECKED_INCLUDES[include] = ok
-- failed
if not ok then return false end
@@ -278,84 +302,24 @@ function option:_check_cincludes(cfile, objectfile)
return true
end
--- check option for checking cxxincludes
-function option:_check_cxxincludes(cxxfile, objectfile)
+-- check option for checking functions
+function option:_check_functions(kind, file, objectfile, targetfile)
-- done
- for _, cxxinclude in ipairs(table.wrap(self:get("cxxincludes"))) do
-
- -- this cxxinclude has been checked?
- option._CHECKED_CXXINCLUDES = option._CHECKED_CXXINCLUDES or {}
- if option._CHECKED_CXXINCLUDES[cinclude] then return true end
+ for _, checkinfo in ipairs(table.wrap(self:get(kind .. "funcs"))) do
- -- check cinclude
- local ok, errors = self:_check_include(cxxinclude, cxxfile, objectfile)
-
- -- trace
- utils.cprint("checking for the c++ include %s ... %s", cxxinclude, utils.ifelse(ok, "${green}ok", "${red}no"))
- if not ok and option_.get("verbose") then
- utils.cprint("${red}" .. (errors or ""))
- end
-
- -- cache the result
- option._CHECKED_CXXINCLUDES[cxxinclude] = ok
-
- -- failed
- if not ok then return false end
- end
-
- -- ok
- return true
-end
-
--- check option for checking cfunctions
-function option:_check_cfuncs(cfile, objectfile, targetfile)
-
- -- done
- for _, checkinfo in ipairs(table.wrap(self:get("cfuncs"))) do
-
- -- parse the check code
- local checkname, checkcode = option.checkinfo(checkinfo)
- assert(checkname and checkcode)
-
- -- check function
- local ok, errors = self:_check_function(checkcode, cfile, objectfile)
-
- -- check link
- if ok and self:get("links") then ok, errors = self:_check_link(cfile, objectfile, targetfile) end
-
- -- trace
- utils.cprint("checking for the c function %s ... %s", checkname, utils.ifelse(ok, "${green}ok", "${red}no"))
- if not ok and option_.get("verbose") then
- utils.cprint("${red}" .. (errors or ""))
- end
-
- -- failed
- if not ok then return false end
- end
-
- -- ok
- return true
-end
-
--- check option for checking cxxfunctions
-function option:_check_cxxfuncs(cxxfile, objectfile, targetfile)
-
- -- done
- for _, checkinfo in ipairs(table.wrap(self:get("cxxfuncs"))) do
-
-- parse the check code
local checkname, checkcode = option.checkinfo(checkinfo)
assert(checkname and checkcode)
-- check function
- local ok, errors = self:_check_function(checkcode, cxxfile, objectfile)
+ local ok, errors = self:_check_function(checkcode, file, objectfile)
-- check link
- if ok and self:get("links") then ok, errors = self:_check_link(cxxfile, objectfile, targetfile) end
+ if ok and self:get("links") then ok, errors = self:_check_link(file, objectfile, targetfile) end
-- trace
- utils.cprint("checking for the c++ function %s ... %s", checkname, utils.ifelse(ok, "${green}ok", "${red}no"))
+ utils.cprint("checking for the %s function %s ... %s", kind, checkname, utils.ifelse(ok, "${green}ok", "${red}no"))
if not ok and option_.get("verbose") then
utils.cprint("${red}" .. (errors or ""))
end
@@ -368,17 +332,17 @@ function option:_check_cxxfuncs(cxxfile, objectfile, targetfile)
return true
end
--- check option for checking ctypes
-function option:_check_ctypes(cfile, objectfile, targetfile)
+-- check option for checking types
+function option:_check_types(kind, file, objectfile, targetfile)
-- done
- for _, ctype in ipairs(table.wrap(self:get("ctypes"))) do
+ for _, t in ipairs(table.wrap(self:get(kind .. "types"))) do
-- check type
- local ok, errors = self:_check_typedef(ctype, cfile, objectfile)
+ local ok, errors = self:_check_type(t, file, objectfile)
-- trace
- utils.cprint("checking for the c type %s ... %s", ctype, utils.ifelse(ok, "${green}ok", "${red}no"))
+ utils.cprint("checking for the %s type %s ... %s", kind, t, utils.ifelse(ok, "${green}ok", "${red}no"))
if not ok and option_.get("verbose") then
utils.cprint("${red}" .. (errors or ""))
end
@@ -391,17 +355,17 @@ function option:_check_ctypes(cfile, objectfile, targetfile)
return true
end
--- check option for checking cxxtypes
-function option:_check_cxxtypes(cxxfile, objectfile, targetfile)
+-- check option for checking snippets
+function option:_check_snippets(kind, file, objectfile, targetfile)
-- done
- for _, cxxtype in ipairs(table.wrap(self:get("cxxtypes"))) do
+ for name, snippet in pairs(table.wrap(self:get(kind .. "snippet"))) do
- -- check type
- local ok, errors = self:_check_typedef(cxxtype, cxxfile, objectfile)
+ -- check snippet
+ local ok, errors = self:_check_snippet(snippet, file, objectfile)
-- trace
- utils.cprint("checking for the c++ type %s ... %s", cxxtype, utils.ifelse(ok, "${green}ok", "${red}no"))
+ utils.cprint("checking for the %s snippet %s ... %s", kind, name, utils.ifelse(ok, "${green}ok", "${red}no"))
if not ok and option_.get("verbose") then
utils.cprint("${red}" .. (errors or ""))
end
@@ -426,27 +390,24 @@ function option:_check_condition()
-- check links
if not self:_check_links(cfile, objectfile, targetfile) then return false end
- -- check ctypes
- if not self:_check_ctypes(cfile, objectfile, targetfile) then return false end
+ -- check types
+ if not self:_check_types("c", cfile, objectfile, targetfile) then return false end
+ if not self:_check_types("cxx", cxxfile, objectfile, targetfile) then return false end
- -- check cxxtypes
- if not self:_check_cxxtypes(cxxfile, objectfile, targetfile) then return false end
+ -- check csnippets
+ if not self:_check_snippets("c", cfile, objectfile, targetfile) then return false end
+ if not self:_check_snippets("cxx", cxxfile, objectfile, targetfile) then return false end
-- check includes and functions
if self:get("cincludes") or self:get("cxxincludes") then
- -- check cincludes
- if not self:_check_cincludes(cfile, objectfile) then return false end
-
- -- check cxxincludes
- if not self:_check_cxxincludes(cxxfile, objectfile) then return false end
-
- -- check cfuncs
- if not self:_check_cfuncs(cfile, objectfile, targetfile) then return false end
-
- -- check cxxfuncs
- if not self:_check_cxxfuncs(cxxfile, objectfile, targetfile) then return false end
+ -- check includes
+ if not self:_check_includes("c", cfile, objectfile) then return false end
+ if not self:_check_includes("cxx", cxxfile, objectfile) then return false end
+ -- check functions
+ if not self:_check_functions("c", cfile, objectfile, targetfile) then return false end
+ if not self:_check_functions("cxx", cxxfile, objectfile, targetfile) then return false end
end
-- remove files
diff --git a/xmake/languages/c++/api.lua b/xmake/languages/c++/api.lua
index 436d75628..8937ddf74 100644
--- a/xmake/languages/c++/api.lua
+++ b/xmake/languages/c++/api.lua
@@ -194,6 +194,12 @@ function apis()
, "option.add_rpathdirs"
, "option.add_includedirs"
}
+ _g.dictionary =
+ {
+ -- option.add_xxx
+ "option.add_csnippet"
+ , "option.add_cxxsnippet"
+ }
_g.custom =
{
-- target.add_xxx