diff options
Diffstat (limited to 'xmake/actions/build/builder.lua')
| -rwxr-xr-x | xmake/actions/build/builder.lua | 221 |
1 files changed, 20 insertions, 201 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 |
