summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorruki <[email protected]>2016-03-21 20:57:23 +0800
committerruki <[email protected]>2016-03-21 20:57:37 +0800
commitb898400a3a5f18d332ce7ef159769d8f17fd28e5 (patch)
tree275f124aa7c17c6090d25fefb226b0678f6d231d
parentf0623bf26279430deb6799b7816fb61996120166 (diff)
add project option
-rwxr-xr-xxmake/actions/config/makefile.lua25
-rw-r--r--xmake/core/base/table.lua4
-rw-r--r--xmake/core/platform/compiler.lua307
-rw-r--r--xmake/core/platform/linker.lua242
-rw-r--r--xmake/core/platform/tools/clang++.lua2
-rw-r--r--xmake/core/project/option.lua302
-rw-r--r--xmake/core/project/project.lua378
-rw-r--r--xmake/core/project/target.lua35
8 files changed, 724 insertions, 571 deletions
diff --git a/xmake/actions/config/makefile.lua b/xmake/actions/config/makefile.lua
index 6f2f60771..293fb45c0 100755
--- a/xmake/actions/config/makefile.lua
+++ b/xmake/actions/config/makefile.lua
@@ -23,6 +23,13 @@
-- imports
import("core.project.project")
+-- get log file
+function _logfile()
+
+ -- get it
+ return vformat("$(buildir)/.build.log")
+end
+
-- make the object
function _make_object(makefile, target, srcfile, objfile)
@@ -47,14 +54,6 @@ end
-- make target
function _make_target(makefile, target)
---[[ -- get the linker from the given kind
- local l = linker.get(target.kind)
- if not l then
- utils.error("cannot get linker with kind: %s", target.kind)
- return false
- end
-]]
-
-- make head
local targetfile = target:targetfile()
makefile:printf("%s: %s\n", name, targetfile)
@@ -77,13 +76,13 @@ function _make_target(makefile, target)
makefile:print("")
-- make the command
- local srcfiles = target:sourcefiles()
- local cmd = ""--linker.make(l, target, srcfiles, objfiles, targetfile, makefile._LOGFILE)
+ local linker = target:linker()
+ local cmd = linker:makecmd(target, objfiles, targetfile, _logfile())
-- make the verbose info
local verbose = cmd:encode()
if verbose and #verbose > 256 then
- verbose = nil--linker.make(l, target, srcfiles, {rule.filename("*", "object")}, targetfile)
+ verbose = linker:makecmd(target, {target.filename("*", "object")}, targetfile)
verbose = verbose:encode()
end
@@ -110,7 +109,7 @@ function _make_target(makefile, target)
makefile:print("")
-- make objects for this target
- _make_objects(makefile, target, srcfiles, objfiles)
+ _make_objects(makefile, target, target:sourcefiles(), objfiles)
end
@@ -145,7 +144,7 @@ function make()
os.cd("$(projectdir)")
-- remove the log file first
- os.rm("$(buildir)/.build.log")
+ os.rm(_logfile())
-- open the makefile
local makefile = io.open("$(buildir)/makefile", "w")
diff --git a/xmake/core/base/table.lua b/xmake/core/base/table.lua
index c99985dab..7427f3a53 100644
--- a/xmake/core/base/table.lua
+++ b/xmake/core/base/table.lua
@@ -87,7 +87,7 @@ function table.copy(copied)
-- copy it
local result = {}
- for k, v in pairs(copied) do
+ for k, v in pairs(table.wrap(copied)) do
result[k] = v
end
@@ -108,7 +108,7 @@ function table.copy2(self, copied)
table.clear(self)
-- copy it
- for k, v in pairs(copied) do
+ for k, v in pairs(table.wrap(copied)) do
self[k] = v
end
diff --git a/xmake/core/platform/compiler.lua b/xmake/core/platform/compiler.lua
index 51c111a56..0b6d6fdb4 100644
--- a/xmake/core/platform/compiler.lua
+++ b/xmake/core/platform/compiler.lua
@@ -20,7 +20,7 @@
-- @file compiler.lua
--
--- define module: compiler
+-- define module
local compiler = compiler or {}
-- load modules
@@ -28,29 +28,29 @@ local io = require("base/io")
local path = require("base/path")
local utils = require("base/utils")
local table = require("base/table")
-local option = require("base/option")
local string = require("base/string")
+local option = require("base/option")
local config = require("project/config")
local tool = require("platform/tool")
local platform = require("platform/platform")
-- map gcc flag to the given compiler flag
-function compiler._mapflag(module, flag)
+function compiler._mapflag(self, flag)
-- check
- assert(module.mapflags and flag)
+ assert(self.mapflags and flag)
-- attempt to map it directly
- local flag_mapped = module.mapflags[flag]
+ local flag_mapped = self.mapflags[flag]
if flag_mapped and type(flag_mapped) == "string" then
return flag_mapped
end
-- find and replace it using pattern
- for k, v in pairs(module.mapflags) do
+ for k, v in pairs(self.mapflags) do
local flag_mapped, count = flag:gsub("^" .. k .. "$", function (w)
if type(v) == "function" then
- return v(module, w)
+ return v(self, w)
else
return v
end
@@ -65,16 +65,16 @@ function compiler._mapflag(module, flag)
end
-- map gcc flags to the given compiler flags
-function compiler._mapflags(module, flags)
+function compiler._mapflags(self, flags)
-- check
- assert(module)
+ assert(self)
-- wrap flags first
flags = table.wrap(flags)
-- need not map flags? return it directly
- if not module.mapflags then
+ if not self.mapflags then
return flags
end
@@ -82,7 +82,7 @@ function compiler._mapflags(module, flags)
local flags_mapped = {}
for _, flag in pairs(flags) do
-- map it
- local flag_mapped = compiler._mapflag(module, flag)
+ local flag_mapped = compiler._mapflag(self, flag)
if flag_mapped then
table.insert(flags_mapped, flag_mapped)
end
@@ -93,7 +93,7 @@ function compiler._mapflags(module, flags)
end
-- get the compiler flags from names
-function compiler._getflags(module, names, flags)
+function compiler._getflags(self, names, flags)
-- check
assert(flags)
@@ -104,7 +104,7 @@ function compiler._getflags(module, names, flags)
-- wrap it first
names = table.wrap(names)
for _, name in ipairs(names) do
- table.join2(flags_mapped, compiler._mapflags(module, flags[name]))
+ table.join2(flags_mapped, compiler._mapflags(self, flags[name]))
end
-- get it
@@ -112,29 +112,29 @@ function compiler._getflags(module, names, flags)
end
-- add flags from the compiler
-function compiler._addflags_from_compiler(module, flags, flagnames, kind)
+function compiler._addflags_from_compiler(self, flags, flagnames, kind)
-- check
- assert(module and flags and flagnames)
+ assert(self and flags and flagnames)
-- done
for _, flagname in ipairs(flagnames) do
-- add compiler.xxflags
- table.join2(flags, module, module[flagname])
+ table.join2(flags, self, self[flagname])
-- add compiler.kind.xxflags
- if kind ~= nil and module[kind] ~= nil then
- table.join2(flags, module, module[kind][flagname])
+ if kind ~= nil and self[kind] ~= nil then
+ table.join2(flags, self, self[kind][flagname])
end
end
end
-- add flags from the configure
-function compiler._addflags_from_config(module, flags, flagnames)
+function compiler._addflags_from_config(self, flags, flagnames)
-- check
- assert(module and flags and flagnames)
+ assert(self and flags and flagnames)
-- done
for _, flagname in ipairs(flagnames) do
@@ -143,82 +143,82 @@ function compiler._addflags_from_config(module, flags, flagnames)
end
-- add flags from the platform
-function compiler._addflags_from_platform(module, flags, flagnames)
+function compiler._addflags_from_platform(self, flags, flagnames)
-- check
- assert(module and flags and flagnames)
+ assert(self and flags and flagnames)
-- add flags
for _, flagname in ipairs(flagnames) do
- table.join2(flags, compiler._mapflags(module, platform.get(flagname)))
+ table.join2(flags, compiler._mapflags(self, platform.get(flagname)))
end
-- add the includedirs flags
- if module.flag_includedir then
+ if self.flag_includedir then
for _, includedir in ipairs(table.wrap(platform.get("includedirs"))) do
- table.join2(flags, module:flag_includedir(includedir))
+ table.join2(flags, self:flag_includedir(includedir))
end
end
-- add the defines flags
- if module.flag_define then
+ if self.flag_define then
for _, define in ipairs(table.wrap(platform.get("defines"))) do
- table.join2(flags, module:flag_define(define))
+ table.join2(flags, self:flag_define(define))
end
end
-- append the undefines flags
- if module.flag_undefine then
+ if self.flag_undefine then
for _, undefine in ipairs(table.wrap(platform.get("undefines"))) do
- table.join2(flags, module:flag_undefine(undefine))
+ table.join2(flags, self:flag_undefine(undefine))
end
end
end
-- add flags from the target
-function compiler._addflags_from_target(module, flags, flagnames, target)
+function compiler._addflags_from_target(self, flags, flagnames, target)
-- check
- assert(module and flags and flagnames and target)
+ assert(self and flags and flagnames and target)
-- add the target flags from the current project
for _, flagname in ipairs(flagnames) do
- table.join2(flags, compiler._mapflags(module, target[flagname]))
+ table.join2(flags, compiler._mapflags(self, target:get(flagname)))
end
-- add the symbols flags from the current project
- table.join2(flags, compiler._getflags(module, target.symbols, { debug = "-g"
- , hidden = "-fvisibility=hidden"
- }))
+ table.join2(flags, compiler._getflags(self, target:get("symbols"), { debug = "-g"
+ , hidden = "-fvisibility=hidden"
+ }))
-- add the warning flags from the current project
- table.join2(flags, compiler._getflags(module, target.warnings, { none = "-w"
- , less = "-W1"
- , more = "-W3"
- , all = "-Wall"
- , error = "-Werror"
- }))
+ table.join2(flags, compiler._getflags(self, target:get("warnings"), { none = "-w"
+ , less = "-W1"
+ , more = "-W3"
+ , all = "-Wall"
+ , error = "-Werror"
+ }))
-- add the optimize flags from the current project
- table.join2(flags, compiler._getflags(module, target.optimize, { none = "-O0"
- , fast = "-O1"
- , faster = "-O2"
- , fastest = "-O3"
- , smallest = "-Os"
- , aggressive = "-Ofast"
- }))
+ table.join2(flags, compiler._getflags(self, target:get("optimize"), { none = "-O0"
+ , fast = "-O1"
+ , faster = "-O2"
+ , fastest = "-O3"
+ , smallest = "-Os"
+ , aggressive = "-Ofast"
+ }))
-- add the vector extensions flags from the current project
- table.join2(flags, compiler._getflags(module, target.vectorexts, { mmx = "-mmmx"
- , sse = "-msse"
- , sse2 = "-msse2"
- , sse3 = "-msse3"
- , ssse3 = "-mssse3"
- , avx = "-mavx"
- , avx2 = "-mavx2"
- , neon = "-mfpu=neon"
- }))
+ table.join2(flags, compiler._getflags(self, target:get("vectorexts"), { mmx = "-mmmx"
+ , sse = "-msse"
+ , sse2 = "-msse2"
+ , sse3 = "-msse3"
+ , ssse3 = "-mssse3"
+ , avx = "-mavx"
+ , avx2 = "-mavx2"
+ , neon = "-mfpu=neon"
+ }))
-- add the language flags from the current project
local languages = {}
@@ -242,55 +242,49 @@ function compiler._addflags_from_target(module, flags, flagnames, target)
})
end
end
- table.join2(flags, compiler._getflags(module, target.languages, languages))
+ table.join2(flags, compiler._getflags(self, target:get("languages"), languages))
-- add the includedirs flags from the current project
- if module.flag_includedir then
- for _, includedir in ipairs(table.wrap(target.includedirs)) do
- table.join2(flags, module:flag_includedir(includedir))
+ if self.flag_includedir then
+ for _, includedir in ipairs(table.wrap(target:get("includedirs"))) do
+ table.join2(flags, self:flag_includedir(includedir))
end
end
-- add the defines flags from the current project
- if module.flag_define then
- for _, define in ipairs(table.wrap(target.defines)) do
- table.join2(flags, module:flag_define(define))
+ if self.flag_define then
+ for _, define in ipairs(table.wrap(target:get("defines"))) do
+ table.join2(flags, self:flag_define(define))
end
end
-- append the undefines flags from the current project
- if module.flag_undefine then
- for _, undefine in ipairs(table.wrap(target.undefines)) do
- table.join2(flags, module:flag_undefine(undefine))
+ if self.flag_undefine then
+ for _, undefine in ipairs(table.wrap(target:get("undefines"))) do
+ table.join2(flags, self:flag_undefine(undefine))
end
end
- -- the options
+ -- is target?
if target.options then
- for _, name in ipairs(table.wrap(target.options)) do
- -- get option if be enabled
- local opt = nil
- if config.get(name) then opt = config.get("__" .. name) end
- if nil ~= opt then
+ -- add the flags for the target options
+ for name, opt in ipairs(target:options()) do
- -- add the flags from the option
- compiler._addflags_from_target(module, flags, flagnames, opt)
+ -- add the flags from the option
+ compiler._addflags_from_target(self, flags, flagnames, opt)
- -- append the defines flags
- if opt.defines_if_ok and module.flag_define then
- local defines = table.wrap(opt.defines_if_ok)
- for _, define in ipairs(defines) do
- table.join2(flags, module:flag_define(define))
- end
+ -- append the defines flags
+ if self.flag_define then
+ for _, define in ipairs(table.wrap(opt:get("defines_if_ok"))) do
+ table.join2(flags, self:flag_define(define))
end
+ end
- -- append the undefines flags
- if opt.undefines_if_ok and module.flag_undefine then
- local undefines = table.wrap(opt.undefines_if_ok)
- for _, undefine in ipairs(undefines) do
- table.join2(flags, module:flag_undefine(undefine))
- end
+ -- append the undefines flags
+ if self.flag_undefine then
+ for _, undefine in ipairs(table.wrap(opt:get("undefines_if_ok"))) do
+ table.join2(flags, self:flag_undefine(undefine))
end
end
end
@@ -298,13 +292,13 @@ function compiler._addflags_from_target(module, flags, flagnames, target)
end
-- add flags from the option
-function compiler._addflags_from_option(module, flags, flagnames, opt)
+function compiler._addflags_from_option(self, flags, flagnames, opt)
-- check
- assert(module and flags and flagnames and opt)
+ assert(self and flags and flagnames and opt)
-- add the flags from the option
- compiler._addflags_from_target(module, flags, flagnames, opt)
+ compiler._addflags_from_target(self, flags, flagnames, opt)
end
@@ -361,39 +355,39 @@ function compiler._kind(srcfile)
end
-- make the compile command for option
-function compiler._make_for_option(module, opt, srcfile, objfile, logfile)
+function compiler._make_for_option(self, opt, srcfile, objfile, logfile)
-- check
- assert(module and opt)
+ assert(self and self._TOOL and opt)
-- the flag names
- local flagnames = compiler._flagnames(module._KIND)
+ local flagnames = compiler._flagnames(self._KIND)
assert(flagnames)
-- init flags
local flags = {}
-- add flags from the configure
- compiler._addflags_from_config(module, flags, flagnames)
+ compiler._addflags_from_config(self, flags, flagnames)
-- add flags from the option
- compiler._addflags_from_option(module, flags, flagnames, opt)
+ compiler._addflags_from_option(self, flags, flagnames, opt)
-- add flags from the platform
- compiler._addflags_from_platform(module, flags, flagnames)
+ compiler._addflags_from_platform(self, flags, flagnames)
-- add flags from the compiler
- compiler._addflags_from_compiler(module, flags, flagnames)
+ compiler._addflags_from_compiler(self, flags, flagnames)
-- remove repeat
flags = table.unique(flags)
-- execute the compile command
- return module:command_compile(srcfile, objfile, table.concat(flags, " "):trim(), logfile)
+ return self._TOOL:command_compile(srcfile, objfile, table.concat(flags, " "):trim(), logfile)
end
--- get the compiler from the given source file
-function compiler.get(srcfile)
+-- init the compiler from the given source file
+function compiler.init(srcfile)
-- get the compiler kind
local kind = compiler._kind(srcfile)
@@ -401,60 +395,73 @@ function compiler.get(srcfile)
return nil, string.format("unknown source file: %s", srcfile)
end
+ -- init instance
+ local instance = table.inherit(compiler)
+
-- ignore "*.a/lib" and "*.o/obj" kind
if kind == "lib" or kind == "obj" then
- return {}
+ return instance
end
- -- get compiler from the source file type
- local module = tool.get(kind)
- if module then
+ -- get compiler tool from the source file type
+ instance._TOOL = tool.get(kind)
+ if instance._TOOL then
-- invalid compiler
- if not module.command_compile then
+ if not instance._TOOL.command_compile then
return nil, string.format("invalid compiler for %s", kind)
end
-- save kind
- module._KIND = kind
+ instance._KIND = kind
else
return nil, string.format("unknown compiler for %s", kind)
end
- -- ok?
- return module
+ -- ok
+ return instance
end
-- make the compile command
-function compiler.make(module, target, srcfile, objfile, logfile)
+function compiler.makecmd(self, target, srcfile, objfile, logfile)
-- check
- assert(module and target)
+ assert(self and self._TOOL and target)
-- the flag names
- local flagnames = compiler._flagnames(module._KIND)
+ local flagnames = compiler._flagnames(self._KIND)
assert(flagnames)
+ -- get flags
+ local flags = self:flags(flagnames, target)
+
+ -- make the compile command
+ return self._TOOL:command_compile(srcfile, objfile, table.concat(flags, " "):trim(), logfile)
+end
+
+-- get flags from the given flag names
+function compiler.flags(self, flagnames, target)
+
-- init flags
local flags = {}
-- add flags from the configure
- compiler._addflags_from_config(module, flags, flagnames)
+ self:_addflags_from_config(flags, flagnames)
-- add flags from the target
- compiler._addflags_from_target(module, flags, flagnames, target)
+ self:_addflags_from_target(flags, flagnames, target)
-- add flags from the platform
- compiler._addflags_from_platform(module, flags, flagnames)
+ self:_addflags_from_platform(flags, flagnames)
-- add flags from the compiler
- compiler._addflags_from_compiler(module, flags, flagnames, target.kind)
+ self:_addflags_from_compiler(flags, flagnames, target:get("kind"))
-- remove repeat
flags = table.unique(flags)
- -- make the compile command
- return module:command_compile(srcfile, objfile, table.concat(flags, " "):trim(), logfile)
+ -- ok?
+ return flags
end
-- check include for the project option
@@ -469,24 +476,24 @@ function compiler.check_include(opt, include, srcpath, objpath)
-- make include
if include then
- srcfile:write(string.format("#include <%s>\n\n", include))
+ srcfile:print("#include <%s>\n", include)
end
-- make the main function header
- srcfile:write("int main(int argc, char** argv)\n")
- srcfile:write("{\n")
- srcfile:write(" return 0;\n")
- srcfile:write("}\n")
+ srcfile:print("int main(int argc, char** argv)")
+ srcfile:print("{")
+ srcfile:print(" return 0;")
+ srcfile:print("}")
-- exit this file
srcfile:close()
-- get the compiler
- local module = compiler.get(srcpath)
- if not module then return end
+ local self = compiler.init(srcpath)
+ if not self then return end
-- execute the compile command
- return module:main(compiler._make_for_option(module, opt, srcpath, objpath, utils.ifelse(option.get("verbose"), nil, xmake._NULDEV)))
+ return self._TOOL:main(self:_make_for_option(opt, srcpath, objpath, utils.ifelse(option.get("verbose"), nil, xmake._NULDEV)))
end
-- check function for the project option
@@ -500,37 +507,37 @@ function compiler.check_function(opt, interface, srcpath, objpath)
if not srcfile then return end
-- get the compiler
- local module = compiler.get(srcpath)
- if not module then return end
+ local self = compiler.init(srcpath)
+ if not self then return end
-- make includes
local includes = nil
- if module._KIND == "cc" then includes = opt.cincludes
- elseif module._KIND == "cxx" then includes = opt.cxxincludes
+ if self._KIND == "cc" then includes = opt:get("cincludes")
+ elseif self._KIND == "cxx" then includes = opt:get("cxxincludes")
end
if includes then
for _, include in ipairs(table.wrap(includes)) do
- srcfile:write(string.format("#include <%s>\n", include))
+ srcfile:print("#include <%s>", include)
end
- srcfile:write("\n")
+ srcfile:print("")
end
-- make the main function header
- srcfile:write("int main(int argc, char** argv)\n")
- srcfile:write("{\n")
+ srcfile:print("int main(int argc, char** argv)")
+ srcfile:print("{")
-- make interfaces
- srcfile:write(string.format(" volatile void* p%s = (void*)&%s;\n\n", interface, interface))
+ srcfile:print(" volatile void* p%s = (void*)&%s;\n", interface, interface)
-- make the main function tailer
- srcfile:write(" return 0;\n")
- srcfile:write("}\n")
+ srcfile:print(" return 0;")
+ srcfile:print("}")
-- exit this file
srcfile:close()
-- execute the compile command
- return module:main(compiler._make_for_option(module, opt, srcpath, objpath, utils.ifelse(option.get("verbose"), nil, xmake._NULDEV)))
+ return self._TOOL:main(self:_make_for_option(opt, srcpath, objpath, utils.ifelse(option.get("verbose"), nil, xmake._NULDEV)))
end
-- check typedef for the project option
@@ -544,38 +551,38 @@ function compiler.check_typedef(opt, typedef, srcpath, objpath)
if not srcfile then return end
-- get the compiler
- local module = compiler.get(srcpath)
- if not module then return end
+ local self = compiler.init(srcpath)
+ if not self then return end
-- make includes
local includes = nil
- if module._KIND == "cc" then includes = opt.cincludes
- elseif module._KIND == "cxx" then includes = opt.cxxincludes
+ if self._KIND == "cc" then includes = opt:get("cincludes")
+ elseif self._KIND == "cxx" then includes = opt:get("cxxincludes")
end
if includes then
for _, include in ipairs(table.wrap(includes)) do
- srcfile:write(string.format("#include <%s>\n", include))
+ srcfile:print("#include <%s>", include)
end
- srcfile:write("\n")
+ srcfile:print("")
end
-- make the main function header
- srcfile:write("int main(int argc, char** argv)\n")
- srcfile:write("{\n")
+ srcfile:print("int main(int argc, char** argv)")
+ srcfile:print("{")
-- make interfaces
- srcfile:write(string.format(" typedef %s __type_xxx;\n\n", typedef))
+ srcfile:print(" typedef %s __type_xxx;\n", typedef)
-- make the main function tailer
- srcfile:write(" return 0;\n")
- srcfile:write("}\n")
+ srcfile:print(" return 0;")
+ srcfile:print("}")
-- exit this file
srcfile:close()
-- execute the compile command
- return module:main(compiler._make_for_option(module, opt, srcpath, objpath, utils.ifelse(option.get("verbose"), nil, xmake._NULDEV)))
+ return self._TOOL:main(self:_make_for_option(opt, srcpath, objpath, utils.ifelse(option.get("verbose"), nil, xmake._NULDEV)))
end
--- return module: compiler
+-- return module
return compiler
diff --git a/xmake/core/platform/linker.lua b/xmake/core/platform/linker.lua
index e123760be..015dbac2f 100644
--- a/xmake/core/platform/linker.lua
+++ b/xmake/core/platform/linker.lua
@@ -20,7 +20,7 @@
-- @file linker.lua
--
--- define module: linker
+-- define module
local linker = linker or {}
-- load modules
@@ -34,22 +34,22 @@ local tool = require("platform/tool")
local platform = require("platform/platform")
-- map gcc flag to the given linker flag
-function linker._mapflag(module, flag)
+function linker._mapflag(self, flag)
-- check
- assert(module.mapflags and flag)
+ assert(self.mapflags and flag)
-- attempt to map it directly
- local flag_mapped = module.mapflags[flag]
+ local flag_mapped = self.mapflags[flag]
if flag_mapped and type(flag_mapped) == "string" then
return flag_mapped
end
-- find and replace it using pattern
- for k, v in pairs(module.mapflags) do
+ for k, v in pairs(self.mapflags) do
local flag_mapped, count = flag:gsub("^" .. k .. "$", function (w)
if type(v) == "function" then
- return v(module, w)
+ return v(self, w)
else
return v
end
@@ -64,16 +64,16 @@ function linker._mapflag(module, flag)
end
-- map gcc flags to the given linker flags
-function linker._mapflags(module, flags)
+function linker._mapflags(self, flags)
-- check
- assert(module)
+ assert(self)
-- wrap flags first
flags = table.wrap(flags)
-- need not map flags? return it directly
- if not module.mapflags then
+ if not self.mapflags then
return flags
end
@@ -81,7 +81,7 @@ function linker._mapflags(module, flags)
local flags_mapped = {}
for _, flag in pairs(flags) do
-- map it
- local flag_mapped = linker._mapflag(module, flag)
+ local flag_mapped = linker._mapflag(self, flag)
if flag_mapped then
table.insert(flags_mapped, flag_mapped)
end
@@ -92,7 +92,7 @@ function linker._mapflags(module, flags)
end
-- get the linker flags from names
-function linker._getflags(module, names, flags)
+function linker._getflags(self, names, flags)
-- check
assert(flags)
@@ -103,7 +103,7 @@ function linker._getflags(module, names, flags)
-- wrap it first
names = table.wrap(names)
for _, name in ipairs(names) do
- table.join2(flags_mapped, linker._mapflags(module, flags[name]))
+ table.join2(flags_mapped, linker._mapflags(self, flags[name]))
end
-- get it
@@ -112,42 +112,42 @@ end
-- add flags from the links
-function linker._addflags_from_links(module, flags, links)
+function linker._addflags_from_links(self, flags, links)
-- check
- assert(module and flags and links)
+ assert(self and flags and links)
-- done
- if module.flag_link then
+ if self.flag_link then
for _, link in ipairs(table.wrap(links)) do
- table.join2(flags, module:flag_link(link))
+ table.join2(flags, self:flag_link(link))
end
end
end
-- add flags from the linker
-function linker._addflags_from_linker(module, flags, flagname)
+function linker._addflags_from_linker(self, flags, flagname)
-- check
- assert(module and flags and flagname)
+ assert(self and flags and flagname)
-- done
- table.join2(flags, module[flagname])
+ table.join2(flags, self[flagname])
end
-- add flags from the compiler
-function linker._addflags_from_compiler(module, flags, flagname, srcfiles)
+function linker._addflags_from_compiler(self, flags, flagname, srcfiles)
-- check
- assert(module and flags and flagname)
+ assert(self and flags and flagname)
-- add the flags for compiler
local flags_for_compiler = {}
if srcfiles then
for _, srcfile in ipairs(table.wrap(srcfiles)) do
- -- get the compiler
- local c, errors = compiler.get(srcfile)
+ -- init a compiler instance
+ local c, errors = compiler.init(srcfile)
if not c then
-- error
utils.error(errors)
@@ -164,119 +164,117 @@ function linker._addflags_from_compiler(module, flags, flagname, srcfiles)
end
-- add flags from the configure
-function linker._addflags_from_config(module, flags, flagname)
+function linker._addflags_from_config(self, flags, flagname)
-- check
- assert(module and flags and flagname)
+ assert(self and flags and flagname)
-- done
table.join2(flags, config.get(flagname))
end
-- add flags from the platform
-function linker._addflags_from_platform(module, flags, flagname)
+function linker._addflags_from_platform(self, flags, flagname)
-- check
- assert(module and flags and flagname)
+ assert(self and flags and flagname)
-- add flags
- table.join2(flags, linker._mapflags(module, platform.get(flagname)))
+ table.join2(flags, linker._mapflags(self, platform.get(flagname)))
-- add the linkdirs flags
- if module.flag_linkdir then
+ if self.flag_linkdir then
for _, linkdir in ipairs(table.wrap(platform.get("linkdirs"))) do
- table.join2(flags, module:flag_linkdir(linkdir))
+ table.join2(flags, self:flag_linkdir(linkdir))
end
end
-- add the links flags
- if module.flag_link then
+ if self.flag_link then
for _, link in ipairs(table.wrap(platform.get("links"))) do
- table.join2(flags, module:flag_link(link))
+ table.join2(flags, self:flag_link(link))
end
end
end
-- add flags from the target
-function linker._addflags_from_target(module, flags, flagname, target)
+function linker._addflags_from_target(self, flags, flagname, target)
-- check
- assert(module and flags and flagname and target)
+ assert(self and flags and flagname and target)
-- add the target flags from the current project
- table.join2(flags, linker._mapflags(module, target[flagname]))
+ table.join2(flags, linker._mapflags(self, target[flagname]))
-- add the linkdirs flags from the current project
- if module.flag_linkdir then
- for _, linkdir in ipairs(table.wrap(target.linkdirs)) do
- table.join2(flags, module:flag_linkdir(linkdir))
+ if self.flag_linkdir then
+ for _, linkdir in ipairs(table.wrap(target:get("linkdirs"))) do
+ table.join2(flags, self:flag_linkdir(linkdir))
end
end
-- add the links flags from the current project
- if module.flag_link then
- for _, link in ipairs(table.wrap(target.links)) do
- table.join2(flags, module:flag_link(link))
+ if self.flag_link then
+ for _, link in ipairs(table.wrap(target:get("links"))) do
+ table.join2(flags, self:flag_link(link))
end
end
-- the options
- if target.options then
- for _, name in ipairs(table.wrap(target.options)) do
+ for _, name in ipairs(table.wrap(target:get("options"))) do
- -- get option if be enabled
- local opt = nil
- if config.get(name) then opt = config.get("__" .. name) end
- if nil ~= opt then
+ -- get option if be enabled
+ local opt = nil
+ if config.get(name) then opt = config.get("__" .. name) end
+ if nil ~= opt then
- -- add the flags from the option
- table.join2(flags, linker._mapflags(module, opt[flagname]))
-
- -- add the linkdirs flags from the option
- if module.flag_linkdir then
- for _, linkdir in ipairs(table.wrap(opt.linkdirs)) do
- table.join2(flags, module:flag_linkdir(linkdir))
- end
+ -- add the flags from the option
+ table.join2(flags, linker._mapflags(self, opt[flagname]))
+
+ -- add the linkdirs flags from the option
+ if self.flag_linkdir then
+ for _, linkdir in ipairs(table.wrap(opt.linkdirs)) do
+ table.join2(flags, self:flag_linkdir(linkdir))
end
+ end
- -- add the links flags from the option
- if module.flag_link then
- for _, link in ipairs(table.wrap(opt.links)) do
- table.join2(flags, module:flag_link(link))
- end
+ -- add the links flags from the option
+ if self.flag_link then
+ for _, link in ipairs(table.wrap(opt.links)) do
+ table.join2(flags, self:flag_link(link))
end
end
end
end
-- add the flags from the configure
- table.join2(flags, linker._mapflags(module, config.get(flagname)))
+ table.join2(flags, linker._mapflags(self, config.get(flagname)))
-- add the strip flags from the current project
- table.join2(flags, linker._getflags(module, target.strip, { debug = "-S"
- , all = "-s"
- }))
+ table.join2(flags, linker._getflags(self, target:get("strip"), { debug = "-S"
+ , all = "-s"
+ }))
end
-- add flags from the option
-function linker._addflags_from_option(module, flags, flagname, opt)
+function linker._addflags_from_option(self, flags, flagname, opt)
-- check
- assert(module and flags and flagname and opt)
+ assert(self and flags and flagname and opt)
-- append the option flags
- table.join2(flags, linker._mapflags(module, opt[flagname]))
+ table.join2(flags, linker._mapflags(self, opt:get("flagname")))
-- append the linkdirs flags
- if opt.linkdirs and module.flag_linkdir then
- for _, linkdir in ipairs(table.wrap(opt.linkdirs)) do
- table.join2(flags, module:flag_linkdir(linkdir))
+ if opt.linkdirs and self.flag_linkdir then
+ for _, linkdir in ipairs(table.wrap(opt:get("linkdirs"))) do
+ table.join2(flags, self:flag_linkdir(linkdir))
end
end
end
--- get the linker from the given kind
-function linker.get(kind)
+-- init a linker instance from the given kind
+function linker.init(kind)
-- check
assert(kind)
@@ -287,101 +285,109 @@ function linker.get(kind)
elseif kind == "static" then name = "ar"
elseif kind == "shared" then name = "sh"
else return end
-
- -- get it
- local module = tool.get(name)
- -- invalid linker?
- if module and not module.command_link then
- return
- end
+ -- init instance
+ local instance = table.inherit(linker)
+
+ -- get the linker tool
+ instance._TOOL = tool.get(name)
+ assert(instance._TOOL and instance._TOOL.command_link)
-- ok?
- return module
+ return instance
end
--- make the link command
-function linker.make(module, target, srcfiles, objfiles, targetfile, logfile)
-
- -- check
- assert(module and target)
-
- -- the target kind
- local kind = target.kind or ""
-
- -- the flag name
- local flagname = nil
- if kind == "binary" then flagname = "ldflags"
- elseif kind == "static" then flagname = "arflags"
- elseif kind == "shared" then flagname = "shflags"
- else
- -- error
- utils.error("unknown type for linker: %s", kind)
- return
- end
+-- get flags from the given flag name
+function linker.flags(self, flagname, target)
-- init flags
local flags = {}
-- add flags from the configure
- linker._addflags_from_config(module, flags, flagname)
+ self:_addflags_from_config(flags, flagname)
-- add flags from the target
- linker._addflags_from_target(module, flags, flagname, target)
+ self:_addflags_from_target(flags, flagname, target)
-- add flags from the platform
- linker._addflags_from_platform(module, flags, flagname)
+ self:_addflags_from_platform(flags, flagname)
-- add flags from the compiler
- linker._addflags_from_compiler(module, flags, flagname, srcfiles)
+ self:_addflags_from_compiler(flags, flagname, target:sourcefiles())
-- add flags from the linker
- linker._addflags_from_linker(module, flags, flagname)
+ self:_addflags_from_linker(flags, flagname)
-- remove repeat
flags = table.unique(flags)
+ -- ok?
+ return flags
+end
+
+-- make the link command
+function linker.makecmd(self, target, objfiles, targetfile, logfile)
+
+ -- check
+ assert(self and self._TOOL and target)
+
+ -- the target kind
+ local kind = target:get("kind") or ""
+
+ -- the flag name
+ local flagname = nil
+ if kind == "binary" then flagname = "ldflags"
+ elseif kind == "static" then flagname = "arflags"
+ elseif kind == "shared" then flagname = "shflags"
+ else
+ -- error
+ os.raise("unknown type for linker: %s", kind)
+ end
+
+ -- get flags
+ local flags = self:flags(flagname, target)
+
-- make the link command
- return module:command_link(table.concat(objfiles, " "), targetfile, table.concat(flags, " "):trim(), logfile)
+ return self._TOOL:command_link(table.concat(objfiles, " "), targetfile, table.concat(flags, " "):trim(), logfile)
end
-- check link for the project option
-function linker.check_links(opt, links, sourcefile, objectfile, targetfile)
+function linker.check_links(opt, sourcefile, objectfile, targetfile)
-- check
- assert(opt and links and objectfile and targetfile)
+ assert(opt and objectfile and targetfile)
- -- get the linker
- local module = linker.get("binary")
- assert(module and module.flag_link)
+ -- init the linker
+ local self = linker.init("binary")
+ assert(self and self._TOOL)
-- init flags
local flags = {}
-- add flags from the configure
- linker._addflags_from_config(module, flags, "ldflags")
+ linker._addflags_from_config(self, flags, "ldflags")
-- add flags from the option
- linker._addflags_from_option(module, flags, "ldflags", opt)
+ linker._addflags_from_option(self, flags, "ldflags", opt)
-- add flags from the platform
- linker._addflags_from_platform(module, flags, "ldflags")
+ linker._addflags_from_platform(self, flags, "ldflags")
-- add flags from the links
- linker._addflags_from_links(module, flags, links)
+ linker._addflags_from_links(self, flags, opt:get("links"))
-- add flags from the compiler
- linker._addflags_from_compiler(module, flags, "ldflags", sourcefile)
+ linker._addflags_from_compiler(self, flags, "ldflags", sourcefile)
-- add flags from the linker
- linker._addflags_from_linker(module, flags, "ldflags")
+ linker._addflags_from_linker(self, flags, "ldflags")
-- remove repeat
flags = table.unique(flags)
-- execute the link command
- return module:main(module:command_link(objectfile, targetfile, table.concat(flags, " "):trim(), utils.ifelse(option.get("verbose"), nil, xmake._NULDEV)))
+ return self._TOOL:main(self._TOOL:command_link(objectfile, targetfile, table.concat(flags, " "):trim(), utils.ifelse(option.get("verbose"), nil, xmake._NULDEV)))
end
--- return module: linker
+-- return module
return linker
diff --git a/xmake/core/platform/tools/clang++.lua b/xmake/core/platform/tools/clang++.lua
index a71679e4b..dd261df7d 100644
--- a/xmake/core/platform/tools/clang++.lua
+++ b/xmake/core/platform/tools/clang++.lua
@@ -21,7 +21,7 @@
--
-- load modules
-local gcc = require("tools/gcc")
+local gcc = require("platform/tools/gcc")
-- define module: clang++
local clangxx = clangxx or {}
diff --git a/xmake/core/project/option.lua b/xmake/core/project/option.lua
new file mode 100644
index 000000000..2c4fd1876
--- /dev/null
+++ b/xmake/core/project/option.lua
@@ -0,0 +1,302 @@
+--!The Automatic Cross-platform Build Tool
+--
+-- XMake is free software; you can redistribute it and/or modify
+-- it under the terms of the GNU Lesser General Public License as published by
+-- the Free Software Foundation; either version 2.1 of the License, or
+-- (at your option) any later version.
+--
+-- XMake is distributed in the hope that it will be useful,
+-- but WITHOUT ANY WARRANTY; without even the implied warranty of
+-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+-- GNU Lesser General Public License for more details.
+--
+-- You should have received a copy of the GNU Lesser General Public License
+-- along with XMake;
+-- If not, see <a href="http://www.gnu.org/licenses/"> http://www.gnu.org/licenses/</a>
+--
+-- Copyright (C) 2015 - 2016, ruki All rights reserved.
+--
+-- @author ruki
+-- @file option.lua
+--
+
+-- define module
+local option = option or {}
+
+-- load modules
+local os = require("base/os")
+local path = require("base/path")
+local table = require("base/table")
+local utils = require("base/utils")
+local config = require("project/config")
+local linker = require("platform/linker")
+local compiler = require("platform/compiler")
+
+-- check option for checking links
+function option._check_links(self, cfile, objectfile, targetfile)
+
+ -- get links
+ local links = self:get("links")
+ if not links then
+ return true
+ end
+
+ -- the links string
+ local links_str = table.concat(table.wrap(links), ", ")
+
+ -- this links has been checked?
+ option._CHECKED_LINKS = option._CHECKED_LINKS or {}
+ if option._CHECKED_LINKS[links_str] then
+ return true
+ end
+
+ -- only for compile a object file
+ local ok = compiler.check_include(self, nil, cfile, objectfile)
+
+ -- check link
+ if ok then ok = linker.check_links(self, cfile, objectfile, targetfile) end
+
+ -- trace
+ utils.printf("checking for the links %s ... %s", links_str, utils.ifelse(ok, "ok", "no"))
+
+ -- cache the result
+ option._CHECKED_LINKS[links_str] = ok
+
+ -- ok?
+ return ok
+end
+
+-- check option for checking cincludes
+function option._check_cincludes(self, cfile, objectfile)
+
+ -- done
+ for _, cinclude in ipairs(table.wrap(self:get("cincludes"))) do
+
+ -- this cinclude has been checked?
+ option._CHECKED_CINCLUDES = option._CHECKED_CINCLUDES or {}
+ if option._CHECKED_CINCLUDES[cinclude] then return true end
+
+ -- check cinclude
+ local ok = compiler.check_include(self, cinclude, cfile, objectfile)
+
+ -- trace
+ utils.printf("checking for the c include %s ... %s", cinclude, utils.ifelse(ok, "ok", "no"))
+
+ -- cache the result
+ option._CHECKED_CINCLUDES[cinclude] = ok
+
+ -- failed
+ if not ok then return false end
+ end
+
+ -- ok
+ return true
+end
+
+-- check option for checking cxxincludes
+function option._check_cxxincludes(self, cxxfile, objectfile)
+
+ -- 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
+
+ -- check cinclude
+ local ok = compiler.check_include(self, cxxinclude, cxxfile, objectfile)
+
+ -- trace
+ utils.printf("checking for the c++ include %s ... %s", cxxinclude, utils.ifelse(ok, "ok", "no"))
+
+ -- 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(self, cfile, objectfile, targetfile)
+
+ -- done
+ for _, cfunc in ipairs(table.wrap(self:get("cfuncs"))) do
+
+ -- check function
+ local ok = compiler.check_function(self, cfunc, cfile, objectfile)
+
+ -- check link
+ if ok and self:get("links") then ok = linker.check_links(self, cfile, objectfile, targetfile) end
+
+ -- trace
+ utils.printf("checking for the c function %s ... %s", cfunc, utils.ifelse(ok, "ok", "no"))
+
+ -- failed
+ if not ok then return false end
+ end
+
+ -- ok
+ return true
+end
+
+-- check option for checking cxxfunctions
+function option._check_cxxfuncs(self, cxxfile, objectfile, targetfile)
+
+ -- done
+ for _, cxxfunc in ipairs(table.wrap(self:get("cxxfuncs"))) do
+
+ -- check function
+ local ok = compiler.check_function(self, cxxfunc, cxxfile, objectfile)
+
+ -- check link
+ if ok and self:get("links") then ok = linker.check_links(self, cxxfile, objectfile, targetfile) end
+
+ -- trace
+ utils.printf("checking for the c++ function %s ... %s", cxxfunc, utils.ifelse(ok, "ok", "no"))
+
+ -- failed
+ if not ok then return false end
+ end
+
+ -- ok
+ return true
+end
+
+-- check option for checking ctypes
+function option._check_ctypes(self, cfile, objectfile, targetfile)
+
+ -- done
+ for _, ctype in ipairs(table.wrap(self:get("ctypes"))) do
+
+ -- check type
+ local ok = compiler.check_typedef(self, ctype, cfile, objectfile)
+
+ -- trace
+ utils.printf("checking for the c type %s ... %s", ctype, utils.ifelse(ok, "ok", "no"))
+
+ -- failed
+ if not ok then return false end
+ end
+
+ -- ok
+ return true
+end
+
+-- check option for checking cxxtypes
+function option._check_cxxtypes(self, cxxfile, objectfile, targetfile)
+
+ -- done
+ for _, cxxtype in ipairs(table.wrap(self:get("cxxtypes"))) do
+
+ -- check type
+ local ok = compiler.check_typedef(self, cxxtype, cxxfile, objectfile)
+
+ -- trace
+ utils.printf("checking for the c++ type %s ... %s", cxxtype, utils.ifelse(ok, "ok", "no"))
+
+ -- failed
+ if not ok then return false end
+ end
+
+ -- ok
+ return true
+end
+
+-- check option
+function option.check(self, cfile, cxxfile, objectfile, targetfile)
+
+ -- 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 cxxtypes
+ if not self:_check_cxxtypes(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
+
+ end
+
+ -- ok
+ return true
+end
+
+-- get the option info
+function option.get(self, infoname)
+
+ -- check
+ assert(self and self._INFO and infoname)
+
+ -- get it
+ return self._INFO[infoname]
+end
+
+-- save the option info to the project configure
+function option.save(self, is_clear)
+
+ -- check
+ assert(self)
+
+ -- save it
+ config.set("__option_" .. self:name(), self._INFO)
+end
+
+-- clear the option info for the project configure
+function option.clear(self)
+
+ -- check
+ assert(self)
+
+ -- clear it
+ config.set("__option_" .. self:name(), nil)
+end
+
+-- load the option info from the project configure
+function option.load(name)
+
+ -- check
+ assert(name)
+
+ -- get info
+ local info = config.get("__option_" .. name)
+ if info == nil then
+ return
+ end
+
+ -- init option instance
+ local instance = {}
+ instance._INFO = info
+ instance._NAME = name
+
+ -- ok
+ return instance
+end
+
+-- get the option name
+function option.name(self)
+
+ -- get it
+ return self._NAME
+end
+
+
+-- return module
+return option
diff --git a/xmake/core/project/project.lua b/xmake/core/project/project.lua
index 8e941fb2e..491eb4a44 100644
--- a/xmake/core/project/project.lua
+++ b/xmake/core/project/project.lua
@@ -29,11 +29,11 @@ local io = require("base/io")
local path = require("base/path")
local utils = require("base/utils")
local table = require("base/table")
-local option = require("base/option")
local filter = require("base/filter")
local interpreter = require("base/interpreter")
local target = require("project/target")
local config = require("project/config")
+local option = require("project/option")
local deprecated_project = require("project/deprecated/project")
local linker = require("platform/linker")
local compiler = require("platform/compiler")
@@ -150,7 +150,7 @@ function project._api_add_cfunc(interp, module, alias, links, includes, cfunc)
-- save the current scope
local scope = interp:scope_save()
- -- make option
+ -- check option
interp:api_call("option", name)
interp:api_call("set_option_category", "cfuncs")
interp:api_call("add_option_cfuncs", cfunc)
@@ -196,7 +196,7 @@ function project._api_add_cfuncs(interp, module, links, includes, ...)
-- save the current scope
local scope = interp:scope_save()
- -- make option
+ -- check option
interp:api_call("option", name)
interp:api_call("set_option_category", "cfuncs")
interp:api_call("add_option_cfuncs", cfunc)
@@ -237,7 +237,7 @@ function project._api_add_cxxfunc(interp, module, alias, links, includes, cxxfun
-- save the current scope
local scope = interp:scope_save()
- -- make option
+ -- check option
interp:api_call("option", name)
interp:api_call("set_option_category", "cxxfuncs")
interp:api_call("add_option_cxxfuncs", cxxfunc)
@@ -283,7 +283,7 @@ function project._api_add_cxxfuncs(interp, module, links, includes, ...)
-- save the current scope
local scope = interp:scope_save()
- -- make option
+ -- check option
interp:api_call("option", name)
interp:api_call("set_option_category", "cxxfuncs")
interp:api_call("add_option_cxxfuncs", cxxfunc)
@@ -476,251 +476,60 @@ function project._interpreter()
return interp
end
--- make option for checking links
-function project._make_option_for_checking_links(opt, links, cfile, objectfile, targetfile)
-
- -- the links string
- local links_str = table.concat(table.wrap(links), ", ")
-
- -- this links has been checked?
- project._CHECKED_LINKS = project._CHECKED_LINKS or {}
- if project._CHECKED_LINKS[links_str] then return true end
-
- -- only for compile a object file
- local ok = compiler.check_include(opt, nil, cfile, objectfile)
-
- -- check link
- if ok then ok = linker.check_links(opt, links, cfile, objectfile, targetfile) end
-
- -- trace
- utils.printf("checking for the links %s ... %s", links_str, utils.ifelse(ok, "ok", "no"))
-
- -- cache the result
- project._CHECKED_LINKS[links_str] = ok
-
- -- ok?
- return ok
-end
-
--- make option for checking cincludes
-function project._make_option_for_checking_cincludes(opt, cincludes, cfile, objectfile)
-
- -- done
- for _, cinclude in ipairs(table.wrap(cincludes)) do
-
- -- this cinclude has been checked?
- project._CHECKED_CINCLUDES = project._CHECKED_CINCLUDES or {}
- if project._CHECKED_CINCLUDES[cinclude] then return true end
-
- -- check cinclude
- local ok = compiler.check_include(opt, cinclude, cfile, objectfile)
-
- -- trace
- utils.printf("checking for the c include %s ... %s", cinclude, utils.ifelse(ok, "ok", "no"))
-
- -- cache the result
- project._CHECKED_CINCLUDES[cinclude] = ok
-
- -- failed
- if not ok then return false end
- end
-
- -- ok
- return true
-end
-
--- make option for checking cxxincludes
-function project._make_option_for_checking_cxxincludes(opt, cxxincludes, cxxfile, objectfile)
-
- -- done
- for _, cxxinclude in ipairs(table.wrap(cxxincludes)) do
-
- -- this cxxinclude has been checked?
- project._CHECKED_CXXINCLUDES = project._CHECKED_CXXINCLUDES or {}
- if project._CHECKED_CXXINCLUDES[cinclude] then return true end
-
- -- check cinclude
- local ok = compiler.check_include(opt, cxxinclude, cxxfile, objectfile)
-
- -- trace
- utils.printf("checking for the c++ include %s ... %s", cxxinclude, utils.ifelse(ok, "ok", "no"))
-
- -- cache the result
- project._CHECKED_CXXINCLUDES[cxxinclude] = ok
-
- -- failed
- if not ok then return false end
- end
-
- -- ok
- return true
-end
-
--- make option for checking cfunctions
-function project._make_option_for_checking_cfuncs(opt, cfuncs, cfile, objectfile, targetfile)
-
- -- done
- for _, cfunc in ipairs(table.wrap(cfuncs)) do
-
- -- check function
- local ok = compiler.check_function(opt, cfunc, cfile, objectfile)
-
- -- check link
- if ok and opt.links then ok = linker.check_links(opt, opt.links, cfile, objectfile, targetfile) end
-
- -- trace
- utils.printf("checking for the c function %s ... %s", cfunc, utils.ifelse(ok, "ok", "no"))
-
- -- failed
- if not ok then return false end
- end
-
- -- ok
- return true
-end
-
--- make option for checking cxxfunctions
-function project._make_option_for_checking_cxxfuncs(opt, cxxfuncs, cxxfile, objectfile, targetfile)
-
- -- done
- for _, cxxfunc in ipairs(table.wrap(cxxfuncs)) do
-
- -- check function
- local ok = compiler.check_function(opt, cxxfunc, cxxfile, objectfile)
-
- -- check link
- if ok and opt.links then ok = linker.check_links(opt, opt.links, cxxfile, objectfile, targetfile) end
-
- -- trace
- utils.printf("checking for the c++ function %s ... %s", cxxfunc, utils.ifelse(ok, "ok", "no"))
-
- -- failed
- if not ok then return false end
- end
-
- -- ok
- return true
-end
-
--- make option for checking ctypes
-function project._make_option_for_checking_ctypes(opt, ctypes, cfile, objectfile, targetfile)
-
- -- done
- for _, ctype in ipairs(table.wrap(ctypes)) do
-
- -- check type
- local ok = compiler.check_typedef(opt, ctype, cfile, objectfile)
-
- -- trace
- utils.printf("checking for the c type %s ... %s", ctype, utils.ifelse(ok, "ok", "no"))
-
- -- failed
- if not ok then return false end
- end
-
- -- ok
- return true
-end
-
--- make option for checking cxxtypes
-function project._make_option_for_checking_cxxtypes(opt, cxxtypes, cxxfile, objectfile, targetfile)
-
- -- done
- for _, cxxtype in ipairs(table.wrap(cxxtypes)) do
-
- -- check type
- local ok = compiler.check_typedef(opt, cxxtype, cxxfile, objectfile)
-
- -- trace
- utils.printf("checking for the c++ type %s ... %s", cxxtype, utils.ifelse(ok, "ok", "no"))
+-- probe the project
+function project.probe()
- -- failed
- if not ok then return false end
+ -- enter the project directory
+ local ok, errors = os.cd(xmake._PROJECT_DIR)
+ if not ok then
+ return false, errors
end
- -- ok
- return true
-end
-
--- make option
-function project._make_option(name, opt, cfile, cxxfile, objectfile, targetfile)
-
- -- check links
- if opt.links and not project._make_option_for_checking_links(opt, opt.links, cfile, objectfile, targetfile) then return end
-
- -- check ctypes
- if opt.ctypes and not project._make_option_for_checking_ctypes(opt, opt.ctypes, cfile, objectfile, targetfile) then return end
-
- -- check cxxtypes
- if opt.cxxtypes and not project._make_option_for_checking_cxxtypes(opt, opt.cxxtypes, cxxfile, objectfile, targetfile) then return end
-
- -- check includes and functions
- if opt.cincludes or opt.cxxincludes then
-
- -- check cincludes
- if opt.cincludes and not project._make_option_for_checking_cincludes(opt, opt.cincludes, cfile, objectfile) then return end
-
- -- check cxxincludes
- if opt.cxxincludes and not project._make_option_for_checking_cxxincludes(opt, opt.cxxincludes, cxxfile, objectfile) then return end
-
- -- check cfuncs
- if opt.cfuncs and not project._make_option_for_checking_cfuncs(opt, opt.cfuncs, cfile, objectfile, targetfile) then return end
-
- -- check cxxfuncs
- if opt.cxxfuncs and not project._make_option_for_checking_cxxfuncs(opt, opt.cxxfuncs, cxxfile, objectfile, targetfile) then return end
-
+ -- load the options from the the project file
+ local options, errors = project.options(true)
+ if not options then
+ return false, errors
end
-
- -- ok
- return opt
-end
-
--- make options from the project file
-function project._make_options(options)
-
- -- check
- assert(options)
-
+
-- the source file path
- local cfile = os.tmpdir() .. "/__checking.c"
- local cxxfile = os.tmpdir() .. "/__checking.cpp"
+ local cfile = path.join(os.tmpdir(), "__checking.c")
+ local cxxfile = path.join(os.tmpdir(), "__checking.cpp")
-- the object file path
- local objectfile = os.tmpdir() .. "/" .. target.filename("__checking", "object")
+ local objectfile = path.join(os.tmpdir(), target.filename("__checking", "object"))
-- the target file path
- local targetfile = os.tmpdir() .. "/" .. target.filename("__checking", "binary")
+ local targetfile = path.join(os.tmpdir(), target.filename("__checking", "binary"))
-- make all options
- for k, v in pairs(options) do
+ for name, opt in pairs(options) do
-- this option need be probed automatically?
if config.get(name) == nil then
- -- make option
- local o = project._make_option(k, v, cfile, cxxfile, objectfile, targetfile)
- if o then
+ -- check option
+ if opt:check(cfile, cxxfile, objectfile, targetfile) then
-- enable this option
- config.set(k, true)
+ config.set(name, true)
-- save this option to configure
- config.set("__" .. k, o)
+ opt:save()
else
-- disable this option
- config.set(k, false)
+ config.set(name, false)
-- clear this option to configure
- config.set("__" .. k, nil)
+ opt:clear()
end
- elseif nil == config.get("__" .. k) then
+ elseif nil == option.load(name) then
-- save this option to configure
- config.set("__" .. k, v)
+ opt:save()
end
end
@@ -730,54 +539,6 @@ function project._make_options(options)
os.rm(objectfile)
os.rm(targetfile)
-end
-
--- get the given target
-function project.target(targetname)
-
- -- check
- assert(targetname and targetname ~= "all")
-
- -- the targets
- local targets = project.targets()
- assert(targets)
-
- -- get it
- return targets[targetname]
-end
-
--- get the current configure for targets
-function project.targets()
-
- -- check
- assert(project._TARGETS)
-
- -- return it
- return project._TARGETS
-end
-
--- probe the project
-function project.probe()
-
- -- get interpreter
- local interp = project._interpreter()
- assert(interp)
-
- -- enter the project directory
- local ok, errors = os.cd(xmake._PROJECT_DIR)
- if not ok then
- return false, errors
- end
-
- -- load the options from the the project file
- local options, errors = interp:load(xmake._PROJECT_FILE, "option", true, true)
- if not options then
- return false, errors
- end
-
- -- make the options from the the project file
- project._make_options(options)
-
-- leave the project directory
ok, errors = os.cd("-")
if not ok then
@@ -836,29 +597,72 @@ function project.load()
return true
end
--- dump the current configure
-function project.dump()
-
- -- dump
- if option.get("verbose") then
- table.dump(project.targets())
- end
-
+-- get the given target
+function project.target(targetname)
+
+ -- check
+ assert(targetname and targetname ~= "all")
+
+ -- the targets
+ local targets = project.targets()
+ assert(targets)
+
+ -- get it
+ return targets[targetname]
end
--- get the project menu
-function project.menu()
+-- get the current configure for targets
+function project.targets()
+
+ -- check
+ assert(project._TARGETS)
+
+ -- return it
+ return project._TARGETS
+end
+
+-- get options
+function project.options(enable_filter)
-- get interpreter
local interp = project._interpreter()
assert(interp)
+ -- load the options from the the project file
+ local results, errors = interp:load(xmake._PROJECT_FILE, "option", true, enable_filter)
+ if not results then
+ return nil, errors
+ end
+
+ -- check options
+ local options = {}
+ for optionname, optioninfo in pairs(results) do
+
+ -- init a option instance
+ local instance = table.inherit(option)
+ assert(instance)
+
+ -- save name and info
+ instance._NAME = optionname
+ instance._INFO = optioninfo
+
+ -- save it
+ options[optionname] = instance
+ end
+
+ -- ok?
+ return options
+
+end
+
+-- get the project menu
+function project.menu()
+
-- attempt to load options from the project file
local options = nil
local errors = nil
- local projectfile = xmake._PROJECT_FILE
- if projectfile and os.isfile(projectfile) then
- options, errors = interp:load(projectfile, "option", true, false)
+ if os.isfile(xmake._PROJECT_FILE) then
+ options, errors = project.options(false)
end
-- failed?
@@ -873,7 +677,7 @@ function project.menu()
-- make the category
local category = "default"
- if opt.category then category = table.unwrap(opt.category) end
+ if opt:get("category") then category = table.unwrap(opt:get("category")) end
options_by_category[category] = options_by_category[category] or {}
-- append option to the current category
@@ -889,12 +693,12 @@ function project.menu()
for name, opt in pairs(opts) do
-- show menu?
- if opt.showmenu then
+ if opt:get("showmenu") then
-- the default value
local default = "auto"
- if opt.enable ~= nil then
- default = opt.enable
+ if opt:get("enable") ~= nil then
+ default = opt:get("enable")
end
-- is first?
@@ -908,8 +712,8 @@ function project.menu()
end
-- append it
- if opt.description then
- table.insert(menu, {nil, name, "kv", default, opt.description})
+ if opt:get("description") then
+ table.insert(menu, {nil, name, "kv", default, opt:get("description")})
else
table.insert(menu, {nil, name, "kv", default, nil})
end
diff --git a/xmake/core/project/target.lua b/xmake/core/project/target.lua
index 6b1da3215..a7fd954d3 100644
--- a/xmake/core/project/target.lua
+++ b/xmake/core/project/target.lua
@@ -27,7 +27,9 @@ local target = target or {}
local os = require("base/os")
local path = require("base/path")
local table = require("base/table")
+local option = require("project/option")
local config = require("project/config")
+local linker = require("platform/linker")
local platform = require("platform/platform")
-- get the filename from the given name and kind
@@ -60,6 +62,39 @@ function target.name(self)
return self._NAME
end
+-- get the linker with the target kind
+function target.linker(self)
+
+ -- init the linker from the given kind
+ local result = linker.init(self:get("kind"))
+ if not result then
+ os.raise("cannot get linker with kind: %s", self:get("kind"))
+ end
+
+ -- ok?
+ return result
+
+end
+
+-- get the options
+function target.options(self)
+
+ -- the options
+ local options = {}
+ for _, name in ipairs(table.wrap(self:get("options"))) do
+
+ -- get option if be enabled
+ local opt = nil
+ if config.get(name) then opt = poption.load(name) end
+ if nil ~= opt then
+ options[name] = opt
+ end
+ end
+
+ -- ok?
+ return options
+end
+
-- get the object file directory
function target.objectdir(self)