diff options
| author | ruki <[email protected]> | 2016-07-09 22:34:16 +0800 |
|---|---|---|
| committer | ruki <[email protected]> | 2016-07-09 22:34:16 +0800 |
| commit | f54223a97ba93b02128df84d52d3efe7abd2a36a (patch) | |
| tree | b6d5e5d1b4d70bd1eeadf936751eb50930f3bab6 | |
| parent | 0d3075a0739eff0e28db11889a62ed3db8f4ab9f (diff) | |
add archiver and extractor
31 files changed, 947 insertions, 382 deletions
diff --git a/xmake/actions/build/builder.lua b/xmake/actions/build/builder.lua index b10e76bbe..e56b18ede 100755 --- a/xmake/actions/build/builder.lua +++ b/xmake/actions/build/builder.lua @@ -21,212 +21,28 @@ -- -- imports -import("core.base.option") -import("core.project.task") -import("core.project.config") import("core.project.project") -import("core.tool.tool") -import("core.tool.linker") -import("core.tool.compiler") -import("core.project.cache") import("core.platform.environment") --- build the object for the *.[o|obj] source file -function _build_object_for_object(target, sourcefile, objectfile, percent) +-- on build the given target +function _on_build_target(target) - -- trace - print("[%02d%%]: inserting.$(mode) %s", percent, sourcefile) - - -- trace verbose info - if option.get("verbose") then - print("cp %s %s", sourcefile, objectfile) - end - - -- insert this object file - os.cp(sourcefile, objectfile) -end - --- build the object for the *.[a|lib] source file -function _build_object_for_static(target, sourcefile, objectfile, percent) - - -- trace - print("[%02d%%]: inserting.$(mode) %s", percent, sourcefile) - - -- trace verbose info - if option.get("verbose") then - print("ex %s %s", sourcefile, objectfile) - end - - -- extract the static library to object directory - tool.run("ex", sourcefile, path.directory(objectfile)) -end - --- build object -function _build_object(target, index) - - -- the object and source files - local objectfiles = target:objectfiles() - local sourcefiles = target:sourcefiles() - - -- get the object and source with the given index - local sourcefile = sourcefiles[index] - local objectfile = objectfiles[index] - - -- we need not rebuild it if the files are not modified - if os.mtime(sourcefile) < os.mtime(objectfile) then - return - end - - -- get the source file type - local filetype = path.extension(sourcefile):lower() - - -- calculate percent - local percent = ((_g.targetindex + (index - 1) / #objectfiles) * 100 / _g.targetcount) - - -- build the object for the *.o/obj source makefile - if filetype == ".o" or filetype == ".obj" then - return _build_object_for_object(target, sourcefile, objectfile, percent) - -- build the object for the *.[a|lib] source file - elseif filetype == ".a" or filetype == ".lib" then - return _build_object_for_static(target, sourcefile, objectfile, percent) - end - - -- uses ccache - local ccache = nil - if config.get("ccache") then - ccache = tool.shellname("ccache") - end - - -- trace - print("[%02d%%]: %scompiling.$(mode) %s", percent, ifelse(ccache, "ccache ", ""), sourcefile) - - -- trace verbose info - if option.get("verbose") then - - -- make command - local command = compiler.compcmd(sourcefile, objectfile, target) - if ccache then - command = ccache:append(command, " ") - end - - -- trace - print(command) - end - - -- complie it and enable multitasking - compiler.compile(sourcefile, objectfile, target, true) -end - --- make objects for the given target -function _build_objects(target) - - -- get the max job count - local jobs = tonumber(option.get("jobs") or "4") - - -- make objects - local index = 1 - local total = #target:objectfiles() - local tasks = {} - repeat - - -- consume tasks - local pendings = {} - for i, task in ipairs(tasks) do - - -- get job - local job = task[1] - - -- get job index - local job_index = task[2] - - -- pending? - local status = coroutine.status(job) - if status ~= "dead" then - - -- resume it - coroutine.resume(job, job_index) - - -- append the pending task - table.insert(pendings, task) - end - end - - -- update the pending tasks - tasks = pendings - - -- produce tasks - while #tasks < jobs and index <= total do - table.insert(tasks, {coroutine.create(function (index) - - -- build object - _build_object(target, index) - - end), index}) - index = index + 1 - end - - until #tasks == 0 + -- the target kind + local kind = target:get("kind") + assert(kind, "target(%s).kind not found!", target:name()) + -- build target + import("kinds." .. kind).build(target, _g) end --- build the given target +-- build the given target function _build_target(target) - -- build objects - _build_objects(target) - - -- make headers - local srcheaders, dstheaders = target:headerfiles() - if srcheaders and dstheaders then - local i = 1 - for _, srcheader in ipairs(srcheaders) do - local dstheader = dstheaders[i] - if dstheader then - os.cp(srcheader, dstheader) - end - i = i + 1 - end - end - - -- update target index - _g.targetindex = _g.targetindex + 1 - - -- expand object files with *.o/obj - local objectfiles = {} - for _, objectfile in ipairs(target:objectfiles()) do - if objectfile:find("%*") then - local matchfiles = os.match(objectfile) - if matchfiles then - table.join2(objectfiles, matchfiles) - end - else - table.insert(objectfiles, objectfile) - end - end - - -- the target file - local targetfile = target:targetfile() - - -- trace - print("[%02d%%]: linking.$(mode) %s", _g.targetindex * 100 / _g.targetcount, path.filename(targetfile)) - - -- trace verbose info - if option.get("verbose") then - print(linker.linkcmd(objectfiles, targetfile, target)) - end - - -- link it - linker.link(objectfiles, targetfile, target) -end - --- make the given target -function _make_target(target) - -- the target scripts local scripts = { target:get("build_before") - , target:get("build") or _build_target + , target:get("build") or _on_build_target , target:get("build_after") } @@ -237,10 +53,13 @@ function _make_target(target) script(target) end end + + -- update target index + _g.targetindex = _g.targetindex + 1 end --- make the given target and deps -function _make_target_and_deps(target) +-- build the given target and deps +function _build_target_and_deps(target) -- this target have been finished? if _g.finished[target:name()] then @@ -249,11 +68,11 @@ function _make_target_and_deps(target) -- make for all dependent targets for _, depname in ipairs(target:get("deps")) do - _make_target_and_deps(project.target(depname)) + _build_target_and_deps(project.target(depname)) end -- make target - _make_target(target) + _build_target(target) -- finished _g.finished[target:name()] = true @@ -302,8 +121,8 @@ function _stat_target_count(targetname) end end --- make -function make(targetname) +-- build +function build(targetname) -- enter toolchains environment environment.enter("toolchains") @@ -322,12 +141,12 @@ function make(targetname) -- make all targets for _, target in pairs(project.targets()) do - _make_target_and_deps(target) + _build_target_and_deps(target) end else -- make target - _make_target_and_deps(project.target(targetname)) + _build_target_and_deps(project.target(targetname)) end -- leave toolchains environment diff --git a/xmake/actions/build/kinds/binary.lua b/xmake/actions/build/kinds/binary.lua new file mode 100755 index 000000000..aa4749869 --- /dev/null +++ b/xmake/actions/build/kinds/binary.lua @@ -0,0 +1,61 @@ +--!The Automatic Cross-platform Build Tool +-- +-- XMake is free software; you can redistribute it and/or modify +-- it under the terms of the GNU Lesser General Public License as published by +-- the Free Software Foundation; either version 2.1 of the License, or +-- (at your option) any later version. +-- +-- XMake is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU Lesser General Public License for more details. +-- +-- You should have received a copy of the GNU Lesser General Public License +-- along with XMake; +-- If not, see <a href="http://www.gnu.org/licenses/"> http://www.gnu.org/licenses/</a> +-- +-- Copyright (C) 2015 - 2016, ruki All rights reserved. +-- +-- @author ruki +-- @file binary.lua +-- + +-- imports +import("core.base.option") +import("core.tool.linker") +import("kinds.object") + +-- build binary target +function build(target, g) + + -- build all objects + object.buildall(target, g) + + -- expand object files with *.o/obj + local objectfiles = {} + for _, objectfile in ipairs(target:objectfiles()) do + if objectfile:find("%*") then + local matchfiles = os.match(objectfile) + if matchfiles then + table.join2(objectfiles, matchfiles) + end + else + table.insert(objectfiles, objectfile) + end + end + + -- the target file + local targetfile = target:targetfile() + + -- trace + print("[%02d%%]: linking.$(mode) %s", (g.targetindex + 1) * 100 / g.targetcount, path.filename(targetfile)) + + -- trace verbose info + if option.get("verbose") then + print(linker.linkcmd(objectfiles, targetfile, target)) + end + + -- link it + linker.link(objectfiles, targetfile, target) +end + diff --git a/xmake/actions/build/kinds/object.lua b/xmake/actions/build/kinds/object.lua new file mode 100755 index 000000000..4750add95 --- /dev/null +++ b/xmake/actions/build/kinds/object.lua @@ -0,0 +1,158 @@ +--!The Automatic Cross-platform Build Tool +-- +-- XMake is free software; you can redistribute it and/or modify +-- it under the terms of the GNU Lesser General Public License as published by +-- the Free Software Foundation; either version 2.1 of the License, or +-- (at your option) any later version. +-- +-- XMake is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU Lesser General Public License for more details. +-- +-- You should have received a copy of the GNU Lesser General Public License +-- along with XMake; +-- If not, see <a href="http://www.gnu.org/licenses/"> http://www.gnu.org/licenses/</a> +-- +-- Copyright (C) 2015 - 2016, ruki All rights reserved. +-- +-- @author ruki +-- @file object.lua +-- + +-- imports +import("core.base.option") +import("core.tool.tool") +import("core.tool.compiler") +import("core.tool.extractor") +import("core.project.config") + +-- build the object from the *.[o|obj] source file +function _build_from_object(target, sourcefile, objectfile, percent) + + -- trace + print("[%02d%%]: inserting.$(mode) %s", percent, sourcefile) + + -- trace verbose info + if option.get("verbose") then + print("cp %s %s", sourcefile, objectfile) + end + + -- insert this object file + os.cp(sourcefile, objectfile) +end + +-- build the object from the *.[a|lib] source file +function _build_from_static(target, sourcefile, objectfile, percent) + + -- trace + print("[%02d%%]: inserting.$(mode) %s", percent, sourcefile) + + -- trace verbose info + if option.get("verbose") then + print("ex %s %s", sourcefile, objectfile) + end + + -- extract the static library to object directory + extractor.extract(sourcefile, path.directory(objectfile)) +end + +-- build object +function _build(target, g, index) + + -- the object and source files + local objectfiles = target:objectfiles() + local sourcefiles = target:sourcefiles() + + -- get the object and source with the given index + local sourcefile = sourcefiles[index] + local objectfile = objectfiles[index] + + -- we need not rebuild it if the files are not modified + if os.mtime(sourcefile) < os.mtime(objectfile) then + return + end + + -- get the source file type + local filetype = path.extension(sourcefile):lower() + + -- calculate percent + local percent = ((g.targetindex + (index - 1) / #objectfiles) * 100 / g.targetcount) + + -- build the object for the *.o/obj source makefile + if filetype == ".o" or filetype == ".obj" then + return _build_from_object(target, sourcefile, objectfile, percent) + -- build the object for the *.[a|lib] source file + elseif filetype == ".a" or filetype == ".lib" then + return _build_from_static(target, sourcefile, objectfile, percent) + end + + -- get ccache + local ccache = nil + if config.get("ccache") then + ccache = tool.shellname("ccache") + end + + -- trace + print("[%02d%%]: %scompiling.$(mode) %s", percent, ifelse(ccache, "ccache ", ""), sourcefile) + + -- trace verbose info + if option.get("verbose") then + print(compiler.compcmd(sourcefile, objectfile, target)) + end + + -- complie it and enable multitasking + compiler.compile(sourcefile, objectfile, target, true) +end + +-- build objects for the given target +function buildall(target, g) + + -- get the max job count + local jobs = tonumber(option.get("jobs") or "4") + + -- make objects + local index = 1 + local total = #target:objectfiles() + local tasks = {} + repeat + + -- consume tasks + local pendings = {} + for i, task in ipairs(tasks) do + + -- get job + local job = task[1] + + -- get job index + local job_index = task[2] + + -- pending? + local status = coroutine.status(job) + if status ~= "dead" then + + -- resume it + coroutine.resume(job, job_index) + + -- append the pending task + table.insert(pendings, task) + end + end + + -- update the pending tasks + tasks = pendings + + -- produce tasks + while #tasks < jobs and index <= total do + table.insert(tasks, {coroutine.create(function (index) + + -- build object + _build(target, g, index) + + end), index}) + index = index + 1 + end + + until #tasks == 0 +end + diff --git a/xmake/actions/build/kinds/shared.lua b/xmake/actions/build/kinds/shared.lua new file mode 100755 index 000000000..b725d52dd --- /dev/null +++ b/xmake/actions/build/kinds/shared.lua @@ -0,0 +1,74 @@ +--!The Automatic Cross-platform Build Tool +-- +-- XMake is free software; you can redistribute it and/or modify +-- it under the terms of the GNU Lesser General Public License as published by +-- the Free Software Foundation; either version 2.1 of the License, or +-- (at your option) any later version. +-- +-- XMake is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU Lesser General Public License for more details. +-- +-- You should have received a copy of the GNU Lesser General Public License +-- along with XMake; +-- If not, see <a href="http://www.gnu.org/licenses/"> http://www.gnu.org/licenses/</a> +-- +-- Copyright (C) 2015 - 2016, ruki All rights reserved. +-- +-- @author ruki +-- @file shared.lua +-- + +-- imports +import("core.base.option") +import("core.tool.linker") +import("kinds.object") + +-- build binary target +function build(target, g) + + -- build all objects + object.buildall(target, g) + + -- make headers + local srcheaders, dstheaders = target:headerfiles() + if srcheaders and dstheaders then + local i = 1 + for _, srcheader in ipairs(srcheaders) do + local dstheader = dstheaders[i] + if dstheader then + os.cp(srcheader, dstheader) + end + i = i + 1 + end + end + + -- expand object files with *.o/obj + local objectfiles = {} + for _, objectfile in ipairs(target:objectfiles()) do + if objectfile:find("%*") then + local matchfiles = os.match(objectfile) + if matchfiles then + table.join2(objectfiles, matchfiles) + end + else + table.insert(objectfiles, objectfile) + end + end + + -- the target file + local targetfile = target:targetfile() + + -- trace + print("[%02d%%]: linking.$(mode) %s", (g.targetindex + 1) * 100 / g.targetcount, path.filename(targetfile)) + + -- trace verbose info + if option.get("verbose") then + print(linker.linkcmd(objectfiles, targetfile, target)) + end + + -- link it + linker.link(objectfiles, targetfile, target) +end + diff --git a/xmake/actions/build/kinds/static.lua b/xmake/actions/build/kinds/static.lua new file mode 100755 index 000000000..c159f327f --- /dev/null +++ b/xmake/actions/build/kinds/static.lua @@ -0,0 +1,74 @@ +--!The Automatic Cross-platform Build Tool +-- +-- XMake is free software; you can redistribute it and/or modify +-- it under the terms of the GNU Lesser General Public License as published by +-- the Free Software Foundation; either version 2.1 of the License, or +-- (at your option) any later version. +-- +-- XMake is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU Lesser General Public License for more details. +-- +-- You should have received a copy of the GNU Lesser General Public License +-- along with XMake; +-- If not, see <a href="http://www.gnu.org/licenses/"> http://www.gnu.org/licenses/</a> +-- +-- Copyright (C) 2015 - 2016, ruki All rights reserved. +-- +-- @author ruki +-- @file static.lua +-- + +-- imports +import("core.base.option") +import("core.tool.archiver") +import("kinds.object") + +-- build binary target +function build(target, g) + + -- build all objects + object.buildall(target, g) + + -- make headers + local srcheaders, dstheaders = target:headerfiles() + if srcheaders and dstheaders then + local i = 1 + for _, srcheader in ipairs(srcheaders) do + local dstheader = dstheaders[i] + if dstheader then + os.cp(srcheader, dstheader) + end + i = i + 1 + end + end + + -- expand object files with *.o/obj + local objectfiles = {} + for _, objectfile in ipairs(target:objectfiles()) do + if objectfile:find("%*") then + local matchfiles = os.match(objectfile) + if matchfiles then + table.join2(objectfiles, matchfiles) + end + else + table.insert(objectfiles, objectfile) + end + end + + -- the target file + local targetfile = target:targetfile() + + -- trace + print("[%02d%%]: archiving.$(mode) %s", (g.targetindex + 1) * 100 / g.targetcount, path.filename(targetfile)) + + -- trace verbose info + if option.get("verbose") then + print(archiver.archivecmd(objectfiles, targetfile, target)) + end + + -- archive it + archiver.archive(objectfiles, targetfile, target) +end + diff --git a/xmake/actions/build/main.lua b/xmake/actions/build/main.lua index d09454be6..d6c1faac0 100755 --- a/xmake/actions/build/main.lua +++ b/xmake/actions/build/main.lua @@ -63,8 +63,8 @@ function main() { function () - -- make - builder.make(targetname or "all") + -- build + builder.build(targetname or "all") end, diff --git a/xmake/core/project/option.lua b/xmake/core/project/option.lua index 71226516f..1d554d887 100644 --- a/xmake/core/project/option.lua +++ b/xmake/core/project/option.lua @@ -52,7 +52,7 @@ function option:_check_link(sourcefile, objectfile, targetfile) end -- attempt to run this command - local ok, errors = instance:run(instance:linkcmd(objectfile, targetfile, self)) + local ok, errors = instance:link(objectfile, targetfile, self) if not ok and option_.get("verbose") then print(errors) end @@ -94,7 +94,7 @@ function option:_check_include(include, srcpath, objpath) end -- attempt to run this command - local ok, errors = instance:run(instance:compcmd(srcpath, objpath, self)) + local ok, errors = instance:compile(srcpath, objpath, self) if not ok and option_.get("verbose") then print(errors) end @@ -148,7 +148,7 @@ function option:_check_function(checkcode, srcpath, objpath) srcfile:close() -- execute the compile command - local ok, errors = instance:run(instance:compcmd(srcpath, objpath, self)) + local ok, errors = instance:compile(srcpath, objpath, self) if not ok and option_.get("verbose") then print(errors) end @@ -202,7 +202,7 @@ function option:_check_typedef(typedef, srcpath, objpath) srcfile:close() -- execute the compile command - local ok, errors = instance:run(instance:compcmd(srcpath, objpath, self)) + local ok, errors = instance:compile(srcpath, objpath, self) if not ok and option_.get("verbose") then print(errors) end diff --git a/xmake/core/project/target.lua b/xmake/core/project/target.lua index a1f75be5f..5e3669c69 100644 --- a/xmake/core/project/target.lua +++ b/xmake/core/project/target.lua @@ -64,26 +64,6 @@ function target:name() return self._NAME end --- get the linker -function target:linker() - - -- check - assert(self) - - -- load the linker from the given kind - return linker.load(self:get("kind")) -end - --- get the compiler with the given source file -function target:compiler(srcfile) - - -- check - assert(self and srcfile) - - -- load the compiler - return compiler.load(compiler.kind_of_file(srcfile)) -end - -- get the options function target:options() diff --git a/xmake/core/sandbox/modules/import/core/tool/archiver.lua b/xmake/core/sandbox/modules/import/core/tool/archiver.lua new file mode 100644 index 000000000..db354258c --- /dev/null +++ b/xmake/core/sandbox/modules/import/core/tool/archiver.lua @@ -0,0 +1,61 @@ +--!The Automatic Cross-platform Build Tool +-- +-- XMake is free software; you can redistribute it and/or modify +-- it under the terms of the GNU Lesser General Public License as published by +-- the Free Software Foundation; either version 2.1 of the License, or +-- (at your option) any later version. +-- +-- XMake is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU Lesser General Public License for more details. +-- +-- You should have received a copy of the GNU Lesser General Public License +-- along with XMake; +-- If not, see <a href="http://www.gnu.org/licenses/"> http://www.gnu.org/licenses/</a> +-- +-- Copyright (C) 2015 - 2016, ruki All rights reserved. +-- +-- @author ruki +-- @file archiver.lua +-- + +-- define module +local sandbox_core_tool_archiver = sandbox_core_tool_archiver or {} + +-- load modules +local platform = require("platform/platform") +local archiver = require("tool/archiver") +local raise = require("sandbox/modules/raise") + +-- make command for archiving library file +function sandbox_core_tool_archiver.archivecmd(objectfiles, targetfile, target) + + -- get the archiver instance + local instance, errors = archiver.load() + if not instance then + raise(errors) + end + + -- make command + return instance:archivecmd(objectfiles, targetfile, target) +end + +-- archive library file +function sandbox_core_tool_archiver.archive(objectfiles, targetfile, target) + + -- get the archiver instance + local instance, errors = archiver.load() + if not instance then + raise(errors) + end + + -- archive it + local ok, errors = instance:archive(objectfiles, targetfile, target) + if not ok then + raise(errors) + end +end + +-- return module +return sandbox_core_tool_archiver diff --git a/xmake/core/sandbox/modules/import/core/tool/extractor.lua b/xmake/core/sandbox/modules/import/core/tool/extractor.lua new file mode 100644 index 000000000..5c7ec29f1 --- /dev/null +++ b/xmake/core/sandbox/modules/import/core/tool/extractor.lua @@ -0,0 +1,48 @@ +--!The Automatic Cross-platform Build Tool +-- +-- XMake is free software; you can redistribute it and/or modify +-- it under the terms of the GNU Lesser General Public License as published by +-- the Free Software Foundation; either version 2.1 of the License, or +-- (at your option) any later version. +-- +-- XMake is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU Lesser General Public License for more details. +-- +-- You should have received a copy of the GNU Lesser General Public License +-- along with XMake; +-- If not, see <a href="http://www.gnu.org/licenses/"> http://www.gnu.org/licenses/</a> +-- +-- Copyright (C) 2015 - 2016, ruki All rights reserved. +-- +-- @author ruki +-- @file extractor.lua +-- + +-- define module +local sandbox_core_tool_extractor = sandbox_core_tool_extractor or {} + +-- load modules +local platform = require("platform/platform") +local extractor = require("tool/extractor") +local raise = require("sandbox/modules/raise") + +-- extract library file +function sandbox_core_tool_extractor.extract(libraryfile, objectdir) + + -- get the extractor instance + local instance, errors = extractor.load() + if not instance then + raise(errors) + end + + -- extract it + local ok, errors = instance:extract(libraryfile, objectdir) + if not ok then + raise(errors) + end +end + +-- return module +return sandbox_core_tool_extractor diff --git a/xmake/core/sandbox/modules/import/core/tool/tool.lua b/xmake/core/sandbox/modules/import/core/tool/tool.lua index 539c9eeb6..27e20d6f4 100644 --- a/xmake/core/sandbox/modules/import/core/tool/tool.lua +++ b/xmake/core/sandbox/modules/import/core/tool/tool.lua @@ -36,22 +36,6 @@ function sandbox_core_tool.shellname(name) return platform.tool(name) end --- run the tool -function sandbox_core_tool.run(name, ...) - - -- check - assert(name) - - -- load the tool instance - local instance, errors = tool.load(name) - if not instance then - raise(errors) - end - - -- run it - instance.run(...) -end - -- check the tool and return the absolute path if exists function sandbox_core_tool.check(shellname, dirs, check) diff --git a/xmake/core/tool/archiver.lua b/xmake/core/tool/archiver.lua new file mode 100644 index 000000000..1fcb840b6 --- /dev/null +++ b/xmake/core/tool/archiver.lua @@ -0,0 +1,289 @@ +--!The Automatic Cross-platform Build Tool +-- +-- XMake is free software; you can redistribute it and/or modify +-- it under the terms of the GNU Lesser General Public License as published by +-- the Free Software Foundation; either version 2.1 of the License, or +-- (at your option) any later version. +-- +-- XMake is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU Lesser General Public License for more details. +-- +-- You should have received a copy of the GNU Lesser General Public License +-- along with XMake; +-- If not, see <a href="http://www.gnu.org/licenses/"> http://www.gnu.org/licenses/</a> +-- +-- Copyright (C) 2015 - 2016, ruki All rights reserved. +-- +-- @author ruki +-- @file archiver.lua +-- + +-- define module +local archiver = archiver or {} + +-- load modules +local io = require("base/io") +local path = require("base/path") +local utils = require("base/utils") +local table = require("base/table") +local string = require("base/string") +local config = require("project/config") +local sandbox = require("sandbox/sandbox") +local platform = require("platform/platform") +local tool = require("tool/tool") + +-- get the current tool +function archiver:_tool() + + -- get it + return self._TOOL +end + +-- get the current flag name +function archiver:_flagname() + + -- get it + return self._FLAGNAME +end + +-- get the flags +function archiver:_flags(target) + + -- get the target key + local key = tostring(target) + + -- get it directly from cache dirst + self._FLAGS = self._FLAGS or {} + if self._FLAGS[key] then + return self._FLAGS[key] + end + + -- add flags from the configure + local flags = {} + self:_addflags_from_config(flags) + + -- add flags from the target + self:_addflags_from_target(flags, target) + + -- add flags from the platform + self:_addflags_from_platform(flags) + + -- add flags from the archiver + self:_addflags_from_archiver(flags) + + -- remove repeat + flags = table.unique(flags) + + -- merge flags + flags = table.concat(flags, " "):trim() + + -- save flags + self._FLAGS[key] = flags + + -- get it + return flags +end + +-- map gcc flag to the given archiver flag +function archiver:_mapflag(flag, mapflags) + + -- attempt to map it directly + local flag_mapped = mapflags[flag] + if flag_mapped then + return flag_mapped + end + + -- find and replace it using pattern + for k, v in pairs(mapflags) do + local flag_mapped, count = flag:gsub("^" .. k .. "$", function (w) return v end) + if flag_mapped and count ~= 0 then + return utils.ifelse(#flag_mapped ~= 0, flag_mapped, nil) + end + end + + -- check it + if self:check(flag) then + return flag + end +end + +-- map gcc flags to the given archiver flags +function archiver:_mapflags(flags) + + -- wrap flags first + flags = table.wrap(flags) + + -- done + local results = {} + local mapflags = self:get("mapflags") + if mapflags then + + -- map flags + for _, flag in pairs(flags) do + local flag_mapped = self:_mapflag(flag, mapflags) + if flag_mapped then + table.insert(results, flag_mapped) + end + end + + else + + -- check flags + for _, flag in pairs(flags) do + if self:check(flag) then + table.insert(results, flag) + end + end + + end + + -- ok? + return results +end + +-- get the named flags +function archiver:_named_flags(names, flags) + + -- map it + local flags_mapped = {} + for _, name in ipairs(table.wrap(names)) do + table.join2(flags_mapped, self:_mapflags(flags[name])) + end + + -- get it + return flags_mapped +end + +-- add flags from the configure +function archiver:_addflags_from_config(flags) + + -- done + table.join2(flags, config.get(self:_flagname())) +end + +-- add flags from the target +function archiver:_addflags_from_target(flags, target) + + -- add the target flags + table.join2(flags, self:_mapflags(target:get(self:_flagname()))) + + -- add the strip flags + table.join2(flags, self:_named_flags(target:get("strip"), { debug = "-S" + , all = "-s" + })) +end + +-- add flags from the platform +function archiver:_addflags_from_platform(flags) + + -- add flags + table.join2(flags, platform.get(self:_flagname())) +end + +-- add flags from the archiver +function archiver:_addflags_from_archiver(flags) + + -- done + table.join2(flags, self:get(self:_flagname())) +end + +-- load the archiver +function archiver.load() + + -- get it directly from cache dirst + if archiver._INSTANCE then + return archiver._INSTANCE + end + + -- new instance + local instance = table.inherit(archiver) + + -- load the archiver tool from the source file type + local result, errors = tool.load("ar") + if not result then + return nil, errors + end + + -- save tool + instance._TOOL = result + + -- init flag name + instance._FLAGNAME = "arflags" + + -- save this instance + archiver._INSTANCE = instance + + -- ok + return instance +end + +-- get properties of the tool +function archiver:get(name) + + -- get it + return self:_tool().get(name) +end + +-- archive the library file +function archiver:archive(objectfiles, targetfile, target) + + -- get flags + local flags = nil + if target then + flags = self:_flags(target) + end + + -- archive it + return sandbox.load(self:_tool().archive, table.concat(table.wrap(objectfiles), " "), targetfile, flags or "") +end + +-- get the archive command +function archiver:archivecmd(objectfiles, targetfile, target) + + -- get flags + local flags = nil + if target then + flags = self:_flags(target) + end + + -- get it + return self:_tool().archivecmd(table.concat(table.wrap(objectfiles), " "), targetfile, flags or "") +end + +-- check the given flags +function archiver:check(flags) + + -- the archiver tool + local ltool = self:_tool() + + -- no check? + if not ltool.check then + return true + end + + -- have been checked? return it directly + self._CHECKED = self._CHECKED or {} + if self._CHECKED[flags] ~= nil then + return self._CHECKED[flags] + end + + -- check it + local ok, errors = sandbox.load(ltool.check, flags) + + -- trace + utils.verbose("checking for the flags %s ... %s", flags, utils.ifelse(ok, "ok", "no")) + if not ok then + utils.verbose(errors) + end + + -- save the checked result + self._CHECKED[flags] = ok + + -- ok? + return ok +end + +-- return module +return archiver diff --git a/xmake/core/tool/compiler.lua b/xmake/core/tool/compiler.lua index da4e284fd..bb4aa2455 100644 --- a/xmake/core/tool/compiler.lua +++ b/xmake/core/tool/compiler.lua @@ -478,22 +478,5 @@ function compiler:check(flags) return ok end --- run the command -function compiler:run(...) - - -- the compiler tool - local ctool = self:_tool() - - -- no run interface? - if not ctool.run then - - -- run it - return os.run(...) - end - - -- run it - return sandbox.load(ctool.run, ...) -end - -- return module return compiler diff --git a/xmake/core/tool/extractor.lua b/xmake/core/tool/extractor.lua new file mode 100644 index 000000000..cca1977a8 --- /dev/null +++ b/xmake/core/tool/extractor.lua @@ -0,0 +1,86 @@ +--!The Automatic Cross-platform Build Tool +-- +-- XMake is free software; you can redistribute it and/or modify +-- it under the terms of the GNU Lesser General Public License as published by +-- the Free Software Foundation; either version 2.1 of the License, or +-- (at your option) any later version. +-- +-- XMake is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU Lesser General Public License for more details. +-- +-- You should have received a copy of the GNU Lesser General Public License +-- along with XMake; +-- If not, see <a href="http://www.gnu.org/licenses/"> http://www.gnu.org/licenses/</a> +-- +-- Copyright (C) 2015 - 2016, ruki All rights reserved. +-- +-- @author ruki +-- @file extractor.lua +-- + +-- define module +local extractor = extractor or {} + +-- load modules +local io = require("base/io") +local path = require("base/path") +local utils = require("base/utils") +local table = require("base/table") +local string = require("base/string") +local config = require("project/config") +local sandbox = require("sandbox/sandbox") +local platform = require("platform/platform") +local tool = require("tool/tool") + +-- get the current tool +function extractor:_tool() + + -- get it + return self._TOOL +end + +-- load the extractor +function extractor.load() + + -- get it directly from cache dirst + if extractor._INSTANCE then + return extractor._INSTANCE + end + + -- new instance + local instance = table.inherit(extractor) + + -- load the extractor tool + local result, errors = tool.load("ex") + if not result then + return nil, errors + end + + -- save tool + instance._TOOL = result + + -- save this instance + extractor._INSTANCE = instance + + -- ok + return instance +end + +-- get properties of the tool +function extractor:get(name) + + -- get it + return self:_tool().get(name) +end + +-- extract the library file +function extractor:extract(libraryfile, objectdir) + + -- extract it + return sandbox.load(self:_tool().extract, libraryfile, objectdir) +end + +-- return module +return extractor diff --git a/xmake/core/tool/linker.lua b/xmake/core/tool/linker.lua index 41ce9bfd3..360259cb7 100644 --- a/xmake/core/tool/linker.lua +++ b/xmake/core/tool/linker.lua @@ -56,7 +56,6 @@ function linker._kind_of_target(targetkind) local kinds = { ["binary"] = "ld" - , ["static"] = "ar" , ["shared"] = "sh" } @@ -308,7 +307,6 @@ function linker.load(targetkind) local flagname = { ld = "ldflags" - , ar = "arflags" , sh = "shflags" } instance._FLAGNAME = flagname[kind] @@ -341,7 +339,7 @@ function linker:link(objectfiles, targetfile, target) flags = self:_flags(target) end - -- get it + -- link it return sandbox.load(self:_tool().link, table.concat(table.wrap(objectfiles), " "), targetfile, flags or "") end @@ -405,22 +403,5 @@ function linker:check(flags) return ok end --- run the command -function linker:run(...) - - -- the linker tool - local ltool = self:_tool() - - -- no run interface? - if not ltool.run then - - -- run it - return os.run(...) - end - - -- run it - return sandbox.load(ltool.run, ...) -end - -- return module return linker diff --git a/xmake/platforms/android/checker.lua b/xmake/platforms/android/checker.lua index ae77bab8d..315882425 100644 --- a/xmake/platforms/android/checker.lua +++ b/xmake/platforms/android/checker.lua @@ -112,7 +112,7 @@ function _check_toolchains(config) checker.check_toolchain(config, "cxx", cross, "g++", "the c++ compiler") checker.check_toolchain(config, "as", cross, "gcc", "the assember") checker.check_toolchain(config, "ld", cross, "g++", "the linker") - checker.check_toolchain(config, "ar", cross, "ar", "the static library linker") + checker.check_toolchain(config, "ar", cross, "ar", "the static library archiver") checker.check_toolchain(config, "ex", cross, "ar", "the static library extractor") checker.check_toolchain(config, "sh", cross, "g++", "the shared library linker") end diff --git a/xmake/platforms/iphoneos/checker.lua b/xmake/platforms/iphoneos/checker.lua index 172b9d889..8577eae0b 100644 --- a/xmake/platforms/iphoneos/checker.lua +++ b/xmake/platforms/iphoneos/checker.lua @@ -53,7 +53,7 @@ function _check_toolchains(config) checker.check_toolchain(config, "as", "xcrun -sdk iphonesimulator ", "clang", "the assember") checker.check_toolchain(config, "ld", "xcrun -sdk iphonesimulator ", "clang++", "the linker") checker.check_toolchain(config, "ld", "xcrun -sdk iphonesimulator ", "clang", "the linker") - checker.check_toolchain(config, "ar", "xcrun -sdk iphonesimulator ", "ar", "the static library linker") + checker.check_toolchain(config, "ar", "xcrun -sdk iphonesimulator ", "ar", "the static library archiver") checker.check_toolchain(config, "ex", "xcrun -sdk iphonesimulator ", "ar", "the static library extractor") checker.check_toolchain(config, "sh", "xcrun -sdk iphonesimulator ", "clang++", "the shared library linker") checker.check_toolchain(config, "sh", "xcrun -sdk iphonesimulator ", "clang", "the shared library linker") @@ -68,7 +68,7 @@ function _check_toolchains(config) checker.check_toolchain(config, "as", path.join(os.toolsdir(), "utils/gas-preprocessor.pl xcrun -sdk iphoneos "), "clang", "the assember", _check_as) checker.check_toolchain(config, "ld", "xcrun -sdk iphoneos ", "clang++", "the linker") checker.check_toolchain(config, "ld", "xcrun -sdk iphoneos ", "clang", "the linker") - checker.check_toolchain(config, "ar", "xcrun -sdk iphoneos ", "ar", "the static library linker") + checker.check_toolchain(config, "ar", "xcrun -sdk iphoneos ", "ar", "the static library archiver") checker.check_toolchain(config, "ex", "xcrun -sdk iphoneos ", "ar", "the static library extractor") checker.check_toolchain(config, "sh", "xcrun -sdk iphoneos ", "clang++", "the shared library linker") checker.check_toolchain(config, "sh", "xcrun -sdk iphoneos ", "clang", "the shared library linker") diff --git a/xmake/platforms/linux/checker.lua b/xmake/platforms/linux/checker.lua index b7e24f1a5..b2ebd2998 100644 --- a/xmake/platforms/linux/checker.lua +++ b/xmake/platforms/linux/checker.lua @@ -68,7 +68,7 @@ function _check_toolchains(config) checker.check_toolchain(config, "cxx", cross, "g++", "the c++ compiler") checker.check_toolchain(config, "as", cross, "gcc", "the assember") checker.check_toolchain(config, "ld", cross, "g++", "the linker") - checker.check_toolchain(config, "ar", cross, "ar", "the static library linker") + checker.check_toolchain(config, "ar", cross, "ar", "the static library archiver") checker.check_toolchain(config, "ex", cross, "ar", "the static library extractor") checker.check_toolchain(config, "sh", cross, "g++", "the shared library linker") end diff --git a/xmake/platforms/macosx/checker.lua b/xmake/platforms/macosx/checker.lua index 777f45d96..dc996841c 100644 --- a/xmake/platforms/macosx/checker.lua +++ b/xmake/platforms/macosx/checker.lua @@ -37,7 +37,7 @@ function _check_toolchains(config) checker.check_toolchain(config, "as", "xcrun -sdk macosx ", "clang", "the assember") checker.check_toolchain(config, "ld", "xcrun -sdk macosx ", "clang++", "the linker") checker.check_toolchain(config, "ld", "xcrun -sdk macosx ", "clang", "the linker") - checker.check_toolchain(config, "ar", "xcrun -sdk macosx ", "ar", "the static library linker") + checker.check_toolchain(config, "ar", "xcrun -sdk macosx ", "ar", "the static library archiver") checker.check_toolchain(config, "ex", "xcrun -sdk macosx ", "ar", "the static library extractor") checker.check_toolchain(config, "sh", "xcrun -sdk macosx ", "clang++", "the shared library linker") checker.check_toolchain(config, "sh", "xcrun -sdk macosx ", "clang", "the shared library linker") diff --git a/xmake/platforms/mingw/checker.lua b/xmake/platforms/mingw/checker.lua index d45057e54..c5f78de20 100644 --- a/xmake/platforms/mingw/checker.lua +++ b/xmake/platforms/mingw/checker.lua @@ -55,7 +55,7 @@ function _check_toolchains(config) checker.check_toolchain(config, "as", cross, "gcc", "the assember") checker.check_toolchain(config, "ld", cross, "g++", "the linker") checker.check_toolchain(config, "ld", cross, "gcc", "the linker") - checker.check_toolchain(config, "ar", cross, "ar", "the static library linker") + checker.check_toolchain(config, "ar", cross, "ar", "the static library archiver") checker.check_toolchain(config, "ex", cross, "ar", "the static library extractor") checker.check_toolchain(config, "sh", cross, "g++", "the shared library linker") checker.check_toolchain(config, "sh", cross, "gcc", "the shared library linker") diff --git a/xmake/platforms/watchos/checker.lua b/xmake/platforms/watchos/checker.lua index 2cdd0d5a7..3dfe39964 100644 --- a/xmake/platforms/watchos/checker.lua +++ b/xmake/platforms/watchos/checker.lua @@ -53,7 +53,7 @@ function _check_toolchains(config) checker.check_toolchain(config, "as", "xcrun -sdk watchsimulator ", "clang", "the assember") checker.check_toolchain(config, "ld", "xcrun -sdk watchsimulator ", "clang++", "the linker") checker.check_toolchain(config, "ld", "xcrun -sdk watchsimulator ", "clang", "the linker") - checker.check_toolchain(config, "ar", "xcrun -sdk watchsimulator ", "ar", "the static library linker") + checker.check_toolchain(config, "ar", "xcrun -sdk watchsimulator ", "ar", "the static library archiver") checker.check_toolchain(config, "ex", "xcrun -sdk watchsimulator ", "ar", "the static library extractor") checker.check_toolchain(config, "sh", "xcrun -sdk watchsimulator ", "clang++", "the shared library linker") checker.check_toolchain(config, "sh", "xcrun -sdk watchsimulator ", "clang", "the shared library linker") @@ -68,7 +68,7 @@ function _check_toolchains(config) checker.check_toolchain(config, "as", path.join(os.toolsdir(), "utils/gas-preprocessor.pl xcrun -sdk watchos "), "clang", "the assember", _check_as) checker.check_toolchain(config, "ld", "xcrun -sdk watchos ", "clang++", "the linker") checker.check_toolchain(config, "ld", "xcrun -sdk watchos ", "clang", "the linker") - checker.check_toolchain(config, "ar", "xcrun -sdk watchos ", "ar", "the static library linker") + checker.check_toolchain(config, "ar", "xcrun -sdk watchos ", "ar", "the static library archiver") checker.check_toolchain(config, "ex", "xcrun -sdk watchos ", "ar", "the static library extractor") checker.check_toolchain(config, "sh", "xcrun -sdk watchos ", "clang++", "the shared library linker") checker.check_toolchain(config, "sh", "xcrun -sdk watchos ", "clang", "the shared library linker") diff --git a/xmake/platforms/windows/checker.lua b/xmake/platforms/windows/checker.lua index 7b185f252..d0dbaff10 100644 --- a/xmake/platforms/windows/checker.lua +++ b/xmake/platforms/windows/checker.lua @@ -155,7 +155,7 @@ function _check_toolchains(config) checker.check_toolchain(config, "cxx", "", "cl.exe", "the c++ compiler") checker.check_toolchain(config, "as", "", "ml.exe", "the assember") checker.check_toolchain(config, "ld", "", "link.exe", "the linker") - checker.check_toolchain(config, "ar", "", "link.exe -lib", "the static library linker") + checker.check_toolchain(config, "ar", "", "link.exe -lib", "the static library archiver") checker.check_toolchain(config, "sh", "", "link.exe -dll", "the shared library linker") checker.check_toolchain(config, "ex", "", "lib.exe", "the static library extractor") diff --git a/xmake/plugins/project/makefile.lua b/xmake/plugins/project/makefile.lua index 405441368..7620293ae 100755 --- a/xmake/plugins/project/makefile.lua +++ b/xmake/plugins/project/makefile.lua @@ -23,6 +23,7 @@ -- imports import("core.tool.tool") import("core.tool.linker") +import("core.tool.archiver") import("core.tool.compiler") import("core.project.project") @@ -79,9 +80,6 @@ function _make_object(makefile, target, srcfile, objfile) -- make command local ccache = tool.shellname("ccache") local command = compiler.compcmd(srcfile, objfile, target) - if ccache then - command = ccache:append(command, " ") - end -- make head makefile:printf("%s:", objfile) @@ -140,7 +138,12 @@ function _make_target(makefile, target) makefile:print("") -- make the command - local command = linker.linkcmd(target:objectfiles(), targetfile, target) + local command = nil + if target:get("kind") == "static" then + command = archiver.archivecmd(target:objectfiles(), targetfile, target) + else + command = linker.linkcmd(target:objectfiles(), targetfile, target) + end -- make body makefile:print("\t@echo linking.$(mode) %s", path.filename(targetfile)) @@ -212,5 +215,4 @@ function make(outputfile) -- leave project directory os.cd(olddir) - end diff --git a/xmake/tools/ar.lua b/xmake/tools/ar.lua index 79d3cdc58..b81126971 100644 --- a/xmake/tools/ar.lua +++ b/xmake/tools/ar.lua @@ -44,29 +44,21 @@ function get(name) return _g[name] end --- make the linklib flag -function linklib(lib) -end - --- make the linkdir flag -function linkdir(dir) -end - --- make the link command -function linkcmd(objectfiles, targetfile, flags) +-- make the archive command +function archivecmd(objectfiles, targetfile, flags) -- make it return format("%s %s %s %s", _g.shellname, flags, targetfile, objectfiles) end --- link the target file -function link(objectfiles, targetfile, flags) +-- archive the library file +function archive(objectfiles, targetfile, flags) -- ensure the target directory os.mkdir(path.directory(targetfile)) -- link it - os.run(linkcmd(objectfiles, targetfile, flags)) + os.run(archivecmd(objectfiles, targetfile, flags)) end -- extract the static library to object directory @@ -98,26 +90,14 @@ function extract(libraryfile, objectdir) os.cd(olddir) end --- run command -function run(...) - - -- extract it - if _g.kind == "ex" then - return extract(...) - end - - -- run it - os.run(...) -end - -- check the given flags function check(flags) -- make an stub source file - local libfile = path.join(os.tmpdir(), "xmake.ar.a") - local objfile = path.join(os.tmpdir(), "xmake.ar.o") - local srcfile = path.join(os.tmpdir(), "xmake.ar.c") - io.write(srcfile, "int test(void)\n{return 0;}") + local libraryfile = path.join(os.tmpdir(), "xmake.ar.a") + local objectfile = path.join(os.tmpdir(), "xmake.ar.o") + local sourcefile = path.join(os.tmpdir(), "xmake.ar.c") + io.write(sourcefile, "int test(void)\n{return 0;}") -- make flags local arflags = table.concat(_g.arflags, " ") @@ -125,14 +105,14 @@ function check(flags) arflags = arflags .. " " .. flags end - -- make the compile command - os.run(compiler.compcmd(srcfile, objfile)) + -- compile it + compiler.compile(sourcefile, objectfile) -- check it - os.run(linkcmd(objfile, libfile, arflags)) + archive(objectfile, libraryfile, arflags) -- remove files - os.rm(objfile) - os.rm(srcfile) - os.rm(libfile) + os.rm(objectfile) + os.rm(sourcefile) + os.rm(libraryfile) end diff --git a/xmake/tools/ccache.lua b/xmake/tools/ccache.lua index cd91dba0d..964f2f8d1 100644 --- a/xmake/tools/ccache.lua +++ b/xmake/tools/ccache.lua @@ -35,13 +35,6 @@ function get(name) return _g[name] end --- run it -function run(...) - - -- run it - os.run(...) -end - -- check the given flags function check(flags) diff --git a/xmake/tools/cl.lua b/xmake/tools/cl.lua index d9a145f8b..c71111300 100755 --- a/xmake/tools/cl.lua +++ b/xmake/tools/cl.lua @@ -125,13 +125,6 @@ function compile(sourcefile, objectfile, flags, multitasking) end end --- run command -function run(...) - - -- run it - os.run(...) -end - -- check the given flags function check(flags) diff --git a/xmake/tools/gcc.lua b/xmake/tools/gcc.lua index 9b81c456c..5019aa06f 100755 --- a/xmake/tools/gcc.lua +++ b/xmake/tools/gcc.lua @@ -20,6 +20,10 @@ -- @file gcc.lua -- +-- imports +import("core.tool.tool") +import("core.project.config") + -- init it function init(shellname, kind) @@ -111,8 +115,20 @@ end -- make the complie command function compcmd(sourcefile, objectfile, flags) + -- get ccache + local ccache = nil + if config.get("ccache") then + ccache = tool.shellname("ccache") + end + -- make it - return format("%s -c %s -o %s %s", _g.shellname, flags, objectfile, sourcefile) + local command = format("%s -c %s -o %s %s", _g.shellname, flags, objectfile, sourcefile) + if ccache then + command = ccache:append(command, " ") + end + + -- ok + return command end -- link the target file @@ -139,13 +155,6 @@ function compile(sourcefile, objectfile, flags, multitasking) end end --- run command -function run(...) - - -- run it - os.run(...) -end - -- check the given flags function check(flags) diff --git a/xmake/tools/lib.lua b/xmake/tools/lib.lua index 4c7f6c819..cde70ae69 100755 --- a/xmake/tools/lib.lua +++ b/xmake/tools/lib.lua @@ -72,18 +72,6 @@ function extract(libraryfile, objectdir) end end --- run command -function run(...) - - -- extract it - if _g.kind == "ex" then - return extract(...) - end - - -- run it - os.run(...) -end - -- check the given flags function check(flags) diff --git a/xmake/tools/link.lua b/xmake/tools/link.lua index 85c97fb95..3b57e551a 100755 --- a/xmake/tools/link.lua +++ b/xmake/tools/link.lua @@ -110,11 +110,14 @@ function link(objectfiles, targetfile, flags) os.run(linkcmd(objectfiles, targetfile, flags)) end --- run command -function run(...) +-- make the archive command +function archivecmd(objectfiles, targetfile, flags) + return linkcmd(objectfiles, targetfile, flags) +end - -- run it - os.run(...) +-- archive the library file +function archive(objectfiles, targetfile, flags) + link(objectfile, targetfile, flags) end -- check the given flags diff --git a/xmake/tools/ml.lua b/xmake/tools/ml.lua index 02e37d0df..26233c8ae 100755 --- a/xmake/tools/ml.lua +++ b/xmake/tools/ml.lua @@ -116,13 +116,6 @@ function compile(sourcefile, objectfile, flags, multitasking) end end --- run command -function run(...) - - -- run it - os.run(...) -end - -- check the given flags function check(flags) diff --git a/xmake/tools/swiftc.lua b/xmake/tools/swiftc.lua index cb391b0f8..9f7842440 100644 --- a/xmake/tools/swiftc.lua +++ b/xmake/tools/swiftc.lua @@ -21,6 +21,7 @@ -- -- imports +import("core.tool.tool") import("core.project.config") -- init it @@ -76,8 +77,20 @@ end -- make the compile command function compcmd(sourcefile, objectfile, flags) + -- get ccache + local ccache = nil + if config.get("ccache") then + ccache = tool.shellname("ccache") + end + -- make it - return format("%s -c %s -o %s %s", _g.shellname, flags, objectfile, sourcefile) + local command = format("%s -c %s -o %s %s", _g.shellname, flags, objectfile, sourcefile) + if ccache then + command = ccache:append(command, " ") + end + + -- ok + return command end -- complie the source file @@ -115,13 +128,6 @@ function undefine(macro) return "-Xcc -U" .. macro end --- run command -function run(...) - - -- run it - os.run(...) -end - -- check the given flags function check(flags) |
