From caa96b31a9657b79e110af6eba75b3ed664f4932 Mon Sep 17 00:00:00 2001 From: ruki Date: Tue, 16 Jul 2024 23:07:03 +0800 Subject: rename utils.symbols.depend --- xmake/modules/target/action/install/main.lua | 2 +- xmake/modules/target/action/uninstall/main.lua | 2 +- xmake/modules/utils/binary/deplibs.lua | 226 +++++++++++++++++++++++++ xmake/modules/utils/symbols/depend.lua | 226 ------------------------- xmake/plugins/pack/batchcmds.lua | 2 +- 5 files changed, 229 insertions(+), 229 deletions(-) create mode 100644 xmake/modules/utils/binary/deplibs.lua delete mode 100644 xmake/modules/utils/symbols/depend.lua diff --git a/xmake/modules/target/action/install/main.lua b/xmake/modules/target/action/install/main.lua index 3c1a12a8e..82a6eea8d 100644 --- a/xmake/modules/target/action/install/main.lua +++ b/xmake/modules/target/action/install/main.lua @@ -21,7 +21,7 @@ -- imports import("core.base.option") import("core.base.hashset") -import("utils.symbols.depend", {alias = "get_depend_libraries"}) +import("utils.binary.deplibs", {alias = "get_depend_libraries"}) function _get_target_package_libfiles(target, opt) if option.get("nopkgs") then diff --git a/xmake/modules/target/action/uninstall/main.lua b/xmake/modules/target/action/uninstall/main.lua index 73c28f02c..8b8662f90 100644 --- a/xmake/modules/target/action/uninstall/main.lua +++ b/xmake/modules/target/action/uninstall/main.lua @@ -21,7 +21,7 @@ -- imports import("core.base.option") import("core.base.hashset") -import("utils.symbols.depend", {alias = "get_depend_libraries"}) +import("utils.binary.deplibs", {alias = "get_depend_libraries"}) import("private.action.clean.remove_files") function _get_target_package_libfiles(target, opt) diff --git a/xmake/modules/utils/binary/deplibs.lua b/xmake/modules/utils/binary/deplibs.lua new file mode 100644 index 000000000..36e54d4af --- /dev/null +++ b/xmake/modules/utils/binary/deplibs.lua @@ -0,0 +1,226 @@ +--!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 deplibs.lua +-- + +-- imports +import("core.base.option") +import("core.tool.toolchain") +import("lib.detect.find_tool") + +function _get_all_depends_by_dumpbin(binaryfile, opt) + local depends + local plat = opt.plat or os.host() + local arch = opt.arch or os.arch() + local cachekey = "utils.binary.deplibs" + local msvc = toolchain.load("msvc", {plat = plat, arch = arch}) + if msvc:check() then + local dumpbin = find_tool("dumpbin", {cachekey = cachekey, envs = msvc:runenvs()}) + if dumpbin then + local binarydir = path.directory(binaryfile) + local result = try { function () return os.iorunv(dumpbin.program, {"/dependents", "/nologo", binaryfile}) end } + if result then + for _, line in ipairs(result:split("\n")) do + line = line:trim() + if line:endswith(".dll") then + depends = depends or {} + table.insert(depends, line) + end + end + end + end + end + return depends +end + +function _get_all_depends_by_objdump(binaryfile, opt) + local depends + local plat = opt.plat or os.host() + local arch = opt.arch or os.arch() + local cachekey = "utils.binary.deplibs" + local objdump = find_tool("llvm-objdump", {cachekey = cachekey}) or find_tool("objdump", {cachekey = cachekey}) + if objdump then + local binarydir = path.directory(binaryfile) + local argv = {"-p", binaryfile} + if plat == "macosx" or plat == "iphoneos" or plat == "appletvos" or plat == "watchos" then + argv = {"--macho", "--dylibs-used", binaryfile} + end + local result = try { function () return os.iorunv(objdump.program, argv) end } + if result then + for _, line in ipairs(result:split("\n")) do + line = line:trim() + if plat == "windows" or plat == "mingw" then + if line:startswith("DLL Name:") then + local filename = line:split(":")[2]:trim() + if filename:endswith(".dll") then + depends = depends or {} + table.insert(depends, filename) + end + end + elseif plat == "macosx" or plat == "iphoneos" or plat == "appletvos" or plat == "watchos" then + local filename = line:match(".-%.dylib") or line:match(".-%.framework") + if filename then + depends = depends or {} + table.insert(depends, filename) + end + else + if line:startswith("NEEDED") then + local filename = line:split("%s+")[2] + if filename and filename:endswith(".so") then + depends = depends or {} + table.insert(depends, filename) + end + end + end + end + end + end + return depends +end + +-- $ldd ./build/linux/x86_64/release/test +-- linux-vdso.so.1 (0x00007ffc51fdd000) +-- libfoo.so => /mnt/xmake/tests/projects/c/shared_library/./build/linux/x86_64/release/libfoo.so (0x00007fe241233000) +-- libstdc++.so.6 => /lib64/libstdc++.so.6 (0x00007fe240fca000) +-- libm.so.6 => /lib64/libm.so.6 (0x00007fe240ee7000) +-- libgcc_s.so.1 => /lib64/libgcc_s.so.1 (0x00007fe240eba000) +-- libc.so.6 => /lib64/libc.so.6 (0x00007fe240ccd000) +-- /lib64/ld-linux-x86-64.so.2 (0x00007fe24123a000) +-- +function _get_all_depends_by_ldd(binaryfile, opt) + local plat = opt.plat or os.host() + local arch = opt.arch or os.arch() + if plat ~= "linux" and plat ~= "bsd" then + return + end + local depends + local cachekey = "utils.binary.deplibs" + local ldd = find_tool("ldd", {cachekey = cachekey}) + if ldd then + local binarydir = path.directory(binaryfile) + local result = try { function () return os.iorunv(ldd.program, {binaryfile}) end } + if result then + for _, line in ipairs(result:split("\n")) do + local splitinfo = line:split("=>") + line = splitinfo[2] + if not line or line:find("not found", 1, true) then + line = splitinfo[1] + end + line = line:gsub("%(.+%)", ""):trim() + local filename = line:match(".-%.so$") or line:match(".-%.so%.%d+") + if filename then + depends = depends or {} + table.insert(depends, filename:trim()) + end + end + end + end + return depends +end + +-- $ readelf -d build/linux/x86_64/release/test +-- +-- Dynamic section at offset 0x2db8 contains 29 entries: +-- Tag Type Name/Value +-- 0x0000000000000001 (NEEDED) Shared library: [libfoo.so] +-- 0x0000000000000001 (NEEDED) Shared library: [libstdc++.so.6] +-- 0x0000000000000001 (NEEDED) Shared library: [libm.so.6] +-- 0x0000000000000001 (NEEDED) Shared library: [libgcc_s.so.1] +-- 0x0000000000000001 (NEEDED) Shared library: [libc.so.6] +-- 0x000000000000001d (RUNPATH) Library runpath: [$ORIGIN] +function _get_all_depends_by_readelf(binaryfile, opt) + local plat = opt.plat or os.host() + local arch = opt.arch or os.arch() + if plat ~= "linux" and plat ~= "bsd" and plat ~= "android" and plat ~= "cross" then + return + end + local depends + local cachekey = "utils.binary.deplibs" + local readelf = find_tool("readelf", {cachekey = cachekey}) + if readelf then + local binarydir = path.directory(binaryfile) + local result = try { function () return os.iorunv(readelf.program, {"-d", binaryfile}) end } + if result then + for _, line in ipairs(result:split("\n")) do + if line:find("NEEDED", 1, true) then + local filename = line:match("Shared library: %[(.-)%]") + if filename then + depends = depends or {} + table.insert(depends, filename:trim()) + end + end + end + end + end + return depends +end + +-- $ otool -L build/iphoneos/arm64/release/test +-- build/iphoneos/arm64/release/test: +-- @rpath/libfoo.dylib (compatibility version 0.0.0, current version 0.0.0) +-- /System/Library/Frameworks/Foundation.framework/Foundation (compatibility version 300.0.0, current version 2048.1.101) +-- /usr/lib/libobjc.A.dylib (compatibility version 1.0.0, current version 228.0.0) +-- /usr/lib/libc++.1.dylib (compatibility version 1.0.0, current version 1600.151.0) +-- /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1336.0.0) +-- +function _get_all_depends_by_otool(binaryfile, opt) + local plat = opt.plat or os.host() + local arch = opt.arch or os.arch() + if plat ~= "macosx" and plat ~= "iphoneos" and plat ~= "appletvos" and plat ~= "watchos" then + return + end + local depends + local cachekey = "utils.binary.deplibs" + local otool = find_tool("otool", {cachekey = cachekey}) + if otool then + local binarydir = path.directory(binaryfile) + local result = try { function () return os.iorunv(otool.program, {"-L", binaryfile}) end } + if result then + for _, line in ipairs(result:split("\n")) do + local filename = line:match(".-%.dylib") or line:match(".-%.framework") + if filename then + depends = depends or {} + table.insert(depends, filename:trim()) + end + end + end + end + return depends +end + +function main(binaryfile, opt) + opt = opt or {} + local dumpers = { + _get_all_depends_by_objdump, + _get_all_depends_by_readelf + } + if is_host("windows") then + table.insert(dumpers, 2, _get_all_depends_by_dumpbin) + elseif is_host("linux", "bsd") then + table.insert(dumpers, 1, _get_all_depends_by_ldd) + elseif is_host("macosx") then + table.insert(dumpers, 1, _get_all_depends_by_otool) + end + for _, dump in ipairs(dumpers) do + local depends = dump(binaryfile, opt) + if depends then + return depends + end + end +end + diff --git a/xmake/modules/utils/symbols/depend.lua b/xmake/modules/utils/symbols/depend.lua deleted file mode 100644 index c9101f6d0..000000000 --- a/xmake/modules/utils/symbols/depend.lua +++ /dev/null @@ -1,226 +0,0 @@ ---!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 depend.lua --- - --- imports -import("core.base.option") -import("core.tool.toolchain") -import("lib.detect.find_tool") - -function _get_all_depends_by_dumpbin(binaryfile, opt) - local depends - local plat = opt.plat or os.host() - local arch = opt.arch or os.arch() - local cachekey = "utils.symbols.depend" - local msvc = toolchain.load("msvc", {plat = plat, arch = arch}) - if msvc:check() then - local dumpbin = find_tool("dumpbin", {cachekey = cachekey, envs = msvc:runenvs()}) - if dumpbin then - local binarydir = path.directory(binaryfile) - local result = try { function () return os.iorunv(dumpbin.program, {"/dependents", "/nologo", binaryfile}) end } - if result then - for _, line in ipairs(result:split("\n")) do - line = line:trim() - if line:endswith(".dll") then - depends = depends or {} - table.insert(depends, line) - end - end - end - end - end - return depends -end - -function _get_all_depends_by_objdump(binaryfile, opt) - local depends - local plat = opt.plat or os.host() - local arch = opt.arch or os.arch() - local cachekey = "utils.symbols.depend" - local objdump = find_tool("llvm-objdump", {cachekey = cachekey}) or find_tool("objdump", {cachekey = cachekey}) - if objdump then - local binarydir = path.directory(binaryfile) - local argv = {"-p", binaryfile} - if plat == "macosx" or plat == "iphoneos" or plat == "appletvos" or plat == "watchos" then - argv = {"--macho", "--dylibs-used", binaryfile} - end - local result = try { function () return os.iorunv(objdump.program, argv) end } - if result then - for _, line in ipairs(result:split("\n")) do - line = line:trim() - if plat == "windows" or plat == "mingw" then - if line:startswith("DLL Name:") then - local filename = line:split(":")[2]:trim() - if filename:endswith(".dll") then - depends = depends or {} - table.insert(depends, filename) - end - end - elseif plat == "macosx" or plat == "iphoneos" or plat == "appletvos" or plat == "watchos" then - local filename = line:match(".-%.dylib") or line:match(".-%.framework") - if filename then - depends = depends or {} - table.insert(depends, filename) - end - else - if line:startswith("NEEDED") then - local filename = line:split("%s+")[2] - if filename and filename:endswith(".so") then - depends = depends or {} - table.insert(depends, filename) - end - end - end - end - end - end - return depends -end - --- $ldd ./build/linux/x86_64/release/test --- linux-vdso.so.1 (0x00007ffc51fdd000) --- libfoo.so => /mnt/xmake/tests/projects/c/shared_library/./build/linux/x86_64/release/libfoo.so (0x00007fe241233000) --- libstdc++.so.6 => /lib64/libstdc++.so.6 (0x00007fe240fca000) --- libm.so.6 => /lib64/libm.so.6 (0x00007fe240ee7000) --- libgcc_s.so.1 => /lib64/libgcc_s.so.1 (0x00007fe240eba000) --- libc.so.6 => /lib64/libc.so.6 (0x00007fe240ccd000) --- /lib64/ld-linux-x86-64.so.2 (0x00007fe24123a000) --- -function _get_all_depends_by_ldd(binaryfile, opt) - local plat = opt.plat or os.host() - local arch = opt.arch or os.arch() - if plat ~= "linux" and plat ~= "bsd" then - return - end - local depends - local cachekey = "utils.symbols.depend" - local ldd = find_tool("ldd", {cachekey = cachekey}) - if ldd then - local binarydir = path.directory(binaryfile) - local result = try { function () return os.iorunv(ldd.program, {binaryfile}) end } - if result then - for _, line in ipairs(result:split("\n")) do - local splitinfo = line:split("=>") - line = splitinfo[2] - if not line or line:find("not found", 1, true) then - line = splitinfo[1] - end - line = line:gsub("%(.+%)", ""):trim() - local filename = line:match(".-%.so$") or line:match(".-%.so%.%d+") - if filename then - depends = depends or {} - table.insert(depends, filename:trim()) - end - end - end - end - return depends -end - --- $ readelf -d build/linux/x86_64/release/test --- --- Dynamic section at offset 0x2db8 contains 29 entries: --- Tag Type Name/Value --- 0x0000000000000001 (NEEDED) Shared library: [libfoo.so] --- 0x0000000000000001 (NEEDED) Shared library: [libstdc++.so.6] --- 0x0000000000000001 (NEEDED) Shared library: [libm.so.6] --- 0x0000000000000001 (NEEDED) Shared library: [libgcc_s.so.1] --- 0x0000000000000001 (NEEDED) Shared library: [libc.so.6] --- 0x000000000000001d (RUNPATH) Library runpath: [$ORIGIN] -function _get_all_depends_by_readelf(binaryfile, opt) - local plat = opt.plat or os.host() - local arch = opt.arch or os.arch() - if plat ~= "linux" and plat ~= "bsd" and plat ~= "android" and plat ~= "cross" then - return - end - local depends - local cachekey = "utils.symbols.depend" - local readelf = find_tool("readelf", {cachekey = cachekey}) - if readelf then - local binarydir = path.directory(binaryfile) - local result = try { function () return os.iorunv(readelf.program, {"-d", binaryfile}) end } - if result then - for _, line in ipairs(result:split("\n")) do - if line:find("NEEDED", 1, true) then - local filename = line:match("Shared library: %[(.-)%]") - if filename then - depends = depends or {} - table.insert(depends, filename:trim()) - end - end - end - end - end - return depends -end - --- $ otool -L build/iphoneos/arm64/release/test --- build/iphoneos/arm64/release/test: --- @rpath/libfoo.dylib (compatibility version 0.0.0, current version 0.0.0) --- /System/Library/Frameworks/Foundation.framework/Foundation (compatibility version 300.0.0, current version 2048.1.101) --- /usr/lib/libobjc.A.dylib (compatibility version 1.0.0, current version 228.0.0) --- /usr/lib/libc++.1.dylib (compatibility version 1.0.0, current version 1600.151.0) --- /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1336.0.0) --- -function _get_all_depends_by_otool(binaryfile, opt) - local plat = opt.plat or os.host() - local arch = opt.arch or os.arch() - if plat ~= "macosx" and plat ~= "iphoneos" and plat ~= "appletvos" and plat ~= "watchos" then - return - end - local depends - local cachekey = "utils.symbols.depend" - local otool = find_tool("otool", {cachekey = cachekey}) - if otool then - local binarydir = path.directory(binaryfile) - local result = try { function () return os.iorunv(otool.program, {"-L", binaryfile}) end } - if result then - for _, line in ipairs(result:split("\n")) do - local filename = line:match(".-%.dylib") or line:match(".-%.framework") - if filename then - depends = depends or {} - table.insert(depends, filename:trim()) - end - end - end - end - return depends -end - -function main(binaryfile, opt) - opt = opt or {} - local dumpers = { - _get_all_depends_by_objdump, - _get_all_depends_by_readelf - } - if is_host("windows") then - table.insert(dumpers, 2, _get_all_depends_by_dumpbin) - elseif is_host("linux", "bsd") then - table.insert(dumpers, 1, _get_all_depends_by_ldd) - elseif is_host("macosx") then - table.insert(dumpers, 1, _get_all_depends_by_otool) - end - for _, dump in ipairs(dumpers) do - local depends = dump(binaryfile, opt) - if depends then - return depends - end - end -end - diff --git a/xmake/plugins/pack/batchcmds.lua b/xmake/plugins/pack/batchcmds.lua index 26ab4f7b0..e745cd19d 100644 --- a/xmake/plugins/pack/batchcmds.lua +++ b/xmake/plugins/pack/batchcmds.lua @@ -22,7 +22,7 @@ import("core.base.option") import("core.base.hashset") import("utils.archive") -import("utils.symbols.depend", {alias = "get_depend_libraries"}) +import("utils.binary.deplibs", {alias = "get_depend_libraries"}) import("private.utils.batchcmds") function _get_target_bindir(package, target) -- cgit v1.3.1