diff options
| author | ruki <[email protected]> | 2016-01-14 09:19:14 +0800 |
|---|---|---|
| committer | ruki <[email protected]> | 2016-01-14 09:19:14 +0800 |
| commit | cdcf953259aee5e7e1a06855ddbedbaabf585bc9 (patch) | |
| tree | 47b8e5de10522cca3b67354fa527b3525193e880 /xmake/scripts/base | |
| parent | 8c50566e7ab2139b9f6c2976b9ce875b7ad11b7a (diff) | |
rename script directory to core
Diffstat (limited to 'xmake/scripts/base')
| -rw-r--r-- | xmake/scripts/base/clean.lua | 192 | ||||
| -rw-r--r-- | xmake/scripts/base/compiler.lua | 574 | ||||
| -rw-r--r-- | xmake/scripts/base/config.lua | 395 | ||||
| -rw-r--r-- | xmake/scripts/base/global.lua | 246 | ||||
| -rw-r--r-- | xmake/scripts/base/install.lua | 143 | ||||
| -rw-r--r-- | xmake/scripts/base/io.lua | 324 | ||||
| -rw-r--r-- | xmake/scripts/base/linker.lua | 386 | ||||
| -rw-r--r-- | xmake/scripts/base/main.lua | 179 | ||||
| -rw-r--r-- | xmake/scripts/base/makefile.lua | 417 | ||||
| -rw-r--r-- | xmake/scripts/base/option.lua | 650 | ||||
| -rw-r--r-- | xmake/scripts/base/os.lua | 237 | ||||
| -rw-r--r-- | xmake/scripts/base/package.lua | 314 | ||||
| -rw-r--r-- | xmake/scripts/base/path.lua | 72 | ||||
| -rw-r--r-- | xmake/scripts/base/project.lua | 1469 | ||||
| -rw-r--r-- | xmake/scripts/base/rule.lua | 300 | ||||
| -rw-r--r-- | xmake/scripts/base/string.lua | 115 | ||||
| -rw-r--r-- | xmake/scripts/base/table.lua | 99 | ||||
| -rw-r--r-- | xmake/scripts/base/template.lua | 77 | ||||
| -rw-r--r-- | xmake/scripts/base/uninstall.lua | 104 | ||||
| -rw-r--r-- | xmake/scripts/base/utils.lua | 258 |
20 files changed, 0 insertions, 6551 deletions
diff --git a/xmake/scripts/base/clean.lua b/xmake/scripts/base/clean.lua deleted file mode 100644 index 9fbb3258a..000000000 --- a/xmake/scripts/base/clean.lua +++ /dev/null @@ -1,192 +0,0 @@ ---!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) 2009 - 2015, ruki All rights reserved. --- --- @author ruki --- @file clean.lua --- - --- define module: clean -local clean = clean or {} - --- load modules -local os = require("base/os") -local rule = require("base/rule") -local utils = require("base/utils") -local config = require("base/config") -local project = require("base/project") - --- remove the given files or directories -function clean._remove(filedirs) - - -- empty? - if not filedirs then return true end - - -- wrap it first - filedirs = utils.wrap(filedirs) - for _, filedir in ipairs(filedirs) do - - -- exists? remove it - if os.exists(filedir) then - -- remove it - local ok, errors = os.rm(filedir) - if not ok then - -- error - utils.error(errors) - return false - end - end - end - - -- ok - return true -end - --- remove the given target name -function clean._remove_target(target_name, target, mode, buildir) - - -- check - assert(target_name and target) - - -- remove the target file - if not clean._remove(rule.targetfile(target_name, target, buildir)) then - return false - end - - -- not only remove target file? - if mode ~= "targets" then - - -- remove the object files - if not clean._remove(rule.objectfiles(target_name, target, rule.sourcefiles(target), buildir)) then - return false - end - - -- remove the header files - local _, dstheaders = rule.headerfiles(target) - if not clean._remove(dstheaders) then - return false - end - - -- remove the config.h file - if mode == "all" and target.config_h then - - -- translate file path - local config_h = nil - if not path.is_absolute(target.config_h) then - config_h = path.absolute(target.config_h, xmake._PROJECT_DIR) - else - config_h = path.translate(target.config_h) - end - if not clean._remove(config_h) then - return false - end - end - end - - -- ok - return true -end - --- remove the given target and all dependent targets -function clean._remove_target_and_deps(target_name, mode, buildir) - - -- the targets - local targets = project.targets() - assert(targets) - - -- the target - local target = targets[target_name] - assert(target) - - -- remove the target - if not clean._remove_target(target_name, target, mode, buildir) then - return false - end - - -- exists the dependent targets? - if target.deps then - local deps = utils.wrap(target.deps) - for _, dep in ipairs(deps) do - if not clean._remove_target_and_deps(dep, mode, buildir) then return false end - end - end - - -- ok - return true -end - --- remove the target and object files for the given target --- --- mode: --- all --- build --- targets --- -function clean.remove(target_name, mode) - - -- the build directory - local buildir = config.get("buildir") - assert(buildir and mode) - - -- the target name - if target_name and target_name ~= "all" then - -- remove target - if not clean._remove_target_and_deps(target_name, mode, buildir) then return false end - else - - -- the targets - local targets = project.targets() - assert(targets) - - -- remove targets - for target_name, target in pairs(targets) do - if not clean._remove_target(target_name, target, mode, buildir) then return false end - end - end - - -- remove all - if mode == "all" then - - -- remove makefile - if not clean._remove(rule.makefile()) then - return false - end - - -- remove the configure directory - if not clean._remove(config.directory()) then - return false - end - - -- remove the log file - if not clean._remove(rule.logfile()) then - return false - end - - -- remove build directory if be empty - local buildir = config.get("buildir") - if os.isdir(buildir) then - os.rm(buildir, true) - end - - end - - -- ok - return true -end - --- return module: clean -return clean diff --git a/xmake/scripts/base/compiler.lua b/xmake/scripts/base/compiler.lua deleted file mode 100644 index a64f8bae0..000000000 --- a/xmake/scripts/base/compiler.lua +++ /dev/null @@ -1,574 +0,0 @@ ---!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) 2009 - 2015, ruki All rights reserved. --- --- @author ruki --- @file compiler.lua --- - --- define module: compiler -local compiler = compiler or {} - --- load modules -local io = require("base/io") -local path = require("base/path") -local rule = require("base/rule") -local utils = require("base/utils") -local table = require("base/table") -local string = require("base/string") -local config = require("base/config") -local tools = require("tools/tools") -local platform = require("platform/platform") - --- map gcc flag to the given compiler flag -function compiler._mapflag(module, flag) - - -- check - assert(module.mapflags and flag) - - -- attempt to map it directly - local flag_mapped = module.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 - local flag_mapped, count = flag:gsub("^" .. k .. "$", function (w) - if type(v) == "function" then - return v(module, w) - else - return v - end - end) - if flag_mapped and count ~= 0 then - return utils.ifelse(#flag_mapped ~= 0, flag_mapped, nil) - end - end - - -- return it directly - return flag -end - --- map gcc flags to the given compiler flags -function compiler._mapflags(module, flags) - - -- check - assert(module) - - -- wrap flags first - flags = utils.wrap(flags) - - -- need not map flags? return it directly - if not module.mapflags then - return flags - end - - -- map flags - local flags_mapped = {} - for _, flag in pairs(flags) do - -- map it - local flag_mapped = compiler._mapflag(module, flag) - if flag_mapped then - table.insert(flags_mapped, flag_mapped) - end - end - - -- ok? - return flags_mapped -end - --- get the compiler flags from names -function compiler._getflags(module, names, flags) - - -- check - assert(flags) - - -- the mapped flags - local flags_mapped = {} - - -- wrap it first - names = utils.wrap(names) - for _, name in ipairs(names) do - table.join2(flags_mapped, compiler._mapflags(module, flags[name])) - end - - -- get it - return flags_mapped -end - --- add flags from the compiler -function compiler._addflags_from_compiler(module, flags, flagnames, kind) - - -- check - assert(module and flags and flagnames) - - -- done - for _, flagname in ipairs(flagnames) do - - -- add compiler.xxflags - table.join2(flags, module, module[flagname]) - - -- add compiler.kind.xxflags - if kind ~= nil and module[kind] ~= nil then - table.join2(flags, module, module[kind][flagname]) - end - end -end - --- add flags from the configure -function compiler._addflags_from_config(module, flags, flagnames) - - -- check - assert(module and flags and flagnames) - - -- done - for _, flagname in ipairs(flagnames) do - table.join2(flags, config.get(flagname)) - end -end - --- add flags from the platform -function compiler._addflags_from_platform(module, flags, flagnames) - - -- check - assert(module and flags and flagnames) - - -- add flags - for _, flagname in ipairs(flagnames) do - table.join2(flags, compiler._mapflags(module, platform.get(flagname))) - end - - -- add the includedirs flags - if module.flag_includedir then - for _, includedir in ipairs(utils.wrap(platform.get("includedirs"))) do - table.join2(flags, module:flag_includedir(includedir)) - end - end - - -- add the defines flags - if module.flag_define then - for _, define in ipairs(utils.wrap(platform.get("defines"))) do - table.join2(flags, module:flag_define(define)) - end - end - - -- append the undefines flags - if module.flag_undefine then - for _, undefine in ipairs(utils.wrap(platform.get("undefines"))) do - table.join2(flags, module:flag_undefine(undefine)) - end - end -end - - --- add flags from the target -function compiler._addflags_from_target(module, flags, flagnames, target) - - -- check - assert(module 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])) - end - - -- add the symbols flags from the current project - table.join2(flags, compiler._getflags(module, target.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" - })) - - -- 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" - })) - - -- 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" - })) - - -- add the language flags from the current project - local languages = {} - for _, flagname in ipairs(flagnames) do - if flagname == "cflags" or flagname == "mflags" then - table.join2(languages, { ansi = "-ansi" - , c89 = "-std=c89" - , gnu89 = "-std=gnu89" - , c99 = "-std=c99" - , gnu99 = "-std=gnu99" - , c11 = "-std=c11" - , gnu11 = "-std=gnu11" - }) - elseif flagname == "cxxflags" or flagname == "mxxflags" then - table.join2(languages, { cxx98 = "-std=c++98" - , gnuxx98 = "-std=gnu++98" - , cxx11 = "-std=c++11" - , gnuxx11 = "-std=gnu++11" - , cxx14 = "-std=c++14" - , gnuxx14 = "-std=gnu++14" - }) - end - end - table.join2(flags, compiler._getflags(module, target.languages, languages)) - - -- add the includedirs flags from the current project - if module.flag_includedir then - for _, includedir in ipairs(utils.wrap(target.includedirs)) do - table.join2(flags, module:flag_includedir(includedir)) - end - end - - -- add the defines flags from the current project - if module.flag_define then - for _, define in ipairs(utils.wrap(target.defines)) do - table.join2(flags, module:flag_define(define)) - end - end - - -- append the undefines flags from the current project - if module.flag_undefine then - for _, undefine in ipairs(utils.wrap(target.undefines)) do - table.join2(flags, module:flag_undefine(undefine)) - end - end - - -- the options - if target.options then - for _, name in ipairs(utils.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 from the option - compiler._addflags_from_target(module, flags, flagnames, opt) - - -- append the defines flags - if opt.defines_if_ok and module.flag_define then - local defines = utils.wrap(opt.defines_if_ok) - for _, define in ipairs(defines) do - table.join2(flags, module:flag_define(define)) - end - end - - -- append the undefines flags - if opt.undefines_if_ok and module.flag_undefine then - local undefines = utils.wrap(opt.undefines_if_ok) - for _, undefine in ipairs(undefines) do - table.join2(flags, module:flag_undefine(undefine)) - end - end - end - end - end -end - --- add flags from the option -function compiler._addflags_from_option(module, flags, flagnames, opt) - - -- check - assert(module and flags and flagnames and opt) - - -- add the flags from the option - compiler._addflags_from_target(module, flags, flagnames, opt) - -end - --- get the flag names from the given compiler name -function compiler._flagnames(name) - - -- check - assert(name) - - -- the flag names - local flagnames = nil - if name == "cc" then flagnames = { "cxflags", "cflags" } - elseif name == "cxx" then flagnames = { "cxflags", "cxxflags" } - elseif name == "mm" then flagnames = { "mxflags", "mflags" } - elseif name == "mxx" then flagnames = { "mxflags", "mxxflags" } - elseif name == "as" then flagnames = { "asflags" } - elseif name == "sc" then flagnames = { "scflags" } - else - -- error - utils.error("unknown compiler: %s", name) - return - end - - -- ok - return flagnames -end - --- get the compiler kind from the source file type -function compiler._kind(srcfile) - - -- get the source file type - local filetype = path.extension(srcfile) - if not filetype then - return nil - end - - -- get the lower file type - filetype = filetype:lower() - - -- get the compiler kind - local kind = nil - if filetype == ".c" then kind = "cc" - elseif filetype == ".cpp" or filetype == ".cc" then kind = "cxx" - elseif filetype == ".m" then kind = "mm" - elseif filetype == ".mm" then kind = "mxx" - elseif filetype == ".s" or filetype == ".asm" then kind = "as" - elseif filetype == ".swift" then kind = "sc" - end - - -- ok - return kind -end - --- make the compile command for option -function compiler._make_for_option(module, opt, srcfile, objfile, logfile) - - -- check - assert(module and opt) - - -- the flag names - local flagnames = compiler._flagnames(module._KIND) - assert(flagnames) - - -- init flags - local flags = {} - - -- add flags from the configure - compiler._addflags_from_config(module, flags, flagnames) - - -- add flags from the option - compiler._addflags_from_option(module, flags, flagnames, opt) - - -- add flags from the platform - compiler._addflags_from_platform(module, flags, flagnames) - - -- add flags from the compiler - compiler._addflags_from_compiler(module, flags, flagnames) - - -- remove repeat - flags = utils.unique(flags) - - -- execute the compile command - return module:command_compile(srcfile, objfile, table.concat(flags, " "):trim(), logfile) -end - --- get the compiler from the given source file -function compiler.get(srcfile) - - -- get the compiler kind - local kind = compiler._kind(srcfile) - if not kind then - return nil, string.format("unknown source file: %s", srcfile) - end - - -- get compiler from the source file type - local module = tools.get(kind) - if module then - - -- invalid compiler - if not module.command_compile then - return nil, string.format("invalid compiler for %s", kind) - end - - -- save kind - module._KIND = kind - else - return nil, string.format("unknown compiler for %s", kind) - end - - -- ok? - return module -end - --- make the compile command -function compiler.make(module, target, srcfile, objfile, logfile) - - -- check - assert(module and target) - - -- the flag names - local flagnames = compiler._flagnames(module._KIND) - assert(flagnames) - - -- init flags - local flags = {} - - -- add flags from the configure - compiler._addflags_from_config(module, flags, flagnames) - - -- add flags from the target - compiler._addflags_from_target(module, flags, flagnames, target) - - -- add flags from the platform - compiler._addflags_from_platform(module, flags, flagnames) - - -- add flags from the compiler - compiler._addflags_from_compiler(module, flags, flagnames, target.kind) - - -- remove repeat - flags = utils.unique(flags) - - -- make the compile command - return module:command_compile(srcfile, objfile, table.concat(flags, " "):trim(), logfile) -end - --- check include for the project option -function compiler.check_include(opt, include, srcpath, objpath) - - -- check - assert(opt and srcpath and objpath) - - -- open the checking source file - local srcfile = io.openmk(srcpath) - if not srcfile then return end - - -- make include - if include then - srcfile:write(string.format("#include <%s>\n\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") - - -- exit this file - srcfile:close() - - -- get the compiler - local module = compiler.get(srcpath) - if not module then return end - - -- execute the compile command - return module:main(compiler._make_for_option(module, opt, srcpath, objpath, utils.ifelse(xmake._OPTIONS.verbose, nil, xmake._NULDEV))) -end - --- check function for the project option -function compiler.check_function(opt, interface, srcpath, objpath) - - -- check - assert(opt and interface) - - -- open the checking source file - local srcfile = io.openmk(srcpath) - if not srcfile then return end - - -- get the compiler - local module = compiler.get(srcpath) - if not module then return end - - -- make includes - local includes = nil - if module._KIND == "cc" then includes = opt.cincludes - elseif module._KIND == "cxx" then includes = opt.cxxincludes - end - if includes then - for _, include in ipairs(utils.wrap(includes)) do - srcfile:write(string.format("#include <%s>\n", include)) - end - srcfile:write("\n") - end - - -- make the main function header - srcfile:write("int main(int argc, char** argv)\n") - srcfile:write("{\n") - - -- make interfaces - srcfile:write(string.format(" volatile void* p%s = (void*)&%s;\n\n", interface, interface)) - - -- make the main function tailer - srcfile:write(" return 0;\n") - srcfile:write("}\n") - - -- exit this file - srcfile:close() - - -- execute the compile command - return module:main(compiler._make_for_option(module, opt, srcpath, objpath, utils.ifelse(xmake._OPTIONS.verbose, nil, xmake._NULDEV))) -end - --- check typedef for the project option -function compiler.check_typedef(opt, typedef, srcpath, objpath) - - -- check - assert(opt and typedef) - - -- open the checking source file - local srcfile = io.openmk(srcpath) - if not srcfile then return end - - -- get the compiler - local module = compiler.get(srcpath) - if not module then return end - - -- make includes - local includes = nil - if module._KIND == "cc" then includes = opt.cincludes - elseif module._KIND == "cxx" then includes = opt.cxxincludes - end - if includes then - for _, include in ipairs(utils.wrap(includes)) do - srcfile:write(string.format("#include <%s>\n", include)) - end - srcfile:write("\n") - end - - -- make the main function header - srcfile:write("int main(int argc, char** argv)\n") - srcfile:write("{\n") - - -- make interfaces - srcfile:write(string.format(" typedef %s __type_xxx;\n\n", typedef)) - - -- make the main function tailer - srcfile:write(" return 0;\n") - srcfile:write("}\n") - - -- exit this file - srcfile:close() - - -- execute the compile command - return module:main(compiler._make_for_option(module, opt, srcpath, objpath, utils.ifelse(xmake._OPTIONS.verbose, nil, xmake._NULDEV))) -end - --- return module: compiler -return compiler diff --git a/xmake/scripts/base/config.lua b/xmake/scripts/base/config.lua deleted file mode 100644 index 3cea6a652..000000000 --- a/xmake/scripts/base/config.lua +++ /dev/null @@ -1,395 +0,0 @@ ---!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) 2009 - 2015, ruki All rights reserved. --- --- @author ruki --- @file config.lua --- - --- define module: config -local config = config or {} - --- load modules -local io = require("base/io") -local os = require("base/os") -local utils = require("base/utils") -local option = require("base/option") -local global = require("base/global") - --- make configure for the current target -function config._make(configs) - - -- the options - local options = xmake._OPTIONS - assert(options) - - -- init current target configure - local current = {} - - -- get configs from the default configure - if configs._DEFAULTS then - for k, v in pairs(configs._DEFAULTS) do - if type(v) ~= "string" or v ~= "auto" then current[k] = v end - end - end - - -- get configs from the global configure - if global._CURRENT then - for k, v in pairs(global._CURRENT) do - current[k] = v - end - end - - -- get configs from all targets - for k, v in pairs(configs) do - if type(k) == "string" and not k:find("^_%u+") then - current[k] = v - end - end - - -- get configs from the current target - if configs._TARGETS and current.target ~= "all" then - - -- get the target config - local target_config = configs._TARGETS[current.target] - if target_config then - - -- merge it - for k, v in pairs(target_config) do - current[k] = v - end - end - end - - -- ok? - return current -end - --- get the configure file -function config._file() - - -- get it - return config.directory() .. "/xmake.conf" -end - --- need configure? -function config._need(name) - return name and name ~= "target" and name ~= "file" and name ~= "project" and name ~= "verbose" and name ~= "clean" -end - --- get the current target scope -function config._target() - - -- the options - local options = xmake._OPTIONS - assert(options) - - -- check - local configs = config._CONFIGS - assert(configs) - - -- the target name - local name = options.target or options._DEFAULTS.target - assert(name and type(name) == "string") - - -- for all targets? - if name == "all" then - return configs - elseif configs._TARGETS then - -- get it - return configs._TARGETS[name] - end -end - --- get the given configure from the current -function config.get(name) - - -- the configure has been not loaded - if not config._CURRENT then return end - - -- get it - return config._CURRENT[name] -end - --- set the given configure to the current -function config.set(name, value) - - -- check - assert(config._CURRENT and name) - - -- get the current target - local target = config._target() - assert(target) - - -- set it to the current target configure for saving to file - target[name] = value - - -- set it to the current configure - config._CURRENT[name] = value -end - --- the given configure need probe automatically -function config.auto(name) - - -- the configs - local configs = config._CONFIGS - assert(configs) - - -- need probe it automatically? - if configs._DEFAULTS then - local value = configs._DEFAULTS[name] - if value then - if type(value) == "string" and value == "auto" then - return true - end - end - end - - -- need not probe it if have been setted manually - if config._CURRENT and nil ~= config._CURRENT[name] then - return false - end - - -- attempt to probe it if not exists - return true -end - --- get the configure directory -function config.directory() - - -- the directory - local dir = xmake._PROJECT_DIR .. "/.xmake" - - -- create it directly first if not exists - if not os.isdir(dir) then - assert(os.mkdir(dir)) - end - - -- get it - return dir -end - --- save xmake.conf -function config.save() - - -- the configs - local configs = config._CONFIGS - assert(configs) - - -- save to the configure file - return io.save(config._file(), configs) -end - -function config.load() - - -- the options - local options = xmake._OPTIONS - assert(options) - - -- check - assert(option._MENU) - assert(option._MENU.config) - - -- the target name - local name = options.target or options._DEFAULTS.target - if not name then - return "no given target name!" - end - - -- does not clean the cached configure? - if not options.clean then - - -- load and execute the xmake.xconf - local filepath = config._file() - if os.isfile(filepath) then - - -- load the configure file - local configs, errors = io.load(filepath) - - -- exists local configures? - if configs then - - -- save configs - config._CONFIGS = configs - - -- make the current target configs - local current = config._make(configs) - - -- clear configs and mark as "rebuild" and "reconfig" if the host has been changed - if (current and current.host ~= xmake._HOST) then - - -- clear configs and mark as "rebuild" - config._CONFIGS = { __rebuild = true } - - -- mark as "reconfig" if the current action is not "config" - if options._ACTION ~= "config" then - config._RECONFIG = true - end - end - - -- clear configs and mark as "rebuild" if the plat has been changed - if current and current.plat and options.plat and current.plat ~= options.plat then - - -- clear configs and mark as "rebuild" - config._CONFIGS = { __rebuild = true } - end - - -- mark as "rebuild" if the arch has been changed - if current and current.arch and options.arch and current.arch ~= options.arch then - - -- mark as "rebuild" - config._CONFIGS.__rebuild = true - end - - -- mark as "rebuild" if the mode has been changed - if current and current.mode and options.mode and current.mode ~= options.mode then - - -- mark as "rebuild" - config._CONFIGS.__rebuild = true - end - elseif errors then - -- error - utils.error(errors) - end - end - end - - -- init configs if not exists - if not config._CONFIGS then - -- clear configs and mark as "rebuild" - config._CONFIGS = { __rebuild = true } - - -- mark as "reconfig" if the current action is not "config" - if options._ACTION ~= "config" then - config._RECONFIG = true - end - end - - -- the configs - local configs = config._CONFIGS - - -- mark as "rebuild" if clean the cached configure - if options.clean then - configs.__rebuild = true - end - - -- init the defaults - local defaults = nil - if not configs._DEFAULTS then - if config._RECONFIG then defaults = option.defaults("config") - elseif options._ACTION == "config" then defaults = options._DEFAULTS - end - if defaults then - for k, v in pairs(defaults) do - - -- check - assert(type(k) == "string") - - -- skip some options - if config._need(k) then - - -- save the default option - configs._DEFAULTS = configs._DEFAULTS or {} - configs._DEFAULTS[k] = v - end - end - end - end - defaults = configs._DEFAULTS - - -- init targets - configs._TARGETS = configs._TARGETS or {} - if name ~= "all" then - configs._TARGETS[name] = configs._TARGETS[name] or {} - end - - -- get the current target scope - local target = config._target() - assert(target and type(target) == "table") - - -- merge xmake._OPTIONS to target - if options._ACTION == "config" then - for k, v in pairs(options) do - - -- check - assert(type(k) == "string") - - -- skip some options - if not k:startswith("_") and config._need(k) then - - -- save the option to the target - target[k] = v - - -- remove it from the defaults, because we have setted it manually - if defaults then defaults[k] = nil end - end - end - end - - -- make the current config - config._CURRENT = config._make(config._CONFIGS) -end - --- clear up and remove all auto values -function config.clearup() - - -- clear up the current configure - local current = config._CURRENT - if current then - for k, v in pairs(current) do - if type(v) == "string" and v == "auto" then - current[k] = nil - end - end - end - - -- clear up the current target configure - local target = config._target() - if target then - for k, v in pairs(target) do - if type(v) == "string" and v == "auto" then - target[k] = nil - end - end - end - -end - --- reload configure -function config.reload() - - -- clear the old configure - config._CURRENT = nil - config._CONFIGS = nil - - -- load it - return config.load() -end - --- dump the current configure -function config.dump() - - -- check - assert(config._CURRENT) - - -- dump - utils.dump(config._CURRENT, "__%w*", "configure") - -end - --- return module: config -return config diff --git a/xmake/scripts/base/global.lua b/xmake/scripts/base/global.lua deleted file mode 100644 index 0017590c6..000000000 --- a/xmake/scripts/base/global.lua +++ /dev/null @@ -1,246 +0,0 @@ ---!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) 2009 - 2015, ruki All rights reserved. --- --- @author ruki --- @file global.lua --- - --- define module: global -local global = global or {} - --- load modules -local io = require("base/io") -local os = require("base/os") -local utils = require("base/utils") -local option = require("base/option") - --- make configure -function global._make() - - -- the configs - local configs = global._CONFIGS - assert(configs) - - -- the options - local options = xmake._OPTIONS - assert(options) - - -- init current global configure - global._CURRENT = global._CURRENT or {} - local current = global._CURRENT - - -- make current global configure - for k, v in pairs(configs) do - if type(k) == "string" and not k:find("^_%u+") then - current[k] = v - end - end -end - --- get the configure file -function global._file() - - -- get it - return global.directory() .. "/xmake.conf" -end - --- need configure? -function global._need(name) - return name and name ~= "verbose" and name ~= "clean" -end - --- get the given configure from the current -function global.get(name) - - -- check - assert(global._CURRENT) - - -- the value - local value = global._CURRENT[name] - if value and value == "auto" then - value = nil - end - - -- get it - return value -end - --- set the given configure to the current -function global.set(name, value) - - -- check - assert(global._CURRENT and global._CONFIGS) - assert(name and value and type(value) ~= "table") - - -- set it to the current configure - global._CURRENT[name] = value - - -- set it to the configure for saving to file - global._CONFIGS[name] = value - -end - --- get the global configure directory -function global.directory() - - -- the directory - local dir = path.translate("~/.xmake") - - -- create it directly first if not exists - if not os.isdir(dir) then - assert(os.mkdir(dir)) - end - - -- get it - return dir -end - --- save xmake.conf -function global.save() - - -- the configs - local configs = global._CONFIGS - assert(configs) - - -- save to the configure file - return io.save(global._file(), configs) -end - --- load xmake.conf -function global.load() - - -- the options - local options = xmake._OPTIONS - assert(options) - - -- check - assert(option._MENU) - assert(option._MENU.global) - - -- get all configure names - local i = 1 - local configures = {} - for _, o in ipairs(option._MENU.global.options) do - local name = o[2] - if global._need(name) then - configures[i] = name - i = i + 1 - end - end - - -- does not clean the cached configure? - if not options.clean then - - -- load and execute the xmake.conf - local filepath = global._file() - if os.isfile(filepath) then - - -- load the configure file - local configs, errors = io.load(filepath) - - -- exists local configures? - if configs then - -- save configs - global._CONFIGS = configs - elseif errors then - -- error - utils.error(errors) - end - end - end - - -- init configs - global._CONFIGS = global._CONFIGS or {} - local configs = global._CONFIGS - - -- xmake global? - if options._ACTION == "global" then - - -- merge xmake._OPTIONS to the global configure - for k, v in pairs(options) do - - -- check - assert(type(k) == "string") - - -- need configure it? - if not k:startswith("_") and global._need(k) then - configs[k] = v - end - end - - -- merge the default global configure options to the global configure - local defaults = options._DEFAULTS - if defaults then - for k, v in pairs(defaults) do - - -- check - assert(type(k) == "string") - - -- need configure it? - if global._need(k) then - - -- save the default option - if nil == configs[k] then - configs[k] = v - end - end - end - end - end - - -- make the current global - global._make() -end - --- clear up and remove all auto values -function global.clearup() - - -- clear up the current configure - local current = global._CURRENT - if current then - for k, v in pairs(current) do - if v and type(v) and v == "auto" then - current[k] = nil - end - end - end - - -- clear up the configure - local configs = global._CONFIGS - if configs then - for k, v in pairs(configs) do - if v and type(v) and v == "auto" then - configs[k] = nil - end - end - end -end - --- dump the current configure -function global.dump() - - -- check - assert(global._CURRENT) - - -- dump - utils.dump(global._CURRENT, "__%w*", "configure") - -end - --- return module: global -return global diff --git a/xmake/scripts/base/install.lua b/xmake/scripts/base/install.lua deleted file mode 100644 index 9fc41a14a..000000000 --- a/xmake/scripts/base/install.lua +++ /dev/null @@ -1,143 +0,0 @@ ---!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) 2009 - 2015, ruki All rights reserved. --- --- @author ruki --- @file install.lua --- - --- define module: install -local install = install or {} - --- load modules -local os = require("base/os") -local io = require("base/io") -local rule = require("base/rule") -local path = require("base/path") -local utils = require("base/utils") -local config = require("base/config") -local platform = require("platform/platform") - --- install target from the project script -function install._done_from_project(target) - - -- check - assert(target) - - -- install it using the project script first - local installscript = target.installscript - if type(installscript) == "function" then - - -- remove it - target.installscript = nil - - -- install it - return installscript(target) - end - - -- continue - return 0 -end - --- install target from the platform script -function install._done_from_platform(target) - - -- check - assert(target) - - -- the platform install script file - local installscript = nil - local scriptfile = platform.directory() .. "/install.lua" - if os.isfile(scriptfile) then - - -- load the install script - local script, errors = loadfile(scriptfile) - if script then - installscript = script() - if type(installscript) == "table" and installscript.main then - installscript = installscript.main - end - else - utils.error(errors) - end - end - - -- install it - if type(installscript) == "function" then - return installscript(target) - end - - -- continue - return 0 -end - --- install target from the given target configure -function install._done(target) - - -- check - assert(target) - - -- install it from the project script - local ok = install._done_from_project(target) - if ok ~= 0 then return utils.ifelse(ok == 1, true, false) end - - -- install it from the platform script - local ok = install._done_from_platform(target) - if ok ~= 0 then return utils.ifelse(ok == 1, true, false) end - - -- ok - return true -end - --- get the configure file -function install._file() - - -- get it - return config.directory() .. "/install.conf" -end - --- done install from the configure -function install.done(configs) - - -- check - assert(configs) - - -- install targets - for _, target in pairs(configs) do - - -- install it - if not install._done(target) then - -- errors - utils.error("install %s failed!", target.name) - return false - end - - end - - -- save to the configure file - return io.save(install._file(), configs) -end - --- load the install configure -function install.load() - - -- load it - return io.load(install._file()) -end - --- return module: install -return install diff --git a/xmake/scripts/base/io.lua b/xmake/scripts/base/io.lua deleted file mode 100644 index 66b23911a..000000000 --- a/xmake/scripts/base/io.lua +++ /dev/null @@ -1,324 +0,0 @@ ---!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) 2009 - 2015, ruki All rights reserved. --- --- @author ruki --- @file io.lua --- - --- define module: io -local io = io or {} - --- load modules -local path = require("base/path") -local utils = require("base/utils") - --- save object with the level -function io._save_with_level(file, object, level) - - -- save string - if type(object) == "string" then - file:write(string.format("%q", object)) - -- save boolean - elseif type(object) == "boolean" then - file:write(tostring(object)) - -- save number - elseif type(object) == "number" then - file:write(object) - -- save table - elseif type(object) == "table" then - - -- save head - file:write("\n") - for l = 1, level do - file:write(" ") - end - file:write("{\n") - - -- save body - local i = 0 - for k, v in pairs(object) do - - -- save spaces and separator - for l = 1, level do - file:write(" ") - end - - file:write(utils.ifelse(i == 0, " ", ", ")) - - -- save key - if type(k) == "string" then - file:write(string.format("[%q]", k), " = ") - end - - -- save value - if not io._save_with_level(file, v, level + 1) then - return false - end - - -- save newline - file:write("\n") - i = i + 1 - end - - -- save tail - for l = 1, level do - file:write(" ") - end - file:write("}\n") - else - -- error - utils.error("invalid object type: %s", type(object)) - return false - end - - -- ok - return true -end - --- save object to given file -function io._save(file, object) - - -- save it - return io._save_with_level(file, object, 0) -end - --- create directory and open a writable file -function io.openmk(filepath) - - -- check - assert(filepath) - - -- get the file directory - local dir = path.directory(filepath) - - -- ensure the file directory - if not os.isdir(dir) then os.mkdir(dir) end - - -- open it - return io.open(filepath, "w") -end - --- read all data from file -function io.readall(filepath) - - -- open file - local file = io.open(filepath, "r") - if not file then - -- error - return nil, string.format("open %s failed!", filepath) - end - - -- read all - local data = file:read("*all") - - -- exit file - file:close() - - -- ok? - return data -end - --- write all data to file -function io.writall(filepath, data) - - -- open file - local file = io.open(filepath, "w") - if not file then - -- error - return false, string.format("open %s failed!", filepath) - end - - -- write all - file:write(data) - - -- exit file - file:close() - - -- ok? - return true -end - --- save object the the given filepath -function io.save(filepath, object) - - -- open the file - local file = io.openmk(filepath) - if not file then - -- error - return false, string.format("open %s failed!", filepath) - end - - -- save object to file - if not io._save(file, object) then - -- error - file:close() - return false, string.format("save %s failed!", filepath) - end - - -- close file - file:close() - - -- ok - return true -end - --- load object from the given file -function io.load(filepath) - - -- open the file - local file = io.open(filepath, "r") - if not file then - -- error - return nil, string.format("open %s failed!", filepath) - end - - -- load data - local result = nil - local errors = nil - local data = file:read("*all") - if data and type(data) == "string" then - - -- load script - local script, errs = loadstring("return " .. data) - if script then - - -- load object - local ok, object = pcall(script) - if ok and object then - result = object - elseif object then - -- error - errors = object - else - -- error - errors = string.format("load %s failed!", filepath) - end - -- errors - else errors = errs end - end - - -- close file - file:close() - - -- ok? - return result, errors -end - --- gsub the given file and return replaced data -function io.gsub(filepath, pattern, replace) - - -- read all data from file - local data, errors = io.readall(filepath) - if not data then return nil, 0, errors end - - -- replace it - local count = 0 - if type(data) == "string" then - data, count = data:gsub(pattern, replace) - else - return nil, 0, string.format("data is not string!") - end - - -- replace ok? - if count ~= 0 then - -- write all data to file - local ok, errors = io.writall(filepath, data) - if not ok then return nil, 0, errors end - end - - -- ok - return data, count -end - --- cat the given file -function io.cat(filepath, linecount) - - -- open file - local file = io.open(filepath, "r") - if file then - - -- show file - local count = 1 - for line in file:lines() do - - -- show line - print(line) - - -- end? - if linecount and count >= linecount then - break - end - - -- update the line count - count = count + 1 - end - - -- exit file - file:close() - end -end - --- tail the given file -function io.tail(filepath, linecount) - - -- open file - local file = io.open(filepath, "r") - if file then - - -- read lines - local lines = {} - for line in file:lines() do - table.insert(lines, line) - end - - -- tail lines - local tails = {} - if #lines ~= 0 then - local count = 1 - for index = #lines, 1, -1 do - - -- show line - table.insert(tails, lines[index]) - - -- end? - if linecount and count >= linecount then - break - end - - -- update the line count - count = count + 1 - end - end - - -- show tails - if #tails ~= 0 then - for index = #tails, 1, -1 do - - -- show tail - print(tails[index]) - - end - end - - -- exit file - file:close() - end -end - --- return module: io -return io diff --git a/xmake/scripts/base/linker.lua b/xmake/scripts/base/linker.lua deleted file mode 100644 index 9a0388757..000000000 --- a/xmake/scripts/base/linker.lua +++ /dev/null @@ -1,386 +0,0 @@ ---!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) 2009 - 2015, ruki All rights reserved. --- --- @author ruki --- @file linker.lua --- - --- define module: linker -local linker = linker or {} - --- load modules -local utils = require("base/utils") -local table = require("base/table") -local string = require("base/string") -local config = require("base/config") -local compiler = require("base/compiler") -local tools = require("tools/tools") -local platform = require("platform/platform") - --- map gcc flag to the given linker flag -function linker._mapflag(module, flag) - - -- check - assert(module.mapflags and flag) - - -- attempt to map it directly - local flag_mapped = module.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 - local flag_mapped, count = flag:gsub("^" .. k .. "$", function (w) - if type(v) == "function" then - return v(module, w) - else - return v - end - end) - if flag_mapped and count ~= 0 then - return utils.ifelse(#flag_mapped ~= 0, flag_mapped, nil) - end - end - - -- return it directly - return flag -end - --- map gcc flags to the given linker flags -function linker._mapflags(module, flags) - - -- check - assert(module) - - -- wrap flags first - flags = utils.wrap(flags) - - -- need not map flags? return it directly - if not module.mapflags then - return flags - end - - -- map flags - local flags_mapped = {} - for _, flag in pairs(flags) do - -- map it - local flag_mapped = linker._mapflag(module, flag) - if flag_mapped then - table.insert(flags_mapped, flag_mapped) - end - end - - -- ok? - return flags_mapped -end - --- get the linker flags from names -function linker._getflags(module, names, flags) - - -- check - assert(flags) - - -- the mapped flags - local flags_mapped = {} - - -- wrap it first - names = utils.wrap(names) - for _, name in ipairs(names) do - table.join2(flags_mapped, linker._mapflags(module, flags[name])) - end - - -- get it - return flags_mapped -end - - --- add flags from the links -function linker._addflags_from_links(module, flags, links) - - -- check - assert(module and flags and links) - - -- done - if module.flag_link then - for _, link in ipairs(utils.wrap(links)) do - table.join2(flags, module:flag_link(link)) - end - end -end - --- add flags from the linker -function linker._addflags_from_linker(module, flags, flagname) - - -- check - assert(module and flags and flagname) - - -- done - table.join2(flags, module[flagname]) -end - --- add flags from the compiler -function linker._addflags_from_compiler(module, flags, flagname, srcfiles) - - -- check - assert(module and flags and flagname) - - -- add the flags for compiler - local flags_for_compiler = {} - if srcfiles then - for _, srcfile in ipairs(utils.wrap(srcfiles)) do - - -- get the compiler - local c, errors = compiler.get(srcfile) - if not c then - -- error - utils.error(errors) - return - end - - -- add flags - table.join2(flags_for_compiler, c[flagname]) - end - end - - -- done - table.join2(flags, utils.unique(flags_for_compiler)) -end - --- add flags from the configure -function linker._addflags_from_config(module, flags, flagname) - - -- check - assert(module 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) - - -- check - assert(module and flags and flagname) - - -- add flags - table.join2(flags, linker._mapflags(module, platform.get(flagname))) - - -- add the linkdirs flags - if module.flag_linkdir then - for _, linkdir in ipairs(utils.wrap(platform.get("linkdirs"))) do - table.join2(flags, module:flag_linkdir(linkdir)) - end - end - - -- add the links flags - if module.flag_link then - for _, link in ipairs(utils.wrap(platform.get("links"))) do - table.join2(flags, module:flag_link(link)) - end - end -end - --- add flags from the target -function linker._addflags_from_target(module, flags, flagname, target) - - -- check - assert(module and flags and flagname and target) - - -- add the target flags from the current project - table.join2(flags, linker._mapflags(module, target[flagname])) - - -- add the linkdirs flags from the current project - if module.flag_linkdir then - for _, linkdir in ipairs(utils.wrap(target.linkdirs)) do - table.join2(flags, module:flag_linkdir(linkdir)) - end - end - - -- add the links flags from the current project - if module.flag_link then - for _, link in ipairs(utils.wrap(target.links)) do - table.join2(flags, module:flag_link(link)) - end - end - - -- the options - if target.options then - for _, name in ipairs(utils.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 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(utils.wrap(opt.linkdirs)) do - table.join2(flags, module:flag_linkdir(linkdir)) - end - end - - -- add the links flags from the option - if module.flag_link then - for _, link in ipairs(utils.wrap(opt.links)) do - table.join2(flags, module:flag_link(link)) - end - end - end - end - end - - -- add the flags from the configure - table.join2(flags, linker._mapflags(module, config.get(flagname))) - - -- add the strip flags from the current project - table.join2(flags, linker._getflags(module, target.strip, { debug = "-S" - , all = "-s" - })) -end - --- add flags from the option -function linker._addflags_from_option(module, flags, flagname, opt) - - -- check - assert(module and flags and flagname and opt) - - -- append the option flags - table.join2(flags, linker._mapflags(module, opt[flagname])) - - -- append the linkdirs flags - if opt.linkdirs and module.flag_linkdir then - for _, linkdir in ipairs(utils.wrap(opt.linkdirs)) do - table.join2(flags, module:flag_linkdir(linkdir)) - end - end -end - --- get the linker from the given kind -function linker.get(kind) - - -- check - assert(kind) - - -- get the linker name from the kind - local name = nil - if kind == "binary" then name = "ld" - elseif kind == "static" then name = "ar" - elseif kind == "shared" then name = "sh" - else return end - - -- get it - local module = tools.get(name) - - -- invalid linker? - if module and not module.command_link then - return - end - - -- ok? - return module -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 - - -- init flags - local flags = {} - - -- add flags from the configure - linker._addflags_from_config(module, flags, flagname) - - -- add flags from the target - linker._addflags_from_target(module, flags, flagname, target) - - -- add flags from the platform - linker._addflags_from_platform(module, flags, flagname) - - -- add flags from the compiler - linker._addflags_from_compiler(module, flags, flagname, srcfiles) - - -- add flags from the linker - linker._addflags_from_linker(module, flags, flagname) - - -- remove repeat - flags = utils.unique(flags) - - -- make the link command - return module: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) - - -- check - assert(opt and links and objectfile and targetfile) - - -- get the linker - local module = linker.get("binary") - assert(module and module.flag_link) - - -- init flags - local flags = {} - - -- add flags from the configure - linker._addflags_from_config(module, flags, "ldflags") - - -- add flags from the option - linker._addflags_from_option(module, flags, "ldflags", opt) - - -- add flags from the platform - linker._addflags_from_platform(module, flags, "ldflags") - - -- add flags from the links - linker._addflags_from_links(module, flags, links) - - -- add flags from the compiler - linker._addflags_from_compiler(module, flags, "ldflags", sourcefile) - - -- add flags from the linker - linker._addflags_from_linker(module, flags, "ldflags") - - -- remove repeat - flags = utils.unique(flags) - - -- execute the link command - return module:main(module:command_link(objectfile, targetfile, table.concat(flags, " "):trim(), utils.ifelse(xmake._OPTIONS.verbose, nil, xmake._NULDEV))) -end - --- return module: linker -return linker diff --git a/xmake/scripts/base/main.lua b/xmake/scripts/base/main.lua deleted file mode 100644 index 470815701..000000000 --- a/xmake/scripts/base/main.lua +++ /dev/null @@ -1,179 +0,0 @@ ---!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) 2009 - 2015, ruki All rights reserved. --- --- @author ruki --- @file main.lua --- - --- define module: main -local main = main or {} - --- load modules -local os = require("base/os") -local path = require("base/path") -local utils = require("base/utils") -local option = require("base/option") -local action = require("action/action") - --- init the option menu -local menu = -{ - -- title - title = xmake._VERSION .. ", The Automatic Cross-platform Build Tool" - - -- copyright -, copyright = "Copyright (C) 2015-2016 Ruki Wang, tboox.org\nCopyright (C) 2005-2014 Mike Pall, luajit.org" - - -- build project: xmake -, main = - { - -- usage - usage = "xmake [action] [options] [target]" - - -- description - , description = "Build the project if no given action." - - -- actions - , actions = action.list - - -- options - , options = - { - {'b', "build", "k", nil, "Build project. This is default building mode and optional." } - , {'u', "update", "k", nil, "Only relink and update the binary files." } - , {'r', "rebuild", "k", nil, "Rebuild the project." } - - , {} - , {'f', "file", "kv", "xmake.lua", "Read a given xmake.lua file." } - , {'P', "project", "kv", nil, "Change to the given project directory." - , "Search priority:" - , " 1. The Given Command Argument" - , " 2. The Envirnoment Variable: XMAKE_PROJECT_DIR" - , " 3. The Current Directory" } - - - , {} - , {'j', "jobs", "kv", nil, "Specifies the number of jobs to build simultaneously" } - , {'v', "verbose", "k", nil, "Print lots of verbose information." } - , {nil, "version", "k", nil, "Print the version number and exit." } - , {'h', "help", "k", nil, "Print this help message and exit." } - - , {} - , {nil, "target", "v", "all", "Build the given target." } - } - } - - -- the actions: xmake [action] -, action.menu - -} - --- done help -function main._done_help() - - -- the options - local options = xmake._OPTIONS - assert(options) - - -- done help - if options.help then - - -- print menu - option.print_menu(options._ACTION) - - -- ok - return true - - -- done version - elseif options.version then - - -- print title - if option._MENU.title then - print(option._MENU.title) - end - - -- print copyright - if option._MENU.copyright then - print(option._MENU.copyright) - end - - -- ok - return true - end -end - --- done option -function main._done_option() - - -- the options - local options = xmake._OPTIONS - assert(options) - - -- done help? - if main._done_help() then - return true - end - - -- done action - return action.done(options._ACTION or "build") -end - --- the init function for main -function main._init() - - -- init the project directory - local projectdir = option.find(xmake._ARGV, "project", "P") or xmake._PROJECT_DIR - if projectdir and not path.is_absolute(projectdir) then - projectdir = path.absolute(projectdir) - elseif projectdir then - projectdir = path.translate(projectdir) - end - xmake._PROJECT_DIR = projectdir - assert(projectdir) - - -- init the xmake.lua file path - local projectfile = option.find(xmake._ARGV, "file", "f") or xmake._PROJECT_FILE - if projectfile and not path.is_absolute(projectfile) then - projectfile = path.absolute(projectfile, projectdir) - end - xmake._PROJECT_FILE = projectfile - assert(projectfile) -end - --- the main function -function main.done() - - -- init - main._init() - - -- init option - if not option.init(xmake._ARGV, menu) then - return -1 - end - - -- done option - if not main._done_option() then - return -1 - end - - -- ok - return 0 -end - --- return module: main -return main diff --git a/xmake/scripts/base/makefile.lua b/xmake/scripts/base/makefile.lua deleted file mode 100644 index 826310d1a..000000000 --- a/xmake/scripts/base/makefile.lua +++ /dev/null @@ -1,417 +0,0 @@ ---!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) 2009 - 2015, ruki All rights reserved. --- --- @author ruki --- @file makefile.lua --- - --- define module: makefile -local makefile = makefile or {} - --- load modules -local io = require("base/io") -local os = require("base/os") -local rule = require("base/rule") -local path = require("base/path") -local utils = require("base/utils") -local config = require("base/config") -local project = require("base/project") -local linker = require("base/linker") -local compiler = require("base/compiler") -local tools = require("tools/tools") -local platform = require("platform/platform") - --- make object for the *.[o|obj] source file -function makefile._make_object_for_object(file, target, srcfile, objfile) - - -- get the source file type - local filetype = path.extension(srcfile) - if not filetype then return false end - - -- get the lower file type - filetype = filetype:lower() - - -- not object file? - if filetype ~= ".o" and filetype ~= ".obj" then return false end - - -- get mode - local mode = config.get("mode") - if mode then - mode = "." .. mode - else - mode = "" - end - - -- make command - local cmd = string.format("xmake l cp %s %s", srcfile, objfile) - - -- make head - file:write(string.format("%s:", objfile)) - - -- make dependence - file:write(string.format(" %s\n", srcfile)) - - -- make body - file:write(string.format("\t@echo inserting%s %s\n", mode, srcfile)) - file:write(string.format("\t@xmake l $(VERBOSE) verbose \"%s\"\n", cmd:encode())) - file:write(string.format("\t@%s\n", cmd)) - - -- make tail - file:write("\n") - - -- ok - return true -end - --- make object for the *.[a|lib] source file -function makefile._make_object_for_static(file, target, srcfile, objfile) - - -- get the source file type - local filetype = path.extension(srcfile) - if not filetype then return false end - - -- get the lower file type - filetype = filetype:lower() - - -- not static file? - if filetype ~= ".a" and filetype ~= ".lib" then return false end - - -- get mode - local mode = config.get("mode") - if mode then - mode = "." .. mode - else - mode = "" - end - - -- make command - local cmd = string.format("xmake l -P %s -f %s dispatcher ex extract %s %s > %s 2>&1", xmake._PROJECT_DIR, xmake._PROJECT_FILE, srcfile:encode(), objfile:encode(), makefile._LOGFILE) - - -- make head - file:write(string.format("%s:", objfile)) - - -- make dependence - file:write(string.format(" %s\n", srcfile)) - - -- make body - file:write(string.format("\t@echo inserting%s %s\n", mode, srcfile)) - file:write(string.format("\t@xmake l $(VERBOSE) verbose \"%s\"\n", cmd:encode())) - file:write(string.format("\t@xmake l rmdir %s\n", path.directory(objfile))) - file:write(string.format("\t@%s\n", cmd)) - - -- make tail - file:write("\n") - - -- ok - return true -end - --- make the object to the makefile -function makefile._make_object(file, target, srcfile, objfile) - - -- check - assert(file and target and srcfile and objfile) - - -- make object for the *.o/obj source file - if makefile._make_object_for_object(file, target, srcfile, objfile) then - return true - elseif makefile._make_object_for_static(file, target, srcfile, objfile) then - return true - end - - -- get the compiler - local c, errors = compiler.get(srcfile) - if not c then - -- error - utils.error(errors) - return false - end - - -- get mode - local mode = config.get("mode") - if mode then - mode = "." .. mode - else - mode = "" - end - - -- get ccache - local ccache = platform.tool("ccache") - - -- make command - local cmd = compiler.make(c, target, srcfile, objfile, makefile._LOGFILE) - if ccache then - cmd = ccache:append(cmd, " ") - end - - -- make head - file:write(string.format("%s:", objfile)) - - -- make dependence - file:write(string.format(" %s\n", srcfile)) - - -- make body - file:write(string.format("\t@echo %scompiling%s %s\n", utils.ifelse(ccache, "ccache ", ""), mode, srcfile)) - file:write(string.format("\t@xmake l $(VERBOSE) verbose \"%s\"\n", cmd:encode())) - file:write(string.format("\t@xmake l mkdir %s\n", path.directory(objfile))) - file:write(string.format("\t@%s\n", cmd)) - - -- make tail - file:write("\n") - - -- ok - return true -end - --- make all objects of the given target to the makefile -function makefile._make_objects(file, target, srcfiles, objfiles) - - -- check - assert(file and target and srcfiles and objfiles) - - -- make all objects - local i = 1 - for _, objfile in ipairs(objfiles) do - - -- make object - if not makefile._make_object(file, target, srcfiles[i], objfile) then - return false - end - - -- next - i = i + 1 - end - - -- ok - return true -end - --- make the given target to the makefile -function makefile._make_target(file, name, target) - - -- check - assert(file and name and target and target.kind) - - -- get source and object files - local srcfiles = rule.sourcefiles(target) - local objfiles = rule.objectfiles(name, target, srcfiles) - assert(srcfiles and objfiles) - - -- get source and destinate header files - local srcheaders, dstheaders = rule.headerfiles(target) - - -- get target file - local targetfile = rule.targetfile(name, target) - assert(targetfile) - - -- get the targets - local targets = project.targets() - assert(targets) - - -- 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 - file:write(string.format("%s: %s\n", name, targetfile)) - file:write(string.format("%s:", targetfile)) - - -- make dependence for the dependent targets - if target.deps then - - -- get all dependent target - local deps = utils.wrap(target.deps) - for _, dep in ipairs(deps) do - - -- the dependent target - local deptarget = targets[dep] - if not deptarget then - utils.error("the dependent target: %s is invalid!", dep) - return false - end - - -- get the dependent target file - local depfile = rule.targetfile(dep, deptarget) - assert(depfile) - - -- add dependence - file:write(" " .. depfile) - end - end - - -- make dependence for objects - for _, objfile in ipairs(objfiles) do - file:write(" " .. objfile) - end - - -- make dependence end - file:write("\n") - - -- get mode - local mode = config.get("mode") - if mode then - mode = "." .. mode - else - mode = "" - end - - -- make the command - local cmd = linker.make(l, target, srcfiles, objfiles, targetfile, makefile._LOGFILE) - - -- the verbose - local verbose = cmd:encode() - -- too long? - if verbose and #verbose > 256 then - verbose = linker.make(l, target, srcfiles, {rule.filename("*", "object")}, targetfile) - verbose = verbose:encode() - end - - -- make body - file:write(string.format("\t@echo linking%s %s\n", mode, path.filename(targetfile))) - file:write(string.format("\t@xmake l $(VERBOSE) verbose \"%s\"\n", verbose)) - file:write(string.format("\t@xmake l mkdir %s\n", path.directory(targetfile))) - file:write(string.format("\t@%s\n", cmd)) - if srcheaders and dstheaders then - local i = 1 - for _, srcheader in ipairs(srcheaders) do - local dstheader = dstheaders[i] - if dstheader then - file:write(string.format("\t@xmake l cp %s %s\n", srcheader, dstheader)) - end - i = i + 1 - end - end - - -- make tail - file:write("\n") - - -- make objects for this target - return makefile._make_objects(file, target, srcfiles, objfiles) -end - --- make all targets to the makefile -function makefile._make_targets(file) - - -- check - assert(file) - - -- get all project targets - local targets = project.targets() - if not targets then - -- error - utils.error("not found target in this project!") - return false - end - - -- make all first - local all = "" - for name, _ in pairs(targets) do - -- append the target name to all - all = all .. " " .. name - end - file:write(string.format("all: %s\n\n", all)) - file:write(string.format(".PHONY: all %s\n\n", all)) - - -- make it for all targets - for name, target in pairs(targets) do - -- make target - if not makefile._make_target(file, name, target) then - -- error - utils.error("failed to make target %s to makefile!", name) - return false - end - - -- append the target name to all - all = all .. " " .. name - end - - -- ok - return true -end - --- make makefile in the build directory -function makefile.make() - - -- get the build directory - local buildir = config.get("buildir") - assert(buildir) - - -- init the log file - local logfile = rule.logfile() - if logfile and os.isfile(logfile) then - os.rmfile(logfile) - end - - -- save the log file - makefile._LOGFILE = logfile - assert(logfile) - - -- open the makefile - local path = rule.makefile() - local file = io.openmk(path) - if not file then - -- error - utils.error("open %s failed!", path) - return false - end - - -- make all targets to the makefile - if not makefile._make_targets(file) then - - -- error - utils.error("save %s failed!", path) - - -- close the makefile - file:close() - - -- remove the makefile - os.rm(path) - - -- failed - return false - end - - -- close the makefile - file:close() - - -- ok - return true -end - --- build target -function makefile.build(target) - - -- check - assert(target and type(target) == "string") - - -- load make - local make = tools.get("make") - if not make then - utils.error("not found the make command!") - return false - end - - -- done make - return make:main(rule.makefile(), target) -end - --- return module: makefile -return makefile diff --git a/xmake/scripts/base/option.lua b/xmake/scripts/base/option.lua deleted file mode 100644 index 1c8c35573..000000000 --- a/xmake/scripts/base/option.lua +++ /dev/null @@ -1,650 +0,0 @@ ---!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) 2009 - 2015, ruki All rights reserved. --- --- @author ruki --- @file option.lua --- - --- define module: option -local option = option or {} - --- load modules -local utils = require("base/utils") -local table = require("base/table") - --- save the option menu -function option._save_menu(menu) - - -- translate the action menus if exists function - local submenus_all = {} - for k, submenu in pairs(menu) do - if type(submenu) == "function" then - local _submenus = submenu() - if _submenus then - for k, m in pairs(_submenus) do - submenus_all[k] = m - end - end - else - submenus_all[k] = submenu - end - end - table.copy2(menu, submenus_all) - - -- translate the actions of the main menu if exists function - if menu.main and type(menu.main.actions) == "function" then - menu.main.actions = menu.main.actions() - end - - -- translate it if exists function in the option menu - for _, submenu in pairs(menu) do - - -- exits options? - if submenu.options then - - -- translate options - local options_all = {} - for _, option in ipairs(submenu.options) do - - -- this option is function? translate it - if type(option) == "function" then - local _options = option() - if _options then - for _, o in ipairs(_options) do - table.insert(options_all, o) - end - end - else - table.insert(options_all, option) - end - end - - -- update the options - submenu.options = options_all - end - end - - -- save menu - option._MENU = menu - -end - --- init the option -function option.init(argv, menu) - - -- check - assert(argv and menu) - - -- the main menu - local main = menu.main - assert(main) - - -- init _OPTIONS - xmake._OPTIONS = {} - xmake._OPTIONS._DEFAULTS = {} - - -- save menu - option._save_menu(menu) - - -- parse _ARGV to _OPTIONS - local _iter, _s, _k = ipairs(argv) - while true do - - -- the idx and arg - local idx, arg = _iter(_s, _k) - - -- end? - _k = idx - if idx == nil then break end - - -- parse key and value - local key, value - local i = arg:find("=", 1, true) - - -- key=value? - if i then - key = arg:sub(1, i - 1) - value = arg:sub(i + 1) - -- only key? - else - key = arg - value = true - end - - -- --key? - local prefix = 0 - if key:startswith("--") then - key = key:sub(3) - prefix = 2 - -- -k? - elseif key:startswith("-") then - key = key:sub(2) - prefix = 1 - end - - -- check key - if prefix and #key == 0 then - - -- invalid option - print("invalid option: " .. arg) - - -- print menu - option.print_menu(xmake._OPTIONS._ACTION) - - -- failed - return false - end - - -- --key=value or -k value or -k? - if prefix ~= 0 then - - -- find this option - local opt = nil - for _, o in ipairs(menu[xmake._OPTIONS._ACTION or "main"].options) do - - -- check - assert(o) - - -- --key? - if prefix == 2 and key == o[2] then - opt = o - break - -- k? - elseif prefix == 1 and key == o[1] then - opt = o - break - end - end - - -- not found? - if not opt then - - -- invalid option - print("invalid option: " .. arg) - - -- print menu - option.print_menu(xmake._OPTIONS._ACTION) - - -- failed - return false - end - - -- -k value? continue to get the value - if prefix == 1 and opt[3] == "kv" then - - -- get the next idx and arg - idx, arg = _iter(_s, _k) - - -- exists value? - _k = idx - if idx == nil or arg:startswith("-") then - - -- invalid option - print("invalid option: " .. utils.ifelse(idx, arg, key)) - - -- print menu - option.print_menu(xmake._OPTIONS._ACTION) - - -- failed - return false - end - - -- get value - value = arg - end - - -- check mode - if (opt[3] == "k" and type(value) ~= "boolean") or (opt[3] == "kv" and type(value) ~= "string") then - - -- invalid option - print("invalid option: " .. arg) - - -- print menu - option.print_menu(xmake._OPTIONS._ACTION) - - -- failed - return false - end - - -- value is "true" or "false", translate it - if type(value) == "string" then - if value == "true" then value = true - elseif value == "false" then value = false - end - end - - -- save option - xmake._OPTIONS[utils.ifelse(prefix == 1 and opt[2], opt[2], key)] = value - - -- action? - elseif idx == 1 then - - -- find this action - for _, action in ipairs(main.actions) do - - -- check - assert(menu[action]) - - -- ok? - if action == key or menu[action].shortname == key then - -- save this action - xmake._OPTIONS._ACTION = action - break - end - end - - -- not found? - if not xmake._OPTIONS._ACTION or not menu[xmake._OPTIONS._ACTION] then - - -- invalid action - print("invalid action: " .. key) - - -- print the main menu - option.print_main() - - -- failed - return false - - end - - -- value? - else - - -- find a value option with name - local opt = nil - for _, o in ipairs(menu[xmake._OPTIONS._ACTION or "main"].options) do - - -- the mode - local mode = o[3] - - -- the name - local name = o[2] - - -- check - assert(o and ((mode ~= "v" and mode ~= "vs") or name)) - - -- is value and with name? - if mode == "v" and name and not xmake._OPTIONS[name] then - opt = o - break - -- is values and with name? - elseif mode == "vs" and name then - opt = o - break - end - end - - -- ok? save this value with name opt[2] - if opt then - - -- the mode - local mode = opt[3] - - -- the name - local name = opt[2] - - -- save value - if mode == "v" then - xmake._OPTIONS[name] = key - elseif mode == "vs" then - -- the option - local o = xmake._OPTIONS[name] - if not o then - xmake._OPTIONS[name] = {} - o = xmake._OPTIONS[name] - end - - -- append value - table.insert(o, key) - end - else - -- invalid option - print("invalid option: " .. arg) - - -- print menu - option.print_menu(xmake._OPTIONS._ACTION) - - -- failed - return false - end - - end - end - - -- init the default value - for _, o in ipairs(menu[xmake._OPTIONS._ACTION or "main"].options) do - - -- key=value? - if o[3] == "kv" then - - -- the key - local key = o[2] or o[1] - assert(key) - - -- save the default value - xmake._OPTIONS._DEFAULTS[key] = o[4] - -- value with name? - elseif o[3] == "v" and o[2] then - -- save the default value - xmake._OPTIONS._DEFAULTS[o[2]] = o[4] - end - end - - -- ok - return true -end - --- find the value of a given name from the arguments --- only for kv mode and need not check it using menu --- -function option.find(argv, name, shortname) - - -- check - assert(argv and (name or shortname)) - - -- find it - local nextvalue = false - for _, arg in ipairs(argv) do - - -- get this value - if nextvalue then return arg end - - -- --name=value? - if name and arg:startswith("--" .. name) then - - -- get value - local i = arg:find("=", 1, true) - if i then return arg:sub(i + 1) end - - -- -shortname value? - elseif shortname and arg:startswith("-" .. shortname) then - - -- get value - nextvalue = true - end - - end -end - --- get all default options from the given action -function option.defaults(action) - - -- make defaults - local defaults = {} - - -- init the default value - for _, o in ipairs(option._MENU[action or "main"].options) do - - -- key=value? - if o[3] == "kv" then - - -- the key - local key = o[2] or o[1] - assert(key) - - -- save the default value - defaults[key] = o[4] - -- value with name? - elseif o[3] == "v" and o[2] then - -- save the default value - defaults[o[2]] = o[4] - end - end - - -- ok? - return defaults -end - --- print the menu -function option.print_menu(action) - - -- no action? print main menu - if not action then - option.print_main() - return - end - - -- the menu - local menu = option._MENU - assert(menu) - - -- the action - action = menu[action] - assert(action) - - -- print title - if menu.title then - print(menu.title) - end - - -- print copyright - if menu.copyright then - print(menu.copyright) - end - - -- print usage - if action.usage then - print("") - print("Usage: " .. action.usage) - end - - -- print description - if action.description then - print("") - print(action.description) - end - - -- print options - if action.options then - option.print_options(action.options) - end -end - --- print the main menu -function option.print_main() - - -- the menu - local menu = option._MENU - assert(menu) - - -- the main menu - local main = menu.main - assert(main) - - -- print title - if menu.title then - print(menu.title) - end - - -- print copyright - if menu.copyright then - print(menu.copyright) - end - - -- print usage - if main.usage then - print("") - print("Usage: " .. main.usage) - end - - -- print description - if main.description then - print("") - print(main.description) - end - - -- print actions - if main.actions then - - -- print header - print("") - print("Actions: ") - - -- the padding spaces - local padding = 42 - - -- print actions - for _, action in ipairs(main.actions) do - - -- the action menu - local action_menu = menu[action] - - -- init the action info - local action_info = " " - if action_menu and action_menu.shortname then - action_info = action_info .. action_menu.shortname .. ", " - else - action_info = action_info .. " " - end - - -- append the action - action_info = action_info .. action - - if action_menu then - -- append spaces - for i = (#action_info), padding do - action_info = action_info .. " " - end - - -- append the action description - if action_menu.description then - action_info = action_info .. action_menu.description - end - end - - -- print action info - print(action_info) - end - end - - -- print options - if main.options then - option.print_options(main.options) - end -end - --- print the options menu -function option.print_options(options) - - -- check - assert(options) - - -- print header - print("") - print("Options: ") - - -- the padding spaces - local padding = 42 - - -- print options - for _, option in ipairs(options) do - - -- init the option info - local option_info = "" - - -- append the shortname - local shortname = option[1]; - local name = option[2]; - local mode = option[3]; - if shortname then - option_info = option_info .. " -" .. shortname - if mode == "kv" then - option_info = option_info .. " " .. utils.ifelse(name, name:upper(), "XXX") - end - end - - -- append the name - if name then - if mode == "v" then - option_info = option_info .. " " .. name - else - option_info = option_info .. utils.ifelse(shortname, ", --", " --") .. name - end - if mode == "kv" then - option_info = option_info .. "=" .. name:upper() - end - elseif mode == "v" then - option_info = option_info .. " ..." - end - - -- append spaces - for i = (#option_info), padding do - option_info = option_info .. " " - end - - -- append the option description - local description = option[5] - if description then - option_info = option_info .. description - end - - -- append the default value - local default = option[4] - if default then - option_info = option_info .. " (default: " .. tostring(default) .. ")" - end - - -- print option info - print(option_info) - - -- print more description if exists - for i = 6, 64 do - - -- the description, @note some option may be nil - local description = option[i] - if not description then break end - - -- is function? get results - if type(description) == "function" then - description = description() - end - - -- the description is string? - if type(description) == "string" then - - -- make spaces - local spaces = "" - for i = 0, padding do - spaces = spaces .. " " - end - - -- print this description - print(spaces .. description) - - -- the description is table? - elseif type(description) == "table" then - - -- print all descriptions - for _, v in pairs(description) do - - -- make spaces - local spaces = "" - for i = 0, padding do - spaces = spaces .. " " - end - - -- print this description - print(spaces .. v) - end - end - end - end -end - --- return module: option -return option diff --git a/xmake/scripts/base/os.lua b/xmake/scripts/base/os.lua deleted file mode 100644 index b08ac3820..000000000 --- a/xmake/scripts/base/os.lua +++ /dev/null @@ -1,237 +0,0 @@ ---!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) 2009 - 2015, ruki All rights reserved. --- --- @author ruki --- @file os.lua --- - --- define module: os -local os = os or {} - --- load modules -local path = require("base/path") -local utils = require("base/utils") -local string = require("base/string") - --- match files or directories --- --- @param pattern the search pattern --- uses "*" to match any part of a file or directory name, --- uses "**" to recurse into subdirectories. --- --- @param findir true: find directory, false: find file --- @return the result array and count --- --- @code --- local dirs, count = os.match("./src/*", true) --- local files, count = os.match("./src/**.c") --- local file = os.match("./src/test.c") --- @endcode --- -function os.match(pattern, findir) - - -- get the excludes - local excludes = pattern:match("|.*$") - if excludes then excludes = excludes:split("|") end - - -- translate excludes - if excludes then - local _excludes = {} - for _, exclude in ipairs(excludes) do - exclude = path.translate(exclude) - exclude = exclude:gsub("([%+%.%-%^%$%(%)%%])", "%%%1") - exclude = exclude:gsub("%*%*", "\001") - exclude = exclude:gsub("%*", "\002") - exclude = exclude:gsub("\001", ".*") - exclude = exclude:gsub("\002", "[^/]*") - table.insert(_excludes, exclude) - end - excludes = _excludes - end - - -- translate path and remove some repeat separators - pattern = path.translate(pattern:gsub("|.*$", "")) - - -- get the root directory - local rootdir = pattern - local starpos = pattern:find("%*") - if starpos then - rootdir = rootdir:sub(1, starpos - 1) - end - rootdir = path.directory(rootdir) - - -- is recurse? - local recurse = pattern:find("**", nil, true) - - -- convert pattern to a lua pattern - pattern = pattern:gsub("([%+%.%-%^%$%(%)%%])", "%%%1") - pattern = pattern:gsub("%*%*", "\001") - pattern = pattern:gsub("%*", "\002") - pattern = pattern:gsub("\001", ".*") - pattern = pattern:gsub("\002", "[^/]*") - - -- patch "./" for matching ok if root directory is '.' - if rootdir == '.' then - pattern = "./" .. pattern - end - - -- find it - return os.find(rootdir, pattern, recurse, findir, excludes) -end - --- copy file or directory -function os.cp(src, dst) - - -- check - assert(src and dst) - - -- is file? - if os.isfile(src) then - - -- the destination is directory? append the filename - if os.isdir(dst) then - dst = string.format("%s/%s", dst, path.filename(src)) - end - - -- copy file - if not os.cpfile(src, dst) then - return false, string.format("cannot copy file %s to %s %s", src, dst, os.strerror()) - end - -- is directory? - elseif os.isdir(src) then - -- copy directory - if not os.cpdir(src, dst) then - return false, string.format("cannot copy directory %s to %s %s", src, dst, os.strerror()) - end - -- cp dir/*? - elseif src:find("%*") then - - -- get the root directory - local starpos = src:find("%*") - - -- match all files - local files = os.match((src:gsub("%*+", "**"))) - if files then - for _, file in ipairs(files) do - local dstfile = string.format("%s/%s", dst, file:sub(starpos)) - if not os.cpfile(file, dstfile) then - return false, string.format("cannot copy file %s to %s %s", file, dstfile, os.strerror()) - end - end - end - - -- not exists? - else - return false, string.format("cannot copy file %s, not found this file %s", src, os.strerror()) - end - - -- ok - return true -end - --- move file or directory -function os.mv(src, dst) - - -- check - assert(src and dst) - - -- exists file or directory? - if os.exists(src) then - -- move file or directory - if not os.rename(src, dst) then - return false, string.format("cannot move %s to %s %s", src, dst, os.strerror()) - end - -- not exists? - else - return false, string.format("cannot move %s to %s, not found this file %s", src, dst, os.strerror()) - end - - -- ok - return true -end - --- remove file or directory -function os.rm(file_or_dir, emptydir) - - -- check - assert(file_or_dir) - - -- is file? - if os.isfile(file_or_dir) then - -- remove file - if not os.rmfile(file_or_dir) then - return false, string.format("cannot remove file %s %s", file_or_dir, os.strerror()) - end - -- is directory? - elseif os.isdir(file_or_dir) then - -- remove directory - if not os.rmdir(file_or_dir, emptydir) then - return false, string.format("cannot remove directory %s %s", file_or_dir, os.strerror()) - end - -- not exists? - else - return false, string.format("cannot remove file %s, not found this file %s", file_or_dir, os.strerror()) - end - - -- ok - return true -end - --- change to directory -function os.cd(dir) - - -- check - assert(dir) - - -- change to the previous directory? - if dir == "-" then - -- exists the previous directory? - if os._PREDIR then - dir = os._PREDIR - os._PREDIR = nil - else - -- error - return false, string.format("not found the previous directory %s", os.strerror()) - end - end - - -- is directory? - if os.isdir(dir) then - - -- get the current directory - local current = os.curdir() - - -- change to directory - if not os.chdir(dir) then - return false, string.format("cannot change directory %s %s", dir, os.strerror()) - end - - -- save the previous directory - os._PREDIR = current - - -- not exists? - else - return false, string.format("cannot change directory %s, not found this directory %s", dir, os.strerror()) - end - - -- ok - return true -end - --- return module: os -return os diff --git a/xmake/scripts/base/package.lua b/xmake/scripts/base/package.lua deleted file mode 100644 index ffb1a0d38..000000000 --- a/xmake/scripts/base/package.lua +++ /dev/null @@ -1,314 +0,0 @@ ---!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) 2009 - 2015, ruki All rights reserved. --- --- @author ruki --- @file package.lua --- - --- define module: package -local package = package or {} - --- load modules -local os = require("base/os") -local io = require("base/io") -local rule = require("base/rule") -local path = require("base/path") -local utils = require("base/utils") -local config = require("base/config") -local platform = require("platform/platform") - --- package target for the library file -function package._done_library(target) - - -- check - assert(target and target.name and target.archs) - - -- the output directory - local outputdir = target.outputdir - assert(outputdir) - - -- the plat and mode - local plat = config.get("plat") - local mode = config.get("mode") - assert(plat and mode) - - -- package it - for arch, info in pairs(target.archs) do - - -- check - assert(info.targetdir and info.targetfile) - - -- copy the library file to the output directory - local ok, errors = os.cp(string.format("%s/%s", info.targetdir, info.targetfile), string.format("%s/%s.pkg/lib/%s/%s/%s/%s", outputdir, target.name, mode, plat, arch, path.filename(info.targetfile))) - if not ok then - utils.error(errors) - return -1 - end - - -- copy the config.h to the output directory - if info.config_h then - local ok, errors = os.cp(string.format("%s/%s", info.targetdir, info.config_h), string.format("%s/%s.pkg/inc/%s/%s", outputdir, target.name, plat, path.filename(info.config_h))) - if not ok then - utils.error(errors) - return -1 - end - end - end - - -- copy headers - if target.headers then - local srcheaders, dstheaders = rule.headerfiles(target, string.format("%s/%s.pkg/inc", outputdir, target.name)) - if srcheaders and dstheaders then - local i = 1 - for _, srcheader in ipairs(srcheaders) do - local dstheader = dstheaders[i] - if dstheader then - local ok, errors = os.cp(srcheader, dstheader) - if not ok then - utils.error(errors) - return -1 - end - end - i = i + 1 - end - end - end - - -- make xmake.lua - local file = io.open(string.format("%s/%s.pkg/xmake.lua", outputdir, target.name), "w") - if file then - - -- the xmake.lua template content - local template = [[ --- add [targetname] package -add_option("[targetname]") - - -- show menu - set_option_showmenu(true) - - -- set category - set_option_category("package") - - -- set description - set_option_description("The [targetname] package") - - -- set language: c99, c++11 - set_option_languages("c99", "cxx11") - - -- add defines to config.h if checking ok - add_option_defines_h_if_ok("$(prefix)_PACKAGE_HAVE_[TARGETNAME]") - - -- add links for checking - add_option_links("[targetname]") - - -- add link directories - add_option_linkdirs("lib/$(mode)/$(plat)/$(arch)") - - -- add c includes for checking - add_option_cincludes("[targetname]/[targetname].h") - - -- add include directories - add_option_includedirs("inc/$(plat)", "inc") -]] - - -- save file - file:write((template:gsub("%[targetname%]", target.name):gsub("%[TARGETNAME%]", target.name:upper()))) - - -- exit file - file:close() - end - - -- ok - return 1 -end - --- package target for the binary file -function package._done_binary(target) - - -- check - assert(target and target.archs) - - -- the output directory - local outputdir = target.outputdir - assert(outputdir) - - -- the count of architectures - local count = 0 - for _, _ in pairs(target.archs) do count = count + 1 end - - -- package it - local ok = nil - local errors = nil - for arch, info in pairs(target.archs) do - - -- check - assert(info.targetdir and info.targetfile) - - -- copy the binary file to the output directory - if count == 1 then - ok, errors = os.cp(string.format("%s/%s", info.targetdir, info.targetfile), string.format("%s/%s", outputdir, path.filename(info.targetfile))) - else - ok, errors = os.cp(string.format("%s/%s", info.targetdir, info.targetfile), string.format("%s/%s", outputdir, rule.filename(path.basename(info.targetfile) .. "_" .. arch, "binary"))) - end - - -- ok? - if not ok then - utils.error(errors) - return -1 - end - end - - -- ok - return 1 -end - --- package target from the default script -function package._done_from_default(target) - - -- check - assert(target.kind) - - -- the package scripts - local packagescripts = - { - static = package._done_library - , shared = package._done_library - , binary = package._done_binary - } - - -- package it - local packagescript = packagescripts[target.kind] - if packagescript then return packagescript(target) end - - -- continue - return 0 -end - --- package target from the project script -function package._done_from_project(target) - - -- check - assert(target) - - -- package it using the project script first - local packagescript = target.packagescript - if type(packagescript) == "function" then - - -- remove it - target.packagescript = nil - - -- package it - return packagescript(target) - end - - -- continue - return 0 -end - --- package target from the platform script -function package._done_from_platform(target) - - -- check - assert(target) - - -- the platform package script file - local packagescript = nil - local scriptfile = platform.directory() .. "/package.lua" - if os.isfile(scriptfile) then - - -- load the package script - local script, errors = loadfile(scriptfile) - if script then - packagescript = script() - if type(packagescript) == "table" and packagescript.main then - packagescript = packagescript.main - end - else - utils.error(errors) - end - end - - -- package it - if type(packagescript) == "function" then - return packagescript(target) - end - - -- continue - return 0 -end - --- get the configure file -function package._file() - - -- get it - return config.directory() .. "/package.conf" -end - --- package target from the given target configure -function package._done(target) - - -- check - assert(target) - - -- package it from the project script - local ok = package._done_from_project(target) - if ok ~= 0 then return utils.ifelse(ok == 1, true, false) end - - -- package it from the platform script - local ok = package._done_from_platform(target) - if ok ~= 0 then return utils.ifelse(ok == 1, true, false) end - - -- package it from the default script - local ok = package._done_from_default(target) - if ok ~= 0 then return utils.ifelse(ok == 1, true, false) end - - -- ok - return true -end - --- done package from the configure -function package.done(configs) - - -- check - assert(configs) - - -- package targets - for _, target in pairs(configs) do - - -- package it - if not package._done(target) then - -- errors - utils.error("package %s failed!", target.name) - return false - end - - end - - -- save to the configure file - return io.save(package._file(), configs) -end - --- load the package configure -function package.load() - - -- load it - return io.load(package._file()) -end - --- return module: package -return package diff --git a/xmake/scripts/base/path.lua b/xmake/scripts/base/path.lua deleted file mode 100644 index eb35283b2..000000000 --- a/xmake/scripts/base/path.lua +++ /dev/null @@ -1,72 +0,0 @@ ---!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) 2009 - 2015, ruki All rights reserved. --- --- @author ruki --- @file path.lua --- - --- define module: path -local path = path or {} - --- load modules -local string = require("base/string") - --- get the directory of the path -function path.directory(p) - local i = p:find_last("[/\\]") - if i then - if i > 1 then i = i - 1 end - return p:sub(1, i) - else - return "." - end -end - --- get the filename of the path -function path.filename(p) - local i = p:find_last("[/\\]") - if i then - return p:sub(i + 1) - else - return p - end -end - --- get the basename of the path -function path.basename(p) - local name = path.filename(p) - local i = name:find_last(".", true) - if i then - return name:sub(1, i - 1) - else - return name - end -end - --- get the file extension of the path: .xxx -function path.extension(p) - local i = p:find_last(".", true) - if i then - return p:sub(i) - else - return "" - end -end - --- return module: path -return path diff --git a/xmake/scripts/base/project.lua b/xmake/scripts/base/project.lua deleted file mode 100644 index abc7897d4..000000000 --- a/xmake/scripts/base/project.lua +++ /dev/null @@ -1,1469 +0,0 @@ ---!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) 2009 - 2015, ruki All rights reserved. --- --- @author ruki --- @file project.lua --- - --- define module: project -local project = project or {} - --- load modules -local os = require("base/os") -local io = require("base/io") -local rule = require("base/rule") -local path = require("base/path") -local utils = require("base/utils") -local table = require("base/table") -local config = require("base/config") -local linker = require("base/linker") -local compiler = require("base/compiler") -local platform = require("platform/platform") - --- import module -function project._api_import(env, module) - - -- import - return require("module/" .. module) -end - --- the current os is belong to the given os? -function project._api_os(env, ...) - - -- get the current os - local os = platform.os() - if not os then return false end - - -- exists this os? - for _, o in ipairs(table.join(...)) do - if o and type(o) == "string" and o == os then - return true - end - end -end - --- the current mode is belong to the given modes? -function project._api_modes(env, ...) - - -- get the current mode - local mode = config.get("mode") - if not mode then return false end - - -- exists this mode? - for _, m in ipairs(table.join(...)) do - if m and type(m) == "string" and m == mode then - return true - end - end -end - --- the current platform is belong to the given platforms? -function project._api_plats(env, ...) - - -- get the current platform - local plat = config.get("plat") - if not plat then return false end - - -- exists this platform? and escape '-' - for _, p in ipairs(table.join(...)) do - if p and type(p) == "string" and plat:find(p:gsub("%-", "%%-")) then - return true - end - end -end - --- the current platform is belong to the given architectures? -function project._api_archs(env, ...) - - -- get the current architecture - local arch = config.get("arch") - if not arch then return false end - - -- exists this architecture? and escape '-' - for _, a in ipairs(table.join(...)) do - if a and type(a) == "string" and arch:find(a:gsub("%-", "%%-")) then - return true - end - end -end - --- the current kind is belong to the given kinds? -function project._api_kind(env, ...) - - -- get the current kind - local kind = config.get("kind") - if not kind then return false end - - -- exists this kind? - for _, k in ipairs(table.join(...)) do - if k and type(k) == "string" and k == kind then - return true - end - end -end - --- enable options? -function project._api_options(env, ...) - - -- some options are enabled? - for _, o in ipairs(table.join(...)) do - if o and type(o) == "string" and config.get(o) then - return true - end - end -end - --- get all pathes and translate it -function project._api_get_pathes(...) - - -- check - assert(project._CURDIR) - - -- get all pathes - local pathes = table.join(...) - - -- translate the relative path - local results = {} - for _, p in ipairs(pathes) do - if not p:find("^%s-%$%(.-%)") and not path.is_absolute(p) then - table.insert(results, path.relative(path.absolute(p, project._CURDIR), project._PROJECT_DIR)) - else - table.insert(results, p) - end - end - - -- ok? - return results -end - --- add c function -function project._api_add_cfunc(env, module, alias, links, includes, cfunc) - - -- check - assert(env and cfunc) - - -- make the option name - local name = nil - if module ~= nil then - name = string.format("__%s_%s", module, cfunc) - else - name = string.format("__%s", cfunc) - end - - -- make the option define - local define = nil - if module ~= nil then - define = string.format("$(prefix)_%s_HAVE_%s", module:upper(), utils.ifelse(alias, alias, cfunc:upper())) - else - define = string.format("$(prefix)_HAVE_%s", utils.ifelse(alias, alias, cfunc:upper())) - end - - -- make option - env.add_option(name) - env.set_option_category("cfuncs") - env.add_option_cfuncs(cfunc) - if links then env.add_option_links(links) end - if includes then env.add_option_cincludes(includes) end - env.add_option_defines_h_if_ok(define) - - -- add this option - env.add_options(name) -end - --- add c functions -function project._api_add_cfuncs(env, module, links, includes, ...) - - -- check - assert(env) - - -- done - for _, cfunc in ipairs({...}) do - - -- check - assert(cfunc) - - -- make the option name - local name = nil - if module ~= nil then - name = string.format("__%s_%s", module, cfunc) - else - name = string.format("__%s", cfunc) - end - - -- make the option define - local define = nil - if module ~= nil then - define = string.format("$(prefix)_%s_HAVE_%s", module:upper(), cfunc:upper()) - else - define = string.format("$(prefix)_HAVE_%s", cfunc:upper()) - end - - -- make option - env.add_option(name) - env.set_option_category("cfuncs") - env.add_option_cfuncs(cfunc) - if links then env.add_option_links(links) end - if includes then env.add_option_cincludes(includes) end - env.add_option_defines_h_if_ok(define) - - -- add this option - env.add_options(name) - end -end - --- add c++ function -function project._api_add_cxxfunc(env, module, alias, links, includes, cxxfunc) - - -- check - assert(env and cxxfunc) - - -- make the option name - local name = nil - if module ~= nil then - name = string.format("__%s_%s", module, cxxfunc) - else - name = string.format("__%s", cxxfunc) - end - - -- make the option define - local define = nil - if module ~= nil then - define = string.format("$(prefix)_%s_HAVE_%s", module:upper(), utils.ifelse(alias, alias, cxxfunc:upper())) - else - define = string.format("$(prefix)_HAVE_%s", utils.ifelse(alias, alias, cxxfunc:upper())) - end - - -- make option - env.add_option(name) - env.set_option_category("cxxfuncs") - env.add_option_cxxfuncs(cxxfunc) - if links then env.add_option_links(links) end - if includes then env.add_option_cxxincludes(includes) end - env.add_option_defines_h_if_ok(define) - - -- add this option - env.add_options(name) -end - --- add c++ functions -function project._api_add_cxxfuncs(env, module, links, includes, ...) - - -- check - assert(env and module) - - -- done - for _, cxxfunc in ipairs({...}) do - - -- check - assert(cxxfunc) - - -- make the option name - local name = nil - if module ~= nil then - name = string.format("__%s_%s", module, cxxfunc) - else - name = string.format("__%s", cxxfunc) - end - - -- make the option define - local define = nil - if module ~= nil then - define = string.format("$(prefix)_%s_HAVE_%s", module:upper(), cxxfunc:upper()) - else - define = string.format("$(prefix)_HAVE_%s", cxxfunc:upper()) - end - - -- make option - env.add_option(name) - env.set_option_category("cxxfuncs") - env.add_option_cxxfuncs(cxxfunc) - if links then env.add_option_links(links) end - if includes then env.add_option_cxxincludes(includes) end - env.add_option_defines_h_if_ok(define) - - -- add this option - env.add_options(name) - end -end - --- add target -function project._api_add_target(env, name) - - -- check - assert(env and name) - - -- the targets - local targets = env._CONFIGS._TARGETS - assert(targets) - - -- init the target scope - targets[name] = targets[name] or {} - - -- switch to this target scope - env._TARGET = targets[name] -end - --- add option -function project._api_add_option(env, name) - - -- check - assert(env and name) - - -- the options - local options = env._CONFIGS._OPTIONS - assert(options) - - -- init the option scope - options[name] = options[name] or {} - - -- switch to this option scope - env._OPTION = options[name] -end - --- load all subprojects from the given directories -function project._api_add_subdirs(env, ...) - - -- check - assert(env) - - -- init mtime for files - project._MTIMES = project._MTIMES or {} - - -- save the current project file directory - local curdir = project._CURDIR - - -- get all subdirs - local subdirs = project._api_get_pathes(...) - - -- match all subdirs - local subdirs_matched = {} - for _, subdir in ipairs(subdirs) do - local dirs = os.match(subdir, true) - if dirs then table.join2(subdirs_matched, dirs) end - end - - -- done - for _, subdir in ipairs(subdirs_matched) do - if subdir and type(subdir) == "string" then - - -- the project file - local file = subdir .. "/xmake.lua" - if not path.is_absolute(file) then - file = path.absolute(file, xmake._PROJECT_DIR) - end - - -- update the current project file directory - project._CURDIR = path.directory(file) - - -- load the project script - local script = loadfile(file) - if script then - - -- bind environment - setfenv(script, env) - - -- done the project script - local ok, errors = pcall(script) - if not ok then - utils.error(errors) - assert(false) - end - - -- get mtime of the file - project._MTIMES[path.relative(file, xmake._PROJECT_DIR)] = os.mtime(file) - end - end - end - - -- restore the current project file directory - project._CURDIR = curdir - -end - --- load all subprojects from the given files -function project._api_add_subfiles(env, ...) - - -- check - assert(env) - - -- init mtime for files - project._MTIMES = project._MTIMES or {} - - -- save the current project file directory - local curdir = project._CURDIR - - -- get all subfiles - local subfiles = project._api_get_pathes(...) - - -- match all subfiles - local subfiles_matched = {} - for _, subfile in ipairs(subfiles) do - local files = os.match(subfile) - if files then table.join2(subfiles_matched, files) end - end - - -- done - for _, file in ipairs(subfiles_matched) do - if file and type(file) == "string" then - - -- the project file - if not path.is_absolute(file) then - file = path.absolute(file, xmake._PROJECT_DIR) - end - - -- update the current project file directory - project._CURDIR = path.directory(file) - - -- load the project script - local script = loadfile(file) - if script then - - -- bind environment - setfenv(script, env) - - -- done the project script - local ok, errors = pcall(script) - if not ok then - utils.error(errors) - assert(false) - end - - -- get mtime of the file - project._MTIMES[path.relative(file, xmake._PROJECT_DIR)] = os.mtime(file) - end - end - end - - -- restore the current project file directory - project._CURDIR = curdir -end - --- load all packages from the given directories -function project._api_add_pkgdirs(env, ...) - - -- get all directories - local pkgdirs = {} - local dirs = table.join(...) - for _, dir in ipairs(dirs) do - table.insert(pkgdirs, dir .. "/*.pkg") - end - - -- add all packages - project._api_add_subdirs(env, pkgdirs) -end - --- set configure values -function project._api_set_values(scope, name, ...) - - -- check - assert(scope and name) - - -- update values - scope[name] = {} - table.join2(scope[name], ...) -end - --- add configure values -function project._api_add_values(scope, name, ...) - - -- check - assert(scope and name) - - -- append values - scope[name] = scope[name] or {} - table.join2(scope[name], ...) -end - --- set configure pathes -function project._api_set_pathes(scope, name, ...) - - -- check - assert(scope and name) - - -- update pathes - scope[name] = {} - table.join2(scope[name], project._api_get_pathes(...)) -end - --- add configure pathes -function project._api_add_pathes(scope, name, ...) - - -- check - assert(scope and name) - - -- append pathes - scope[name] = scope[name] or {} - table.join2(scope[name], project._api_get_pathes(...)) -end - --- filter the configure value -function project._filter(values) - - -- check - assert(values) - - -- filter all - local newvals = {} - for _, v in ipairs(utils.wrap(values)) do - if type(v) == "string" then - v = v:gsub("%$%((.-)%)", function (w) - - -- is upper? - local isupper = false - local c = string.char(w:byte()) - if c >= 'A' and c <= 'Z' then isupper = true end - - -- attempt to get it directly from the configure - local r = config.get(w) - if not r or type(r) ~= "string" then - - -- attempt to get it from the configure and the lower key - w = w:lower() - r = config.get(w) - if not r or type(r) ~= "string" then - - -- get the other keys - if w == "projectdir" then r = xmake._PROJECT_DIR - elseif w == "os" then r = platform.os() - end - end - end - - -- upper? - if r and type(r) == "string" and isupper then - r = r:upper() - end - - -- ok? - return r - end) - end - table.insert(newvals, v) - end - - -- ok? - return newvals -end - --- make configure for the given target_name -function project._makeconf_for_target(target_name, target) - - -- check - assert(target_name and target) - - -- get the target configure file - local config_h = target.config_h - if not config_h then - return true - end - - -- translate file path - if not path.is_absolute(config_h) then - config_h = path.absolute(config_h, xmake._PROJECT_DIR) - else - config_h = path.translate(config_h) - end - - -- the prefix - local prefix = target.config_h_prefix or (target_name:upper() .. "_CONFIG") - - -- open the file - local file = project._CONFILES[config_h] or io.openmk(config_h) - assert(file) - - -- make the head - if project._CONFILES[config_h] then file:write("\n") end - file:write(string.format("#ifndef %s_H\n", prefix)) - file:write(string.format("#define %s_H\n", prefix)) - file:write("\n") - - -- make version - if target.version then - file:write("// version\n") - file:write(string.format("#define %s_VERSION \"%s\"\n", prefix, target.version)) - local i = 1 - local m = {"MAJOR", "MINOR", "ALTER"} - for v in target.version:gmatch("%d+") do - file:write(string.format("#define %s_VERSION_%s %s\n", prefix, m[i], v)) - i = i + 1 - if i > 3 then break end - end - file:write(string.format("#define %s_VERSION_BUILD %s\n", prefix, os.date("%Y%m%d%H%M", os.time()))) - file:write("\n") - end - - -- make the defines - local defines = {} - if target.defines_h then table.join2(defines, target.defines_h) end - - -- make the undefines - local undefines = {} - if target.undefines_h then table.join2(undefines, target.undefines_h) end - - -- the options - if target.options then - for _, name in ipairs(utils.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 - - -- get the option defines - if opt.defines_h_if_ok then table.join2(defines, opt.defines_h_if_ok) end - - -- get the option undefines - if opt.undefines_h_if_ok then table.join2(undefines, opt.undefines_h_if_ok) end - - end - end - end - - -- make the defines - if #defines ~= 0 then - file:write("// defines\n") - for _, define in ipairs(defines) do - file:write(string.format("#define %s 1\n", define:gsub("=", " "):gsub("%$%((.-)%)", function (w) if w == "prefix" then return prefix end end))) - end - file:write("\n") - end - - -- make the undefines - if #undefines ~= 0 then - file:write("// undefines\n") - for _, undefine in ipairs(undefines) do - file:write(string.format("#undef %s\n", undefine:gsub("%$%((.-)%)", function (w) if w == "prefix" then return prefix end end))) - end - file:write("\n") - end - - -- make the tail - file:write("#endif\n") - - -- cache the file - project._CONFILES[config_h] = file - - -- ok - return true -end - --- make the configure file for the given target and dependents -function project._makeconf_for_target_and_deps(target_name) - - -- the targets - local targets = project.targets() - assert(targets) - - -- the target - local target = targets[target_name] - assert(target) - - -- make configure for the target - if not project._makeconf_for_target(target_name, target) then - return false - end - - -- exists the dependent targets? - if target.deps then - local deps = utils.wrap(target.deps) - for _, dep in ipairs(deps) do - if not project._makeconf_for_target_and_deps(dep) then return false end - end - end - - -- ok - return true -end - --- make targets from the project file -function project._make_targets(configs) - - -- check - assert(configs and configs._TARGETS) - - -- init - project._TARGETS = project._TARGETS or {} - local targets = project._TARGETS - - -- make all targets - for k, v in pairs(configs._TARGETS) do - targets[k] = v - end - - -- merge the root configures to all targets - for _, target in pairs(targets) do - - -- merge the setted configures - for k, v in pairs(configs._SET) do - if nil == target[k] then - target[k] = v - end - end - - -- merge the added configures - for k, v in pairs(configs._ADD) do - if nil == target[k] then - target[k] = v - else - target[k] = table.join(v, target[k]) - end - end - - -- remove repeat values and unwrap it - for k, v in pairs(target) do - - -- remove repeat first - v = utils.unique(v) - - -- filter values - v = project._filter(v) - - -- unwrap it if be only one - v = utils.unwrap(v) - - -- update it - target[k] = v - end - end - - -- init mtime for the project file - project._MTIMES = project._MTIMES or {} - project._MTIMES[path.relative(xmake._PROJECT_FILE, xmake._PROJECT_DIR)] = os.mtime(xmake._PROJECT_FILE) - - -- get the mtimes for configure - local mtimes_config = config.get("__mtimes") - if mtimes_config then - - -- check for all project files and we need reconfig and rebuild it if them have been modified - for file, mtime in pairs(project._MTIMES) do - - -- modified? reconfig and rebuild it - local mtime_old = mtimes_config[file] - if not mtime_old or mtime > mtime_old then - config._RECONFIG = true - config.set("__rebuild", true) - break - end - end - end - - -- update mtimes - config.set("__mtimes", project._MTIMES) - - -- reconfig it? we need reprobe it - if config._RECONFIG then - project.probe() - config.clearup() - end -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(utils.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(utils.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(utils.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(utils.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(utils.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(utils.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(utils.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")) - - -- failed - if not ok then return false end - end - - -- ok - return true -end - --- make option -function project._make_option(name, opt, cfile, cxxfile, objectfile, targetfile) - - -- remove repeat values and unwrap it - for k, v in pairs(opt) do - - -- remove repeat first - v = utils.unique(v) - - -- filter values - v = project._filter(v) - - -- unwrap it if be only one - v = utils.unwrap(v) - - -- update it - opt[k] = v - end - - -- 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 - - end - - -- ok - return opt -end - --- make options from the project file -function project._make_options(configs) - - -- check - assert(configs and configs._OPTIONS) - - -- the source file path - local cfile = os.tmpdir() .. "/__checking.c" - local cxxfile = os.tmpdir() .. "/__checking.cpp" - - -- the object file path - local objectfile = os.tmpdir() .. "/" .. rule.filename("__checking", "object") - - -- the target file path - local targetfile = os.tmpdir() .. "/" .. rule.filename("__checking", "binary") - - -- make all options - for k, v in pairs(configs._OPTIONS) do - - -- this option need be probed automatically? - if config.auto(k) then - - -- make option - local o = project._make_option(k, v, cfile, cxxfile, objectfile, targetfile) - if o then - - -- enable this option - config.set(k, true) - - -- save this option to configure - config.set("__" .. k, o) - - else - - -- disable this option - config.set(k, false) - - -- clear this option to configure - config.set("__" .. k, nil) - - end - - elseif nil == config.get("__" .. k) then - - -- save this option to configure - config.set("__" .. k, v) - end - end - - -- remove files - os.rm(cfile) - os.rm(cxxfile) - os.rm(objectfile) - os.rm(targetfile) - -end - --- only load options from the the project file -function project._load_options(file) - - -- check - assert(file) - - -- load the project script - local script = loadfile(file) - if not script then - return string.format("load %s failed!", file) - end - - -- set the current project file directory - project._CURDIR = path.directory(file) - - -- bind the new environment - local newenv = {_CONFIGS = {_OPTIONS = {}}} - setmetatable(newenv, {__index = function(tbl, key) - local val = rawget(tbl, key) - if nil == val then val = rawget(_G, key) end - if nil == val then return function(...) end end - return val - end}) - setfenv(script, newenv) - - -- register import - newenv.import = function (module) return project._api_import(newenv, module) end - - -- register interfaces for the condition - newenv.os = function (...) return project._api_os(newenv, ...) end - newenv.kind = function (...) return project._api_kind(newenv, ...) end - newenv.modes = function (...) return project._api_modes(newenv, ...) end - newenv.plats = function (...) return project._api_plats(newenv, ...) end - newenv.archs = function (...) return project._api_archs(newenv, ...) end - - -- register interfaces for the option - newenv.set_option = function (...) return project._api_add_option(newenv, ...) end - newenv.add_option = function (...) return project._api_add_option(newenv, ...) end - - -- register interfaces for the subproject files - newenv.add_subdirs = function (...) return project._api_add_subdirs(newenv, ...) end - newenv.add_subfiles = function (...) return project._api_add_subfiles(newenv, ...) end - - -- register interfaces for the functions - newenv.add_cfunc = function (...) return project._api_add_cfunc(newenv, ...) end - newenv.add_cfuncs = function (...) return project._api_add_cfuncs(newenv, ...) end - newenv.add_cxxfunc = function (...) return project._api_add_cxxfunc(newenv, ...) end - newenv.add_cxxfuncs = function (...) return project._api_add_cxxfuncs(newenv, ...) end - - -- register interfaces for the package files - newenv.add_pkgdirs = function (...) return project._api_add_pkgdirs(newenv, ...) end - newenv.add_pkgs = function (...) return project._api_add_subdirs(newenv, ...) end - - -- register interfaces for setting option values - local interfaces = { "enable" - , "showmenu" - , "category" - , "warnings" - , "optimize" - , "languages" - , "description"} - - for _, interface in ipairs(interfaces) do - newenv["set_option_" .. interface] = function (...) return project._api_set_values(newenv._OPTION, interface, ...) end - end - - -- register interfaces for adding option values - interfaces = { "links" - , "cincludes" - , "cxxincludes" - , "cfuncs" - , "cxxfuncs" - , "ctypes" - , "cxxtypes" - , "cflags" - , "cxflags" - , "cxxflags" - , "ldflags" - , "vectorexts" - , "defines" - , "defines_if_ok" - , "defines_h_if_ok" - , "undefines" - , "undefines_if_ok" - , "undefines_h_if_ok"} - - for _, interface in ipairs(interfaces) do - newenv["add_option_" .. interface] = function (...) return project._api_add_values(newenv._OPTION, interface, ...) end - end - - -- register interfaces for adding option pathes - interfaces = { "linkdirs" - , "includedirs"} - - for _, interface in ipairs(interfaces) do - newenv["add_option_" .. interface] = function (...) return project._api_add_pathes(newenv._OPTION, interface, ...) end - end - - -- done the project script - local ok, errors = pcall(script) - if not ok then - return nil, errors - end - - -- get the project configure - return newenv._CONFIGS -end - --- only load targets from the project file -function project._load_targets(file) - - -- check - assert(file) - - -- load the project script - local script = loadfile(file) - if not script then - return string.format("load %s failed!", file) - end - - -- set the current project file directory - project._CURDIR = path.directory(file) - - -- bind the new environment - local newenv = {_CONFIGS = {_SET = {}, _ADD = {}, _TARGETS = {}}} - setmetatable(newenv, {__index = function(tbl, key) - local val = rawget(tbl, key) - if nil == val then val = rawget(_G, key) end - if nil == val and type(key) == "string" and (key:startswith("add_option") or key:startswith("set_option")) then - return function(...) end - end - return val - end}) - setfenv(script, newenv) - - -- register import - newenv.import = function (module) return project._api_import(newenv, module) end - - -- register interfaces for the condition - newenv.os = function (...) return project._api_os(newenv, ...) end - newenv.kind = function (...) return project._api_kind(newenv, ...) end - newenv.modes = function (...) return project._api_modes(newenv, ...) end - newenv.plats = function (...) return project._api_plats(newenv, ...) end - newenv.archs = function (...) return project._api_archs(newenv, ...) end - newenv.options = function (...) return project._api_options(newenv, ...) end - - -- register interfaces for the target - newenv.set_target = function (...) return project._api_add_target(newenv, ...) end - newenv.add_target = function (...) return project._api_add_target(newenv, ...) end - - -- register interfaces for the subproject files - newenv.add_subdirs = function (...) return project._api_add_subdirs(newenv, ...) end - newenv.add_subfiles = function (...) return project._api_add_subfiles(newenv, ...) end - - -- register interfaces for the functions - newenv.add_cfunc = function (...) return project._api_add_cfunc(newenv, ...) end - newenv.add_cfuncs = function (...) return project._api_add_cfuncs(newenv, ...) end - newenv.add_cxxfunc = function (...) return project._api_add_cxxfunc(newenv, ...) end - newenv.add_cxxfuncs = function (...) return project._api_add_cxxfuncs(newenv, ...) end - - -- register interfaces for the package files - newenv.add_pkgdirs = function (...) return project._api_add_pkgdirs(newenv, ...) end - newenv.add_pkgs = function (...) return project._api_add_subdirs(newenv, ...) end - - -- register interfaces for setting values - local interfaces = { "kind" - , "config_h_prefix" - , "version" - , "strip" - , "options" - , "symbols" - , "warnings" - , "optimize" - , "languages" - , "runscript" - , "installscript" - , "packagescript"} - - for _, interface in ipairs(interfaces) do - newenv["set_" .. interface] = function (...) return project._api_set_values(newenv._TARGET or newenv._CONFIGS._SET, interface, ...) end - end - - -- register interfaces for setting pathes - local interfaces = { "headerdir" - , "targetdir" - , "objectdir" - , "config_h"} - - for _, interface in ipairs(interfaces) do - newenv["set_" .. interface] = function (...) return project._api_set_pathes(newenv._TARGET or newenv._CONFIGS._SET, interface, ...) end - end - - -- register interfaces for adding values - interfaces = { "deps" - , "links" - , "cflags" - , "cxflags" - , "cxxflags" - , "mflags" - , "mxflags" - , "mxxflags" - , "ldflags" - , "shflags" - , "options" - , "defines" - , "undefines" - , "defines_h" - , "undefines_h" - , "languages" - , "vectorexts"} - for _, interface in ipairs(interfaces) do - newenv["add_" .. interface] = function (...) return project._api_add_values(newenv._TARGET or newenv._CONFIGS._ADD, interface, ...) end - end - - -- register interfaces for adding pathes - interfaces = { "files" - , "headers" - , "linkdirs" - , "includedirs"} - for _, interface in ipairs(interfaces) do - newenv["add_" .. interface] = function (...) return project._api_add_pathes(newenv._TARGET or newenv._CONFIGS._ADD, interface, ...) end - end - - -- done the project script - local ok, errors = pcall(script) - if not ok then - return nil, errors - end - - -- get the project configure - return newenv._CONFIGS -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() - - -- load the options from the the project file - local configs, errors = project._load_options(xmake._PROJECT_FILE) - if not configs then - return errors - end - - -- make the options from the the project file - project._make_options(configs) -end - --- load the project -function project.load() - - -- load the targets from the the project file - local configs, errors = project._load_targets(xmake._PROJECT_FILE) - if not configs then - return errors - end - - -- make the targets from the the project file - project._make_targets(configs) -end - --- reload the project -function project.reload() - - -- clear it first - project._MTIMES = nil - project._TARGETS = nil - project._CONFILES = nil - project._CURDIR = nil - - -- load it - return project.load() -end - --- dump the current configure -function project.dump() - - -- check - assert(project._TARGETS) - - -- dump - if xmake._OPTIONS.verbose then - utils.dump(project._TARGETS) - end - -end - --- make the configure file for the given target -function project.makeconf(target_name) - - -- init files - project._CONFILES = project._CONFILES or {} - - -- the target name - if target_name and target_name ~= "all" then - -- make configure for the target and dependents - if not project._makeconf_for_target_and_deps(target_name) then return false end - else - - -- the targets - local targets = project.targets() - assert(targets) - - -- make configure for the targets - for target_name, target in pairs(targets) do - if not project._makeconf_for_target(target_name, target) then return false end - end - end - - -- exit files - for _, file in pairs(project._CONFILES) do - file:close() - end - project._CONFILES = nil - - -- ok - return true -end - --- check target -function project.checktarget(target_name) - - -- the targets - local targets = project.targets() - - -- invalid target? - if target_name and target_name ~= "all" and targets and not targets[target_name] then - utils.error("invalid target: %s!", target_name) - return false - elseif not target_name then - utils.error("no target!") - return false - end - - -- ok - return true -end - --- get the project menu -function project.menu() - - -- attempt to load project configure - local configs = nil - local errors = nil - local projectfile = xmake._PROJECT_FILE - if projectfile and os.isfile(projectfile) then - configs, errors = project._load_options(projectfile) - end - - -- failed? - if not configs then - if errors then utils.error(errors) end - return {} - end - - -- the options - local options = configs._OPTIONS - if not options then return {} end - - -- arrange options by category - local options_by_category = {} - for name, opt in pairs(options) do - - -- make the category - local category = "default" - if opt.category then category = utils.unwrap(opt.category) end - options_by_category[category] = options_by_category[category] or {} - - -- append option to the current category - options_by_category[category][name] = opt - end - - -- make menu by category - local menu = {} - for k, opts in pairs(options_by_category) do - - -- insert options - local first = true - for name, opt in pairs(opts) do - - -- show menu? - if opt.showmenu then - - -- the default value - local default = "auto" - if opt.enable ~= nil then - default = utils.unwrap(opt.enable) - end - - -- is first? - if first then - - -- insert a separator - table.insert(menu, {}) - - -- not first - first = false - end - - -- append it - if opt.description then - table.insert(menu, {nil, name, "kv", default, utils.unwrap(opt.description)}) - else - table.insert(menu, {nil, name, "kv", default, nil}) - end - end - end - end - - -- ok? - return menu -end - --- return module: project -return project diff --git a/xmake/scripts/base/rule.lua b/xmake/scripts/base/rule.lua deleted file mode 100644 index b3dc1825c..000000000 --- a/xmake/scripts/base/rule.lua +++ /dev/null @@ -1,300 +0,0 @@ ---!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) 2009 - 2015, ruki All rights reserved. --- --- @author ruki --- @file rule.lua --- - --- define module: rule -local rule = rule 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("base/config") -local platform = require("platform/platform") - --- get the building log file path -function rule.logfile() - - -- the logdir - local logdir = config.get("buildir") or os.tmpdir() - assert(logdir) - - -- get it - return path.translate(logdir .. "/.build.log") -end - --- get the filename from the given name and kind -function rule.filename(name, kind) - - -- check - assert(name and kind) - - -- get format - local format = platform.format(kind) or {"", ""} - - -- make it - return format[1] .. name .. format[2] -end - --- get the makefile path -function rule.makefile() - - -- get the build directory - local buildir = config.get("buildir") - assert(buildir) - - -- get it - return path.translate(buildir .. "/makefile") -end - --- get configure file for the given target -function rule.config_h(target) - - -- get the target configure file - local config_h = target.config_h - if config_h then - -- translate file path - if not path.is_absolute(config_h) then - config_h = path.absolute(config_h, xmake._PROJECT_DIR) - else - config_h = path.translate(config_h) - end - end - - -- ok? - return config_h -end - --- get the temporary backup directory for package -function rule.backupdir(target_name, arch) - - -- the temporary directory - local tmpdir = os.tmpdir() - assert(tmpdir) - - -- the project name - local project_name = path.basename(xmake._PROJECT_DIR) - assert(project_name) - - -- make it - return string.format("%s/.xmake/%s/pkgfiles/%s/%s", tmpdir, project_name, target_name, arch) -end - --- get target file for the given target -function rule.targetfile(target_name, target, buildir) - - -- check - assert(target_name and target and target.kind) - - -- the target directory - local targetdir = target.targetdir or buildir or config.get("buildir") - assert(targetdir and type(targetdir) == "string") - - -- the target file name - local filename = rule.filename(target_name, target.kind) - assert(filename) - - -- make the target file path - return targetdir .. "/" .. filename -end - --- get object files for the given source files -function rule.objectdir(target_name, target, buildir) - - -- check - assert(target_name and target) - - -- the object directory - local objectdir = target.objectdir - if not objectdir then - - -- the build directory - if not buildir then - buildir = config.get("buildir") - end - assert(buildir) - - -- make the default object directory - objectdir = buildir .. "/.objs" - end - - -- ok? - return objectdir -end - --- get object files for the given source files -function rule.objectfiles(target_name, target, sourcefiles, buildir) - - -- check - assert(target_name and target and sourcefiles) - - -- the object directory - local objectdir = rule.objectdir(target_name, target, buildir) - assert(objectdir and type(objectdir) == "string") - - -- make object files - local i = 1 - local objectfiles = {} - for _, sourcefile in ipairs(sourcefiles) do - - -- translate: [lib]xxx*.[a|lib] => xxx/*.[o|obj] object file - sourcefile = sourcefile:gsub(rule.filename("(%w+)", "static"):gsub("%.", "%%.") .. "$", "%1/*") - - -- make object file - local objectfile = string.format("%s/%s/%s/%s", objectdir, target_name, path.directory(sourcefile), rule.filename(path.basename(sourcefile), "object")) - - -- translate path - -- - -- .e.g - -- - -- src/xxx.c - -- project/xmake.lua - -- build/.objs - -- - -- objectfile: project/build/.objs/xxxx/../../xxx.c will be out of range for objectdir - -- - -- we need replace '..' to '__' in this case - -- - objectfile = (path.translate(objectfile):gsub("%.%.", "__")) - - -- save it - objectfiles[i] = objectfile - i = i + 1 - - end - - -- ok? - return objectfiles -end - --- get the source files from the given target -function rule.sourcefiles(target) - - -- check - assert(target) - - -- no files? - if not target.files then - return {} - end - - -- wrap files first - local targetfiles = utils.wrap(target.files) - - -- match files - local i = 1 - local sourcefiles = {} - for _, targetfile in ipairs(targetfiles) do - - -- normalize *.[o|obj] filename - targetfile = targetfile:gsub("([%w%*]+)%.obj|", rule.filename("%1|", "object")) - targetfile = targetfile:gsub("([%w%*]+)%.obj$", rule.filename("%1", "object")) - targetfile = targetfile:gsub("([%w%*]+)%.o|", rule.filename("%1|", "object")) - targetfile = targetfile:gsub("([%w%*]+)%.o$", rule.filename("%1", "object")) - - -- normalize [lib]*.[a|lib] filename - targetfile = targetfile:gsub("([%w%*]+)%.lib|", rule.filename("%1|", "static")) - targetfile = targetfile:gsub("([%w%*]+)%.lib$", rule.filename("%1", "static")) - targetfile = targetfile:gsub("lib([%w%*]+)%.a|", rule.filename("%1|", "static")) - targetfile = targetfile:gsub("lib([%w%*]+)%.a$", rule.filename("%1", "static")) - - -- match source files - local files = os.match(targetfile) - if #files == 0 then - utils.warning("cannot match add_files(\"%s\")", targetfile) - end - - -- process source files - for _, file in ipairs(files) do - - -- convert to the relative path - if path.is_absolute(file) then - file = path.relative(file, xmake._PROJECT_DIR) - end - - -- save it - sourcefiles[i] = file - i = i + 1 - - end - end - - -- remove repeat files - sourcefiles = utils.unique(sourcefiles) - - -- ok? - return sourcefiles -end - --- get the header files from the given target -function rule.headerfiles(target, headerdir) - - -- check - assert(target) - - -- no headers? - local headers = target.headers - if not headers then return end - - -- get the headerdir - if not headerdir then headerdir = target.headerdir or config.get("buildir") end - assert(headerdir) - - -- get the source pathes and destinate pathes - local srcheaders = {} - local dstheaders = {} - for _, header in ipairs(utils.wrap(headers)) do - - -- get the root directory - local rootdir = header:gsub("%(.*%)", ""):gsub("|.*$", "") - - -- remove '(' and ')' - local srcpathes = header:gsub("[%(%)]", "") - if srcpathes then - - -- get the source pathes - srcpathes = os.match(srcpathes) - if srcpathes then - - -- add the source headers - table.join2(srcheaders, srcpathes) - - -- add the destinate headers - for _, srcpath in ipairs(srcpathes) do - - -- the header - local dstheader = path.absolute(path.relative(srcpath, rootdir), headerdir) - assert(dstheader) - - -- add it - table.insert(dstheaders, dstheader) - end - end - end - end - - -- ok? - return srcheaders, dstheaders -end - --- return module: rule -return rule diff --git a/xmake/scripts/base/string.lua b/xmake/scripts/base/string.lua deleted file mode 100644 index b4be08cfa..000000000 --- a/xmake/scripts/base/string.lua +++ /dev/null @@ -1,115 +0,0 @@ ---!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) 2009 - 2015, ruki All rights reserved. --- --- @author ruki --- @file string.lua --- - --- define module: string -local string = string or {} - --- find the last substring with the given pattern -function string.find_last(self, pattern, plain) - - -- find the last substring - local curr = 0 - repeat - local next = self:find(pattern, curr + 1, plain) - if next then - curr = next - end - until (not next) - - -- found? - if curr > 0 then - return curr - end -end - --- split string with the given pattern -function string.split(self, pattern) - - -- split it - local list = {} - self:gsub("[^" .. pattern .."]+", function(v) table.insert(list, v) end ) - return list -end - --- trim the spaces -function string.trim(self) - return (self:gsub("^%s*(.-)%s*$", "%1")) -end - --- trim the left spaces -function string.ltrim(self) - return (self:gsub("^%s*", "")) -end - --- trim the right spaces -function string.rtrim(self) - local n = #self - while n > 0 and s:find("^%s", n) do n = n - 1 end - return self:sub(1, n) -end - --- append a substring with a given separator -function string.append(self, substr, separator) - - -- check - assert(self) - - -- not substr? return self - if not substr then - return self - end - - -- append it - local s = self - if #s == 0 then - s = substr - else - s = string.format("%s%s%s", s, separator or "", substr) - end - - -- ok - return s -end - --- encode: ' ', '=', '\"', '<' -function string.encode(self) - - -- null? - if self == nil then return end - - -- done - return (self:gsub("[%s=\"<]", function (w) return string.format("%%%x", w:byte()) end)) -end - --- decode: ' ', '=', '\"' -function string.decode(self) - - -- null? - if self == nil then return end - - -- done - return (self:gsub("%%(%x%x)", function (w) return string.char(tonumber(w, 16)) end)) -end - - --- return module: string -return string diff --git a/xmake/scripts/base/table.lua b/xmake/scripts/base/table.lua deleted file mode 100644 index 52b726412..000000000 --- a/xmake/scripts/base/table.lua +++ /dev/null @@ -1,99 +0,0 @@ ---!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) 2009 - 2015, ruki All rights reserved. --- --- @author ruki --- @file table.lua --- - --- define module: table -local table = table or {} - --- join all objects and tables -function table.join(...) - - -- done - local args = {...} - local result = {} - for _, t in ipairs(args) do - if type(t) == "table" then - for k, v in pairs(t) do - if type(k) == "number" then table.insert(result, v) - else result[k] = v end - end - else - table.insert(result, t) - end - end - - -- ok? - return result -end - --- join all objects and tables to self -function table.join2(self, ...) - - -- check - assert(self and type(self) == "table") - - -- done - local args = {...} - for _, t in ipairs(args) do - if type(t) == "table" then - for k, v in pairs(t) do - if type(k) == "number" then table.insert(self, v) - else self[k] = v end - end - else - table.insert(self, t) - end - end - - -- ok? - return self -end - --- clear the table -function table.clear(self) - - -- check - assert(self and type(self) == "table") - - -- clear it - for k in next, self do - rawset(self, k, nil) - end -end - --- copy the table to self -function table.copy2(self, copied) - - -- check - assert(self and copied) - - -- clear self first - table.clear(self) - - -- copy it - for k, v in pairs(copied) do - self[k] = v - end - -end - --- return module: table -return table diff --git a/xmake/scripts/base/template.lua b/xmake/scripts/base/template.lua deleted file mode 100644 index c02b135c3..000000000 --- a/xmake/scripts/base/template.lua +++ /dev/null @@ -1,77 +0,0 @@ ---!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) 2009 - 2015, ruki All rights reserved. --- --- @author ruki --- @file template.lua --- - --- define module: template -local template = template or {} - --- load modules -local os = require("base/os") -local path = require("base/path") -local utils = require("base/utils") - --- get the language list -function template.languages() - - -- make list - local list = {} - - -- get the language list - local languages = os.match(xmake._TEMPLATES_DIR .. "/*", true) - if languages then - for _, v in ipairs(languages) do - table.insert(list, path.basename(v)) - end - end - - -- ok? - return list -end - --- load all templates from the given language -function template.loadall(language) - - -- check - assert(language) - - -- load all templates - local modules = {} - local templates = os.match(string.format("%s/%s/**/_template.lua", xmake._TEMPLATES_DIR, language)) - if templates then - for _, t in ipairs(templates) do - local script = assert(loadfile(t)) - if script then - local module = script() - if module then - module._DIRECTORY = path.directory(t) - table.insert(modules, module) - end - end - end - end - - -- ok? - return modules -end - - --- return module: template -return template diff --git a/xmake/scripts/base/uninstall.lua b/xmake/scripts/base/uninstall.lua deleted file mode 100644 index 304b73c92..000000000 --- a/xmake/scripts/base/uninstall.lua +++ /dev/null @@ -1,104 +0,0 @@ ---!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) 2009 - 2015, ruki All rights reserved. --- --- @author ruki --- @file uninstall.lua --- - --- define module: uninstall -local uninstall = uninstall or {} - --- load modules -local os = require("base/os") -local io = require("base/io") -local rule = require("base/rule") -local path = require("base/path") -local utils = require("base/utils") -local config = require("base/config") -local platform = require("platform/platform") - --- uninstall target from the platform script -function uninstall._done_from_platform(target) - - -- check - assert(target) - - -- the platform uninstall script file - local uninstallscript = nil - local scriptfile = platform.directory() .. "/uninstall.lua" - if os.isfile(scriptfile) then - - -- load the uninstall script - local script, errors = loadfile(scriptfile) - if script then - uninstallscript = script() - if type(uninstallscript) == "table" and uninstallscript.main then - uninstallscript = uninstallscript.main - end - else - utils.error(errors) - end - end - - -- uninstall it - if type(uninstallscript) == "function" then - return uninstallscript(target) - end - - -- continue - return 0 -end - --- uninstall target from the given target configure -function uninstall._done(target) - - -- check - assert(target) - - -- uninstall it from the platform script - local ok = uninstall._done_from_platform(target) - if ok ~= 0 then return utils.ifelse(ok == 1, true, false) end - - -- ok - return true -end - --- done uninstall from the configure -function uninstall.done(configs) - - -- check - assert(configs) - - -- uninstall targets - for _, target in pairs(configs) do - - -- uninstall it - if not uninstall._done(target) then - -- errors - utils.error("uninstall %s failed!", target.name) - return false - end - - end - - -- ok - return true -end - --- return module: uninstall -return uninstall diff --git a/xmake/scripts/base/utils.lua b/xmake/scripts/base/utils.lua deleted file mode 100644 index fd1f053d6..000000000 --- a/xmake/scripts/base/utils.lua +++ /dev/null @@ -1,258 +0,0 @@ ---!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) 2009 - 2015, ruki All rights reserved. --- --- @author ruki --- @file utils.lua --- - --- define module: utils -local utils = utils or {} - --- the printf function -function utils.printf(msg, ...) - - -- check - assert(msg) - - -- trace - print(string.format(msg, ...)) -end - --- the verbose function -function utils.verbose(msg, ...) - - if xmake._OPTIONS.verbose then - - -- check - assert(msg) - - -- trace - print(string.format(msg, ...)) - end -end - --- the error function -function utils.error(msg, ...) - - -- check - assert(msg) - - -- trace - print("error: " .. string.format(msg, ...)) -end - --- the warning function -function utils.warning(msg, ...) - - -- check - assert(msg) - - -- trace - print("warning: " .. string.format(msg, ...)) -end - --- ifelse, a? b : c -function utils.ifelse(a, b, c) - if a then return b else return c end -end - --- dump object with the level -function utils._dump_with_level(object, exclude, level) - - -- dump string - if type(object) == "string" then - io.write(string.format("%q", object)) - -- dump boolean - elseif type(object) == "boolean" then - io.write(tostring(object)) - -- dump number - elseif type(object) == "number" then - io.write(object) - -- dump function - elseif type(object) == "function" then - io.write("<function>") - -- dump table - elseif type(object) == "table" then - - -- dump head - io.write("\n") - for l = 1, level do - io.write(" ") - end - io.write("{\n") - - -- dump body - local i = 0 - for k, v in pairs(object) do - - -- exclude some keys - if not exclude or type(k) ~= "string" or not k:find(exclude) then - - -- dump spaces and separator - for l = 1, level do - io.write(" ") - end - - io.write(utils.ifelse(i == 0, " ", ", ")) - - -- dump key - if type(k) == "string" then - io.write(k, " = ") - end - - -- dump value - if not utils._dump_with_level(v, exclude, level + 1) then - return false - end - - -- dump newline - io.write("\n") - i = i + 1 - end - end - - -- dump tail - for l = 1, level do - io.write(" ") - end - io.write("}\n") - else - -- error - utils.error("invalid object type: %s", type(object)) - return false - end - - -- ok - return true -end - --- dump object -function utils.dump(object, exclude, prefix) - - -- dump prefix - if prefix then - io.write(prefix) - end - - -- dump it - utils._dump_with_level(object, exclude, 0) - - -- return it - return object -end - --- unwrap object if be only one -function utils.unwrap(object) - - -- check - assert(object) - - -- unwrap it - if type(object) == "table" and table.getn(object) == 1 then - for _, v in pairs(object) do - return v - end - end - - -- ok - return object -end - --- wrap object to table -function utils.wrap(object) - - -- no object? - if not object then - return {} - end - - -- wrap it if not table - if type(object) ~= "table" then - return {object} - end - - -- ok - return object -end - --- remove repeat from the given array -function utils.unique(array) - - -- check - assert(array) - - -- remove repeat - if type(array) == "table" then - - -- not only one? - if table.getn(array) ~= 1 then - - -- done - local exists = {} - local unique = {} - for _, v in ipairs(array) do - if type(v) == "string" then - if not exists[v] then - exists[v] = true - table.insert(unique, v) - end - else - if not exists["\"" .. v .. "\""] then - exists["\"" .. v .. "\""] = true - table.insert(unique, v) - end - end - end - - -- update it - array = unique - end - end - - -- ok - return array -end - --- call functions -function utils.call(funcs, pred, ...) - - -- check - assert(funcs) - - -- call all - for _, func in ipairs(utils.wrap(funcs)) do - - -- check - assert(type(func) == "function") - - -- call it - local result = func(...) - - -- exists predicate? - if pred and type(pred) == "function" then - if not pred(name, result) then return false end - -- failed? - elseif not result then return false end - end - - -- ok - return true -end - --- return module: utils -return utils |
