summaryrefslogtreecommitdiff
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
parentf0b408a9ae6a72ad4ee8ced642cbdd77dbc1f588 (diff)
rewrite extractor
-rw-r--r--xmake/core/sandbox/modules/import/core/tool/extractor.lua46
-rw-r--r--xmake/core/tool/extractor.lua78
-rw-r--r--xmake/modules/core/tools/ar.lua22
-rw-r--r--xmake/modules/core/tools/lib.lua58
-rw-r--r--xmake/modules/core/tools/llvm_ar.lua29
-rw-r--r--xmake/modules/core/tools/sdar.lua29
-rw-r--r--xmake/rules/utils/merge_archive/merge_archive.lua148
-rw-r--r--xmake/rules/utils/merge_archive/xmake.lua48
8 files changed, 149 insertions, 309 deletions
diff --git a/xmake/core/sandbox/modules/import/core/tool/extractor.lua b/xmake/core/sandbox/modules/import/core/tool/extractor.lua
deleted file mode 100644
index 8424d7791..000000000
--- a/xmake/core/sandbox/modules/import/core/tool/extractor.lua
+++ /dev/null
@@ -1,46 +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 extractor.lua
---
-
--- define module
-local sandbox_core_tool_extractor = sandbox_core_tool_extractor or {}
-
--- load modules
-local platform = require("platform/platform")
-local extractor = require("tool/extractor")
-local raise = require("sandbox/modules/raise")
-
--- extract library file
-function sandbox_core_tool_extractor.extract(libraryfile, objectdir)
-
- -- get the extractor instance
- local instance, errors = extractor.load()
- if not instance then
- raise(errors)
- end
-
- -- extract it
- local ok, errors = instance:extract(libraryfile, objectdir)
- if not ok then
- raise(errors)
- end
-end
-
--- return module
-return sandbox_core_tool_extractor
diff --git a/xmake/core/tool/extractor.lua b/xmake/core/tool/extractor.lua
deleted file mode 100644
index 8037b5266..000000000
--- a/xmake/core/tool/extractor.lua
+++ /dev/null
@@ -1,78 +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 extractor.lua
---
-
--- define module
-local extractor = extractor or {}
-
--- load modules
-local io = require("base/io")
-local path = require("base/path")
-local utils = require("base/utils")
-local table = require("base/table")
-local string = require("base/string")
-local config = require("project/config")
-local sandbox = require("sandbox/sandbox")
-local platform = require("platform/platform")
-local tool = require("tool/tool")
-
--- get the current tool
-function extractor:_tool()
- return self._TOOL
-end
-
--- load the extractor
-function extractor.load()
-
- -- get it directly from cache dirst
- if extractor._INSTANCE then
- return extractor._INSTANCE
- end
-
- -- new instance
- local instance = table.inherit(extractor)
-
- -- load the extractor tool
- local result, errors = tool.load("ex")
- if not result then
- return nil, errors
- end
-
- -- save tool
- instance._TOOL = result
-
- -- save this instance
- extractor._INSTANCE = instance
-
- -- ok
- return instance
-end
-
--- get properties of the tool
-function extractor:get(name)
- return self:_tool():get(name)
-end
-
--- extract the library file
-function extractor:extract(libraryfile, objectdir)
- return sandbox.load(self:_tool().extract, self:_tool(), libraryfile, objectdir)
-end
-
--- return module
-return extractor
diff --git a/xmake/modules/core/tools/ar.lua b/xmake/modules/core/tools/ar.lua
index 31d498a57..868b4eae1 100644
--- a/xmake/modules/core/tools/ar.lua
+++ b/xmake/modules/core/tools/ar.lua
@@ -76,26 +76,4 @@ function link(self, objectfiles, targetkind, targetfile, flags)
os.runv(program, argv, {envs = self:runenvs()})
end
--- extract the static library to object directory
-function extract(self, 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(self:program(), {"-x", libraryfile}, {curdir = objectdir})
-
- -- check repeat object name
- local repeats = {}
- local objectfiles = os.iorunv(self: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
diff --git a/xmake/modules/core/tools/lib.lua b/xmake/modules/core/tools/lib.lua
deleted file mode 100644
index d64714ba7..000000000
--- a/xmake/modules/core/tools/lib.lua
+++ /dev/null
@@ -1,58 +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 lib.lua
---
-
--- imports
-import("private.tools.vstool")
-
--- extract the static library to object directory
-function extract(self, libraryfile, objectdir)
-
- -- make the object directory first
- os.mkdir(objectdir)
-
- -- list object files
- local objectfiles = vstool.iorunv(self:program(), {"-nologo", "-list", libraryfile}, {envs = self: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(self:program(), {"-nologo", "-extract:" .. objectfile, "-out:" .. outputfile, libraryfile}, {envs = self:runenvs()})
- end
- end
-end
-
-
diff --git a/xmake/modules/core/tools/llvm_ar.lua b/xmake/modules/core/tools/llvm_ar.lua
index de128d3a5..fb20c2320 100644
--- a/xmake/modules/core/tools/llvm_ar.lua
+++ b/xmake/modules/core/tools/llvm_ar.lua
@@ -73,32 +73,3 @@ function link(self, objectfiles, targetkind, targetfile, flags)
os.runv(linkargv(self, objectfiles, targetkind, targetfile, flags))
end
--- extract the static library to object directory
-function extract(self, libraryfile, objectdir)
-
- -- make the object directory first
- os.mkdir(objectdir)
-
- -- get the absolute path of this library
- libraryfile = path.absolute(libraryfile)
-
- -- enter the object directory
- local oldir = os.cd(objectdir)
-
- -- extract it
- os.runv(self:program(), {"x", libraryfile})
-
- -- check repeat object name
- local repeats = {}
- local objectfiles = os.iorunv(self: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
-
- -- leave the object directory
- os.cd(oldir)
-end
-
diff --git a/xmake/modules/core/tools/sdar.lua b/xmake/modules/core/tools/sdar.lua
index c975b3608..056ca32d3 100644
--- a/xmake/modules/core/tools/sdar.lua
+++ b/xmake/modules/core/tools/sdar.lua
@@ -75,32 +75,3 @@ function link(self, objectfiles, targetkind, targetfile, flags)
os.runv(linkargv(self, objectfiles, targetkind, targetfile, flags))
end
--- extract the static library to object directory
-function extract(self, libraryfile, objectdir)
-
- -- make the object directory first
- os.mkdir(objectdir)
-
- -- get the absolute path of this library
- libraryfile = path.absolute(libraryfile)
-
- -- enter the object directory
- local oldir = os.cd(objectdir)
-
- -- extract it
- os.runv(self:program(), {"-x", libraryfile})
-
- -- check repeat object name
- local repeats = {}
- local objectfiles = os.iorunv(self: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
-
- -- leave the object directory
- os.cd(oldir)
-end
-
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")