summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorruki <[email protected]>2022-01-18 22:39:28 +0800
committerruki <[email protected]>2022-01-18 22:39:28 +0800
commit4e8b30ad1ff62663440c1165b1f23ed1bcb9dbf4 (patch)
treeca6e8b062d46d694651a679bd1480e6c628fb573
parent4b80511f28926aa82f4d78c3ae2eac6c1a8ac117 (diff)
fix merge archive
-rw-r--r--xmake/rules/utils/merge_archive/merge_archive.lua149
-rw-r--r--xmake/rules/utils/merge_archive/xmake.lua22
2 files changed, 17 insertions, 154 deletions
diff --git a/xmake/rules/utils/merge_archive/merge_archive.lua b/xmake/rules/utils/merge_archive/merge_archive.lua
deleted file mode 100644
index 02d572afc..000000000
--- a/xmake/rules/utils/merge_archive/merge_archive.lua
+++ /dev/null
@@ -1,149 +0,0 @@
---!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-present, TBOOX Open Source Group.
---
--- @author ruki
--- @file merge_archive.lua
---
-
--- imports
-import("core.base.option")
-import("core.theme.theme")
-import("core.project.depend")
-import("core.project.target", {alias = "project_target"})
-import("utils.progress")
-import("core.tool.toolchain")
-import("private.tools.vstool")
-
--- extract the static library for ar
-function _extract_for_ar(program, libraryfile, objectdir)
-
- -- make the object directory first
- os.mkdir(objectdir)
-
- -- get the absolute path of this library
- libraryfile = path.absolute(libraryfile)
-
- -- extract it
- os.runv(program, {"-x", libraryfile}, {curdir = objectdir})
-
- -- check repeat object name
- local repeats = {}
- local objectfiles = os.iorunv(program, {"-t", libraryfile})
- for _, objectfile in ipairs(objectfiles:split('\n')) do
- if repeats[objectfile] then
- raise("object name(%s) conflicts in library: %s", objectfile, libraryfile)
- end
- repeats[objectfile] = true
- end
-end
-
--- extract the static library for msvc/lib
-function _extract_for_msvclib(program, libraryfile, objectdir)
-
- -- make the object directory first
- os.mkdir(objectdir)
-
- -- get runenvs for msvc
- local runenvs
- local msvc = toolchain.load("msvc")
- if msvc then
- runenvs = msvc:runenvs()
- end
-
- -- list object files
- local objectfiles = vstool.iorunv(program, {"-nologo", "-list", libraryfile}, {envs = runenvs})
-
- -- extrace all object files
- for _, objectfile in ipairs(objectfiles:split('\n')) do
-
- -- is object file?
- if objectfile:find("%.obj") then
-
- -- make the outputfile
- local outputfile = path.translate(format("%s\\%s", objectdir, path.filename(objectfile)))
-
- -- repeat? rename it
- if os.isfile(outputfile) then
- for i = 0, 10 do
- outputfile = path.translate(format("%s\\%d_%s", objectdir, i, path.filename(objectfile)))
- if not os.isfile(outputfile) then
- break
- end
- end
- end
-
- -- extract it
- vstool.runv(program, {"-nologo", "-extract:" .. objectfile, "-out:" .. outputfile, libraryfile}, {envs = runenvs})
- end
- end
-end
-
--- do extract
-function _extract(target, libraryfile, objectdir)
- local program, toolname = target:tool("ar")
- if program and toolname then
- if toolname:find("ar") then
- _extract_for_ar(program, libraryfile, objectdir)
- elseif toolname == "link" then
- program = program:replace("link.exe", "lib.exe", {plain = true})
- _extract_for_msvclib(program, libraryfile, objectdir)
- end
- else
- raise("cannot extract %s, extractor not found!", libraryfile)
- end
-end
-
--- main entry
-function main (target, sourcebatch, opt)
-
- -- @note we cannot process archives in parallel because the current directory may be changed
- for i = 1, #sourcebatch.sourcefiles do
-
- -- get library source file
- local sourcefile_lib = sourcebatch.sourcefiles[i]
-
- -- 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
- progress.show(opt.progress, "${color.build.object}inserting.$(mode) %s", sourcefile_lib)
-
- -- extract the archive library
- os.tryrm(objectdir)
- _extract(target, 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
-end
-
diff --git a/xmake/rules/utils/merge_archive/xmake.lua b/xmake/rules/utils/merge_archive/xmake.lua
index fd7805d8b..0112b4429 100644
--- a/xmake/rules/utils/merge_archive/xmake.lua
+++ b/xmake/rules/utils/merge_archive/xmake.lua
@@ -20,16 +20,28 @@
rule("utils.merge.archive")
set_extensions(".a", ".lib")
- on_build_files("merge_archive")
+ on_build_files(function (target, sourcebatch, opt)
+ if sourcebatch.sourcefiles then
+ target:data_set("merge_archive.sourcefiles", sourcebatch.sourcefiles)
+ end
+ end)
after_link(function (target, opt)
- if target:policy("build.merge_archive") and target:is_static() then
+ 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("utils.archive.merge_staticlib")
import("core.project.depend")
import("utils.progress")
local libraryfiles = {}
- for _, dep in ipairs(target:orderdeps()) do
- if dep:is_static() then
- table.insert(libraryfiles, dep:targetfile())
+ if sourcefiles then
+ table.join2(libraryfiles, sourcefiles)
+ else
+ for _, dep in ipairs(target:orderdeps()) do
+ if dep:is_static() then
+ table.insert(libraryfiles, dep:targetfile())
+ end
end
end
if #libraryfiles > 0 then