summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorruki <[email protected]>2019-09-04 10:09:50 +0800
committerGitHub <[email protected]>2019-09-04 10:09:50 +0800
commit1a1eac4f9e099eed250d72f309cf479efbb15a1c (patch)
treebd0341661b3db9fc2f557b6b4186d5193671371d
parentc97ee9d0ba48ac615caa9f239436645bc2e0af5a (diff)
parent3d72809db048911efec3d52106dd6968349ef4d1 (diff)
Merge pull request #563 from xmake-io/buildrules
Separate build rules for specific language files from action/build
-rw-r--r--.travis.yml1
-rw-r--r--core/src/xmake/os/mtime.c2
-rw-r--r--tests/projects/c/shared_library/xmake.lua35
-rw-r--r--tests/projects/c/static_library/xmake.lua35
-rw-r--r--tests/projects/hybrid/static_library/src/main.cpp12
-rw-r--r--tests/projects/hybrid/static_library/src/main2.cpp7
-rw-r--r--tests/projects/hybrid/static_library/src/test.h13
-rw-r--r--tests/projects/hybrid/static_library/src/test1.c5
-rw-r--r--tests/projects/hybrid/static_library/src/test2.m5
-rw-r--r--tests/projects/hybrid/static_library/src/test3.mm5
-rw-r--r--tests/projects/hybrid/static_library/src/test4.cpp5
-rw-r--r--tests/projects/hybrid/static_library/src/test5.d5
-rw-r--r--tests/projects/hybrid/static_library/test.lua (renamed from tests/projects/other/merge_static_library/test.lua)0
-rw-r--r--tests/projects/hybrid/static_library/xmake.lua24
-rw-r--r--tests/projects/other/merge_archive/src/add.c (renamed from tests/projects/other/merge_static_library/src/add.c)0
-rw-r--r--tests/projects/other/merge_archive/src/mul.c (renamed from tests/projects/other/merge_static_library/src/mul.c)0
-rw-r--r--tests/projects/other/merge_archive/src/sub.c (renamed from tests/projects/other/merge_static_library/src/sub.c)0
-rw-r--r--tests/projects/other/merge_archive/test.lua6
-rw-r--r--tests/projects/other/merge_archive/xmake.lua22
-rw-r--r--tests/projects/other/merge_object/xmake.lua11
-rw-r--r--tests/projects/other/merge_static_library/xmake.lua38
-rw-r--r--xmake/actions/build/build.lua49
-rw-r--r--xmake/actions/build/build_files.lua51
-rw-r--r--xmake/actions/build/kinds/binary.lua68
-rw-r--r--xmake/actions/build/kinds/object.lua344
-rw-r--r--xmake/actions/build/kinds/shared.lua68
-rw-r--r--xmake/actions/build/kinds/static.lua68
-rw-r--r--xmake/core/project/target.lua141
-rw-r--r--xmake/core/sandbox/modules/import/core/tool/compiler.lua10
-rw-r--r--xmake/core/tool/builder.lua10
-rw-r--r--xmake/languages/asm/xmake.lua3
-rw-r--r--xmake/languages/c++/xmake.lua3
-rw-r--r--xmake/languages/dlang/xmake.lua3
-rw-r--r--xmake/languages/golang/xmake.lua3
-rw-r--r--xmake/languages/msrc/xmake.lua3
-rw-r--r--xmake/languages/objc++/xmake.lua3
-rw-r--r--xmake/languages/rust/xmake.lua3
-rw-r--r--xmake/languages/swift/xmake.lua3
-rw-r--r--xmake/modules/core/tools/cl.lua6
-rw-r--r--xmake/modules/core/tools/cparser.lua34
-rw-r--r--xmake/modules/core/tools/dmd.lua6
-rw-r--r--xmake/modules/core/tools/fasm.lua6
-rw-r--r--xmake/modules/core/tools/gcc.lua34
-rw-r--r--xmake/modules/core/tools/go.lua6
-rw-r--r--xmake/modules/core/tools/llvm_rc.lua6
-rw-r--r--xmake/modules/core/tools/ml.lua6
-rw-r--r--xmake/modules/core/tools/nvcc.lua34
-rw-r--r--xmake/modules/core/tools/rc.lua6
-rw-r--r--xmake/modules/core/tools/rustc.lua9
-rw-r--r--xmake/modules/core/tools/swiftc.lua34
-rw-r--r--xmake/modules/core/tools/tcc.lua34
-rw-r--r--xmake/modules/core/tools/windres.lua6
-rw-r--r--xmake/modules/core/tools/yasm.lua6
-rw-r--r--xmake/modules/private/action/build/object.lua142
-rw-r--r--xmake/modules/private/action/build/pcheader.lua48
-rw-r--r--xmake/modules/private/tools/ccache.lua59
-rw-r--r--xmake/plugins/project/clang/compile_commands.lua24
-rw-r--r--xmake/plugins/project/clang/compile_flags.lua24
-rw-r--r--xmake/plugins/project/make/makefile.lua69
-rw-r--r--xmake/plugins/project/vstudio/impl/vs200x_vcproj.lua11
-rw-r--r--xmake/plugins/project/vstudio/impl/vs201x.lua5
-rw-r--r--xmake/plugins/project/vstudio/impl/vs201x_vcxproj.lua10
-rw-r--r--xmake/rules/asm/xmake.lua30
-rw-r--r--xmake/rules/c++/xmake.lua51
-rw-r--r--xmake/rules/cuda/devlink/xmake.lua8
-rw-r--r--xmake/rules/cuda/xmake.lua12
-rw-r--r--xmake/rules/dlang/xmake.lua30
-rw-r--r--xmake/rules/go/build/object.lua104
-rw-r--r--xmake/rules/go/xmake.lua30
-rw-r--r--xmake/rules/objc++/xmake.lua39
-rw-r--r--xmake/rules/rust/build/target.lua98
-rw-r--r--xmake/rules/rust/xmake.lua30
-rw-r--r--xmake/rules/swift/xmake.lua30
-rw-r--r--xmake/rules/utils/merge_archive/xmake.lua76
-rw-r--r--xmake/rules/utils/merge_object/xmake.lua70
-rw-r--r--xmake/rules/winsdk/xmake.lua7
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")