diff options
| author | ruki <[email protected]> | 2024-05-11 20:47:33 +0800 |
|---|---|---|
| committer | ruki <[email protected]> | 2024-05-11 20:47:33 +0800 |
| commit | 2d0f7082ce3346e71445a94d0c492472150b94b7 (patch) | |
| tree | 84d00ad2fa687d0350a5cecc8401ae6d80557ef1 | |
| parent | 1924008b1db3bbf3fc6842a2d0afac209979ad5b (diff) | |
improve gcc-ar
| -rw-r--r-- | xmake/modules/core/tools/gcc_ar.lua | 54 | ||||
| -rw-r--r-- | xmake/toolchains/cross/check.lua | 29 | ||||
| -rw-r--r-- | xmake/toolchains/cross/load.lua | 14 |
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 |
