diff options
| author | ruki <[email protected]> | 2016-03-21 20:57:23 +0800 |
|---|---|---|
| committer | ruki <[email protected]> | 2016-03-21 20:57:37 +0800 |
| commit | b898400a3a5f18d332ce7ef159769d8f17fd28e5 (patch) | |
| tree | 275f124aa7c17c6090d25fefb226b0678f6d231d | |
| parent | f0623bf26279430deb6799b7816fb61996120166 (diff) | |
add project option
| -rwxr-xr-x | xmake/actions/config/makefile.lua | 25 | ||||
| -rw-r--r-- | xmake/core/base/table.lua | 4 | ||||
| -rw-r--r-- | xmake/core/platform/compiler.lua | 307 | ||||
| -rw-r--r-- | xmake/core/platform/linker.lua | 242 | ||||
| -rw-r--r-- | xmake/core/platform/tools/clang++.lua | 2 | ||||
| -rw-r--r-- | xmake/core/project/option.lua | 302 | ||||
| -rw-r--r-- | xmake/core/project/project.lua | 378 | ||||
| -rw-r--r-- | xmake/core/project/target.lua | 35 |
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) |
