summaryrefslogtreecommitdiff
path: root/xmake/actions/build/builder.lua
diff options
context:
space:
mode:
Diffstat (limited to 'xmake/actions/build/builder.lua')
-rwxr-xr-xxmake/actions/build/builder.lua221
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