diff options
| author | ruki <[email protected]> | 2019-09-04 10:09:50 +0800 |
|---|---|---|
| committer | GitHub <[email protected]> | 2019-09-04 10:09:50 +0800 |
| commit | 1a1eac4f9e099eed250d72f309cf479efbb15a1c (patch) | |
| tree | bd0341661b3db9fc2f557b6b4186d5193671371d | |
| parent | c97ee9d0ba48ac615caa9f239436645bc2e0af5a (diff) | |
| parent | 3d72809db048911efec3d52106dd6968349ef4d1 (diff) | |
Merge pull request #563 from xmake-io/buildrules
Separate build rules for specific language files from action/build
76 files changed, 1189 insertions, 1115 deletions
diff --git a/.travis.yml b/.travis.yml index 25291faa0..34afdb3f6 100644 --- a/.travis.yml +++ b/.travis.yml @@ -34,6 +34,5 @@ script: - travis_wait 60 xmake lua -v -D tests/run.lua - scripts/archive-all.sh - scripts/makeself/build-runfile.sh - - ls -l scripts/makeself/xmake.gz.run - scripts/makeself/xmake.gz.run --info diff --git a/core/src/xmake/os/mtime.c b/core/src/xmake/os/mtime.c index 690ba46c1..dc9d70a22 100644 --- a/core/src/xmake/os/mtime.c +++ b/core/src/xmake/os/mtime.c @@ -44,7 +44,7 @@ tb_int_t xm_os_mtime(lua_State* lua) // done os.mtime(path) tb_file_info_t info = {0}; - if (tb_file_info(path, &info) && (info.type == TB_FILE_TYPE_FILE)) + if (tb_file_info(path, &info)) lua_pushinteger(lua, (lua_Integer)info.mtime); else lua_pushinteger(lua, 0); diff --git a/tests/projects/c/shared_library/xmake.lua b/tests/projects/c/shared_library/xmake.lua index 50bad8879..48ccc67b3 100644 --- a/tests/projects/c/shared_library/xmake.lua +++ b/tests/projects/c/shared_library/xmake.lua @@ -1,45 +1,12 @@ --- the debug mode -if is_mode("debug") then - - -- enable the debug symbols - set_symbols("debug") +add_rules("mode.release", "mode.debug") - -- disable optimization - set_optimize("none") -end - --- the release mode -if is_mode("release") then - - -- set the symbols visibility: hidden - set_symbols("hidden") - - -- enable fastest optimization - set_optimize("fastest") - - -- strip all symbols - set_strip("all") -end - --- add target target("shared_library_c") - - -- set kind set_kind("shared") - - -- add files add_files("src/interface.c") --- add target target("test") - - -- set kind set_kind("binary") - - -- add deps add_deps("shared_library_c") - - -- add files add_files("src/test.c") diff --git a/tests/projects/c/static_library/xmake.lua b/tests/projects/c/static_library/xmake.lua index 842921894..c3cc56e1a 100644 --- a/tests/projects/c/static_library/xmake.lua +++ b/tests/projects/c/static_library/xmake.lua @@ -1,45 +1,12 @@ --- the debug mode -if is_mode("debug") then - - -- enable the debug symbols - set_symbols("debug") +add_rules("mode.release", "mode.debug") - -- disable optimization - set_optimize("none") -end - --- the release mode -if is_mode("release") then - - -- set the symbols visibility: hidden - set_symbols("hidden") - - -- enable fastest optimization - set_optimize("fastest") - - -- strip all symbols - set_strip("all") -end - --- add target target("static_library_c") - - -- set kind set_kind("static") - - -- add files add_files("src/interface.c") --- add target target("test") - - -- set kind set_kind("binary") - - -- add deps add_deps("static_library_c") - - -- add files add_files("src/test.c") diff --git a/tests/projects/hybrid/static_library/src/main.cpp b/tests/projects/hybrid/static_library/src/main.cpp new file mode 100644 index 000000000..effbee53a --- /dev/null +++ b/tests/projects/hybrid/static_library/src/main.cpp @@ -0,0 +1,12 @@ +#include "test.h" + +int main(int argc, char** argv) +{ + test1(); +#ifdef MACOSX + test2(); + test3(); +#endif + test4(); + return 0; +} diff --git a/tests/projects/hybrid/static_library/src/main2.cpp b/tests/projects/hybrid/static_library/src/main2.cpp new file mode 100644 index 000000000..73890bc01 --- /dev/null +++ b/tests/projects/hybrid/static_library/src/main2.cpp @@ -0,0 +1,7 @@ +#include "test.h" + +int main(int argc, char** argv) +{ + test5(); + return 0; +} diff --git a/tests/projects/hybrid/static_library/src/test.h b/tests/projects/hybrid/static_library/src/test.h new file mode 100644 index 000000000..f794a69c7 --- /dev/null +++ b/tests/projects/hybrid/static_library/src/test.h @@ -0,0 +1,13 @@ +#ifdef __cplusplus +extern "C" { +#endif + +void test1(void); +void test2(void); +void test3(void); +void test4(void); +int test5(void); + +#ifdef __cplusplus +} +#endif diff --git a/tests/projects/hybrid/static_library/src/test1.c b/tests/projects/hybrid/static_library/src/test1.c new file mode 100644 index 000000000..8e0c1e021 --- /dev/null +++ b/tests/projects/hybrid/static_library/src/test1.c @@ -0,0 +1,5 @@ +#include "test.h" + +void test1() +{ +} diff --git a/tests/projects/hybrid/static_library/src/test2.m b/tests/projects/hybrid/static_library/src/test2.m new file mode 100644 index 000000000..2164a8bf5 --- /dev/null +++ b/tests/projects/hybrid/static_library/src/test2.m @@ -0,0 +1,5 @@ +#include "test.h" + +void test2() +{ +} diff --git a/tests/projects/hybrid/static_library/src/test3.mm b/tests/projects/hybrid/static_library/src/test3.mm new file mode 100644 index 000000000..ea33c33d5 --- /dev/null +++ b/tests/projects/hybrid/static_library/src/test3.mm @@ -0,0 +1,5 @@ +#include "test.h" + +void test3() +{ +} diff --git a/tests/projects/hybrid/static_library/src/test4.cpp b/tests/projects/hybrid/static_library/src/test4.cpp new file mode 100644 index 000000000..3cdf598a2 --- /dev/null +++ b/tests/projects/hybrid/static_library/src/test4.cpp @@ -0,0 +1,5 @@ +#include "test.h" + +void test4() +{ +} diff --git a/tests/projects/hybrid/static_library/src/test5.d b/tests/projects/hybrid/static_library/src/test5.d new file mode 100644 index 000000000..d6519665d --- /dev/null +++ b/tests/projects/hybrid/static_library/src/test5.d @@ -0,0 +1,5 @@ + +extern(C) int test5() +{ + return 5; +} diff --git a/tests/projects/other/merge_static_library/test.lua b/tests/projects/hybrid/static_library/test.lua index b76241be2..b76241be2 100644 --- a/tests/projects/other/merge_static_library/test.lua +++ b/tests/projects/hybrid/static_library/test.lua diff --git a/tests/projects/hybrid/static_library/xmake.lua b/tests/projects/hybrid/static_library/xmake.lua new file mode 100644 index 000000000..bc382c7c3 --- /dev/null +++ b/tests/projects/hybrid/static_library/xmake.lua @@ -0,0 +1,24 @@ +add_rules("mode.release", "mode.debug") + +target("test") + set_kind("static") + add_files("src/*.c", "src/*.cpp") + if is_plat("macosx") then + add_files("src/*.m", "src/*.mm") + end + +target("demo") + set_kind("binary") + add_deps("test") + add_files("src/main.cpp") + if is_plat("macosx") then + add_defines("MACOSX") + end + +target("demo2") + set_kind("binary") + add_files("src/main2.cpp", "src/*.d") + if not is_plat("macosx") then + set_enabled(false) + end + diff --git a/tests/projects/other/merge_static_library/src/add.c b/tests/projects/other/merge_archive/src/add.c index be1e084fc..be1e084fc 100644 --- a/tests/projects/other/merge_static_library/src/add.c +++ b/tests/projects/other/merge_archive/src/add.c diff --git a/tests/projects/other/merge_static_library/src/mul.c b/tests/projects/other/merge_archive/src/mul.c index c4292f9aa..c4292f9aa 100644 --- a/tests/projects/other/merge_static_library/src/mul.c +++ b/tests/projects/other/merge_archive/src/mul.c diff --git a/tests/projects/other/merge_static_library/src/sub.c b/tests/projects/other/merge_archive/src/sub.c index b151ec4bc..b151ec4bc 100644 --- a/tests/projects/other/merge_static_library/src/sub.c +++ b/tests/projects/other/merge_archive/src/sub.c diff --git a/tests/projects/other/merge_archive/test.lua b/tests/projects/other/merge_archive/test.lua new file mode 100644 index 000000000..b76241be2 --- /dev/null +++ b/tests/projects/other/merge_archive/test.lua @@ -0,0 +1,6 @@ +-- main entry +function main(t) + + -- build project + t:build() +end diff --git a/tests/projects/other/merge_archive/xmake.lua b/tests/projects/other/merge_archive/xmake.lua new file mode 100644 index 000000000..81b22c5e0 --- /dev/null +++ b/tests/projects/other/merge_archive/xmake.lua @@ -0,0 +1,22 @@ +add_rules("mode.debug", "mode.release") + +target("add") + set_kind("static") + add_files("src/add.c") + set_targetdir("$(buildir)/merge_archive") + +target("sub") + set_kind("static") + add_files("src/sub.c") + set_targetdir("$(buildir)/merge_archive") + +target("mul") + set_kind("static") + add_deps("add", "sub") + add_files("src/mul.c") + if is_plat("windows") then + add_files("$(buildir)/merge_archive/*.lib") + else + add_files("$(buildir)/merge_archive/*.a") + end + diff --git a/tests/projects/other/merge_object/xmake.lua b/tests/projects/other/merge_object/xmake.lua index 39e41be3e..772bc2c18 100644 --- a/tests/projects/other/merge_object/xmake.lua +++ b/tests/projects/other/merge_object/xmake.lua @@ -10,6 +10,11 @@ target("merge_object") -- add files add_files("src/interface.c") + -- save object file + after_build_file(function (target, sourcefile) + os.cp(target:objectfile(sourcefile), "$(buildir)/merge_object/") + end) + -- add target target("test") @@ -21,5 +26,9 @@ target("test") -- add files add_files("src/test.c") - add_files("build/.objs/merge_object/src/interface.c.o") + if is_plat("windows") then + add_files("$(buildir)/merge_object/interface.c.obj") + else + add_files("$(buildir)/merge_object/interface.c.o") + end diff --git a/tests/projects/other/merge_static_library/xmake.lua b/tests/projects/other/merge_static_library/xmake.lua deleted file mode 100644 index 729648ca2..000000000 --- a/tests/projects/other/merge_static_library/xmake.lua +++ /dev/null @@ -1,38 +0,0 @@ --- add rules -add_rules("mode.debug", "mode.release") - --- add target -target("add") - - -- set kind - set_kind("static") - - -- add files - add_files("src/add.c") - --- add target -target("sub") - - -- set kind - set_kind("static") - - -- add files - add_files("src/sub.c") - --- add target -target("mul") - - -- set kind - set_kind("static") - - -- add deps - add_deps("add", "sub") - - -- add files - add_files("src/mul.c") - add_files("build/libadd.a") - add_files("build/libsub.a") - - -- add link directory - add_linkdirs("$(buildir)") - diff --git a/xmake/actions/build/build.lua b/xmake/actions/build/build.lua index 84b5dfa5e..60a17bccb 100644 --- a/xmake/actions/build/build.lua +++ b/xmake/actions/build/build.lua @@ -33,40 +33,41 @@ function _clean_target(target) end -- do build the given target -function _do_build_target(target) +function _do_build_target(target, opt) -- build target if not target:isphony() then - import("kinds." .. target:targetkind()).build(target, _g) + import("kinds." .. target:targetkind()).build(target, opt) end end -- on build the given target -function _on_build_target(target) - - -- has been disabled? - if target:get("enabled") == false then - return - end +function _on_build_target(target, opt) -- build target with rules local done = false for _, r in ipairs(target:orderules()) do local on_build = r:script("build") if on_build then - on_build(target, {origin = _do_build_target}) + on_build(target, opt) done = true end end if done then return end -- do build - _do_build_target(target) + _do_build_target(target, opt) end -- build the given target function _build_target(target) + -- has been disabled? + if target:get("enabled") == false then + _g.targetindex = _g.targetindex + 1 + return + end + -- enter the environments of the target packages local oldenvs = {} for name, values in pairs(target:pkgenvs()) do @@ -74,19 +75,16 @@ function _build_target(target) os.addenv(name, unpack(values)) end + -- compute the progress range + local progress = {} + progress.start = (_g.targetindex * 100) / _g.targetcount + progress.stop = ((_g.targetindex + 1) * 100) / _g.targetcount + -- the target scripts local scripts = { function (target) - -- has been disabled? - if target:get("enabled") == false then - return - end - - -- get progress - local progress = _g.targetindex * 100 / _g.targetcount - -- do before build for target local before_build = target:script("build_before") if before_build then @@ -101,16 +99,15 @@ function _build_target(target) end end end - , target:script("build", _on_build_target) , function (target) - -- has been disabled? - if target:get("enabled") == false then - return + -- do build + local on_build = target:script("build", _on_build_target) + if on_build then + on_build(target, {origin = _do_build_target, progress = progress}) end - - -- get progress - local progress = (_g.targetindex + 1) * 100 / _g.targetcount + end + , function (target) -- do after build for target local after_build = target:script("build_after") @@ -137,7 +134,7 @@ function _build_target(target) for i = 1, 3 do local script = scripts[i] if script ~= nil then - script(target, {origin = (i == 2 and _do_build_target or nil)}) + script(target) end end diff --git a/xmake/actions/build/build_files.lua b/xmake/actions/build/build_files.lua index 6f6641dcb..7b69371d4 100644 --- a/xmake/actions/build/build_files.lua +++ b/xmake/actions/build/build_files.lua @@ -49,24 +49,29 @@ function _prepare_jobs_for_target(jobs, target, filepatterns) local newbatches = {} local sourcecount = 0 - for sourcekind, sourcebatch in pairs(target:sourcebatches()) do + for rulename, sourcebatch in pairs(target:sourcebatches()) do local objectfiles = sourcebatch.objectfiles local dependfiles = sourcebatch.dependfiles + local sourcekind = sourcebatch.sourcekind for idx, sourcefile in ipairs(sourcebatch.sourcefiles) do if _match_sourcefiles(sourcefile, filepatterns) then - local newbatch = newbatches[sourcekind] + local newbatch = newbatches[rulename] if not newbatch then newbatch = {} newbatch.sourcekind = sourcekind - newbatch.rulename = sourcebatch.rulename + newbatch.rulename = rulename newbatch.sourcefiles = {} - newbatch.objectfiles = {} - newbatch.dependfiles = {} end table.insert(newbatch.sourcefiles, sourcefile) - table.insert(newbatch.objectfiles, objectfiles[idx]) - table.insert(newbatch.dependfiles, dependfiles[idx]) - newbatches[sourcekind] = newbatch + if objectfiles then + newbatch.objectfiles = newbatch.objectfiles or {} + table.insert(newbatch.objectfiles, objectfiles[idx]) + end + if dependfiles then + newbatch.dependfiles = newbatch.dependfiles or {} + table.insert(newbatch.dependfiles, dependfiles[idx]) + end + newbatches[rulename] = newbatch sourcecount = sourcecount + 1 end end @@ -117,11 +122,11 @@ function _prepare_jobs(targetname, filepatterns) end -- get source total count - local sourcecount = 0 + local sourcetotal = 0 for _, job in ipairs(jobs) do - sourcecount = sourcecount + job.sourcecount + sourcetotal = sourcetotal + job.sourcecount end - return jobs, sourcecount + return jobs, sourcetotal end -- convert all sourcefiles to lua pattern @@ -179,22 +184,28 @@ function main(targetname, sourcefiles) local filepatterns = _get_file_patterns(sourcefiles) -- prepare jobs - local jobs, sourcecount = _prepare_jobs(targetname, filepatterns) - if #jobs == 0 or sourcecount == 0 then + local jobs, sourcetotal = _prepare_jobs(targetname, filepatterns) + if #jobs == 0 or sourcetotal == 0 then return end -- enter toolchains environment environment.enter("toolchains") - -- build source files for all jobs - _g.finished = {} - _g.targetindex = 0 - _g.targetcount = 1 - _g.sourceindex = 1 - _g.sourcecount = sourcecount + -- build source files + local sourcestart = 1 + local sourcestop = 0 for _, job in ipairs(jobs) do - object.build_sourcefiles(job.target, _g, job.sourcebatches) + + -- compute the sub-progress range + sourcestop = sourcestart + job.sourcecount + local progress_start = (sourcestart * 100) / sourcetotal + local progress_stop = (sourcestop * 100) / sourcetotal + local progress = {start = progress_start, stop = progress_stop} + sourcestart = sourcestop + + -- build files + object.build_sourcefiles(job.target, job.sourcebatches, {progress = progress}) end -- leave toolchains environment diff --git a/xmake/actions/build/kinds/binary.lua b/xmake/actions/build/kinds/binary.lua index a9ff2ad69..0d242108b 100644 --- a/xmake/actions/build/kinds/binary.lua +++ b/xmake/actions/build/kinds/binary.lua @@ -71,7 +71,7 @@ function _do_link_target(target, opt) local verbose = option.get("verbose") -- trace progress into - cprintf("${color.build.progress}" .. theme.get("text.build.progress_format") .. ":${clear} ", opt.progress) + cprintf("${color.build.progress}" .. theme.get("text.build.progress_format") .. ":${clear} ", opt.progress.stop) if verbose then cprint("${dim color.build.target}linking.$(mode) %s", path.filename(targetfile)) else @@ -149,70 +149,12 @@ function _link_target(target, opt) end end --- build target from objects -function _build_from_objects(target, buildinfo) +-- build binary target +function build(target, opt) -- build objects - object.build(target, buildinfo) - - -- get progress - local progress = (buildinfo.targetindex + 1) * 100 / buildinfo.targetcount + object.build(target, opt) -- link target - _link_target(target, {progress = progress}) -end - --- build target from sources -function _build_from_sources(target, buildinfo, sourcebatch, sourcekind) - - -- the target file - local targetfile = target:targetfile() - - -- is verbose? - local verbose = option.get("verbose") - - -- trace progress into - cprintf("${color.build.progress}" .. theme.get("text.build.progress_format") .. ":${clear} ", (buildinfo.targetindex + 1) * 100 / buildinfo.targetcount) - if verbose then - cprint("${dim color.build.target}linking.$(mode) %s", path.filename(targetfile)) - else - cprint("${color.build.target}linking.$(mode) %s", path.filename(targetfile)) - end - - -- trace verbose info - if verbose then - print(compiler.buildcmd(sourcebatch.sourcefiles, targetfile, {target = target, sourcekind = sourcekind})) - end - - -- flush io buffer to update progress info - io.flush() - - -- build it - compiler.build(sourcebatch.sourcefiles, targetfile, {target = target, sourcekind = sourcekind}) -end - --- build binary target -function build(target, buildinfo) - - -- only one source kind? - local kindcount = 0 - local sourcekind = nil - local sourcebatch = nil - for kind, batch in pairs(target:sourcebatches()) do - if not batch.rulename then - sourcekind = kind - sourcebatch = batch - kindcount = kindcount + 1 - if kindcount > 1 then - break - end - end - end - - -- build target - if kindcount == 1 and compiler.buildmode(sourcekind, "binary:sources", {target = target}) then - _build_from_sources(target, buildinfo, sourcebatch, sourcekind) - else - _build_from_objects(target, buildinfo) - end + _link_target(target, opt) end diff --git a/xmake/actions/build/kinds/object.lua b/xmake/actions/build/kinds/object.lua index 8f859054e..8cf9bba99 100644 --- a/xmake/actions/build/kinds/object.lua +++ b/xmake/actions/build/kinds/object.lua @@ -20,294 +20,68 @@ -- imports import("core.base.option") -import("core.theme.theme") -import("core.tool.compiler") -import("core.tool.extractor") import("core.project.rule") import("core.project.config") -import("core.project.depend") import("core.project.project") -import("core.language.language") -import("detect.tools.find_ccache") - --- build the object from the *.[o|obj] source file -function _build_from_object(target, sourcefile, objectfile, progress) - - -- is verbose? - local verbose = option.get("verbose") - - -- trace progress info - cprintf("${color.build.progress}" .. theme.get("text.build.progress_format") .. ":${clear} ", progress) - if verbose then - cprint("${dim color.build.object}inserting.$(mode) %s", sourcefile) - else - cprint("${clear}${color.build.object}inserting.$(mode) %s", sourcefile) - end - - -- trace verbose info - if verbose then - print("cp %s %s", sourcefile, objectfile) - end - - -- flush io buffer to update progress info - io.flush() - - -- 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, progress) - - -- is verbose? - local verbose = option.get("verbose") - - -- trace progress info - cprintf("${color.build.progress}" .. theme.get("text.build.progress_format") .. ":${clear} ", progress) - if verbose then - cprint("${dim color.build.object}inserting.$(mode) %s", sourcefile) - else - cprint("${color.build.object}inserting.$(mode) %s", sourcefile) - end - - -- trace verbose info - if verbose then - print("ex %s %s", sourcefile, objectfile) - end - - -- flush io buffer to update progress info - io.flush() - - -- extract the static library to object directory - extractor.extract(sourcefile, path.directory(objectfile)) -end - --- do build file -function _do_build_file(target, sourcefile, opt) - - -- get build info - local buildinfo = _g.buildinfo - local objectfile = opt.objectfile - local dependfile = opt.dependfile - local sourcekind = opt.sourcekind - local progress = opt.progress - - -- build the object for the *.o/obj source makefile - if sourcekind == "obj" then - return _build_from_object(target, sourcefile, objectfile, progress) - -- build the object for the *.[a|lib] source file - elseif sourcekind == "lib" then - return _build_from_static(target, sourcefile, objectfile, progress) - end - - -- load compiler - local compinst = compiler.load(sourcekind, {target = target}) - - -- get compile flags - local compflags = compinst:compflags({target = target, sourcefile = sourcefile}) - - -- load dependent info - local dependinfo = option.get("rebuild") and {} or (depend.load(dependfile) or {}) - - -- need build this object? - local depvalues = {compinst:program(), compflags} - if not depend.is_changed(dependinfo, {lastmtime = os.mtime(objectfile), values = depvalues}) then - return - end - - -- is verbose? - local verbose = option.get("verbose") - - -- trace progress info - cprintf("${color.build.progress}" .. theme.get("text.build.progress_format") .. ":${clear} ", progress) - if verbose then - cprint("${dim color.build.object}%scompiling.$(mode) %s", buildinfo.ccache and "ccache " or "", sourcefile) - else - cprint("${color.build.object}%scompiling.$(mode) %s", buildinfo.ccache and "ccache " or "", sourcefile) - end - - -- trace verbose info - if verbose then - print(compinst:compcmd(sourcefile, objectfile, {compflags = compflags})) - end - - -- flush io buffer to update progress info - io.flush() - - -- compile it - dependinfo.files = {} - assert(compinst:compile(sourcefile, objectfile, {dependinfo = dependinfo, compflags = compflags})) - - -- update files and values to the dependent file - dependinfo.values = depvalues - table.join2(dependinfo.files, sourcefile, target:pcoutputfile("cxx") or {}, target:pcoutputfile("c")) - depend.save(dependinfo, dependfile) -end - --- build object -function _build_object(target, index, sourcebatch) - - -- get the object and source with the given index - local buildinfo = _g.buildinfo - local sourcefile = sourcebatch.sourcefiles[index] - local objectfile = sourcebatch.objectfiles[index] - local dependfile = sourcebatch.dependfiles[index] - local sourcekind = sourcebatch.sourcekind - - -- calculate progress - local progress = ((buildinfo.targetindex + (buildinfo.sourceindex + index - 1) / buildinfo.sourcecount) * 100 / buildinfo.targetcount) - - -- init build option - local opt = {objectfile = objectfile, dependfile = dependfile, sourcekind = sourcekind, progress = progress} - - -- do before build - local before_build_file = target:script("build_file_before") - if before_build_file then - before_build_file(target, sourcefile, opt) - end - - -- do build - local on_build_file = target:script("build_file") - if on_build_file then - opt.origin = _do_build_file - on_build_file(target, sourcefile, opt) - opt.origin = nil - else - _do_build_file(target, sourcefile, opt) - end - - -- do after build - local after_build_file = target:script("build_file_after") - if after_build_file then - after_build_file(target, sourcefile, opt) - end -end - --- build each objects from the given source batch -function _build_files_for_each(target, sourcebatch, jobs) - - -- run build jobs for each source file - local curdir = os.curdir() - process.runjobs(function (index) - - -- force to set the current directory first because the other jobs maybe changed it - os.cd(curdir) - - -- build object - _build_object(target, index, sourcebatch) - - end, #sourcebatch.sourcefiles, jobs) -end - --- compile source files to single object at the same time -function _build_files_for_single(target, sourcebatch, jobs) - - -- is verbose? - local verbose = option.get("verbose") - - -- get source and object files - local sourcefiles = sourcebatch.sourcefiles - local objectfiles = sourcebatch.objectfiles - local dependfiles = sourcebatch.dependfiles - local sourcekind = sourcebatch.sourcekind - - -- trace progress info - local buildinfo = _g.buildinfo - for index, sourcefile in ipairs(sourcefiles) do - - -- calculate progress - local progress = ((buildinfo.targetindex + (buildinfo.sourceindex + index - 1) / buildinfo.sourcecount) * 100 / buildinfo.targetcount) - - -- trace progress info - cprintf("${color.build.progress}" .. theme.get("text.build.progress_format") .. ":${clear} ", progress) - if verbose then - cprint("${dim color.build.object}%scompiling.$(mode) %s", buildinfo.ccache and "ccache " or "", sourcefile) - else - cprint("${color.build.object}%scompiling.$(mode) %s", buildinfo.ccache and "ccache " or "", sourcefile) - end - end - - -- trace verbose info - if verbose then - print(compiler.compcmd(sourcefiles, objectfiles, {target = target, sourcekind = sourcekind})) - end - - -- compile them - compiler.compile(sourcefiles, objectfiles, {dependfiles = dependfiles, target = target, sourcekind = sourcekind}) -end -- build source files with the custom rule -function _build_files_for_rule(target, sourcebatch, jobs, suffix) +function _build_files_with_rule(target, sourcebatch, opt, suffix) -- the rule name - local rulename = sourcebatch.rulename - local buildinfo = _g.buildinfo + local rulename = assert(sourcebatch.rulename, "unknown rule for sourcebatch!") -- get rule instance - local ruleinst = project.rule(rulename) or rule.rule(rulename) - assert(ruleinst, "unknown rule: %s", rulename) + local ruleinst = assert(project.rule(rulename) or rule.rule(rulename), "unknown rule: %s", rulename) -- on_build_files? local on_build_files = ruleinst:script("build_files" .. (suffix and ("_" .. suffix) or "")) if on_build_files then - - -- calculate progress - local progress = (buildinfo.targetindex + buildinfo.sourceindex / buildinfo.sourcecount) * 100 / buildinfo.targetcount - - -- do build files - on_build_files(target, sourcebatch, {jobs = jobs, progress = progress}) + on_build_files(target, sourcebatch, opt) else -- get the build file script local on_build_file = ruleinst:script("build_file" .. (suffix and ("_" .. suffix) or "")) if on_build_file then + -- get the max job count + local jobs = tonumber(option.get("jobs") or "4") + + -- get progress range + local progress = opt.progress + -- run build jobs for each source file local curdir = os.curdir() + local sourcecount = #sourcebatch.sourcefiles process.runjobs(function (index) -- force to set the current directory first because the other jobs maybe changed it os.cd(curdir) -- calculate progress - local progress = ((buildinfo.targetindex + (buildinfo.sourceindex + index - 1) / buildinfo.sourcecount) * 100 / buildinfo.targetcount) - if suffix then - progress = ((buildinfo.targetindex + (suffix == "before" and buildinfo.sourceindex or buildinfo.sourcecount) / buildinfo.sourcecount) * 100 / buildinfo.targetcount) + local progress_now = progress.start + ((index - 1) * (progress.stop - progress.start)) / sourcecount + if suffix == "before" then + progress_now = progress.start + elseif suffix == "after" then + progress_now = progress.stop end -- get source file local sourcefile = sourcebatch.sourcefiles[index] -- do build file - on_build_file(target, sourcefile, {sourcekind = sourcebatch.sourcekind, progress = progress}) + on_build_file(target, sourcefile, {sourcekind = sourcebatch.sourcekind, progress = progress_now}) - end, #sourcebatch.sourcefiles, jobs) + end, sourcecount, jobs) end end end -- do build files function _do_build_files(target, sourcebatch, opt) - - -- compile source files with custom rule - if sourcebatch.rulename then - _build_files_for_rule(target, sourcebatch, opt.jobs) - -- compile source files to single object at once - elseif type(sourcebatch.objectfiles) == "string" then - _build_files_for_single(target, sourcebatch, opt.jobs) - else - _build_files_for_each(target, sourcebatch, opt.jobs) - end + _build_files_with_rule(target, sourcebatch, opt) end -- build files -function _build_files(target, sourcebatch, jobs) - - -- calculate progress - local buildinfo = _g.buildinfo - local progress = (buildinfo.targetindex + buildinfo.sourceindex / buildinfo.sourcecount) * 100 / buildinfo.targetcount - - -- init build option - local opt = {jobs = jobs, progress = progress} +function _build_files(target, sourcebatch, opt) -- do before build local before_build_files = target:script("build_files_before") @@ -325,9 +99,6 @@ function _build_files(target, sourcebatch, jobs) _do_build_files(target, sourcebatch, opt) end - -- update object index - buildinfo.sourceindex = buildinfo.sourceindex + #sourcebatch.sourcefiles - -- do after build local after_build_files = target:script("build_files_after") if after_build_files then @@ -335,77 +106,48 @@ function _build_files(target, sourcebatch, jobs) end end --- build precompiled header files (only for c/c++) -function _build_pcheaderfiles(target, buildinfo) - - -- for c/c++ - _g.buildinfo = buildinfo - for _, langkind in ipairs({"c", "cxx"}) do - - -- get the precompiled header - local pcheaderfile = target:pcheaderfile(langkind) - if pcheaderfile then - - -- init sourcefile, objectfile and dependfile - local sourcefile = pcheaderfile - local objectfile = target:pcoutputfile(langkind) - local dependfile = target:dependfile(objectfile) - local sourcekind = language.langkinds()[langkind] - - -- init source batch - local sourcebatch = {sourcekind = sourcekind, sourcefiles = {sourcefile}, objectfiles = {objectfile}, dependfiles = {dependfile}} - - -- build this precompiled header - _build_object(target, 1, sourcebatch, false) - end - end -end - -- build source files -function build_sourcefiles(target, buildinfo, sourcebatches) +function build_sourcefiles(target, sourcebatches, opt) - -- get the max job count - local jobs = tonumber(option.get("jobs") or "4") + -- init options + opt = opt or {} - -- save buildinfo - _g.buildinfo = buildinfo + -- get progress range + local progress = assert(opt.progress, "no build progress!") -- build source batches with custom rules before building other sources for _, sourcebatch in pairs(sourcebatches) do - if sourcebatch.rulename then - _build_files_for_rule(target, sourcebatch, jobs, "before") - end + _build_files_with_rule(target, sourcebatch, opt, "before") end -- build source batches + local sourcestart = 0 + local sourcestop = 0 + local sourcetotal = target:sourcecount() for _, sourcebatch in pairs(sourcebatches) do - _build_files(target, sourcebatch, jobs) + + -- compute the sub-progress range + sourcestop = sourcestart + #sourcebatch.sourcefiles + local progress_range = progress.stop - progress.start + local progress_start = progress.start + (sourcestart * progress_range) / sourcetotal + local progress_stop = progress.start + (sourcestop * progress_range) / sourcetotal + opt.progress = {start = progress_start, stop = progress_stop} + sourcestart = sourcestop + + -- build files + _build_files(target, sourcebatch, opt) end -- build source batches with custom rules after building other sources for _, sourcebatch in pairs(sourcebatches) do - if sourcebatch.rulename then - _build_files_for_rule(target, sourcebatch, jobs, "after") - end + _build_files_with_rule(target, sourcebatch, opt, "after") end end -- build objects for the given target -function build(target, buildinfo) - - -- init source index and count - buildinfo.sourceindex = 0 - buildinfo.sourcecount = target:sourcecount() - - -- init ccache - if config.get("ccache") and buildinfo.ccache == nil then - buildinfo.ccache = find_ccache() - end - - -- build precompiled headers - _build_pcheaderfiles(target, buildinfo) +function build(target, opt) -- build source files - build_sourcefiles(target, buildinfo, target:sourcebatches()) + build_sourcefiles(target, target:sourcebatches(), opt) end diff --git a/xmake/actions/build/kinds/shared.lua b/xmake/actions/build/kinds/shared.lua index 598d7da8a..f6a8d6161 100644 --- a/xmake/actions/build/kinds/shared.lua +++ b/xmake/actions/build/kinds/shared.lua @@ -84,7 +84,7 @@ function _do_link_target(target, opt) local verbose = option.get("verbose") -- trace progress info - cprintf("${color.build.progress}" .. theme.get("text.build.progress_format") .. ":${clear} ", opt.progress) + cprintf("${color.build.progress}" .. theme.get("text.build.progress_format") .. ":${clear} ", opt.progress.stop) if verbose then cprint("${dim color.build.target}linking.$(mode) %s", path.filename(targetfile)) else @@ -162,70 +162,12 @@ function _link_target(target, opt) end end --- build target from objects -function _build_from_objects(target, buildinfo) +-- build shared target +function build(target, opt) -- build objects - object.build(target, buildinfo) - - -- get progress - local progress = (buildinfo.targetindex + 1) * 100 / buildinfo.targetcount + object.build(target, opt) -- link target - _link_target(target, {progress = progress}) -end - --- build target from sources -function _build_from_sources(target, buildinfo, sourcebatch, sourcekind) - - -- the target file - local targetfile = target:targetfile() - - -- is verbose? - local verbose = option.get("verbose") - - -- trace progress into - cprintf("${color.build.progress}" .. theme.get("text.build.progress_format") .. ":${clear} ", (buildinfo.targetindex + 1) * 100 / buildinfo.targetcount) - if verbose then - cprint("${dim color.build.target}linking.$(mode) %s", path.filename(targetfile)) - else - cprint("${color.build.target}linking.$(mode) %s", path.filename(targetfile)) - end - - -- trace verbose info - if verbose then - print(compiler.buildcmd(sourcebatch.sourcefiles, targetfile, {target = target, sourcekind = sourcekind})) - end - - -- flush io buffer to update progress info - io.flush() - - -- build it - compiler.build(sourcebatch.sourcefiles, targetfile, {target = target, sourcekind = sourcekind}) -end - --- build shared target -function build(target, buildinfo) - - -- only one source kind? - local kindcount = 0 - local sourcekind = nil - local sourcebatch = nil - for kind, batch in pairs(target:sourcebatches()) do - if not batch.rulename then - sourcekind = kind - sourcebatch = batch - kindcount = kindcount + 1 - if kindcount > 1 then - break - end - end - end - - -- build target - if kindcount == 1 and compiler.buildmode(sourcekind, "shared:sources", {target = target}) then - _build_from_sources(target, buildinfo, sourcebatch, sourcekind) - else - _build_from_objects(target, buildinfo) - end + _link_target(target, opt) end diff --git a/xmake/actions/build/kinds/static.lua b/xmake/actions/build/kinds/static.lua index dfd07f4e9..c9a6987dd 100644 --- a/xmake/actions/build/kinds/static.lua +++ b/xmake/actions/build/kinds/static.lua @@ -80,7 +80,7 @@ function _do_link_target(target, opt) local verbose = option.get("verbose") -- trace progress info - cprintf("${color.build.progress}" .. theme.get("text.build.progress_format") .. ":${clear} ", opt.progress) + cprintf("${color.build.progress}" .. theme.get("text.build.progress_format") .. ":${clear} ", opt.progress.stop) if verbose then cprint("${dim color.build.target}archiving.$(mode) %s", path.filename(targetfile)) else @@ -158,70 +158,12 @@ function _link_target(target, opt) end end --- build target from objects -function _build_from_objects(target, buildinfo) +-- build static target +function build(target, opt) -- build objects - object.build(target, buildinfo) - - -- get progress - local progress = (buildinfo.targetindex + 1) * 100 / buildinfo.targetcount + object.build(target, opt) -- link target - _link_target(target, {progress = progress}) -end - --- build target from sources -function _build_from_sources(target, buildinfo, sourcebatch, sourcekind) - - -- the target file - local targetfile = target:targetfile() - - -- is verbose? - local verbose = option.get("verbose") - - -- trace progress into - cprintf("${color.build.progress}" .. theme.get("text.build.progress_format") .. ":${clear} ", (buildinfo.targetindex + 1) * 100 / buildinfo.targetcount) - if verbose then - cprint("${dim color.build.target}archiving.$(mode) %s", path.filename(targetfile)) - else - cprint("${color.build.target}archiving.$(mode) %s", path.filename(targetfile)) - end - - -- trace verbose info - if verbose then - print(compiler.buildcmd(sourcebatch.sourcefiles, targetfile, {target = target, sourcekind = sourcekind})) - end - - -- flush io buffer to update progress info - io.flush() - - -- build it - compiler.build(sourcebatch.sourcefiles, targetfile, {target = target, sourcekind = sourcekind}) -end - --- build static target -function build(target, buildinfo) - - -- only one source kind? - local kindcount = 0 - local sourcekind = nil - local sourcebatch = nil - for kind, batch in pairs(target:sourcebatches()) do - if not batch.rulename then - sourcekind = kind - sourcebatch = batch - kindcount = kindcount + 1 - if kindcount > 1 then - break - end - end - end - - -- build target - if kindcount == 1 and compiler.buildmode(sourcekind, "static:sources", {target = target}) then - _build_from_sources(target, buildinfo, sourcebatch, sourcekind) - else - _build_from_objects(target, buildinfo) - end + _link_target(target, opt) end diff --git a/xmake/core/project/target.lua b/xmake/core/project/target.lua index 7cf262262..911d8ddbf 100644 --- a/xmake/core/project/target.lua +++ b/xmake/core/project/target.lua @@ -868,13 +868,14 @@ function _instance:filerules(sourcefile) extension2rules = {} for _, r in pairs(table.wrap(self:rules())) do for _, extension in ipairs(table.wrap(r:get("extensions"))) do + extension = extension:lower() extension2rules[extension] = extension2rules[extension] or {} table.insert(extension2rules[extension], r) end end self._EXTENSION2RULES = extension2rules end - for _, r in ipairs(table.wrap(extension2rules[path.extension(sourcefile)])) do + for _, r in ipairs(table.wrap(extension2rules[path.extension(sourcefile):lower()])) do table.insert(rules, r) end @@ -946,19 +947,6 @@ function _instance:sourcefiles() return {}, false end - -- the patterns - local patterns = - { - {"([%w%*]+)%.obj|", "%%1|", "object"} - , {"([%w%*]+)%.obj$", "%%1", "object"} - , {"([%w%*]+)%.o|", "%%1|", "object"} - , {"([%w%*]+)%.o$", "%%1", "object"} - , {"([%w%*]+)%.lib|", "%%1|", "static"} - , {"([%w%*]+)%.lib$", "%%1", "static"} - , {"lib([%w%*]+)%.a|", "%%1|", "static"} - , {"lib([%w%*]+)%.a$", "%%1", "static"} - } - -- match files local i = 1 local count = 0 @@ -973,15 +961,6 @@ function _instance:sourcefiles() deleted = true end - -- normalize *.[o|obj] and [lib]*.[a|lib] filename - for _, pattern in ipairs(patterns) do - file, count = file:gsub(pattern[1], target.filename(pattern[2], pattern[3])) - if count > 0 then - -- disable cache because the object and library files will be modified if them depend on previous target file - cache = false - end - end - -- match source files local results = os.match(file) if #results == 0 then @@ -1024,9 +1003,6 @@ end -- get object file from source file function _instance:objectfile(sourcefile) - -- translate: [lib]xxx*.[a|lib] => xxx/*.[o|obj] object file - sourcefile = sourcefile:gsub(target.filename("([%%w%%-_]+)", "static"):gsub("%.", "%%.") .. "$", "%1/*") - -- get relative directory in the autogen directory local relativedir = nil local origindir = path.directory(path.absolute(sourcefile)) @@ -1075,10 +1051,8 @@ function _instance:objectfiles() -- get object files from source batches local objectfiles = {} - for sourcekind, sourcebatch in pairs(self:sourcebatches()) do - if not sourcebatch.rulename then - table.join2(objectfiles, sourcebatch.objectfiles) - end + for _, sourcebatch in pairs(self:sourcebatches()) do + table.join2(objectfiles, sourcebatch.objectfiles) end -- get object files from all dependent targets (object kind) @@ -1285,10 +1259,8 @@ function _instance:dependfiles() -- get dependent files from source batches local dependfiles = {} - for sourcekind, sourcebatch in pairs(self:sourcebatches()) do - if not sourcebatch.rulename then - table.join2(dependfiles, sourcebatch.dependfiles) - end + for _, sourcebatch in pairs(self:sourcebatches()) do + table.join2(dependfiles, sourcebatch.dependfiles) end -- cache it @@ -1346,104 +1318,45 @@ function _instance:sourcebatches() return self._SOURCEBATCHES, false end - -- the extensional source kinds - local sourcekinds_ext = - { - [".o"] = "obj" - , [".obj"] = "obj" - , [".a"] = "lib" - , [".lib"] = "lib" - } - -- make source batches for each source kinds local sourcebatches = {} for _, sourcefile in ipairs(sourcefiles) do - -- add file rules - local builtin_rule = true + -- get file rules local filerules = self:filerules(sourcefile) + if #filerules == 0 then + os.raise("unknown source file: %s", sourcefile) + end + + -- add source batch for the file rules for _, filerule in ipairs(filerules) do - -- get source kind - local sourcekind = "__rule_" .. filerule:name() + -- get rule name + local rulename = filerule:name() -- make this batch - local sourcebatch = sourcebatches[sourcekind] or {sourcefiles = {}} - sourcebatches[sourcekind] = sourcebatch + local sourcebatch = sourcebatches[rulename] or {sourcefiles = {}} + sourcebatches[rulename] = sourcebatch - -- add source kind to this batch - sourcebatch.sourcekind = sourcekind - - -- add source rule to this batch - sourcebatch.rulename = filerule:name() + -- save the rule name + sourcebatch.rulename = rulename -- add source file to this batch table.insert(sourcebatch.sourcefiles, sourcefile) - -- override `on_build_xxx` in filerules? disable the builtin-rule - if filerule:get("build_file") or filerule:get("build_files") or filerule:get("build") then - builtin_rule = false - end - end - - -- add builtin rule - if builtin_rule then - - -- get source kind - sourcekind = language.sourcekind_of(sourcefile) - if not sourcekind then - local sourcekind_ext = sourcekinds_ext[path.extension(sourcefile):lower()] - if sourcekind_ext then - sourcekind = sourcekind_ext - end - end + -- attempt to get source kind from the builtin languages + local sourcekind = language.sourcekind_of(sourcefile) if sourcekind then - -- make this batch - local sourcebatch = sourcebatches[sourcekind] or {sourcefiles = {}} - sourcebatches[sourcekind] = sourcebatch - - -- add source kind to this batch + -- save source kind sourcebatch.sourcekind = sourcekind - -- add source file to this batch - table.insert(sourcebatch.sourcefiles, sourcefile) - - elseif #filerules == 0 then - os.raise("unknown source file: %s", sourcefile) - end - end - end - - -- insert object files to source batches - for sourcekind, sourcebatch in pairs(sourcebatches) do - - -- skip source files with the custom rule - if not sourcebatch.rulename then - - -- this batch support to compile multiple objects at the same time? - local instance = compiler.load(sourcekind, self) - if instance and instance:buildmode("object:sources") then - - -- get the first source file - local sourcefile = sourcebatch.sourcefiles[1] - - -- insert single object file for all source files - sourcebatch.objectfiles = self:objectfile(path.join(path.directory(sourcefile), "__" .. sourcekind)) - - -- insert single dependent file for all source files - sourcebatch.dependfiles = self:dependfile(sourcebatch.objectfiles) - - else - - -- insert object files for each source files - sourcebatch.objectfiles = {} - sourcebatch.dependfiles = {} - for _, sourcefile in ipairs(sourcebatch.sourcefiles) do - local objectfile = self:objectfile(sourcefile) - table.insert(sourcebatch.objectfiles, objectfile) - table.insert(sourcebatch.dependfiles, self:dependfile(objectfile)) - end + -- insert object files to source batches + sourcebatch.objectfiles = sourcebatch.objectfiles or {} + sourcebatch.dependfiles = sourcebatch.dependfiles or {} + local objectfile = self:objectfile(sourcefile) + table.insert(sourcebatch.objectfiles, objectfile) + table.insert(sourcebatch.dependfiles, self:dependfile(objectfile)) end end end diff --git a/xmake/core/sandbox/modules/import/core/tool/compiler.lua b/xmake/core/sandbox/modules/import/core/tool/compiler.lua index f93176181..0a312b813 100644 --- a/xmake/core/sandbox/modules/import/core/tool/compiler.lua +++ b/xmake/core/sandbox/modules/import/core/tool/compiler.lua @@ -43,16 +43,6 @@ function sandbox_core_tool_compiler.load(sourcekind, opt) return instance end --- get the build mode of compiler -function sandbox_core_tool_compiler.buildmode(sourcekind, name, opt) - - -- get the compiler instance - local instance = sandbox_core_tool_compiler.load(sourcekind, opt) - - -- get build mode - return instance:buildmode(name) -end - -- make command for compiling source file function sandbox_core_tool_compiler.compcmd(sourcefiles, objectfile, opt) return os.args(table.join(sandbox_core_tool_compiler.compargv(sourcefiles, objectfile, opt))) diff --git a/xmake/core/tool/builder.lua b/xmake/core/tool/builder.lua index fc73a94fd..ba6f3bcf2 100644 --- a/xmake/core/tool/builder.lua +++ b/xmake/core/tool/builder.lua @@ -524,15 +524,5 @@ function builder:format(targetkind) end end --- get buildmode of the tool -function builder:buildmode(name) - - -- get it - local buildmodes = self:get("buildmodes") - if buildmodes then - return buildmodes[name] - end -end - -- return module return builder diff --git a/xmake/languages/asm/xmake.lua b/xmake/languages/asm/xmake.lua index c25704943..726e82dc3 100644 --- a/xmake/languages/asm/xmake.lua +++ b/xmake/languages/asm/xmake.lua @@ -39,6 +39,9 @@ language("asm") -- set mixing kinds set_mixingkinds("as") + -- add rules + add_rules("asm") + -- on load on_load("load") diff --git a/xmake/languages/c++/xmake.lua b/xmake/languages/c++/xmake.lua index cae820768..93f0eb528 100644 --- a/xmake/languages/c++/xmake.lua +++ b/xmake/languages/c++/xmake.lua @@ -39,6 +39,9 @@ language("c++") -- set mixing kinds set_mixingkinds("cc", "cxx", "as", "mrc") + -- add rules + add_rules("cpp") + -- on load on_load("load") diff --git a/xmake/languages/dlang/xmake.lua b/xmake/languages/dlang/xmake.lua index de997afed..a651c52d9 100644 --- a/xmake/languages/dlang/xmake.lua +++ b/xmake/languages/dlang/xmake.lua @@ -39,6 +39,9 @@ language("dlang") -- set mixing kinds set_mixingkinds("dc", "cc", "cxx", "as") + -- add rules + add_rules("dlang") + -- on load on_load("load") diff --git a/xmake/languages/golang/xmake.lua b/xmake/languages/golang/xmake.lua index 51612350f..ac16d97b1 100644 --- a/xmake/languages/golang/xmake.lua +++ b/xmake/languages/golang/xmake.lua @@ -39,6 +39,9 @@ language("golang") -- set mixing kinds set_mixingkinds("gc") + -- add rules + add_rules("go") + -- on load on_load("load") diff --git a/xmake/languages/msrc/xmake.lua b/xmake/languages/msrc/xmake.lua index d788bc1b6..3288b3627 100644 --- a/xmake/languages/msrc/xmake.lua +++ b/xmake/languages/msrc/xmake.lua @@ -33,6 +33,9 @@ language("msrc") -- set mixing kinds set_mixingkinds("mrc") + -- add rules + add_rules("win.sdk.resource") + -- on load on_load("load") diff --git a/xmake/languages/objc++/xmake.lua b/xmake/languages/objc++/xmake.lua index 2b6276124..7a6b0af4e 100644 --- a/xmake/languages/objc++/xmake.lua +++ b/xmake/languages/objc++/xmake.lua @@ -39,6 +39,9 @@ language("objc++") -- set mixing kinds set_mixingkinds("mm", "mxx", "cc", "cxx", "as") + -- add rules + add_rules("objc++") + -- on load on_load("load") diff --git a/xmake/languages/rust/xmake.lua b/xmake/languages/rust/xmake.lua index 977f815df..d5a386d09 100644 --- a/xmake/languages/rust/xmake.lua +++ b/xmake/languages/rust/xmake.lua @@ -39,6 +39,9 @@ language("rust") -- set mixing kinds set_mixingkinds("rc") + -- add rules + add_rules("rust") + -- on load on_load("load") diff --git a/xmake/languages/swift/xmake.lua b/xmake/languages/swift/xmake.lua index c4e9139c6..57fc4ad64 100644 --- a/xmake/languages/swift/xmake.lua +++ b/xmake/languages/swift/xmake.lua @@ -39,6 +39,9 @@ language("swift") -- set mixing kinds set_mixingkinds("sc", "mm", "mxx", "cc", "cxx") + -- add rules + add_rules("swift") + -- on load on_load("load") diff --git a/xmake/modules/core/tools/cl.lua b/xmake/modules/core/tools/cl.lua index 3fbae583b..c8e20d552 100644 --- a/xmake/modules/core/tools/cl.lua +++ b/xmake/modules/core/tools/cl.lua @@ -77,12 +77,6 @@ function init(self) , ["-ftrapv"] = "" , ["-fsanitize=address"] = "" }) - - -- init buildmodes - self:set("buildmodes", - { - ["object:sources"] = false - }) end -- make the symbol flag diff --git a/xmake/modules/core/tools/cparser.lua b/xmake/modules/core/tools/cparser.lua index 80b903949..a07f8e172 100644 --- a/xmake/modules/core/tools/cparser.lua +++ b/xmake/modules/core/tools/cparser.lua @@ -23,7 +23,7 @@ import("core.base.option") import("core.project.config") import("core.project.project") import("core.language.language") -import("detect.tools.find_ccache") +import("private.tools.ccache") -- init it function init(self) @@ -56,12 +56,6 @@ function init(self) , ["-s"] = "-s" , ["-S"] = "-S" }) - - -- init buildmodes - self:set("buildmodes", - { - ["object:sources"] = false - }) end -- make the strip flag @@ -157,31 +151,7 @@ end -- make the compile arguments list function _compargv1(self, sourcefile, objectfile, flags) - - -- get ccache - local ccache = nil - if config.get("ccache") then - ccache = find_ccache() - end - - -- make argv - local argv = table.join("-c", flags, "-o", objectfile, sourcefile) - - -- uses cache? - local program = self:program() - if ccache then - - -- parse the filename and arguments, e.g. "xcrun -sdk macosx clang" - if not os.isexec(program) then - argv = table.join(program:split("%s"), argv) - else - table.insert(argv, 1, program) - end - return ccache, argv - end - - -- no cache - return program, argv + return ccache.cmdargv(self:program(), table.join("-c", flags, "-o", objectfile, sourcefile)) end -- compile the source file diff --git a/xmake/modules/core/tools/dmd.lua b/xmake/modules/core/tools/dmd.lua index 7c039319e..4ee8ecf9d 100644 --- a/xmake/modules/core/tools/dmd.lua +++ b/xmake/modules/core/tools/dmd.lua @@ -34,12 +34,6 @@ function init(self) -- init dcflags for the kind: shared self:set("shared.dcflags", "-fPIC") - - -- init buildmodes - self:set("buildmodes", - { - ["object:sources"] = false - }) end -- make the optimize flag diff --git a/xmake/modules/core/tools/fasm.lua b/xmake/modules/core/tools/fasm.lua index 59aee4f55..ba34a8078 100644 --- a/xmake/modules/core/tools/fasm.lua +++ b/xmake/modules/core/tools/fasm.lua @@ -40,12 +40,6 @@ function init(self) , ["-ftrapv"] = "" , ["-fsanitize=address"] = "" }) - - -- init buildmodes - self:set("buildmodes", - { - ["object:sources"] = false - }) end -- make the define flag diff --git a/xmake/modules/core/tools/gcc.lua b/xmake/modules/core/tools/gcc.lua index 9b96daf91..301f13ec3 100644 --- a/xmake/modules/core/tools/gcc.lua +++ b/xmake/modules/core/tools/gcc.lua @@ -23,7 +23,7 @@ import("core.base.option") import("core.project.config") import("core.project.project") import("core.language.language") -import("detect.tools.find_ccache") +import("private.tools.ccache") import("private.tools.gcc.parse_deps") -- init it @@ -69,12 +69,6 @@ function init(self) , ["-S"] = "-Wl,-S" }) end - - -- init buildmodes - self:set("buildmodes", - { - ["object:sources"] = false - }) end -- make the strip flag @@ -366,31 +360,7 @@ function _compargv1(self, sourcefile, objectfile, flags) if (extension:startswith(".h") or extension == ".inl") then return _compargv1_pch(self, sourcefile, objectfile, flags) end - - -- get ccache - local ccache = nil - if config.get("ccache") then - ccache = find_ccache() - end - - -- make argv - local argv = table.join("-c", flags, "-o", objectfile, sourcefile) - - -- uses cache? - local program = self:program() - if ccache then - - -- parse the filename and arguments, e.g. "xcrun -sdk macosx clang" - if not os.isexec(program) then - argv = table.join(program:split("%s"), argv) - else - table.insert(argv, 1, program) - end - return ccache, argv - end - - -- no cache - return program, argv + return ccache.cmdargv(self:program(), table.join("-c", flags, "-o", objectfile, sourcefile)) end -- compile the source file diff --git a/xmake/modules/core/tools/go.lua b/xmake/modules/core/tools/go.lua index fa6541898..450240023 100644 --- a/xmake/modules/core/tools/go.lua +++ b/xmake/modules/core/tools/go.lua @@ -31,12 +31,6 @@ function init(self) -- init the file formats self:set("formats", { static = "$(name).a" }) - - -- init buildmodes - self:set("buildmodes", - { - ["object:sources"] = true - }) end -- make the optimize flag diff --git a/xmake/modules/core/tools/llvm_rc.lua b/xmake/modules/core/tools/llvm_rc.lua index ab072d507..75a1b2c8c 100644 --- a/xmake/modules/core/tools/llvm_rc.lua +++ b/xmake/modules/core/tools/llvm_rc.lua @@ -24,12 +24,6 @@ import("core.project.project") -- init it function init(self) - - -- init buildmodes - self:set("buildmodes", - { - ["object:sources"] = false - }) end -- make the define flag diff --git a/xmake/modules/core/tools/ml.lua b/xmake/modules/core/tools/ml.lua index e14cc4e50..81d7c62d5 100644 --- a/xmake/modules/core/tools/ml.lua +++ b/xmake/modules/core/tools/ml.lua @@ -55,12 +55,6 @@ function init(self) , ["-ftrapv"] = "" , ["-fsanitize=address"] = "" }) - - -- init buildmodes - self:set("buildmodes", - { - ["object:sources"] = false - }) end -- make the warning flag diff --git a/xmake/modules/core/tools/nvcc.lua b/xmake/modules/core/tools/nvcc.lua index a4393d994..ab1920552 100644 --- a/xmake/modules/core/tools/nvcc.lua +++ b/xmake/modules/core/tools/nvcc.lua @@ -24,7 +24,7 @@ import("core.project.config") import("core.project.project") import("core.platform.platform") import("core.language.language") -import("detect.tools.find_ccache") +import("private.tools.ccache") import("private.tools.nvcc.parse_deps") -- init it @@ -49,12 +49,6 @@ function init(self) , ["-Wextra"] = "-Wreorder" , ["-Weverything"] = "-Wreorder" }) - - -- init buildmodes - self:set("buildmodes", - { - ["object:sources"] = false - }) end -- make the symbol flag @@ -276,31 +270,7 @@ end -- make the compile arguments list function _compargv1(self, sourcefile, objectfile, flags) - - -- get ccache - local ccache = nil - if config.get("ccache") then - ccache = find_ccache() - end - - -- make argv - local argv = table.join("-c", flags, "-o", objectfile, sourcefile) - - -- uses cache? - local program = self:program() - if ccache then - - -- parse the filename and arguments, e.g. "xcrun -sdk macosx clang" - if not os.isexec(program) then - argv = table.join(program:split("%s"), argv) - else - table.insert(argv, 1, program) - end - return ccache, argv - end - - -- no cache - return program, argv + return ccache.cmdargv(self:program(), table.join("-c", flags, "-o", objectfile, sourcefile)) end -- compile the source file diff --git a/xmake/modules/core/tools/rc.lua b/xmake/modules/core/tools/rc.lua index 2c72d0575..f5050f7f3 100644 --- a/xmake/modules/core/tools/rc.lua +++ b/xmake/modules/core/tools/rc.lua @@ -24,12 +24,6 @@ import("core.project.project") -- init it function init(self) - - -- init buildmodes - self:set("buildmodes", - { - ["object:sources"] = false - }) end -- make the define flag diff --git a/xmake/modules/core/tools/rustc.lua b/xmake/modules/core/tools/rustc.lua index d3fbda362..730815158 100644 --- a/xmake/modules/core/tools/rustc.lua +++ b/xmake/modules/core/tools/rustc.lua @@ -37,15 +37,6 @@ function init(self) -- init the file formats self:set("formats", { static = "lib$(name).rlib" }) - - -- init buildmodes - self:set("buildmodes", - { - ["object:sources"] = false -- compile multiple source filess to the single object - , ["binary:sources"] = true -- build multiple source files to the binary target file - , ["static:sources"] = true -- build multiple source files to the static target file - , ["shared:sources"] = true -- build multiple source files to the shared target file - }) end -- make the optimize flag diff --git a/xmake/modules/core/tools/swiftc.lua b/xmake/modules/core/tools/swiftc.lua index 3f18c0b16..ca1c1abf0 100644 --- a/xmake/modules/core/tools/swiftc.lua +++ b/xmake/modules/core/tools/swiftc.lua @@ -20,7 +20,7 @@ -- imports import("core.project.config") -import("detect.tools.find_ccache") +import("private.tools.ccache") -- init it function init(self) @@ -55,12 +55,6 @@ function init(self) , ["-ftrapv"] = "" , ["-fsanitize=address"] = "" }) - - -- init buildmodes - self:set("buildmodes", - { - ["object:sources"] = false - }) end -- make the strip flag @@ -203,31 +197,7 @@ end -- make the compile arguments list function _compargv1(self, sourcefile, objectfile, flags) - - -- get ccache - local ccache = nil - if config.get("ccache") then - ccache = find_ccache() - end - - -- make argv - local argv = table.join("-c", flags, "-o", objectfile, sourcefile) - - -- uses cache? - local program = self:program() - if ccache then - - -- parse the filename and arguments, e.g. "xcrun -sdk macosx clang" - if not os.isexec(program) then - argv = table.join(program:split("%s"), argv) - else - table.insert(argv, 1, program) - end - return ccache, argv - end - - -- no cache - return program, argv + return ccache.cmdargv(self:program(), table.join("-c", flags, "-o", objectfile, sourcefile)) end -- compile the source file diff --git a/xmake/modules/core/tools/tcc.lua b/xmake/modules/core/tools/tcc.lua index 51a11df93..d4fdbd60e 100644 --- a/xmake/modules/core/tools/tcc.lua +++ b/xmake/modules/core/tools/tcc.lua @@ -23,7 +23,7 @@ import("core.base.option") import("core.project.config") import("core.project.project") import("core.language.language") -import("detect.tools.find_ccache") +import("private.tools.ccache") -- init it function init(self) @@ -55,12 +55,6 @@ function init(self) , ["-s"] = "-s" , ["-S"] = "-S" }) - - -- init buildmodes - self:set("buildmodes", - { - ["object:sources"] = false - }) end -- make the strip flag @@ -157,31 +151,7 @@ end -- make the compile arguments list function _compargv1(self, sourcefile, objectfile, flags) - - -- get ccache - local ccache = nil - if config.get("ccache") then - ccache = find_ccache() - end - - -- make argv - local argv = table.join("-c", flags, "-o", objectfile, sourcefile) - - -- uses cache? - local program = self:program() - if ccache then - - -- parse the filename and arguments, e.g. "xcrun -sdk macosx clang" - if not os.isexec(program) then - argv = table.join(program:split("%s"), argv) - else - table.insert(argv, 1, program) - end - return ccache, argv - end - - -- no cache - return program, argv + return ccache.cmdargv(self:program(), table.join("-c", flags, "-o", objectfile, sourcefile)) end -- compile the source file diff --git a/xmake/modules/core/tools/windres.lua b/xmake/modules/core/tools/windres.lua index c4e4290cd..8ca259538 100644 --- a/xmake/modules/core/tools/windres.lua +++ b/xmake/modules/core/tools/windres.lua @@ -24,12 +24,6 @@ import("core.project.project") -- init it function init(self) - - -- init buildmodes - self:set("buildmodes", - { - ["object:sources"] = false - }) end -- make the define flag diff --git a/xmake/modules/core/tools/yasm.lua b/xmake/modules/core/tools/yasm.lua index d06026857..ce784e29a 100644 --- a/xmake/modules/core/tools/yasm.lua +++ b/xmake/modules/core/tools/yasm.lua @@ -43,12 +43,6 @@ function init(self) , ["-ftrapv"] = "" , ["-fsanitize=address"] = "" }) - - -- init buildmodes - self:set("buildmodes", - { - ["object:sources"] = false - }) end -- make the warning flag diff --git a/xmake/modules/private/action/build/object.lua b/xmake/modules/private/action/build/object.lua new file mode 100644 index 000000000..abfb3682b --- /dev/null +++ b/xmake/modules/private/action/build/object.lua @@ -0,0 +1,142 @@ +--!A cross-platform build utility based on Lua +-- +-- Licensed under the Apache License, Version 2.0 (the "License"); +-- you may not use this file except in compliance with the License. +-- You may obtain a copy of the License at +-- +-- http://www.apache.org/licenses/LICENSE-2.0 +-- +-- Unless required by applicable law or agreed to in writing, software +-- distributed under the License is distributed on an "AS IS" BASIS, +-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +-- See the License for the specific language governing permissions and +-- limitations under the License. +-- +-- Copyright (C) 2015 - 2019, TBOOX Open Source Group. +-- +-- @author ruki +-- @file object.lua +-- + +-- imports +import("core.base.option") +import("core.theme.theme") +import("core.tool.compiler") +import("core.project.depend") +import("private.tools.ccache") + +-- do build file +function _do_build_file(target, sourcefile, opt) + + -- get build info + local objectfile = opt.objectfile + local dependfile = opt.dependfile + local sourcekind = opt.sourcekind + local progress = opt.progress + + -- load compiler + local compinst = compiler.load(sourcekind, {target = target}) + + -- get compile flags + local compflags = compinst:compflags({target = target, sourcefile = sourcefile}) + + -- load dependent info + local dependinfo = option.get("rebuild") and {} or (depend.load(dependfile) or {}) + + -- need build this object? + local depvalues = {compinst:program(), compflags} + if not depend.is_changed(dependinfo, {lastmtime = os.mtime(objectfile), values = depvalues}) then + return + end + + -- is verbose? + local verbose = option.get("verbose") + + -- exists ccache? + local exists_ccache = ccache.exists() + + -- trace progress info + cprintf("${color.build.progress}" .. theme.get("text.build.progress_format") .. ":${clear} ", progress) + if verbose then + cprint("${dim color.build.object}%scompiling.$(mode) %s", exists_ccache and "ccache " or "", sourcefile) + else + cprint("${color.build.object}%scompiling.$(mode) %s", exists_ccache and "ccache " or "", sourcefile) + end + + -- trace verbose info + if verbose then + print(compinst:compcmd(sourcefile, objectfile, {compflags = compflags})) + end + + -- flush io buffer to update progress info + io.flush() + + -- compile it + dependinfo.files = {} + assert(compinst:compile(sourcefile, objectfile, {dependinfo = dependinfo, compflags = compflags})) + + -- update files and values to the dependent file + dependinfo.values = depvalues + table.join2(dependinfo.files, sourcefile, target:pcoutputfile("cxx") or {}, target:pcoutputfile("c")) + depend.save(dependinfo, dependfile) +end + +-- build object +function _build_object(target, sourcebatch, index, opt) + + -- get the object and source with the given index + local sourcefile = sourcebatch.sourcefiles[index] + local objectfile = sourcebatch.objectfiles[index] + local dependfile = sourcebatch.dependfiles[index] + local sourcekind = assert(sourcebatch.sourcekind, "%s: sourcekind not found!", sourcefile) + + -- get progress range + local progress = assert(opt.progress, "no progress!") + + -- calculate progress + local progress_now = progress.start + ((index - 1) * (progress.stop - progress.start)) / #sourcebatch.sourcefiles + + -- init build option + local opt = {objectfile = objectfile, dependfile = dependfile, sourcekind = sourcekind, progress = progress_now} + + -- do before build + local before_build_file = target:script("build_file_before") + if before_build_file then + before_build_file(target, sourcefile, opt) + end + + -- do build + local on_build_file = target:script("build_file") + if on_build_file then + opt.origin = _do_build_file + on_build_file(target, sourcefile, opt) + opt.origin = nil + else + _do_build_file(target, sourcefile, opt) + end + + -- do after build + local after_build_file = target:script("build_file_after") + if after_build_file then + after_build_file(target, sourcefile, opt) + end +end + +-- build the source files +function main(target, sourcebatch, opt) + + -- get the max job count + local jobs = tonumber(option.get("jobs") or "4") + + -- run build jobs for each source file + local curdir = os.curdir() + process.runjobs(function (index) + + -- force to set the current directory first because the other jobs maybe changed it + os.cd(curdir) + + -- build object + _build_object(target, sourcebatch, index, opt) + + end, #sourcebatch.sourcefiles, jobs) +end diff --git a/xmake/modules/private/action/build/pcheader.lua b/xmake/modules/private/action/build/pcheader.lua new file mode 100644 index 000000000..e4cf2b949 --- /dev/null +++ b/xmake/modules/private/action/build/pcheader.lua @@ -0,0 +1,48 @@ +--!A cross-platform build utility based on Lua +-- +-- Licensed under the Apache License, Version 2.0 (the "License"); +-- you may not use this file except in compliance with the License. +-- You may obtain a copy of the License at +-- +-- http://www.apache.org/licenses/LICENSE-2.0 +-- +-- Unless required by applicable law or agreed to in writing, software +-- distributed under the License is distributed on an "AS IS" BASIS, +-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +-- See the License for the specific language governing permissions and +-- limitations under the License. +-- +-- Copyright (C) 2015 - 2019, TBOOX Open Source Group. +-- +-- @author ruki +-- @file pcheader.lua +-- + +-- imports +import("core.language.language") +import("object") + +-- build the precompiled header file +function main(target, langkind, opt) + + -- get the precompiled header + local pcheaderfile = target:pcheaderfile(langkind) + if pcheaderfile then + + -- init sourcefile, objectfile and dependfile + local sourcefile = pcheaderfile + local objectfile = target:pcoutputfile(langkind) + local dependfile = target:dependfile(objectfile) + local sourcekind = language.langkinds()[langkind] + + -- init source batch + local sourcebatch = {sourcekind = sourcekind, sourcefiles = {sourcefile}, objectfiles = {objectfile}, dependfiles = {dependfile}} + + -- build this precompiled header + local progress = opt.progress + if type(progress) == "number" then + progress = {start = progress, stop = progress} + end + object(target, sourcebatch, {progress = progress}) + end +end diff --git a/xmake/modules/private/tools/ccache.lua b/xmake/modules/private/tools/ccache.lua new file mode 100644 index 000000000..5d3e6c6f0 --- /dev/null +++ b/xmake/modules/private/tools/ccache.lua @@ -0,0 +1,59 @@ +--!A cross-platform build utility based on Lua +-- +-- Licensed under the Apache License, Version 2.0 (the "License"); +-- you may not use this file except in compliance with the License. +-- You may obtain a copy of the License at +-- +-- http://www.apache.org/licenses/LICENSE-2.0 +-- +-- Unless required by applicable law or agreed to in writing, software +-- distributed under the License is distributed on an "AS IS" BASIS, +-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +-- See the License for the specific language governing permissions and +-- limitations under the License. +-- +-- Copyright (C) 2015 - 2019, TBOOX Open Source Group. +-- +-- @author ruki +-- @file ccache.lua +-- + +-- imports +import("core.project.config") +import("lib.detect.find_tool") + +-- get ccache tool +function _ccache() + local ccache = _g.ccache + if ccache == nil and config.get("ccache") then + ccache = find_tool("ccache") + _g.ccache = ccache or false + end + return ccache or nil +end + +-- exists ccache? +function exists() + return _ccache() ~= nil +end + +-- uses ccache to wrap the program and arguments +-- +-- e.g. ccache program argv +-- +function cmdargv(program, argv) + + -- uses ccache? + local ccache = _ccache() + if ccache then + + -- parse the filename and arguments, e.g. "xcrun -sdk macosx clang" + if not os.isexec(program) then + argv = table.join(program:split("%s"), argv) + else + table.insert(argv, 1, program) + end + return ccache.program, argv + end + return program, argv +end diff --git a/xmake/plugins/project/clang/compile_commands.lua b/xmake/plugins/project/clang/compile_commands.lua index 4c81c2890..a9f1adf93 100644 --- a/xmake/plugins/project/clang/compile_commands.lua +++ b/xmake/plugins/project/clang/compile_commands.lua @@ -55,21 +55,12 @@ function _make_object(jsonfile, target, sourcefile, objectfile) _g.firstline = false end --- make each objects -function _make_each_objects(jsonfile, target, sourcekind, sourcebatch) +-- make objects +function _make_objects(jsonfile, target, sourcekind, sourcebatch) for index, objectfile in ipairs(sourcebatch.objectfiles) do _make_object(jsonfile, target, sourcebatch.sourcefiles[index], objectfile) end end - --- make single object -function _make_single_object(jsonfile, target, sourcekind, sourcebatch) - - -- not supported now, ignore it directly - for _, sourcefile in ipairs(table.wrap(sourcebatch.sourcefiles)) do - cprint("${bright color.warning}warning: ${clear}ignore[%s]: %s", target:name(), sourcefile) - end -end -- make target function _make_target(jsonfile, target) @@ -80,13 +71,10 @@ function _make_target(jsonfile, target) target:set("pcxxheader", nil) -- build source batches - for sourcekind, sourcebatch in pairs(target:sourcebatches()) do - if not sourcebatch.rulename then - if type(sourcebatch.objectfiles) == "string" then - _make_single_object(jsonfile, target, sourcekind, sourcebatch) - else - _make_each_objects(jsonfile, target, sourcekind, sourcebatch) - end + for _, sourcebatch in pairs(target:sourcebatches()) do + local sourcekind = sourcebatch.sourcekind + if sourcekind then + _make_objects(jsonfile, target, sourcekind, sourcebatch) end end end diff --git a/xmake/plugins/project/clang/compile_flags.lua b/xmake/plugins/project/clang/compile_flags.lua index de557c818..d6205700d 100644 --- a/xmake/plugins/project/clang/compile_flags.lua +++ b/xmake/plugins/project/clang/compile_flags.lua @@ -48,21 +48,12 @@ function _make_object(target, sourcefile, objectfile) _g.firstline = false end --- make each objects -function _make_each_objects(target, sourcekind, sourcebatch) +-- make objects +function _make_objects(target, sourcekind, sourcebatch) for index, objectfile in ipairs(sourcebatch.objectfiles) do _make_object(target, sourcebatch.sourcefiles[index], objectfile) end end - --- make single object -function _make_single_object(target, sourcekind, sourcebatch) - - -- not supported now, ignore it directly - for _, sourcefile in ipairs(table.wrap(sourcebatch.sourcefiles)) do - cprint("${bright yellow}warning: ${default yellow}ignore[%s]: %s", target:name(), sourcefile) - end -end -- make target function _make_target(target) @@ -73,13 +64,10 @@ function _make_target(target) target:set("pcxxheader", nil) -- build source batches - for sourcekind, sourcebatch in pairs(target:sourcebatches()) do - if not sourcebatch.rulename then - if type(sourcebatch.objectfiles) == "string" then - _make_single_object(target, sourcekind, sourcebatch) - else - _make_each_objects(target, sourcekind, sourcebatch) - end + for _, sourcebatch in pairs(target:sourcebatches()) do + local sourcekind = sourcebatch.sourcekind + if sourcekind then + _make_objects(target, sourcekind, sourcebatch) end end end diff --git a/xmake/plugins/project/make/makefile.lua b/xmake/plugins/project/make/makefile.lua index cc15a914f..6b90fc914 100644 --- a/xmake/plugins/project/make/makefile.lua +++ b/xmake/plugins/project/make/makefile.lua @@ -209,63 +209,14 @@ function _make_object(makefile, target, sourcefile, objectfile, sourceflags) makefile:print("") end --- make each objects -function _make_each_objects(makefile, target, sourcekind, sourcebatch, sourceflags) +-- make objects +function _make_objects(makefile, target, sourcekind, sourcebatch, sourceflags) -- make them for index, objectfile in ipairs(sourcebatch.objectfiles) do _make_object(makefile, target, sourcebatch.sourcefiles[index], objectfile, sourceflags) end end - --- make single object -function _make_single_object(makefile, target, sourcekind, sourcebatch, sourceflags) - - -- get source and object files - local sourcefiles = sourcebatch.sourcefiles - local objectfiles = sourcebatch.objectfiles - local dependfiles = sourcebatch.dependfiles - - -- get program - local program = platform.tool(sourcekind) - - -- make command - local macro = "$(" .. target:name() .. '_' .. sourcekind:upper() .. ")" - local command = compiler.compcmd(sourcefiles, objectfiles, {compflags = macro}) - - -- replace program to $(XX) - local p, e = command:find(program, 1, true) - if p then - command = format("%s$(%s)%s", command:sub(1, p - 1), sourcekind:upper(), command:sub(e + 1)) - end - - -- replace ccache to $(CCACHE) - local ccache = false - p, e = command:find("ccache", 1, true) - if p then - command = format("%s$(%s)%s", command:sub(1, p - 1), "CCACHE", command:sub(e + 1)) - ccache = true - end - - -- make head - makefile:printf("%s:", objectfiles) - - -- make dependence - for _, sourcefile in ipairs(sourcefiles) do - makefile:printf(" %s", sourcefile) - end - makefile:print("") - - -- make body - for _, sourcefile in ipairs(sourcefiles) do - makefile:print("\t@echo %scompiling.$(mode) %s", ifelse(ccache, "ccache ", ""), sourcefile) - end - _mkdir(makefile, path.directory(objectfiles)) - makefile:writef("\t@%s > %s 2>&1\n", command, _logfile()) - - -- make tail - makefile:print("") -end -- make phony function _make_phony(makefile, target) @@ -360,15 +311,12 @@ function _make_target(makefile, target, targetflags) makefile:print("") -- build source batches - for sourcekind, sourcebatch in pairs(target:sourcebatches()) do - if not sourcebatch.rulename then + for _, sourcebatch in pairs(target:sourcebatches()) do + local sourcekind = sourcebatch.sourcekind + if sourcekind then -- compile source files to single object at once local sourceflags = targetflags[target:name() .. '_' .. sourcekind:upper()] - if type(sourcebatch.objectfiles) == "string" then - _make_single_object(makefile, target, sourcekind, sourcebatch, sourceflags) - else - _make_each_objects(makefile, target, sourcekind, sourcebatch, sourceflags) - end + _make_objects(makefile, target, sourcekind, sourcebatch, sourceflags) end end end @@ -412,8 +360,9 @@ function _make_all(makefile) local targetflags = {} for targetname, target in pairs(project.targets()) do if not target:isphony() then - for sourcekind, sourcebatch in pairs(target:sourcebatches()) do - if not sourcebatch.rulename then + for _, sourcebatch in pairs(target:sourcebatches()) do + local sourcekind = sourcebatch.sourcekind + if sourcekind then local commonflags, sourceflags = _make_common_flags(target, sourcekind, sourcebatch) makefile:print("%s_%s=%s", targetname, sourcekind:upper(), os.args(commonflags)) targetflags[targetname .. '_' .. sourcekind:upper()] = sourceflags diff --git a/xmake/plugins/project/vstudio/impl/vs200x_vcproj.lua b/xmake/plugins/project/vstudio/impl/vs200x_vcproj.lua index 106b97709..149330276 100644 --- a/xmake/plugins/project/vstudio/impl/vs200x_vcproj.lua +++ b/xmake/plugins/project/vstudio/impl/vs200x_vcproj.lua @@ -251,8 +251,9 @@ function _make_configurations(vcprojfile, vsinfo, target, vcprojdir) -- save compiler flags local compflags=nil - for sourcekind, sourcebatch in pairs(target:sourcebatches()) do - if not sourcebatch.rulename then + for _, sourcebatch in pairs(target:sourcebatches()) do + local sourcekind = sourcebatch.sourcekind + if sourcekind then for _, sourcefile in ipairs(sourcebatch.sourcefiles) do local flags = compiler.compflags(sourcefile, {target = target}) if sourcekind == "cc" or sourcekind == "cxx" then @@ -526,7 +527,8 @@ function _make_files(vcprojfile, vsinfo, target, vcprojdir) local sourcebatches = target:sourcebatches() -- c/cxx files vcprojfile:enter("<Filter Name=\"Source Files\">") - for sourcekind, sourcebatch in pairs(sourcebatches) do + for _, sourcebatch in pairs(sourcebatches) do + local sourcekind = sourcebatch.sourcekind if sourcekind ~= "mrc" then local objectfiles = sourcebatch.objectfiles for idx, sourcefile in ipairs(sourcebatch.sourcefiles) do @@ -540,7 +542,8 @@ function _make_files(vcprojfile, vsinfo, target, vcprojdir) -- *.rc files vcprojfile:enter("<Filter Name=\"Resource Files\">") - for sourcekind, sourcebatch in pairs(sourcebatches) do + for _, sourcebatch in pairs(sourcebatches) do + local sourcekind = sourcebatch.sourcekind if sourcekind == "mrc" then local objectfiles = sourcebatch.objectfiles for idx, sourcefile in ipairs(sourcebatch.sourcefiles) do diff --git a/xmake/plugins/project/vstudio/impl/vs201x.lua b/xmake/plugins/project/vstudio/impl/vs201x.lua index af0a18d0c..4d68019bb 100644 --- a/xmake/plugins/project/vstudio/impl/vs201x.lua +++ b/xmake/plugins/project/vstudio/impl/vs201x.lua @@ -74,8 +74,9 @@ function _make_targetinfo(mode, arch, target) local firstcompflags = nil targetinfo.compflags = {} targetinfo.compargvs = {} - for sourcekind, sourcebatch in pairs(target:sourcebatches()) do - if not sourcebatch.rulename then + for _, sourcebatch in pairs(target:sourcebatches()) do + local sourcekind = sourcebatch.sourcekind + if sourcekind then for idx, sourcefile in ipairs(sourcebatch.sourcefiles) do local compflags = compiler.compflags(sourcefile, {target = target}) if not firstcompflags and (sourcekind == "cc" or sourcekind == "cxx") then diff --git a/xmake/plugins/project/vstudio/impl/vs201x_vcxproj.lua b/xmake/plugins/project/vstudio/impl/vs201x_vcxproj.lua index 8f6549281..65a6bad0a 100644 --- a/xmake/plugins/project/vstudio/impl/vs201x_vcxproj.lua +++ b/xmake/plugins/project/vstudio/impl/vs201x_vcxproj.lua @@ -457,8 +457,9 @@ function _make_common_items(vcxprojfile, vsinfo, target, vcxprojdir) local files_count = 0 local first_flags = nil targetinfo.sourceflags = {} - for sourcekind, sourcebatch in pairs(targetinfo.sourcebatches) do - if not sourcebatch.rulename and (sourcekind == "cc" or sourcekind == "cxx" or sourcekind == "as" or sourcekind == "mrc") then + for _, sourcebatch in pairs(targetinfo.sourcebatches) do + local sourcekind = sourcebatch.sourcekind + if (sourcekind == "cc" or sourcekind == "cxx" or sourcekind == "as" or sourcekind == "mrc") then for _, sourcefile in ipairs(sourcebatch.sourcefiles) do -- make compiler flags @@ -715,8 +716,9 @@ function _make_source_files(vcxprojfile, vsinfo, target, vcxprojdir) -- make source file infos local sourceinfos = {} for _, targetinfo in ipairs(target.info) do - for sourcekind, sourcebatch in pairs(targetinfo.sourcebatches) do - if not sourcebatch.rulename and (sourcekind == "cc" or sourcekind == "cxx" or sourcekind == "as" or sourcekind == "mrc") then + for _, sourcebatch in pairs(targetinfo.sourcebatches) do + local sourcekind = sourcebatch.sourcekind + if (sourcekind == "cc" or sourcekind == "cxx" or sourcekind == "as" or sourcekind == "mrc") then local objectfiles = sourcebatch.objectfiles for idx, sourcefile in ipairs(sourcebatch.sourcefiles) do local objectfile = objectfiles[idx] diff --git a/xmake/rules/asm/xmake.lua b/xmake/rules/asm/xmake.lua new file mode 100644 index 000000000..3a7e85f59 --- /dev/null +++ b/xmake/rules/asm/xmake.lua @@ -0,0 +1,30 @@ +--!A cross-platform build utility based on Lua +-- +-- Licensed under the Apache License, Version 2.0 (the "License"); +-- you may not use this file except in compliance with the License. +-- You may obtain a copy of the License at +-- +-- http://www.apache.org/licenses/LICENSE-2.0 +-- +-- Unless required by applicable law or agreed to in writing, software +-- distributed under the License is distributed on an "AS IS" BASIS, +-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +-- See the License for the specific language governing permissions and +-- limitations under the License. +-- +-- Copyright (C) 2015 - 2019, TBOOX Open Source Group. +-- +-- @author ruki +-- @file xmake.lua +-- + +-- define rule: asm.build +rule("asm.build") + set_extensions(".s", ".asm") + on_build_files(function (target, sourcebatch, opt) + import("private.action.build.object")(target, sourcebatch, opt) + end) + +-- define rule: asm +rule("asm") + add_deps("asm.build", "utils.merge.object", "utils.merge.archive") diff --git a/xmake/rules/c++/xmake.lua b/xmake/rules/c++/xmake.lua new file mode 100644 index 000000000..1330fbfca --- /dev/null +++ b/xmake/rules/c++/xmake.lua @@ -0,0 +1,51 @@ +--!A cross-platform build utility based on Lua +-- +-- Licensed under the Apache License, Version 2.0 (the "License"); +-- you may not use this file except in compliance with the License. +-- You may obtain a copy of the License at +-- +-- http://www.apache.org/licenses/LICENSE-2.0 +-- +-- Unless required by applicable law or agreed to in writing, software +-- distributed under the License is distributed on an "AS IS" BASIS, +-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +-- See the License for the specific language governing permissions and +-- limitations under the License. +-- +-- Copyright (C) 2015 - 2019, TBOOX Open Source Group. +-- +-- @author ruki +-- @file xmake.lua +-- + +-- define rule: c.build.pcheader +rule("c.build.pcheader") + before_build(function (target, opt) + import("private.action.build.pcheader")(target, "c", opt) + end) + +-- define rule: c.build +rule("c.build") + set_extensions(".c") + add_deps("c.build.pcheader") + on_build_files(function (target, sourcebatch, opt) + import("private.action.build.object")(target, sourcebatch, opt) + end) + +-- define rule: cpp.build.pcheader +rule("cpp.build.pcheader") + before_build(function (target, opt) + import("private.action.build.pcheader")(target, "cxx", opt) + end) + +-- define rule: cpp.build +rule("cpp.build") + set_extensions(".cpp", ".cc", ".cxx") + add_deps("cpp.build.pcheader") + on_build_files(function (target, sourcebatch, opt) + import("private.action.build.object")(target, sourcebatch, opt) + end) + +-- define rule: cpp +rule("cpp") + add_deps("cpp.build", "c.build", "utils.merge.object", "utils.merge.archive") diff --git a/xmake/rules/cuda/devlink/xmake.lua b/xmake/rules/cuda/devlink/xmake.lua index 2854bc0d7..90c796370 100644 --- a/xmake/rules/cuda/devlink/xmake.lua +++ b/xmake/rules/cuda/devlink/xmake.lua @@ -19,7 +19,7 @@ -- -- define rule: device-link -rule("cuda.devlink") +rule("cuda.build.devlink") -- add rule: cuda environment add_deps("cuda.env") @@ -36,7 +36,7 @@ rule("cuda.devlink") import("core.platform.platform") -- disable devlink? - if target:values("cuda.devlink") == false then + if target:values("cuda.build.devlink") == false then return end @@ -65,8 +65,8 @@ rule("cuda.devlink") -- get object files local objectfiles = nil - for sourcekind, sourcebatch in pairs(target:sourcebatches()) do - if sourcekind == "cu" then + for _, sourcebatch in pairs(target:sourcebatches()) do + if sourcebatch.sourcekind == "cu" then objectfiles = sourcebatch.objectfiles end end diff --git a/xmake/rules/cuda/xmake.lua b/xmake/rules/cuda/xmake.lua index 09e4c3fbe..d3e137254 100644 --- a/xmake/rules/cuda/xmake.lua +++ b/xmake/rules/cuda/xmake.lua @@ -18,9 +18,15 @@ -- @file xmake.lua -- +-- define rule: cuda.build +rule("cuda.build") + set_extensions(".cu") + add_deps("cuda.build.devlink") + on_build_files(function (target, sourcebatch, opt) + import("private.action.build.object")(target, sourcebatch, opt) + end) + -- define rule: cuda rule("cuda") - - -- add rules - add_deps("cuda.devlink", "cuda.gencodes") + add_deps("cuda.build", "cuda.gencodes") diff --git a/xmake/rules/dlang/xmake.lua b/xmake/rules/dlang/xmake.lua new file mode 100644 index 000000000..27f06c432 --- /dev/null +++ b/xmake/rules/dlang/xmake.lua @@ -0,0 +1,30 @@ +--!A cross-platform build utility based on Lua +-- +-- Licensed under the Apache License, Version 2.0 (the "License"); +-- you may not use this file except in compliance with the License. +-- You may obtain a copy of the License at +-- +-- http://www.apache.org/licenses/LICENSE-2.0 +-- +-- Unless required by applicable law or agreed to in writing, software +-- distributed under the License is distributed on an "AS IS" BASIS, +-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +-- See the License for the specific language governing permissions and +-- limitations under the License. +-- +-- Copyright (C) 2015 - 2019, TBOOX Open Source Group. +-- +-- @author ruki +-- @file xmake.lua +-- + +-- define rule: dlang.build +rule("dlang.build") + set_extensions(".d") + on_build_files(function (target, sourcebatch, opt) + import("private.action.build.object")(target, sourcebatch, opt) + end) + +-- define rule: dlang +rule("dlang") + add_deps("dlang.build", "utils.merge.object", "utils.merge.archive") diff --git a/xmake/rules/go/build/object.lua b/xmake/rules/go/build/object.lua new file mode 100644 index 000000000..5e4626d56 --- /dev/null +++ b/xmake/rules/go/build/object.lua @@ -0,0 +1,104 @@ +--!A cross-platform build utility based on Lua +-- +-- Licensed under the Apache License, Version 2.0 (the "License"); +-- you may not use this file except in compliance with the License. +-- You may obtain a copy of the License at +-- +-- http://www.apache.org/licenses/LICENSE-2.0 +-- +-- Unless required by applicable law or agreed to in writing, software +-- distributed under the License is distributed on an "AS IS" BASIS, +-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +-- See the License for the specific language governing permissions and +-- limitations under the License. +-- +-- Copyright (C) 2015 - 2019, TBOOX Open Source Group. +-- +-- @author ruki +-- @file object.lua +-- + +-- imports +import("core.base.option") +import("core.base.hashset") +import("core.theme.theme") +import("core.tool.compiler") +import("core.project.depend") + +-- build the source files +function main(target, sourcebatch, opt) + + -- is verbose? + local verbose = option.get("verbose") + + -- get progress range + local progress = assert(opt.progress, "no progress!") + + -- get source files and kind + local sourcefiles = sourcebatch.sourcefiles + local sourcekind = sourcebatch.sourcekind + + -- get object file + local objectfile = target:objectfile(path.join(path.directory(sourcefiles[1]), "__go__")) + + -- get depend file + local dependfile = target:dependfile(objectfile) + + -- remove the object files in sourcebatch + local objectfiles_set = hashset.from(sourcebatch.objectfiles) + for idx, file in irpairs(target:objectfiles()) do + if objectfiles_set:has(file) then + table.remove(target:objectfiles(), idx) + end + end + + -- add object file + table.insert(target:objectfiles(), objectfile) + + -- load compiler + local compinst = compiler.load(sourcekind, {target = target}) + + -- get compile flags + local compflags = compinst:compflags({target = target}) + + -- load dependent info + local dependinfo = option.get("rebuild") and {} or (depend.load(dependfile) or {}) + + -- need build this object? + local depvalues = {compinst:program(), compflags} + if not depend.is_changed(dependinfo, {lastmtime = os.mtime(objectfile), values = depvalues}) then + return + end + + -- trace progress info + for index, sourcefile in ipairs(sourcefiles) do + + -- calculate progress + local progress_now = progress.start + ((index - 1) * (progress.stop - progress.start)) / #sourcefiles + + -- trace progress info + cprintf("${color.build.progress}" .. theme.get("text.build.progress_format") .. ":${clear} ", progress_now) + if verbose then + cprint("${dim color.build.object}compiling.$(mode) %s", sourcefile) + else + cprint("${color.build.object}compiling.$(mode) %s", sourcefile) + end + end + + -- trace verbose info + if verbose then + print(compinst:compcmd(sourcefiles, objectfile, {compflags = compflags})) + end + + -- flush io buffer to update progress info + io.flush() + + -- compile it + dependinfo.files = {} + assert(compinst:compile(sourcefiles, objectfile, {dependinfo = dependinfo, compflags = compflags})) + + -- update files and values to the dependent file + dependinfo.values = depvalues + table.join2(dependinfo.files, sourcefiles) + depend.save(dependinfo, dependfile) +end diff --git a/xmake/rules/go/xmake.lua b/xmake/rules/go/xmake.lua new file mode 100644 index 000000000..97d929e08 --- /dev/null +++ b/xmake/rules/go/xmake.lua @@ -0,0 +1,30 @@ +--!A cross-platform build utility based on Lua +-- +-- Licensed under the Apache License, Version 2.0 (the "License"); +-- you may not use this file except in compliance with the License. +-- You may obtain a copy of the License at +-- +-- http://www.apache.org/licenses/LICENSE-2.0 +-- +-- Unless required by applicable law or agreed to in writing, software +-- distributed under the License is distributed on an "AS IS" BASIS, +-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +-- See the License for the specific language governing permissions and +-- limitations under the License. +-- +-- Copyright (C) 2015 - 2019, TBOOX Open Source Group. +-- +-- @author ruki +-- @file xmake.lua +-- + +-- define rule: go.build +rule("go.build") + set_extensions(".go") + on_build_files(function (target, sourcebatch, opt) + import("build.object")(target, sourcebatch, opt) + end) + +-- define rule: cpp +rule("go") + add_deps("go.build") diff --git a/xmake/rules/objc++/xmake.lua b/xmake/rules/objc++/xmake.lua new file mode 100644 index 000000000..986e3d1a3 --- /dev/null +++ b/xmake/rules/objc++/xmake.lua @@ -0,0 +1,39 @@ +--!A cross-platform build utility based on Lua +-- +-- Licensed under the Apache License, Version 2.0 (the "License"); +-- you may not use this file except in compliance with the License. +-- You may obtain a copy of the License at +-- +-- http://www.apache.org/licenses/LICENSE-2.0 +-- +-- Unless required by applicable law or agreed to in writing, software +-- distributed under the License is distributed on an "AS IS" BASIS, +-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +-- See the License for the specific language governing permissions and +-- limitations under the License. +-- +-- Copyright (C) 2015 - 2019, TBOOX Open Source Group. +-- +-- @author ruki +-- @file xmake.lua +-- + +-- define rule: objc.build +rule("objc.build") + set_extensions(".m") + add_deps("c.build.pcheader") + on_build_files(function (target, sourcebatch, opt) + import("private.action.build.object")(target, sourcebatch, opt) + end) + +-- define rule: objc++.build +rule("objc++.build") + set_extensions(".mm") + add_deps("cpp.build.pcheader") + on_build_files(function (target, sourcebatch, opt) + import("private.action.build.object")(target, sourcebatch, opt) + end) + +-- define rule: objc +rule("objc++") + add_deps("objc++.build", "objc.build", "utils.merge.object", "utils.merge.archive") diff --git a/xmake/rules/rust/build/target.lua b/xmake/rules/rust/build/target.lua new file mode 100644 index 000000000..812ba7f95 --- /dev/null +++ b/xmake/rules/rust/build/target.lua @@ -0,0 +1,98 @@ +--!A cross-platform build utility based on Lua +-- +-- Licensed under the Apache License, Version 2.0 (the "License"); +-- you may not use this file except in compliance with the License. +-- You may obtain a copy of the License at +-- +-- http://www.apache.org/licenses/LICENSE-2.0 +-- +-- Unless required by applicable law or agreed to in writing, software +-- distributed under the License is distributed on an "AS IS" BASIS, +-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +-- See the License for the specific language governing permissions and +-- limitations under the License. +-- +-- Copyright (C) 2015 - 2019, TBOOX Open Source Group. +-- +-- @author ruki +-- @file target.lua +-- + +-- imports +import("core.base.option") +import("core.base.hashset") +import("core.theme.theme") +import("core.tool.compiler") +import("core.project.depend") + +-- build the source files +function build_sourcefiles(target, sourcebatch, opt) + + -- is verbose? + local verbose = option.get("verbose") + + -- get progress range + local progress = assert(opt.progress, "no progress!") + + -- get the target file + local targetfile = target:targetfile() + + -- get source files and kind + local sourcefiles = sourcebatch.sourcefiles + local sourcekind = sourcebatch.sourcekind + + -- get depend file + local dependfile = target:dependfile(targetfile) + + -- load compiler + local compinst = compiler.load(sourcekind, {target = target}) + + -- get compile flags + local compflags = compinst:compflags({target = target}) + + -- load dependent info + local dependinfo = option.get("rebuild") and {} or (depend.load(dependfile) or {}) + + -- need build this object? + local depvalues = {compinst:program(), compflags} + if not depend.is_changed(dependinfo, {lastmtime = os.mtime(targetfile), values = depvalues}) then + return + end + + -- trace progress into + cprintf("${color.build.progress}" .. theme.get("text.build.progress_format") .. ":${clear} ", progress.start) + if verbose then + cprint("${dim color.build.target}linking.$(mode) %s", path.filename(targetfile)) + else + cprint("${color.build.target}linking.$(mode) %s", path.filename(targetfile)) + end + + -- trace verbose info + if verbose then + print(compinst:buildcmd(sourcefiles, targetfile, {target = target, compflags = compflags})) + end + + -- flush io buffer to update progress info + io.flush() + + -- compile it + dependinfo.files = {} + assert(compinst:build(sourcefiles, targetfile, {target = target, dependinfo = dependinfo, compflags = compflags})) + + -- update files and values to the dependent file + dependinfo.values = depvalues + table.join2(dependinfo.files, sourcefiles) + depend.save(dependinfo, dependfile) +end + +-- build target +function main(target, opt) + + -- @note only support one source kind! + for _, sourcebatch in pairs(target:sourcebatches()) do + if sourcebatch.sourcekind == "rc" then + build_sourcefiles(target, sourcebatch, opt) + break + end + end +end diff --git a/xmake/rules/rust/xmake.lua b/xmake/rules/rust/xmake.lua new file mode 100644 index 000000000..3d88f2c96 --- /dev/null +++ b/xmake/rules/rust/xmake.lua @@ -0,0 +1,30 @@ +--!A cross-platform build utility based on Lua +-- +-- Licensed under the Apache License, Version 2.0 (the "License"); +-- you may not use this file except in compliance with the License. +-- You may obtain a copy of the License at +-- +-- http://www.apache.org/licenses/LICENSE-2.0 +-- +-- Unless required by applicable law or agreed to in writing, software +-- distributed under the License is distributed on an "AS IS" BASIS, +-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +-- See the License for the specific language governing permissions and +-- limitations under the License. +-- +-- Copyright (C) 2015 - 2019, TBOOX Open Source Group. +-- +-- @author ruki +-- @file xmake.lua +-- + +-- define rule: rust.build +rule("rust.build") + set_extensions(".rs") + on_build(function (target, opt) + import("build.target")(target, opt) + end) + +-- define rule: cpp +rule("rust") + add_deps("rust.build") diff --git a/xmake/rules/swift/xmake.lua b/xmake/rules/swift/xmake.lua new file mode 100644 index 000000000..9be96096d --- /dev/null +++ b/xmake/rules/swift/xmake.lua @@ -0,0 +1,30 @@ +--!A cross-platform build utility based on Lua +-- +-- Licensed under the Apache License, Version 2.0 (the "License"); +-- you may not use this file except in compliance with the License. +-- You may obtain a copy of the License at +-- +-- http://www.apache.org/licenses/LICENSE-2.0 +-- +-- Unless required by applicable law or agreed to in writing, software +-- distributed under the License is distributed on an "AS IS" BASIS, +-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +-- See the License for the specific language governing permissions and +-- limitations under the License. +-- +-- Copyright (C) 2015 - 2019, TBOOX Open Source Group. +-- +-- @author ruki +-- @file xmake.lua +-- + +-- define rule: swift.build +rule("swift.build") + set_extensions(".swift") + on_build_files(function (target, sourcebatch, opt) + import("private.action.build.object")(target, sourcebatch, opt) + end) + +-- define rule: swift +rule("swift") + add_deps("swift.build", "utils.merge.object") diff --git a/xmake/rules/utils/merge_archive/xmake.lua b/xmake/rules/utils/merge_archive/xmake.lua new file mode 100644 index 000000000..d78b0258c --- /dev/null +++ b/xmake/rules/utils/merge_archive/xmake.lua @@ -0,0 +1,76 @@ +--!A cross-platform build utility based on Lua +-- +-- Licensed under the Apache License, Version 2.0 (the "License"); +-- you may not use this file except in compliance with the License. +-- You may obtain a copy of the License at +-- +-- http://www.apache.org/licenses/LICENSE-2.0 +-- +-- Unless required by applicable law or agreed to in writing, software +-- distributed under the License is distributed on an "AS IS" BASIS, +-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +-- See the License for the specific language governing permissions and +-- limitations under the License. +-- +-- Copyright (C) 2015 - 2019, TBOOX Open Source Group. +-- +-- @author ruki +-- @file xmake.lua +-- + +-- define rule: utils.merge.archive +rule("utils.merge.archive") + + -- set extensions + set_extensions(".a", ".lib") + + -- on build file + on_build_file(function (target, sourcefile_lib, opt) + + -- imports + import("core.base.option") + import("core.theme.theme") + import("core.project.depend") + import("core.tool.extractor") + import("core.project.target", {alias = "project_target"}) + + -- get object directory of the archive file + local objectdir = target:objectfile(sourcefile_lib) .. ".dir" + + -- load dependent info + local dependfile = target:dependfile(objectdir) + local dependinfo = option.get("rebuild") and {} or (depend.load(dependfile) or {}) + + -- need build this object? + if not depend.is_changed(dependinfo, {lastmtime = os.mtime(objectdir)}) then + local objectfiles = os.files(path.join(objectdir, "**" .. project_target.filename("", "object"))) + table.join2(target:objectfiles(), objectfiles) + return + end + + -- trace progress info + cprintf("${color.build.progress}" .. theme.get("text.build.progress_format") .. ":${clear} ", opt.progress) + if option.get("verbose") then + cprint("${dim color.build.object}inserting.$(mode) %s", sourcefile_lib) + print("extracting %s to %s", sourcefile_lib, objectdir) + else + cprint("${color.build.object}inserting.$(mode) %s", sourcefile_lib) + end + + -- flush io buffer to update progress info + io.flush() + + -- extract the archive library + os.tryrm(objectdir) + extractor.extract(sourcefile_lib, objectdir) + + -- add objectfiles + local objectfiles = os.files(path.join(objectdir, "**" .. project_target.filename("", "object"))) + table.join2(target:objectfiles(), objectfiles) + + -- update files to the dependent file + dependinfo.files = {} + table.insert(dependinfo.files, sourcefile_lib) + depend.save(dependinfo, dependfile) + end) + diff --git a/xmake/rules/utils/merge_object/xmake.lua b/xmake/rules/utils/merge_object/xmake.lua new file mode 100644 index 000000000..1918631a9 --- /dev/null +++ b/xmake/rules/utils/merge_object/xmake.lua @@ -0,0 +1,70 @@ +--!A cross-platform build utility based on Lua +-- +-- Licensed under the Apache License, Version 2.0 (the "License"); +-- you may not use this file except in compliance with the License. +-- You may obtain a copy of the License at +-- +-- http://www.apache.org/licenses/LICENSE-2.0 +-- +-- Unless required by applicable law or agreed to in writing, software +-- distributed under the License is distributed on an "AS IS" BASIS, +-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +-- See the License for the specific language governing permissions and +-- limitations under the License. +-- +-- Copyright (C) 2015 - 2019, TBOOX Open Source Group. +-- +-- @author ruki +-- @file xmake.lua +-- + +-- define rule: utils.merge.object +rule("utils.merge.object") + + -- set extensions + set_extensions(".o", ".obj") + + -- on build file + on_build_file(function (target, sourcefile_obj, opt) + + -- imports + import("core.base.option") + import("core.theme.theme") + import("core.project.depend") + + -- get object file + local objectfile = target:objectfile(sourcefile_obj) + + -- add objectfile + table.insert(target:objectfiles(), objectfile) + + -- load dependent info + local dependfile = target:dependfile(objectfile) + local dependinfo = option.get("rebuild") and {} or (depend.load(dependfile) or {}) + + -- need build this object? + if not depend.is_changed(dependinfo, {lastmtime = os.mtime(objectfile)}) then + return + end + + -- trace progress info + cprintf("${color.build.progress}" .. theme.get("text.build.progress_format") .. ":${clear} ", opt.progress) + if option.get("verbose") then + cprint("${dim color.build.object}inserting.$(mode) %s", sourcefile_obj) + print("copying %s to %s", sourcefile_obj, objectfile) + else + cprint("${color.build.object}inserting.$(mode) %s", sourcefile_obj) + end + + -- flush io buffer to update progress info + io.flush() + + -- insert this object file + os.cp(sourcefile_obj, objectfile) + + -- update files to the dependent file + dependinfo.files = {} + table.insert(dependinfo.files, sourcefile_obj) + depend.save(dependinfo, dependfile) + end) + diff --git a/xmake/rules/winsdk/xmake.lua b/xmake/rules/winsdk/xmake.lua index d9b08efea..66accd6aa 100644 --- a/xmake/rules/winsdk/xmake.lua +++ b/xmake/rules/winsdk/xmake.lua @@ -18,6 +18,13 @@ -- @file xmake.lua -- +-- define rule: win.sdk.resource +rule("win.sdk.resource") + set_extensions(".rc") + on_build_files(function (target, sourcebatch, opt) + import("private.action.build.object")(target, sourcebatch, opt) + end) + -- define rule: application rule("win.sdk.application") |
