summaryrefslogtreecommitdiff
path: root/xmake/rules
diff options
context:
space:
mode:
authorruki <[email protected]>2020-12-25 22:50:47 +0800
committerruki <[email protected]>2020-12-25 22:50:47 +0800
commit89376b4e876467909a809d622fea762885cc6040 (patch)
treee2682fc01e6e6ab02da9577185e7d92ab0c013ae /xmake/rules
parentf0b408a9ae6a72ad4ee8ced642cbdd77dbc1f588 (diff)
rewrite extractor
Diffstat (limited to 'xmake/rules')
-rw-r--r--xmake/rules/utils/merge_archive/merge_archive.lua148
-rw-r--r--xmake/rules/utils/merge_archive/xmake.lua48
2 files changed, 149 insertions, 47 deletions
diff --git a/xmake/rules/utils/merge_archive/merge_archive.lua b/xmake/rules/utils/merge_archive/merge_archive.lua
new file mode 100644
index 000000000..96069befb
--- /dev/null
+++ b/xmake/rules/utils/merge_archive/merge_archive.lua
@@ -0,0 +1,148 @@
+--!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("private.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("ex")
+ if program and toolname then
+ if toolname:find("ar") then
+ _extract_for_ar(program, libraryfile, objectdir)
+ elseif toolname == "lib" then
+ _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 90e36348b..6d57f55bb 100644
--- a/xmake/rules/utils/merge_archive/xmake.lua
+++ b/xmake/rules/utils/merge_archive/xmake.lua
@@ -25,51 +25,5 @@ rule("utils.merge.archive")
set_extensions(".a", ".lib")
-- on build file
- on_build_files(function (target, sourcebatch, opt)
-
- -- imports
- import("core.base.option")
- import("core.theme.theme")
- import("core.project.depend")
- import("core.tool.extractor")
- import("core.project.target", {alias = "project_target"})
- import("private.utils.progress")
-
- -- @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)
- extractor.extract(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)
+ on_build_files("merge_archive")