summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorruki <[email protected]>2025-12-12 00:47:19 +0800
committerruki <[email protected]>2025-12-12 09:00:46 +0800
commit12e8ee1a5e81efd4e32405171172423698e1b640 (patch)
treeda8e71f3159f4432b9228fdf74afe06d045e3f71
parenteeb70e956f65c2dd4581ead1581dfa7c8e64ed00 (diff)
use binutils.extractlib to rewrite merge staticlib
-rw-r--r--xmake/modules/utils/archive/merge_staticlib.lua55
1 files changed, 10 insertions, 45 deletions
diff --git a/xmake/modules/utils/archive/merge_staticlib.lua b/xmake/modules/utils/archive/merge_staticlib.lua
index f75aa64f6..2246a926e 100644
--- a/xmake/modules/utils/archive/merge_staticlib.lua
+++ b/xmake/modules/utils/archive/merge_staticlib.lua
@@ -20,6 +20,7 @@
-- imports
import("core.base.option")
+import("core.base.binutils")
import("private.tools.vstool")
-- merge *.a archive libraries using libtool
@@ -30,56 +31,20 @@ end
-- merge *.a archive libraries using fallback method (extract and repack)
-- Used for platforms where ar does not support -M option (e.g., Solaris)
function _merge_for_ar_fallback(target, program, outputfile, libraryfiles, opt)
- -- we need to handle duplicate object file names by adding prefixes
- -- convert all library files to absolute paths before changing directory
- local libraryfiles_abs = {}
- for _, libraryfile in ipairs(libraryfiles) do
- if os.isfile(libraryfile) then
- table.insert(libraryfiles_abs, path.absolute(libraryfile))
- end
- end
- if #libraryfiles_abs == 0 then
- return
- end
+
+ -- extract all archives to the temporary directory
local tmpdir = os.tmpfile() .. ".dir"
os.mkdir(tmpdir)
- -- check for duplicate object file names and warn
- for idx, libraryfile_abs in ipairs(libraryfiles_abs) do
- local list = os.iorunv(program, {"-t", libraryfile_abs}, {curdir = tmpdir})
- if list then
- local seen_files = {}
- local duplicates = {}
- for _, line in ipairs(list:split("\n")) do
- line = line:trim()
- if line:endswith(".o") then
- if seen_files[line] then
- if not duplicates[line] then
- duplicates[line] = {}
- end
- table.insert(duplicates[line], libraryfile_abs)
- else
- seen_files[line] = true
- end
- end
- end
- if not table.empty(duplicates) then
- local dup_names = table.keys(duplicates)
- wprint("duplicate object file names found in %s: %s (some files may be lost during merge)",
- path.filename(libraryfile_abs), table.concat(dup_names, ", "))
- end
- end
+ for _, libraryfile in ipairs(libraryfiles) do
+ binutils.extractlib(libraryfile, tmpdir)
end
- -- extract and merge all archives
+
+ -- collect all object files
local objectfiles = {}
- for idx, libraryfile_abs in ipairs(libraryfiles_abs) do
- -- extract all files from this archive
- os.vrunv(program, {"-x", libraryfile_abs}, {curdir = tmpdir})
- -- collect extracted object files (duplicate names will be overwritten)
- for _, objfile in ipairs(os.files(path.join(tmpdir, "*.o"))) do
- -- use relative path (filename only) since ar will run with curdir = tmpdir
- table.insert(objectfiles, path.filename(objfile))
- end
+ for _, objectfile in ipairs(os.files(path.join(tmpdir, "*.o"))) do
+ table.insert(objectfiles, path.filename(objectfile))
end
+
-- create new archive with all object files
if #objectfiles > 0 then
os.mkdir(path.directory(outputfile))