From fea373aa2f5f4bc41f87212baf41510a35243734 Mon Sep 17 00:00:00 2001 From: al1-ce Date: Wed, 3 Jul 2024 14:21:50 +0300 Subject: Improve Vala support When compiling multiple files valac fails to find symbols (i.e SomeClass from a.vala using in b.vala), changed build to process all source files at once --- xmake/rules/vala/xmake.lua | 107 ++++++++++++++++++++++++++------------------- 1 file changed, 61 insertions(+), 46 deletions(-) diff --git a/xmake/rules/vala/xmake.lua b/xmake/rules/vala/xmake.lua index 85a74d239..cc2811cba 100644 --- a/xmake/rules/vala/xmake.lua +++ b/xmake/rules/vala/xmake.lua @@ -58,67 +58,82 @@ rule("vala.build") target:add("sysincludedirs", path.directory(headerfile), {public = true}) end end) - before_buildcmd_file(function (target, batchcmds, sourcefile_vala, opt) + + before_buildcmd_files(function (target, batchcmds, sourcefiles_vala, opt) -- get valac import("lib.detect.find_tool") local valac = assert(find_tool("valac"), "valac not found!") - -- get c source file for vala - local sourcefile_c = target:autogenfile((sourcefile_vala:gsub(".vala$", ".c"))) - local basedir = path.directory(sourcefile_c) - - -- add objectfile - local objectfile = target:objectfile(sourcefile_c) - table.insert(target:objectfiles(), objectfile) - - -- add commands - batchcmds:show_progress(opt.progress, "${color.build.object}compiling.vala %s", sourcefile_vala) - batchcmds:mkdir(basedir) - local argv = {"-C", "-b", path(basedir)} - local packages = target:values("vala.packages") - if packages then - for _, package in ipairs(packages) do - table.insert(argv, "--pkg") - table.insert(argv, path(package)) + local sourcefiles_c = {} + local argv = {"-C", "-d", target:autogendir()} + -- iterating through vala files, otherwise valac would fail when compiling multiple files + for _, sourcefile_vala in ipairs(sourcefiles_vala.sourcefiles) do + -- get c source file for vala + local sourcefile_c = target:autogenfile((sourcefile_vala:gsub(".vala$", ".c"))) + local basedir = path.directory(sourcefile_c) + table.insert(sourcefiles_c, sourcefile_c) + + -- add objectfile + local objectfile = target:objectfile(sourcefile_c) + table.insert(target:objectfiles(), objectfile) + + -- add commands + batchcmds:mkdir(basedir) + local packages = target:values("vala.packages") + if packages then + for _, package in ipairs(packages) do + table.insert(argv, "--pkg") + table.insert(argv, path(package)) + end end - end - if target:is_binary() then - for _, dep in ipairs(target:orderdeps()) do - if dep:is_shared() or dep:is_static() then - local vapifile = dep:data("vala.vapifile") - if vapifile then - table.join2(argv, path(vapifile)) + if target:is_binary() then + for _, dep in ipairs(target:orderdeps()) do + if dep:is_shared() or dep:is_static() then + local vapifile = dep:data("vala.vapifile") + if vapifile then + table.join2(argv, path(vapifile)) + end end end + else + local vapifile = target:data("vala.vapifile") + if vapifile then + table.insert(argv, path(vapifile, function (p) return "--vapi=" .. p end)) + end + local headerfile = target:data("vala.headerfile") + if headerfile then + table.insert(argv, "-H") + table.insert(argv, path(headerfile)) + end end - else - local vapifile = target:data("vala.vapifile") - if vapifile then - table.insert(argv, path(vapifile, function (p) return "--vapi=" .. p end)) + local vapidir = target:data("vala.vapidir") + if vapidir then + table.insert(argv, path(vapidir, function (p) return "--vapidir=" .. p end)) end - local headerfile = target:data("vala.headerfile") - if headerfile then - table.insert(argv, "-H") - table.insert(argv, path(headerfile)) + local valaflags = target:data("vala.flags") + if valaflags then + table.join2(argv, valaflags) end + table.insert(argv, path(sourcefile_vala)) end - local vapidir = target:data("vala.vapidir") - if vapidir then - table.insert(argv, path(vapidir, function (p) return "--vapidir=" .. p end)) - end - local valaflags = target:data("vala.flags") - if valaflags then - table.join2(argv, valaflags) - end - table.insert(argv, path(sourcefile_vala)) + + batchcmds:show_progress(opt.progress, "${color.build.object}compiling.vala") batchcmds:vrunv(valac.program, argv) - batchcmds:compile(sourcefile_c, objectfile) + + for _, sourcefile_c in ipairs(sourcefiles_c) do + batchcmds:show_progress(opt.progress, "${color.build.object}compiling.c %s", sourcefile_c) + batchcmds:compile(sourcefile_c, target:objectfile(sourcefile_c)) + end -- add deps - batchcmds:add_depfiles(sourcefile_vala) - batchcmds:set_depmtime(os.mtime(objectfile)) - batchcmds:set_depcache(target:dependfile(objectfile)) + for _, sourcefile_vala in ipairs(sourcefiles_vala.sourcefiles) do + batchcmds:add_depfiles(sourcefile_vala) + end + for _, objectfile in ipairs(target:objectfiles()) do + batchcmds:set_depmtime(os.mtime(objectfile)) + batchcmds:set_depcache(target:dependfile(objectfile)) + end end) after_install(function (target) -- cgit v1.3.1 From f090b97d39bde78ea8cd5e0a85b0490b3dab1af7 Mon Sep 17 00:00:00 2001 From: al1-ce Date: Thu, 4 Jul 2024 13:32:50 +0300 Subject: Refactor vala buildcmd --- xmake/rules/vala/xmake.lua | 121 ++++++++++++++++++++++++--------------------- 1 file changed, 65 insertions(+), 56 deletions(-) diff --git a/xmake/rules/vala/xmake.lua b/xmake/rules/vala/xmake.lua index cc2811cba..83ab001cc 100644 --- a/xmake/rules/vala/xmake.lua +++ b/xmake/rules/vala/xmake.lua @@ -20,13 +20,11 @@ rule("vala.build") set_extensions(".vala") + -- Since vala can directly compile with C files + -- we can add C sourcekinds + -- And in the end we're going to be compiling C code + set_sourcekinds("cc") on_load(function (target) - -- only vala source files? we need to patch c source kind for linker - local sourcekinds = target:sourcekinds() - if #sourcekinds == 0 then - table.insert(sourcekinds, "cc") - end - -- we disable to build across targets in parallel, because the source files may depend on other target modules target:set("policy", "build.across_targets_in_parallel", false) @@ -58,81 +56,92 @@ rule("vala.build") target:add("sysincludedirs", path.directory(headerfile), {public = true}) end end) - before_buildcmd_files(function (target, batchcmds, sourcefiles_vala, opt) + -- Here we compile vala files into C code + + -- We have to compile entire project each time + -- because otherwise valac can't resolve symbols + -- from other files, however, c files can be + -- incrementally built -- get valac import("lib.detect.find_tool") local valac = assert(find_tool("valac"), "valac not found!") - local sourcefiles_c = {} local argv = {"-C", "-d", target:autogendir()} - -- iterating through vala files, otherwise valac would fail when compiling multiple files + -- iterating through source files, + -- otherwise valac would fail when compiling multiple files for _, sourcefile_vala in ipairs(sourcefiles_vala.sourcefiles) do - -- get c source file for vala - local sourcefile_c = target:autogenfile((sourcefile_vala:gsub(".vala$", ".c"))) - local basedir = path.directory(sourcefile_c) - table.insert(sourcefiles_c, sourcefile_c) + -- if it's only a vala file + if string.match(sourcefile_vala, ".vala$") ~= nil then + table.insert(argv, path(sourcefile_vala)) + end + end - -- add objectfile - local objectfile = target:objectfile(sourcefile_c) - table.insert(target:objectfiles(), objectfile) + -- no vala files, so exit + if #argv == 3 then return end - -- add commands - batchcmds:mkdir(basedir) - local packages = target:values("vala.packages") - if packages then - for _, package in ipairs(packages) do - table.insert(argv, "--pkg") - table.insert(argv, path(package)) - end + -- add commands + local packages = target:values("vala.packages") + if packages then + for _, package in ipairs(packages) do + table.insert(argv, "--pkg") + table.insert(argv, path(package)) end - if target:is_binary() then - for _, dep in ipairs(target:orderdeps()) do - if dep:is_shared() or dep:is_static() then - local vapifile = dep:data("vala.vapifile") - if vapifile then - table.join2(argv, path(vapifile)) - end + end + + if target:is_binary() then + for _, dep in ipairs(target:orderdeps()) do + if dep:is_shared() or dep:is_static() then + local vapifile = dep:data("vala.vapifile") + if vapifile then + table.join2(argv, path(vapifile)) end end - else - local vapifile = target:data("vala.vapifile") - if vapifile then - table.insert(argv, path(vapifile, function (p) return "--vapi=" .. p end)) - end - local headerfile = target:data("vala.headerfile") - if headerfile then - table.insert(argv, "-H") - table.insert(argv, path(headerfile)) - end end - local vapidir = target:data("vala.vapidir") - if vapidir then - table.insert(argv, path(vapidir, function (p) return "--vapidir=" .. p end)) + else + local vapifile = target:data("vala.vapifile") + if vapifile then + table.insert(argv, path(vapifile, function (p) return "--vapi=" .. p end)) end - local valaflags = target:data("vala.flags") - if valaflags then - table.join2(argv, valaflags) + local headerfile = target:data("vala.headerfile") + if headerfile then + table.insert(argv, "-H") + table.insert(argv, path(headerfile)) end - table.insert(argv, path(sourcefile_vala)) + end + + local vapidir = target:data("vala.vapidir") + if vapidir then + table.insert(argv, path(vapidir, function (p) return "--vapidir=" .. p end)) + end + + local valaflags = target:data("vala.flags") + if valaflags then + table.join2(argv, valaflags) end batchcmds:show_progress(opt.progress, "${color.build.object}compiling.vala") batchcmds:vrunv(valac.program, argv) + end) - for _, sourcefile_c in ipairs(sourcefiles_c) do - batchcmds:show_progress(opt.progress, "${color.build.object}compiling.c %s", sourcefile_c) - batchcmds:compile(sourcefile_c, target:objectfile(sourcefile_c)) - end + on_buildcmd_file(function (target, batchcmds, sourcefile_vala, opt) + -- Again, only vala files need special treatment + if string.match(sourcefile_vala, ".vala$") ~= nil then + local sourcefile_c = target:autogenfile((sourcefile_vala:gsub(".vala$", ".c"))) + local basedir = path.directory(sourcefile_c) + + batchcmds:mkdir(basedir) + + local objectfile = target:objectfile(sourcefile_c) + table.insert(target:objectfiles(), objectfile) - -- add deps - for _, sourcefile_vala in ipairs(sourcefiles_vala.sourcefiles) do batchcmds:add_depfiles(sourcefile_vala) - end - for _, objectfile in ipairs(target:objectfiles()) do batchcmds:set_depmtime(os.mtime(objectfile)) batchcmds:set_depcache(target:dependfile(objectfile)) + + batchcmds:show_progress(opt.progress, "${color.build.object}compiling.c %s", sourcefile_c) + batchcmds:compile(sourcefile_c, objectfile, { configs = { force = { cflags = "-w" } } }) end end) -- cgit v1.3.1 From 6c17a5c75bacaedc84ceecdcb7c4045bea972e37 Mon Sep 17 00:00:00 2001 From: al1-ce Date: Thu, 4 Jul 2024 13:33:23 +0300 Subject: Add example for using vala with c --- tests/projects/vala/includec/src/main.vala | 9 +++++++++ tests/projects/vala/includec/src/printer.c | 6 ++++++ tests/projects/vala/includec/src/printer.vala | 5 +++++ tests/projects/vala/includec/xmake.lua | 10 ++++++++++ 4 files changed, 30 insertions(+) create mode 100644 tests/projects/vala/includec/src/main.vala create mode 100644 tests/projects/vala/includec/src/printer.c create mode 100644 tests/projects/vala/includec/src/printer.vala create mode 100644 tests/projects/vala/includec/xmake.lua diff --git a/tests/projects/vala/includec/src/main.vala b/tests/projects/vala/includec/src/main.vala new file mode 100644 index 000000000..acc6c7363 --- /dev/null +++ b/tests/projects/vala/includec/src/main.vala @@ -0,0 +1,9 @@ +extern void printer_from_c(); + +int main (string[] args) { + printer_from_c(); + printer_from_other_file(); + + return 0; +} + diff --git a/tests/projects/vala/includec/src/printer.c b/tests/projects/vala/includec/src/printer.c new file mode 100644 index 000000000..dc7a82c67 --- /dev/null +++ b/tests/projects/vala/includec/src/printer.c @@ -0,0 +1,6 @@ +#include + +void printer_from_c() { + printf("Calling from C"); +} + diff --git a/tests/projects/vala/includec/src/printer.vala b/tests/projects/vala/includec/src/printer.vala new file mode 100644 index 000000000..998bb7a5c --- /dev/null +++ b/tests/projects/vala/includec/src/printer.vala @@ -0,0 +1,5 @@ +using Glib; + +void printer_from_other_file() { + stdout.printf("Calling from other file"); +} diff --git a/tests/projects/vala/includec/xmake.lua b/tests/projects/vala/includec/xmake.lua new file mode 100644 index 000000000..01b3e3eb3 --- /dev/null +++ b/tests/projects/vala/includec/xmake.lua @@ -0,0 +1,10 @@ +add_rules("mode.release", "mode.debug") + +add_requires("glib") + +target("test") + set_kind("binary") + add_rules("vala") + add_files("src/*.vala") + add_files("src/*.c") + add_packages("glib") -- cgit v1.3.1 From 1421536bb40e231b59cfbafa87e2c23ef5e86c4e Mon Sep 17 00:00:00 2001 From: al1-ce Date: Thu, 4 Jul 2024 20:27:42 +0300 Subject: Fix variable names, arg order and compile config --- tests/projects/vala/includec/src/printer.vala | 2 -- xmake/rules/vala/xmake.lua | 42 +++++++++++++-------------- 2 files changed, 20 insertions(+), 24 deletions(-) diff --git a/tests/projects/vala/includec/src/printer.vala b/tests/projects/vala/includec/src/printer.vala index 998bb7a5c..4599c3529 100644 --- a/tests/projects/vala/includec/src/printer.vala +++ b/tests/projects/vala/includec/src/printer.vala @@ -1,5 +1,3 @@ -using Glib; - void printer_from_other_file() { stdout.printf("Calling from other file"); } diff --git a/xmake/rules/vala/xmake.lua b/xmake/rules/vala/xmake.lua index 83ab001cc..15c76dc2c 100644 --- a/xmake/rules/vala/xmake.lua +++ b/xmake/rules/vala/xmake.lua @@ -33,9 +33,9 @@ rule("vala.build") if not vapifile then local vapiname = target:values("vala.vapi") if vapiname then - vapifile = path.join(target:targetdir(), vapiname) + vapifile = path.absolute(path.join(target:targetdir(), vapiname)) else - vapifile = path.join(target:targetdir(), target:name() .. ".vapi") + vapifile = path.absolute(path.join(target:targetdir(), target:name() .. ".vapi")) end target:data_set("vala.vapifile", vapifile) end @@ -45,9 +45,9 @@ rule("vala.build") if not headerfile then local headername = target:values("vala.header") if headername then - headerfile = path.join(target:targetdir(), headername) + headerfile = path.absolute(path.join(target:targetdir(), headername)) else - headerfile = path.join(target:targetdir(), target:name() .. ".h") + headerfile = path.absolute(path.join(target:targetdir(), target:name() .. ".h")) end target:data_set("vala.headerfile", headerfile) end @@ -56,7 +56,7 @@ rule("vala.build") target:add("sysincludedirs", path.directory(headerfile), {public = true}) end end) - before_buildcmd_files(function (target, batchcmds, sourcefiles_vala, opt) + before_buildcmd_files(function (target, batchcmds, sourcebatch, opt) -- Here we compile vala files into C code -- We have to compile entire project each time @@ -69,17 +69,6 @@ rule("vala.build") local valac = assert(find_tool("valac"), "valac not found!") local argv = {"-C", "-d", target:autogendir()} - -- iterating through source files, - -- otherwise valac would fail when compiling multiple files - for _, sourcefile_vala in ipairs(sourcefiles_vala.sourcefiles) do - -- if it's only a vala file - if string.match(sourcefile_vala, ".vala$") ~= nil then - table.insert(argv, path(sourcefile_vala)) - end - end - - -- no vala files, so exit - if #argv == 3 then return end -- add commands local packages = target:values("vala.packages") @@ -111,24 +100,33 @@ rule("vala.build") end end - local vapidir = target:data("vala.vapidir") + local vapidir = target:values("vala.vapidir") if vapidir then table.insert(argv, path(vapidir, function (p) return "--vapidir=" .. p end)) end - local valaflags = target:data("vala.flags") + local valaflags = target:values("vala.flags") if valaflags then table.join2(argv, valaflags) end + -- iterating through source files, + -- otherwise valac would fail when compiling multiple files + for _, sourcefile in ipairs(sourcebatch.sourcefiles) do + -- if it's only a vala file + if path.extension(sourcefile) == ".vala" then + table.insert(argv, path(sourcefile)) + end + end + batchcmds:show_progress(opt.progress, "${color.build.object}compiling.vala") batchcmds:vrunv(valac.program, argv) end) - on_buildcmd_file(function (target, batchcmds, sourcefile_vala, opt) + on_buildcmd_file(function (target, batchcmds, sourcebatch, opt) -- Again, only vala files need special treatment - if string.match(sourcefile_vala, ".vala$") ~= nil then - local sourcefile_c = target:autogenfile((sourcefile_vala:gsub(".vala$", ".c"))) + if path.extension(sourcebatch) == ".vala" then + local sourcefile_c = target:autogenfile((sourcebatch:gsub(".vala$", ".c"))) local basedir = path.directory(sourcefile_c) batchcmds:mkdir(basedir) @@ -136,7 +134,7 @@ rule("vala.build") local objectfile = target:objectfile(sourcefile_c) table.insert(target:objectfiles(), objectfile) - batchcmds:add_depfiles(sourcefile_vala) + batchcmds:add_depfiles(sourcebatch) batchcmds:set_depmtime(os.mtime(objectfile)) batchcmds:set_depcache(target:dependfile(objectfile)) -- cgit v1.3.1 From 3bdf20ec3046c24b52cff3442b87a9e997fe6905 Mon Sep 17 00:00:00 2001 From: al1-ce Date: Fri, 5 Jul 2024 13:05:13 +0300 Subject: Rename build variable and add per file progress message --- xmake/rules/vala/xmake.lua | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/xmake/rules/vala/xmake.lua b/xmake/rules/vala/xmake.lua index 15c76dc2c..c76fc9800 100644 --- a/xmake/rules/vala/xmake.lua +++ b/xmake/rules/vala/xmake.lua @@ -116,17 +116,17 @@ rule("vala.build") -- if it's only a vala file if path.extension(sourcefile) == ".vala" then table.insert(argv, path(sourcefile)) + batchcmds:show_progress(opt.progress, "${color.build.object}compiling.vala %s", sourcefile) end end - batchcmds:show_progress(opt.progress, "${color.build.object}compiling.vala") batchcmds:vrunv(valac.program, argv) end) - on_buildcmd_file(function (target, batchcmds, sourcebatch, opt) + on_buildcmd_file(function (target, batchcmds, sourcefile, opt) -- Again, only vala files need special treatment - if path.extension(sourcebatch) == ".vala" then - local sourcefile_c = target:autogenfile((sourcebatch:gsub(".vala$", ".c"))) + if path.extension(sourcefile) == ".vala" then + local sourcefile_c = target:autogenfile((sourcefile:gsub(".vala$", ".c"))) local basedir = path.directory(sourcefile_c) batchcmds:mkdir(basedir) @@ -134,7 +134,7 @@ rule("vala.build") local objectfile = target:objectfile(sourcefile_c) table.insert(target:objectfiles(), objectfile) - batchcmds:add_depfiles(sourcebatch) + batchcmds:add_depfiles(sourcefile) batchcmds:set_depmtime(os.mtime(objectfile)) batchcmds:set_depcache(target:dependfile(objectfile)) -- cgit v1.3.1 From a388acc43c93d75879b97698034ae72778cea295 Mon Sep 17 00:00:00 2001 From: ruki Date: Fri, 5 Jul 2024 22:12:47 +0800 Subject: Update xmake.lua --- xmake/rules/vala/xmake.lua | 23 +++++++++++++++++------ 1 file changed, 17 insertions(+), 6 deletions(-) diff --git a/xmake/rules/vala/xmake.lua b/xmake/rules/vala/xmake.lua index c76fc9800..caebab9d8 100644 --- a/xmake/rules/vala/xmake.lua +++ b/xmake/rules/vala/xmake.lua @@ -112,15 +112,27 @@ rule("vala.build") -- iterating through source files, -- otherwise valac would fail when compiling multiple files + local lastmtime = 0 + local sourcefiles = {} for _, sourcefile in ipairs(sourcebatch.sourcefiles) do -- if it's only a vala file if path.extension(sourcefile) == ".vala" then - table.insert(argv, path(sourcefile)) + local sourcefile_c = target:autogenfile((sourcefile:gsub(".vala$", ".c"))) batchcmds:show_progress(opt.progress, "${color.build.object}compiling.vala %s", sourcefile) + table.insert(argv, path(sourcefile)) + table.insert(sourcefiles, sourcefile) + local sourcefile_c_mtime = os.mtime(sourcefile_c) + if sourcefile_c_mtime > lastmtime then + lastmtime = sourcefile_c_mtime + end end end - batchcmds:vrunv(valac.program, argv) + if #sourcefiles > 0 then + batchcmds:vrunv(valac.program, argv) + batchcmds:add_depfiles(sourcefiles) + batchcmds:set_depmtime(lastmtime) + end end) on_buildcmd_file(function (target, batchcmds, sourcefile, opt) @@ -134,12 +146,12 @@ rule("vala.build") local objectfile = target:objectfile(sourcefile_c) table.insert(target:objectfiles(), objectfile) + batchcmds:show_progress(opt.progress, "${color.build.object}compiling.c %s", sourcefile_c) + batchcmds:compile(sourcefile_c, objectfile, { configs = { force = { cflags = "-w" } } }) + batchcmds:add_depfiles(sourcefile) batchcmds:set_depmtime(os.mtime(objectfile)) batchcmds:set_depcache(target:dependfile(objectfile)) - - batchcmds:show_progress(opt.progress, "${color.build.object}compiling.c %s", sourcefile_c) - batchcmds:compile(sourcefile_c, objectfile, { configs = { force = { cflags = "-w" } } }) end end) @@ -186,4 +198,3 @@ rule("vala") -- we attempt to extract symbols to the independent file and -- strip self-target binary if `set_symbols("debug")` and `set_strip("all")` are enabled add_deps("utils.symbols.extract") - -- cgit v1.3.1