summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorruki <[email protected]>2024-05-11 20:47:33 +0800
committerruki <[email protected]>2024-05-11 20:47:33 +0800
commit2d0f7082ce3346e71445a94d0c492472150b94b7 (patch)
tree84d00ad2fa687d0350a5cecc8401ae6d80557ef1
parent1924008b1db3bbf3fc6842a2d0afac209979ad5b (diff)
improve gcc-ar
-rw-r--r--xmake/modules/core/tools/gcc_ar.lua54
-rw-r--r--xmake/toolchains/cross/check.lua29
-rw-r--r--xmake/toolchains/cross/load.lua14
3 files changed, 55 insertions, 42 deletions
diff --git a/xmake/modules/core/tools/gcc_ar.lua b/xmake/modules/core/tools/gcc_ar.lua
index ecfdca92a..8a063bead 100644
--- a/xmake/modules/core/tools/gcc_ar.lua
+++ b/xmake/modules/core/tools/gcc_ar.lua
@@ -19,4 +19,58 @@
--
inherit("ar")
+import("lib.detect.find_file")
+
+-- get liblto_plugin.so path for gcc
+function _get_gcc_liblto_plugin_path(self, program)
+ local plugin_path = _g.LTO_PLUGIN_PATH
+ if plugin_path == nil then
+ local gcc = program:gsub("gcc%-ar", "gcc")
+ local outdata = try { function() return os.iorunv(gcc, {"-print-prog-name=lto-wrapper"}) end }
+ if outdata then
+ local lto_plugindir = path.directory(outdata:trim())
+ if os.isdir(lto_plugindir) then
+ if is_host("windows") then
+ plugin_path = find_file("liblto_plugin*.dll", lto_plugindir)
+ else
+ plugin_path = find_file("liblto_plugin.so", lto_plugindir)
+ end
+ end
+ end
+ plugin_path = plugin_path or false
+ _g.LTO_PLUGIN_PATH = plugin_path
+ end
+ return plugin_path or nil
+end
+
+-- link the library file
+function link(self, objectfiles, targetkind, targetfile, flags, opt)
+ opt = opt or {}
+ os.mkdir(path.directory(targetfile))
+
+ -- @note remove the previous archived file first to force recreating a new file
+ os.tryrm(targetfile)
+
+ -- generate link arguments
+ local program, argv = linkargv(self, objectfiles, targetkind, targetfile, flags, opt)
+ if is_host("windows") and argv and #argv > 0 and argv[1]:startswith("@") then
+ -- gcc-ar.exe does not support `@file`, so we need use ar.exe to instead of it.
+ -- @see https://github.com/xmake-io/xmake/issues/5051
+ --
+ -- but ar.exe does not support lto, we need also add lto_plugin.so path in `@file` for gcc
+ -- @see https://github.com/xmake-io/xmake/issues/5015
+ --
+ -- gcc-ar is the wrapper of `ar --plugin lto_plugin.so ...`
+ --
+ program = program:gsub("gcc%-ar", "ar")
+ local _, rawargv = linkargv(self, objectfiles, targetkind, targetfile, flags, table.join(opt, {rawargs = true}))
+ local plugin_path = _get_gcc_liblto_plugin_path(self, program)
+ if plugin_path then
+ argv = winos.cmdargv(table.join({"--plugin", plugin_path}, rawargv), {escape = true})
+ end
+ end
+
+ -- link it
+ os.runv(program, argv, {envs = self:runenvs(), shell = opt.shell})
+end
diff --git a/xmake/toolchains/cross/check.lua b/xmake/toolchains/cross/check.lua
index 6f1df0f9a..3d8245d08 100644
--- a/xmake/toolchains/cross/check.lua
+++ b/xmake/toolchains/cross/check.lua
@@ -21,27 +21,6 @@
-- imports
import("core.project.config")
import("detect.sdks.find_cross_toolchain")
-import("lib.detect.find_file")
-
--- find liblto_plugin.so path for gcc
-function _find_gcc_liblto_plugin_path(cross_toolchain)
- local gcc = find_file((cross_toolchain.cross or "*-") .. "gcc", cross_toolchain.bindir)
- if gcc then
- local plugin_path
- local outdata = try { function() return os.iorunv(gcc, {"-print-prog-name=lto-wrapper"}) end }
- if outdata then
- local lto_plugindir = path.directory(outdata:trim())
- if os.isdir(lto_plugindir) then
- if is_host("windows") then
- plugin_path = find_file("liblto_plugin*.dll", lto_plugindir)
- else
- plugin_path = find_file("liblto_plugin.so", lto_plugindir)
- end
- end
- end
- return plugin_path
- end
-end
-- check the cross toolchain
function main(toolchain)
@@ -78,14 +57,6 @@ function main(toolchain)
if not config.get("target_os") then
config.set("target_os", "linux", {readonly = true, force = true})
end
-
- -- find lto_plugin.so path for gcc
- -- @see https://github.com/xmake-io/xmake/issues/5015
- -- https://github.com/xmake-io/xmake/issues/5051
- local lto_plugin = _find_gcc_liblto_plugin_path(cross_toolchain)
- if lto_plugin then
- toolchain:config_set("lto_plugin", lto_plugin)
- end
else
raise("cross toolchain not found!")
end
diff --git a/xmake/toolchains/cross/load.lua b/xmake/toolchains/cross/load.lua
index ddc645db3..1aca5e247 100644
--- a/xmake/toolchains/cross/load.lua
+++ b/xmake/toolchains/cross/load.lua
@@ -36,6 +36,7 @@ function main(toolchain)
toolchain:add("toolset", "as", cross .. "gcc", cross .. "clang")
toolchain:add("toolset", "ld", cross .. "g++", cross .. "gcc", cross .. "clang++", cross .. "clang")
toolchain:add("toolset", "sh", cross .. "g++", cross .. "gcc", cross .. "clang++", cross .. "clang")
+ toolchain:add("toolset", "ar", cross .. "gcc-ar", cross .. "ar")
toolchain:add("toolset", "ranlib", cross .. "gcc-ranlib", cross .. "ranlib")
toolchain:add("toolset", "strip", cross .. "strip")
@@ -44,18 +45,5 @@ function main(toolchain)
if bindir and is_host("windows") then
toolchain:add("runenvs", "PATH", bindir)
end
-
- -- add lto_plugin.so path for gcc
- -- @see https://github.com/xmake-io/xmake/issues/5015
- --
- -- and we cannot use gcc-ar, @see https://github.com/xmake-io/xmake/issues/5051
- --
- local lto_plugin = toolchain:config("lto_plugin")
- if is_host("windows") and lto_plugin then
- toolchain:add("arflags", {"--plugin", lto_plugin}, {force = true})
- toolchain:add("toolset", "ar", cross .. "ar")
- else
- toolchain:add("toolset", "ar", cross .. "gcc-ar", cross .. "ar")
- end
end