--!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, Xmake Open Source Community. -- -- @author ruki -- @file xmake.lua -- -- define rule: utils.symbols.extract rule("utils.symbols.extract") after_config(function(target) -- need generate symbols? local strip = target:get("strip") local symbols = table.wrap(target:get("symbols")) if table.contains(symbols, "debug") and (strip == "all" or strip == "debug") and not target:is_plat("windows") -- we need not to strip pdb for windows, https://github.com/xmake-io/xmake/issues/6554 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) else target:rule_enable("utils.symbols.extract", false) end end) after_link(function (target, opt) -- need generate symbols? if not target:data("utils.symbols.extract") then return end -- imports import("core.base.option") import("core.theme.theme") import("core.project.depend") import("core.platform.platform") import("utils.progress") -- get strip local strip = target:tool("strip") if not strip then return end -- 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 -- @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 symbolfile = target:symbolfile() local dryrun = option.get("dry-run") depend.on_changed(function () -- 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 -- 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 -- strip it local strip_argv = {} if target:is_plat("macosx", "iphoneos", "watchos") and not strip:find("llvm-strip", 1, true) 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 -- -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 table.insert(strip_argv, targetfile) os.vrunv(strip, strip_argv, {dryrun = dryrun}) -- 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)