diff options
| author | ruki <[email protected]> | 2024-03-13 15:56:10 +0800 |
|---|---|---|
| committer | GitHub <[email protected]> | 2024-03-13 15:56:10 +0800 |
| commit | 18455147337f1d4715822d374ff6cc1fd25f7abf (patch) | |
| tree | 1424c283294365384a840cade955ae13c67ae514 | |
| parent | 5439a4a60f142cc5c238903972409c51341e6be7 (diff) | |
| parent | 8e24507ec973801bcbeec54855a4b83e7c3a7915 (diff) | |
Merge pull request #4829 from xmake-io/gdb
Improve to extract symbols for gdb
| -rw-r--r-- | xmake/core/tool/toolchain.lua | 2 | ||||
| -rw-r--r-- | xmake/modules/detect/tools/find_objcopy.lua | 46 | ||||
| -rw-r--r-- | xmake/modules/detect/tools/find_ranlib.lua | 8 | ||||
| -rw-r--r-- | xmake/rules/utils/symbols/extract/xmake.lua | 118 | ||||
| -rw-r--r-- | xmake/toolchains/clang/xmake.lua | 2 | ||||
| -rw-r--r-- | xmake/toolchains/gcc/xmake.lua | 2 | ||||
| -rw-r--r-- | xmake/toolchains/llvm/xmake.lua | 3 | ||||
| -rw-r--r-- | xmake/toolchains/mingw/xmake.lua | 2 |
8 files changed, 119 insertions, 64 deletions
diff --git a/xmake/core/tool/toolchain.lua b/xmake/core/tool/toolchain.lua index 057153ca7..be4e82810 100644 --- a/xmake/core/tool/toolchain.lua +++ b/xmake/core/tool/toolchain.lua @@ -388,6 +388,8 @@ function _instance:_description(toolkind) ar = "the static library archiver", mrc = "the windows resource compiler", strip = "the symbols stripper", + ranlib = "the archive index generator", + objcopy = "the GNU objcopy utility", dsymutil = "the symbols generator", mm = "the objc compiler", mxx = "the objc++ compiler", diff --git a/xmake/modules/detect/tools/find_objcopy.lua b/xmake/modules/detect/tools/find_objcopy.lua new file mode 100644 index 000000000..8c29fca09 --- /dev/null +++ b/xmake/modules/detect/tools/find_objcopy.lua @@ -0,0 +1,46 @@ +--!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 find_objcopy.lua +-- + +-- imports +import("lib.detect.find_program") +import("lib.detect.find_programver") + +-- find objcopy +-- +-- @param opt the argument options, e.g. {version = true} +-- +-- @return program, version +-- +-- @code +-- +-- local objcopy = find_objcopy() +-- local objcopy, version = find_objcopy({program = "xcrun -sdk macosx objcopy", version = true}) +-- +-- @endcode +-- +function main(opt) + opt = opt or {} + local program = find_program(opt.program or "objcopy", opt) + local version = nil + if program and opt and opt.version then + version = find_programver(program, opt) + end + return program, version +end diff --git a/xmake/modules/detect/tools/find_ranlib.lua b/xmake/modules/detect/tools/find_ranlib.lua index d5db80986..278eedee6 100644 --- a/xmake/modules/detect/tools/find_ranlib.lua +++ b/xmake/modules/detect/tools/find_ranlib.lua @@ -36,19 +36,11 @@ import("lib.detect.find_programver") -- @endcode -- function main(opt) - - -- init options opt = opt or {} - - -- find program local program = find_program(opt.program or "ranlib", opt) - - -- find program version local version = nil if program and opt and opt.version then version = find_programver(program, opt) end - - -- ok? return program, version end diff --git a/xmake/rules/utils/symbols/extract/xmake.lua b/xmake/rules/utils/symbols/extract/xmake.lua index 222634688..c59adc058 100644 --- a/xmake/rules/utils/symbols/extract/xmake.lua +++ b/xmake/rules/utils/symbols/extract/xmake.lua @@ -27,9 +27,8 @@ rule("utils.symbols.extract") -- need generate symbols? local strip = target:get("strip") - local targetkind = target:kind() if target:get("symbols") == "debug" and (strip == "all" or strip == "debug") - and (targetkind == "binary" or targetkind == "shared") and platform.tool("strip") then -- only for strip command + and (target:is_binary() or target:is_shared()) and target:tool("strip") then -- only for strip command target:data_set("utils.symbols.extract", true) target:set("strip", "none") -- disable strip in link stage, because we need to run separate strip commands target:data_set("strip.origin", strip) @@ -55,74 +54,83 @@ rule("utils.symbols.extract") return end - -- get dsymutil - local dsymutil - if is_plat("macosx", "iphoneos", "watchos") then + -- get dsymutil and objcopy + local dsymutil, objcopy + if target:is_plat("macosx", "iphoneos", "watchos") then dsymutil = target:tool("dsymutil") if not dsymutil then return end + else + objcopy = target:tool("objcopy") end - -- need re-generate this symbol file? - local symbolfile = target:symbolfile() + -- @note we use dependfile(targetfile) as sourcefile/mtime instead of targetfile to ensure it's mtime less than mtime(symbolfile), because targetfile will be changed after stripping local targetfile = target:targetfile() - local dependfile = target:dependfile(symbolfile) - local dependinfo = target:is_rebuilt() and {} or (depend.load(dependfile) or {}) - if not depend.is_changed(dependinfo, {lastmtime = os.mtime(dependfile)}) then - return - end - - -- trace progress info - progress.show(opt.progress, "${color.build.target}generating.$(mode) %s", path.filename(symbolfile)) - - -- we remove the previous symbol file to ensure that it will be re-generated and it's mtime will be changed. + local symbolfile = target:symbolfile() local dryrun = option.get("dry-run") - if not dryrun then - os.tryrm(symbolfile) - end + depend.on_changed(function () - -- generate symbols file - if dsymutil then - local dsymutil_argv = {} - local arch = get_config("arch") - if arch then - table.insert(dsymutil_argv, "-arch") - table.insert(dsymutil_argv, arch) + -- trace progress info + progress.show(opt.progress, "${color.build.target}generating.$(mode) %s", path.filename(symbolfile)) + + -- we remove the previous symbol file to ensure that it will be re-generated and it's mtime will be changed. + if not dryrun then + os.tryrm(symbolfile) end - table.insert(dsymutil_argv, targetfile) - table.insert(dsymutil_argv, "-o") - table.insert(dsymutil_argv, symbolfile) - os.vrunv(dsymutil, dsymutil_argv, {dryrun = dryrun}) - elseif not dryrun then - os.vcp(targetfile, symbolfile) - end - -- strip it - local strip_argv = {} - if is_plat("macosx", "iphoneos", "watchos") then - -- do not support `-s`, we can only strip debug symbols - local arch = get_config("arch") - if arch then - table.insert(strip_argv, "-arch") - table.insert(strip_argv, arch) + -- generate symbols file + if dsymutil then + local dsymutil_argv = {} + local arch = target:arch() + if arch then + table.insert(dsymutil_argv, "-arch") + table.insert(dsymutil_argv, arch) + end + table.insert(dsymutil_argv, targetfile) + table.insert(dsymutil_argv, "-o") + table.insert(dsymutil_argv, symbolfile) + os.vrunv(dsymutil, dsymutil_argv, {dryrun = dryrun}) + else + -- @see https://github.com/xmake-io/xmake/issues/4684 + if objcopy then + os.vrunv(objcopy, {"--only-keep-debug", targetfile, symbolfile}, {dryrun = dryrun}) + elseif not dryrun then + os.vcp(targetfile, symbolfile) + end end - table.insert(strip_argv, "-S") - else - -- -s/--strip-all for gnu strip - local strip = target:data("strip.origin") - if strip == "debug" then + + -- strip it + local strip_argv = {} + if target:is_plat("macosx", "iphoneos", "watchos") then + -- do not support `-s`, we can only strip debug symbols + local arch = target:arch() + if arch then + table.insert(strip_argv, "-arch") + table.insert(strip_argv, arch) + end table.insert(strip_argv, "-S") else - table.insert(strip_argv, "-s") + -- -s/--strip-all for gnu strip + local strip = target:data("strip.origin") + if strip == "debug" then + table.insert(strip_argv, "-S") + else + table.insert(strip_argv, "-s") + end end - end - table.insert(strip_argv, targetfile) - os.vrunv(strip, strip_argv, {dryrun = dryrun}) + table.insert(strip_argv, targetfile) + os.vrunv(strip, strip_argv, {dryrun = dryrun}) - -- update files and values to the dependent file - -- @note we use dependfile(targetfile) as sourcefile/mtime instead of targetfile to ensure it's mtime less than mtime(symbolfile), because targetfile will be changed after stripping - dependinfo.files = {target:dependfile(targetfile)} - depend.save(dependinfo, dependfile) + -- attach symbolfile to targetfile + if not target:is_plat("macosx", "iphoneos", "watchos") and objcopy then + -- @see https://github.com/xmake-io/xmake/issues/4684 + os.vrunv(objcopy, {"--add-gnu-debuglink=" .. symbolfile, targetfile}, {dryrun = dryrun}) + end + + end, {dependfile = target:dependfile(symbolfile), + files = target:dependfile(targetfile), + changed = target:is_rebuilt(), + dryrun = dryrun}) end) diff --git a/xmake/toolchains/clang/xmake.lua b/xmake/toolchains/clang/xmake.lua index 0a792ca40..cc8da1d26 100644 --- a/xmake/toolchains/clang/xmake.lua +++ b/xmake/toolchains/clang/xmake.lua @@ -36,6 +36,8 @@ toolchain("clang" .. suffix) set_toolset("sh", "clang++" .. suffix, "clang" .. suffix) set_toolset("ar", "ar", "llvm-ar") set_toolset("strip", "strip", "llvm-strip") + set_toolset("ranlib", "ranlib", "llvm-ranlib") + set_toolset("objcopy", "objcopy", "llvm-objcopy") set_toolset("mm", "clang" .. suffix) set_toolset("mxx", "clang" .. suffix, "clang++" .. suffix) set_toolset("as", "clang" .. suffix) diff --git a/xmake/toolchains/gcc/xmake.lua b/xmake/toolchains/gcc/xmake.lua index 9b01a80f5..9afc56c65 100644 --- a/xmake/toolchains/gcc/xmake.lua +++ b/xmake/toolchains/gcc/xmake.lua @@ -36,6 +36,8 @@ toolchain("gcc" .. suffix) set_toolset("sh", "g++" .. suffix, "gcc" .. suffix) set_toolset("ar", "ar") set_toolset("strip", "strip") + set_toolset("objcopy", "objcopy") + set_toolset("ranlib", "ranlib") set_toolset("mm", "gcc" .. suffix) set_toolset("mxx", "gcc" .. suffix, "g++" .. suffix) set_toolset("as", "gcc" .. suffix) diff --git a/xmake/toolchains/llvm/xmake.lua b/xmake/toolchains/llvm/xmake.lua index 5c6ab2586..71baf9fe6 100644 --- a/xmake/toolchains/llvm/xmake.lua +++ b/xmake/toolchains/llvm/xmake.lua @@ -33,8 +33,9 @@ toolchain("llvm") set_toolset("ld", "clang++", "clang") set_toolset("sh", "clang++", "clang") set_toolset("ar", "llvm-ar") - set_toolset("ranlib", "llvm-ranlib") set_toolset("strip", "llvm-strip") + set_toolset("ranlib", "llvm-ranlib") + set_toolset("objcopy","llvm-objcopy") set_toolset("mrc", "llvm-rc") on_check("check") diff --git a/xmake/toolchains/mingw/xmake.lua b/xmake/toolchains/mingw/xmake.lua index 188b5ae8a..b2d5977fd 100644 --- a/xmake/toolchains/mingw/xmake.lua +++ b/xmake/toolchains/mingw/xmake.lua @@ -63,6 +63,7 @@ toolchain("mingw") toolchain:add("toolset", "ar", path.join(bindir, "ar")) toolchain:add("toolset", "strip", path.join(bindir, "strip")) toolchain:add("toolset", "ranlib", path.join(bindir, "ranlib")) + toolchain:add("toolset", "objcopy", path.join(bindir, "objcopy")) end toolchain:add("toolset", "cc", cross .. "gcc") toolchain:add("toolset", "cxx", cross .. "g++", cross .. "gcc") @@ -73,6 +74,7 @@ toolchain("mingw") toolchain:add("toolset", "ar", cross .. "ar") toolchain:add("toolset", "strip", cross .. "strip") toolchain:add("toolset", "ranlib", cross .. "ranlib") + toolchain:add("toolset", "objcopy", cross .. "objcopy") toolchain:add("toolset", "mrc", cross .. "windres") if is_host("windows") and bindir then -- we use bin/gcc.exe if cross not found |
