summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorruki <[email protected]>2024-05-11 21:58:05 +0800
committerGitHub <[email protected]>2024-05-11 21:58:05 +0800
commit505e5bfcb12baed4d86d6462d9e5e69494024077 (patch)
tree0f4b6ccd970991d538d04361a071759862d08056
parent149845abdec93c886779abfc705d5e4d0c527a9f (diff)
parente2eee64979c35ff8ad3efabc1f51bc21432ea833 (diff)
Merge pull request #5087 from xmake-io/ar
improve ar to support lto
-rw-r--r--xmake/modules/core/tools/gcc_ar.lua61
-rw-r--r--xmake/rules/c++/build_optimization/config.lua3
-rw-r--r--xmake/toolchains/cross/check.lua1
-rw-r--r--xmake/toolchains/cross/load.lua4
-rw-r--r--xmake/toolchains/gnu-rm/xmake.lua9
5 files changed, 57 insertions, 21 deletions
diff --git a/xmake/modules/core/tools/gcc_ar.lua b/xmake/modules/core/tools/gcc_ar.lua
index f6834a20c..b2131d9e8 100644
--- a/xmake/modules/core/tools/gcc_ar.lua
+++ b/xmake/modules/core/tools/gcc_ar.lua
@@ -19,13 +19,41 @@
--
inherit("ar")
+import("lib.detect.find_file")
--- make the link arguments list
--- @see https://github.com/xmake-io/xmake/issues/5051
--- @note gcc-ar.exe does not support `gcc-ar.exe @file`
-function linkargv(self, objectfiles, targetkind, targetfile, flags, opt)
- local argv = table.join(flags, targetfile, objectfiles)
- return self:program(), argv
+-- replace gcc-ar
+function _replace_gcc_ar(program, name)
+ local dir = path.directory(program)
+ local filename = path.filename(program)
+ filename = filename:gsub("gcc%-ar", name)
+ if dir and dir ~= "." then
+ program = path.join(dir, filename)
+ else
+ program = filename
+ end
+ return program
+end
+
+-- 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 = _replace_gcc_ar(program, "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
@@ -36,9 +64,26 @@ function link(self, objectfiles, targetkind, targetfile, flags, opt)
-- @note remove the previous archived file first to force recreating a new file
os.tryrm(targetfile)
- -- link it
+ -- 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-0.dll 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 ...`
+ --
+ 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
+ program = _replace_gcc_ar(program, "ar")
+ end
+
+ -- link it
os.runv(program, argv, {envs = self:runenvs(), shell = opt.shell})
end
-
diff --git a/xmake/rules/c++/build_optimization/config.lua b/xmake/rules/c++/build_optimization/config.lua
index 6baa26802..357c3cf76 100644
--- a/xmake/rules/c++/build_optimization/config.lua
+++ b/xmake/rules/c++/build_optimization/config.lua
@@ -37,7 +37,7 @@ function _add_lto_optimization(target, sourcekind)
end
-- add ldflags and shflags
- local _, ld = target:tool("ld")
+ local program, ld = target:tool("ld")
if ld == "link" then
target:add("ldflags", "-LTCG")
target:add("shflags", "-LTCG")
@@ -47,6 +47,7 @@ function _add_lto_optimization(target, sourcekind)
elseif ld == "gcc" or ld == "gxx" then
target:add("ldflags", "-flto")
target:add("shflags", "-flto")
+
-- to use the link-time optimizer, -flto and optimization options should be specified at compile time and during the final link.
-- @see https://gcc.gnu.org/onlinedocs/gcc/Optimize-Options.html
local optimize = target:get("optimize")
diff --git a/xmake/toolchains/cross/check.lua b/xmake/toolchains/cross/check.lua
index 815b95fd7..3d8245d08 100644
--- a/xmake/toolchains/cross/check.lua
+++ b/xmake/toolchains/cross/check.lua
@@ -47,6 +47,7 @@ function main(toolchain)
end
end
end
+
if cross_toolchain then
toolchain:config_set("cross", cross_toolchain.cross)
toolchain:config_set("bindir", cross_toolchain.bindir)
diff --git a/xmake/toolchains/cross/load.lua b/xmake/toolchains/cross/load.lua
index f34b1fd58..0195b8c9a 100644
--- a/xmake/toolchains/cross/load.lua
+++ b/xmake/toolchains/cross/load.lua
@@ -23,8 +23,6 @@ import("core.project.config")
-- load the cross toolchain
function main(toolchain)
-
- -- get cross prefix
local cross = toolchain:cross() or ""
-- add toolset
@@ -38,7 +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")
- -- old gcc need gcc-ar for lto, @see https://github.com/xmake-io/xmake/issues/5015
+ -- need gcc-ar for lto, @see https://github.com/xmake-io/xmake/issues/5015
toolchain:add("toolset", "ar", cross .. "gcc-ar", cross .. "ar")
toolchain:add("toolset", "ranlib", cross .. "gcc-ranlib", cross .. "ranlib")
toolchain:add("toolset", "strip", cross .. "strip")
diff --git a/xmake/toolchains/gnu-rm/xmake.lua b/xmake/toolchains/gnu-rm/xmake.lua
index 4a1751172..c6cf822a2 100644
--- a/xmake/toolchains/gnu-rm/xmake.lua
+++ b/xmake/toolchains/gnu-rm/xmake.lua
@@ -18,23 +18,14 @@
-- @file xmake.lua
--
--- define toolchain
toolchain("gnu-rm")
-
- -- set homepage
set_homepage("https://developer.arm.com/tools-and-software/open-source-software/developer-tools/gnu-toolchain/gnu-rm")
set_description("GNU Arm Embedded Toolchain")
-
- -- mark as cross-complation toolchain
set_kind("cross")
- -- on load
on_load(function (toolchain)
-
- -- load basic configuration of cross toolchain
toolchain:load_cross_toolchain()
- -- add basic flags
toolchain:add("ldflags", "--specs=nosys.specs", "--specs=nano.specs", {force = true})
toolchain:add("shflags", "--specs=nosys.specs", "--specs=nano.specs", {force = true})
toolchain:add("syslinks", "c", "m")