summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorruki <[email protected]>2026-05-14 22:51:13 +0800
committerruki <[email protected]>2026-05-14 22:51:13 +0800
commita4beaf9875423783c9776017970c4b39eea30744 (patch)
treedabae325a3ee54f0447b5db2cc2399210643ce23
parent1f661ce90b9f3184f8fc1d0159db30b27f81393d (diff)
improve merge archive from packages
-rw-r--r--tests/projects/other/merge_archive_deps/src/add.c3
-rw-r--r--tests/projects/other/merge_archive_deps/src/main.c16
-rw-r--r--tests/projects/other/merge_archive_deps/src/mul.c3
-rw-r--r--tests/projects/other/merge_archive_deps/src/sub.c3
-rw-r--r--tests/projects/other/merge_archive_deps/src/subdir/add.c4
-rw-r--r--tests/projects/other/merge_archive_deps/src/subdir/sub.c4
-rw-r--r--tests/projects/other/merge_archive_deps/test.lua7
-rw-r--r--tests/projects/other/merge_archive_deps/xmake.lua21
-rw-r--r--xmake/modules/private/utils/target.lua2
-rw-r--r--xmake/rules/utils/inherit_links/inherit_links.lua1
-rw-r--r--xmake/rules/utils/merge_archive/xmake.lua31
11 files changed, 75 insertions, 20 deletions
diff --git a/tests/projects/other/merge_archive_deps/src/add.c b/tests/projects/other/merge_archive_deps/src/add.c
new file mode 100644
index 000000000..59aab4983
--- /dev/null
+++ b/tests/projects/other/merge_archive_deps/src/add.c
@@ -0,0 +1,3 @@
+int add(int a, int b) {
+ return a + b;
+}
diff --git a/tests/projects/other/merge_archive_deps/src/main.c b/tests/projects/other/merge_archive_deps/src/main.c
new file mode 100644
index 000000000..df9eef6ac
--- /dev/null
+++ b/tests/projects/other/merge_archive_deps/src/main.c
@@ -0,0 +1,16 @@
+#include <stdio.h>
+
+int add(int a, int b);
+int sub(int a, int b);
+int mul(int a, int b);
+int subdir_add(int a, int b);
+int subdir_sub(int a, int b);
+
+int main(int argc, char** argv) {
+ printf("%d\n", add(1, 1));
+ printf("%d\n", sub(1, 1));
+ printf("%d\n", mul(1, 1));
+ printf("%d\n", subdir_add(1, 1));
+ printf("%d\n", subdir_sub(1, 1));
+ return 0;
+}
diff --git a/tests/projects/other/merge_archive_deps/src/mul.c b/tests/projects/other/merge_archive_deps/src/mul.c
new file mode 100644
index 000000000..0c01379d4
--- /dev/null
+++ b/tests/projects/other/merge_archive_deps/src/mul.c
@@ -0,0 +1,3 @@
+int mul(int a, int b) {
+ return a * b;
+}
diff --git a/tests/projects/other/merge_archive_deps/src/sub.c b/tests/projects/other/merge_archive_deps/src/sub.c
new file mode 100644
index 000000000..a6ffbba20
--- /dev/null
+++ b/tests/projects/other/merge_archive_deps/src/sub.c
@@ -0,0 +1,3 @@
+int sub(int a, int b) {
+ return a - b;
+}
diff --git a/tests/projects/other/merge_archive_deps/src/subdir/add.c b/tests/projects/other/merge_archive_deps/src/subdir/add.c
new file mode 100644
index 000000000..318ed98f8
--- /dev/null
+++ b/tests/projects/other/merge_archive_deps/src/subdir/add.c
@@ -0,0 +1,4 @@
+int subdir_add(int a, int b)
+{
+ return a + b;
+}
diff --git a/tests/projects/other/merge_archive_deps/src/subdir/sub.c b/tests/projects/other/merge_archive_deps/src/subdir/sub.c
new file mode 100644
index 000000000..68c4d13ae
--- /dev/null
+++ b/tests/projects/other/merge_archive_deps/src/subdir/sub.c
@@ -0,0 +1,4 @@
+int subdir_sub(int a, int b)
+{
+ return a - b;
+}
diff --git a/tests/projects/other/merge_archive_deps/test.lua b/tests/projects/other/merge_archive_deps/test.lua
new file mode 100644
index 000000000..88594b1d5
--- /dev/null
+++ b/tests/projects/other/merge_archive_deps/test.lua
@@ -0,0 +1,7 @@
+function main(t)
+ -- Solaris ar does not support merging archives with duplicate object file names
+ if is_host("solaris") then
+ return
+ end
+ t:build()
+end
diff --git a/tests/projects/other/merge_archive_deps/xmake.lua b/tests/projects/other/merge_archive_deps/xmake.lua
new file mode 100644
index 000000000..be1f45de0
--- /dev/null
+++ b/tests/projects/other/merge_archive_deps/xmake.lua
@@ -0,0 +1,21 @@
+add_rules("mode.debug", "mode.release")
+
+target("add")
+ set_kind("static")
+ add_files("src/add.c")
+ add_files("src/subdir/add.c")
+
+target("sub")
+ set_kind("static")
+ add_files("src/sub.c")
+ add_files("src/subdir/sub.c")
+
+target("mul")
+ set_kind("static")
+ add_deps("add", "sub")
+ add_files("src/mul.c")
+ set_policy("build.merge_archive", true)
+
+target("test")
+ add_deps("mul")
+ add_files("src/main.c")
diff --git a/xmake/modules/private/utils/target.lua b/xmake/modules/private/utils/target.lua
index a655c67d6..6d1ad3907 100644
--- a/xmake/modules/private/utils/target.lua
+++ b/xmake/modules/private/utils/target.lua
@@ -291,7 +291,7 @@ end
-- get values from target
function get_values_from_target(target, name)
- local values = table.clone(table.wrap(target:get(tostring(name))))
+ local values = table.clone(table.wrap(target:get(name)))
for _, value in ipairs((target:get_from(name, "option::*"))) do
table.join2(values, value)
end
diff --git a/xmake/rules/utils/inherit_links/inherit_links.lua b/xmake/rules/utils/inherit_links/inherit_links.lua
index 565db32c4..641104082 100644
--- a/xmake/rules/utils/inherit_links/inherit_links.lua
+++ b/xmake/rules/utils/inherit_links/inherit_links.lua
@@ -18,6 +18,7 @@
-- @file inherit_links.lua
--
+-- imports
import("private.utils.target", {alias = "target_utils"})
-- @note we cannot directly set `{interface = true}`, because it will overwrite the previous configuration
diff --git a/xmake/rules/utils/merge_archive/xmake.lua b/xmake/rules/utils/merge_archive/xmake.lua
index 4d4382b02..456008182 100644
--- a/xmake/rules/utils/merge_archive/xmake.lua
+++ b/xmake/rules/utils/merge_archive/xmake.lua
@@ -45,24 +45,11 @@ rule("utils.merge.archive")
end)
after_link(function (target, opt)
- -- Returns full path of a given link archive, if found.
- local function _resolve_link(linkdirs, link)
- -- HELP: assume that 'linkpath' does not exists in multiple directories?
- for _, linkdir in ipairs(linkdirs) do
- local file_extension = target:is_plat("windows") and ".lib" or ".a"
- local link_path = path.join(linkdir, "lib" .. link .. file_extension)
- if os.exists(link_path) then
- return link_path
- end
- end
- end
-
if not target:is_static() then
return
end
local sourcefiles = target:data("merge_archive.sourcefiles")
if target:policy("build.merge_archive") or sourcefiles then
- import("private.utils.target", {alias = "target_utils"})
import("utils.archive.merge_staticlib")
import("core.project.depend")
import("utils.progress")
@@ -71,18 +58,24 @@ rule("utils.merge.archive")
if sourcefiles then
table.join2(libraryfiles, sourcefiles)
else
+
+ -- merge libraryfiles from deps
for _, dep in ipairs(target:orderdeps()) do
if dep:is_static() then
table.insert(libraryfiles, dep:targetfile())
end
end
- -- TODO: what about syslinkdirs and syslinks?
- local linkdirs = target_utils.get_values_from_target(target, "linkdirs")
- for _, link in ipairs(target_utils.get_values_from_target(target, "links")) do
- local link_path = _resolve_link(linkdirs, link)
- if link_path then
- table.insert(libraryfiles, link_path)
+ -- merge libraryfiles from packages
+ -- @see https://github.com/xmake-io/xmake/issues/7531
+ for _, pkg in ipairs(target:orderpkgs()) do
+ if pkg:has_static() then
+ local libfiles = pkg:libraryfiles()
+ for _, libfile in ipairs(libfiles) do
+ if libfile:endswith(".a") or libfile:endswith(".lib") then
+ table.insert(libraryfiles, libfile)
+ end
+ end
end
end
end