summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorruki <[email protected]>2024-09-06 16:33:34 +0800
committerGitHub <[email protected]>2024-09-06 16:33:34 +0800
commitc4249906946dcef8c8ada216b90c4ead28e56e3a (patch)
tree9dcdb8feda99a8f066f46dd7fcc635823efb6abc
parente9df84ad021c7c8ec020384e250ca5b95fe3e700 (diff)
parent37c14c0ef5813b2fe2a768fe22a2710bc3ac987b (diff)
Merge pull request #5536 from ririyeye/swig_jar
add jar generate in swig mode
-rw-r--r--tests/projects/swig/java_c/src/example.c4
-rw-r--r--tests/projects/swig/java_c/src/example.i2
-rw-r--r--tests/projects/swig/java_c/src/example2.i4
-rw-r--r--tests/projects/swig/java_c/src/test.h3
-rw-r--r--tests/projects/swig/java_c/xmake.lua3
-rw-r--r--xmake/rules/swig/build_module_file.lua123
-rw-r--r--xmake/rules/swig/xmake.lua24
7 files changed, 158 insertions, 5 deletions
diff --git a/tests/projects/swig/java_c/src/example.c b/tests/projects/swig/java_c/src/example.c
index 06f76c542..a3f19629d 100644
--- a/tests/projects/swig/java_c/src/example.c
+++ b/tests/projects/swig/java_c/src/example.c
@@ -2,3 +2,7 @@ int fact(int n) {
return n;
}
+int fact2(int n) {
+ return n;
+}
+
diff --git a/tests/projects/swig/java_c/src/example.i b/tests/projects/swig/java_c/src/example.i
index e952f6123..6bac9f7a3 100644
--- a/tests/projects/swig/java_c/src/example.i
+++ b/tests/projects/swig/java_c/src/example.i
@@ -3,3 +3,5 @@
extern int fact(int n);
%}
extern int fact(int n);
+
+%include "example2.i"
diff --git a/tests/projects/swig/java_c/src/example2.i b/tests/projects/swig/java_c/src/example2.i
new file mode 100644
index 000000000..794af702d
--- /dev/null
+++ b/tests/projects/swig/java_c/src/example2.i
@@ -0,0 +1,4 @@
+%inline %{
+#include "test.h"
+%}
+%include "test.h"
diff --git a/tests/projects/swig/java_c/src/test.h b/tests/projects/swig/java_c/src/test.h
new file mode 100644
index 000000000..da669d859
--- /dev/null
+++ b/tests/projects/swig/java_c/src/test.h
@@ -0,0 +1,3 @@
+#pragma once
+
+int fact2(int n);
diff --git a/tests/projects/swig/java_c/xmake.lua b/tests/projects/swig/java_c/xmake.lua
index 65e871ce6..3108859a7 100644
--- a/tests/projects/swig/java_c/xmake.lua
+++ b/tests/projects/swig/java_c/xmake.lua
@@ -7,6 +7,8 @@ target("example")
set_kind('shared')
-- set moduletype to java
add_rules("swig.c", {moduletype = "java"})
+ -- test jar build
+ -- add_rules("swig.c", {moduletype = "java" , buildjar = true})
-- use swigflags to provider package name and output path of java files
add_files("src/example.i", {swigflags = {
"-package",
@@ -15,6 +17,7 @@ target("example")
"build/java/com/example/"
}})
add_files("src/example.c")
+ add_includedirs("src")
before_build(function()
-- ensure output path exists before running swig
os.mkdir("build/java/com/example/")
diff --git a/xmake/rules/swig/build_module_file.lua b/xmake/rules/swig/build_module_file.lua
index 2eecd5fb0..3e6af313f 100644
--- a/xmake/rules/swig/build_module_file.lua
+++ b/xmake/rules/swig/build_module_file.lua
@@ -20,8 +20,62 @@
-- imports
import("lib.detect.find_tool")
+import("utils.progress")
+import("core.project.depend")
+import("core.tool.compiler")
-function main(target, batchcmds, sourcefile, opt)
+function find_user_outdir(fileconfig)
+ -- user specified output path
+ if fileconfig and fileconfig.swigflags then
+ -- find -outdir path
+ for i, par in ipairs(fileconfig.swigflags) do
+ if par == "-outdir" then
+ local dirpath = fileconfig.swigflags[i + 1]
+ if os.isdir(dirpath) then
+ return dirpath
+ end
+ end
+ end
+ end
+end
+
+function jar_build(target, fileconfig, opt)
+ local javac = assert(find_tool("javac"), "javac not found!")
+ local jar = assert(find_tool("jar"), "jar not found!")
+
+ local java_src_dir = path.join(target:autogendir(), "rules", "swig")
+ local java_class_dir = java_src_dir
+
+ local user_outdir = find_user_outdir(fileconfig)
+ if user_outdir then
+ java_src_dir = user_outdir
+ end
+
+ -- get java files
+ local autogenfiles = os.files(path.join(java_src_dir, "*.java"))
+
+ -- write file list
+ local filelistname = path.join(java_src_dir, "buildlist.txt")
+ local file = io.open(filelistname, "w")
+ if file then
+ for _, sourcebatch in ipairs(autogenfiles) do
+ file:print(sourcebatch)
+ end
+ file:close()
+ end
+
+ -- compile to class file
+ progress.show(opt.progress, "${color.build.object}compiling.javac %s class file", target:name())
+ os.vrunv(javac.program, {"--release", "17", "-d", java_class_dir, "@" .. filelistname})
+
+ -- generate jar file
+ progress.show(opt.progress, "${color.build.object}compiling.jar %s", target:name() .. ".jar")
+ os.vrunv(jar.program, {"-cf", path.join(java_src_dir, target:name() .. ".jar"), java_class_dir})
+
+ os.tryrm(filelistname)
+end
+
+function swig_par(target, sourcefile, opt)
-- get swig
opt = opt or {}
local swig = assert(find_tool("swig"), "swig not found!")
@@ -34,7 +88,7 @@ function main(target, batchcmds, sourcefile, opt)
-- add commands
local moduletype = assert(target:data("swig.moduletype"), "swig.moduletype not found!")
- local argv = { "-" .. moduletype, "-o", sourcefile_cx }
+ local argv = {"-" .. moduletype, "-o", sourcefile_cx}
if opt.sourcekind == "cxx" then
table.insert(argv, "-c++")
end
@@ -63,6 +117,26 @@ function main(target, batchcmds, sourcefile, opt)
end
table.insert(argv, sourcefile)
+ return {
+ argv = argv,
+ objectfile = objectfile,
+ swig = swig,
+ sourcefile_cx = sourcefile_cx,
+ moduletype = moduletype,
+ fileconfig = fileconfig
+ }
+end
+
+function swig_build_cmd(target, batchcmds, sourcefile, opt, pars)
+ local par = swig_par(target, sourcefile, opt)
+
+ local objectfile = par.objectfile
+ local argv = par.argv
+ local swig = par.swig
+ local sourcefile_cx = par.sourcefile_cx
+ local moduletype = par.moduletype
+ local fileconfig = par.fileconfig
+
batchcmds:show_progress(opt.progress, "${color.build.object}compiling.swig.%s %s", moduletype, sourcefile)
batchcmds:mkdir(path.directory(sourcefile_cx))
batchcmds:vrunv(swig.program, argv)
@@ -73,3 +147,48 @@ function main(target, batchcmds, sourcefile, opt)
batchcmds:set_depmtime(os.mtime(objectfile))
batchcmds:set_depcache(target:dependfile(objectfile))
end
+
+function swig_build_file(target, sourcefile, opt, par)
+ local par = swig_par(target, sourcefile, opt)
+
+ local objectfile = par.objectfile
+ local argv = par.argv
+ local swig = par.swig
+ local sourcefile_cx = par.sourcefile_cx
+ local moduletype = par.moduletype
+ local fileconfig = par.fileconfig
+
+ local dependfile = target:dependfile(objectfile)
+ local dependinfo = target:is_rebuilt() and {} or (depend.load(dependfile) or {})
+ if not depend.is_changed(dependinfo, {lastmtime = os.mtime(objectfile),
+ values = argv
+ }) then
+ return
+ end
+
+ progress.show(opt.progress, "${color.build.object}compiling.swig.%s %s", moduletype, sourcefile)
+ os.mkdir(path.directory(sourcefile_cx))
+
+ -- gen swig depend file , same with gcc .d
+ local swigdep = os.tmpfile()
+ local argv2 = {"-MMD", "-MF", swigdep}
+ table.join2(argv2, argv)
+
+ -- swig generate file and depend file
+ os.vrunv(swig.program, argv2)
+ compiler.compile(sourcefile_cx, objectfile, {target = target})
+
+ -- update depend file
+ local deps = io.readfile(swigdep, {continuation = "\\"})
+ os.tryrm(swigdep)
+ dependinfo.files = {sourcefile}
+ dependinfo.depfiles_gcc = deps
+ dependinfo.values = argv
+ depend.save(dependinfo, target:dependfile(objectfile))
+
+ -- jar build
+ local buildjar = target:extraconf("rules", "swig.c", "buildjar") or target:extraconf("rules", "swig.cpp", "buildjar")
+ if moduletype == "java" and buildjar then
+ jar_build(target, fileconfig, opt)
+ end
+end
diff --git a/xmake/rules/swig/xmake.lua b/xmake/rules/swig/xmake.lua
index 05db9a3a1..504f786e4 100644
--- a/xmake/rules/swig/xmake.lua
+++ b/xmake/rules/swig/xmake.lua
@@ -27,6 +27,7 @@
rule("swig.base")
on_load(function (target)
target:set("kind", "shared")
+ local find_user_outdir = import("build_module_file").find_user_outdir
local moduletype = target:extraconf("rules", "swig.c", "moduletype") or target:extraconf("rules", "swig.cpp", "moduletype")
if moduletype == "python" then
target:set("prefixname", "_")
@@ -76,12 +77,23 @@ rule("swig.base")
end
local autogenfiles
local autogendir = path.join(target:autogendir(), "rules", "swig")
+
+ local user_outdir = find_user_outdir(fileconfig)
+ if user_outdir then
+ autogendir = user_outdir
+ end
+
if moduletype == "python" then
autogenfiles = os.files(path.join(autogendir, "*.py"))
elseif moduletype == "lua" then
autogenfiles = os.files(path.join(autogendir, "*.lua"))
elseif moduletype == "java" then
- autogenfiles = os.files(path.join(autogendir, "*.java"))
+ local buildjar = target:extraconf("rules", "swig.c", "buildjar") or target:extraconf("rules", "swig.cpp", "buildjar")
+ if buildjar then
+ autogenfiles = path.join(autogendir, target:name() .. ".jar")
+ else
+ autogenfiles = os.files(path.join(autogendir, "*.java"))
+ end
end
if autogenfiles then
table.join2(scriptfiles, autogenfiles)
@@ -101,14 +113,20 @@ rule("swig.c")
set_extensions(".i")
add_deps("swig.base", "c.build")
on_buildcmd_file(function (target, batchcmds, sourcefile, opt)
- import("build_module_file")(target, batchcmds, sourcefile, table.join({sourcekind = "cc"}, opt))
+ import("build_module_file").swig_build_cmd(target, batchcmds, sourcefile, table.join({sourcekind = "cc"}, opt))
+ end)
+ on_build_file(function (target, sourcefile, opt)
+ import("build_module_file").swig_build_file(target, sourcefile, table.join({sourcekind = "cc"}, opt))
end)
rule("swig.cpp")
set_extensions(".i")
add_deps("swig.base", "c++.build")
on_buildcmd_file(function (target, batchcmds, sourcefile, opt)
- import("build_module_file")(target, batchcmds, sourcefile, table.join({sourcekind = "cxx"}, opt))
+ import("build_module_file").swig_build_cmd(target, batchcmds, sourcefile, table.join({sourcekind = "cxx"}, opt))
+ end)
+ on_build_file(function (target, sourcefile, opt)
+ import("build_module_file").swig_build_file(target, sourcefile, table.join({sourcekind = "cxx"}, opt))
end)