From 702a14f8db2bc2c215952398384192e599e71cf4 Mon Sep 17 00:00:00 2001 From: ruki Date: Tue, 16 Jul 2024 23:52:46 +0800 Subject: dump rpath --- xmake/modules/utils/binary/rpath.lua | 170 +++++++++++++++++++++++++++++++++++ 1 file changed, 170 insertions(+) create mode 100644 xmake/modules/utils/binary/rpath.lua (limited to 'xmake/modules/utils/binary/rpath.lua') diff --git a/xmake/modules/utils/binary/rpath.lua b/xmake/modules/utils/binary/rpath.lua new file mode 100644 index 000000000..2730b30bf --- /dev/null +++ b/xmake/modules/utils/binary/rpath.lua @@ -0,0 +1,170 @@ +--!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 rpath.lua +-- + +-- imports +import("core.base.option") +import("lib.detect.find_tool") + +function _get_rpath_list_by_objdump(binaryfile, opt) + local list + local plat = opt.plat or os.host() + local arch = opt.arch or os.arch() + local cachekey = "utils.binary.rpath" + local objdump = find_tool("llvm-objdump", {cachekey = cachekey}) or find_tool("objdump", {cachekey = cachekey}) + if objdump then + local binarydir = path.directory(binaryfile) + local argv = {"-x", binaryfile} + if plat == "macosx" or plat == "iphoneos" or plat == "appletvos" or plat == "watchos" then + argv = {"--macho", "-x", binaryfile} + end + local result = try { function () return os.iorunv(objdump.program, argv) end } + if result then + local cmd = false + for _, line in ipairs(result:split("\n")) do + line = line:trim() + if plat == "macosx" or plat == "iphoneos" or plat == "appletvos" or plat == "watchos" then + if not cmd and line:find("cmd LC_RPATH", 1, true) then + cmd = true + elseif cmd and (line:find("cmd ", 1, true) or line:find("Load command", 1, true)) then + cmd = false + end + if cmd then + local p = line:match("path (.-) %(") + if p then + list = list or {} + table.insert(list, p:trim()) + end + end + else + if line:startswith("RUNPATH") or line:startswith("RPATH") then + local p = line:split("%s+")[2] + if p then + list = list or {} + table.insert(list, p:trim()) + end + end + end + end + end + end + return list +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] +-- ... +-- 0x000000000000000f (RPATH) Library rpath: [$ORIGIN] +function _get_rpath_list_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 list + local cachekey = "utils.binary.rpath" + 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("RUNPATH", 1, true) then + local p = line:match("Library runpath: %[(.-)%]") + if p then + list = list or {} + table.insert(list, p:trim()) + end + elseif line:find("RPATH", 1, true) then + local p = line:match("Library rpath: %[(.-)%]") + if p then + list = list or {} + table.insert(list, p:trim()) + end + end + end + end + end + return list +end + +-- $ otool -l build/iphoneos/arm64/release/test +-- build/iphoneos/arm64/release/test: +-- cmd LC_RPATH +-- cmdsize 32 +-- path @loader_path (offset 12) +-- +function _get_rpath_list_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 list + local cachekey = "utils.binary.rpath" + 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 + local cmd = false + for _, line in ipairs(result:split("\n")) do + if not cmd and line:find("cmd LC_RPATH", 1, true) then + cmd = true + elseif cmd and (line:find("cmd ", 1, true) or line:find("Load command", 1, true)) then + cmd = false + end + if cmd then + local p = line:match("path (.-) %(") + if p then + list = list or {} + table.insert(list, p:trim()) + end + end + end + end + end + return list +end + +-- get rpath list +function list(binaryfile, opt) + opt = opt or {} + local dumpers = { + _get_rpath_list_by_objdump, + _get_rpath_list_by_readelf + } + if is_host("macosx") then + table.insert(dumpers, 1, _get_rpath_list_by_otool) + end + for _, dump in ipairs(dumpers) do + local list = dump(binaryfile, opt) + if list then + return list + end + end +end -- cgit v1.3.1 From 4cd523c8196f631cadda84f4a06747758e3e8fe9 Mon Sep 17 00:00:00 2001 From: ruki Date: Tue, 16 Jul 2024 23:55:27 +0800 Subject: remove rpath on macosx --- xmake/modules/utils/binary/deplibs.lua | 12 ++++----- xmake/modules/utils/binary/rpath.lua | 47 +++++++++++++++++++++++++++++----- 2 files changed, 47 insertions(+), 12 deletions(-) (limited to 'xmake/modules/utils/binary/rpath.lua') diff --git a/xmake/modules/utils/binary/deplibs.lua b/xmake/modules/utils/binary/deplibs.lua index 36e54d4af..146e79504 100644 --- a/xmake/modules/utils/binary/deplibs.lua +++ b/xmake/modules/utils/binary/deplibs.lua @@ -205,19 +205,19 @@ end function main(binaryfile, opt) opt = opt or {} - local dumpers = { + local ops = { _get_all_depends_by_objdump, _get_all_depends_by_readelf } if is_host("windows") then - table.insert(dumpers, 2, _get_all_depends_by_dumpbin) + table.insert(ops, 2, _get_all_depends_by_dumpbin) elseif is_host("linux", "bsd") then - table.insert(dumpers, 1, _get_all_depends_by_ldd) + table.insert(ops, 1, _get_all_depends_by_ldd) elseif is_host("macosx") then - table.insert(dumpers, 1, _get_all_depends_by_otool) + table.insert(ops, 1, _get_all_depends_by_otool) end - for _, dump in ipairs(dumpers) do - local depends = dump(binaryfile, opt) + for _, op in ipairs(ops) do + local depends = op(binaryfile, opt) if depends then return depends end diff --git a/xmake/modules/utils/binary/rpath.lua b/xmake/modules/utils/binary/rpath.lua index 2730b30bf..55abad900 100644 --- a/xmake/modules/utils/binary/rpath.lua +++ b/xmake/modules/utils/binary/rpath.lua @@ -151,20 +151,55 @@ function _get_rpath_list_by_otool(binaryfile, opt) return list end +-- install_name_tool -delete_rpath binaryfile +function _remove_rpath_by_install_name_tool(binaryfile, rpath, 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 false + end + local ok = try { function () + os.vrunv("install_name_tool", {"-delete_rpath", rpath, binaryfile}) + return true + end } + return ok +end + -- get rpath list function list(binaryfile, opt) opt = opt or {} - local dumpers = { + local ops = { _get_rpath_list_by_objdump, _get_rpath_list_by_readelf } if is_host("macosx") then - table.insert(dumpers, 1, _get_rpath_list_by_otool) + table.insert(ops, 1, _get_rpath_list_by_otool) end - for _, dump in ipairs(dumpers) do - local list = dump(binaryfile, opt) - if list then - return list + for _, op in ipairs(ops) do + local result = op(binaryfile, opt) + if result then + return result end end end + +-- remove rpath +function remove(binaryfile, rpath, opt) + opt = opt or {} + local ops = {} + if is_host("macosx") then + table.insert(ops, 1, _remove_rpath_by_install_name_tool) + end + for _, op in ipairs(ops) do + if op(binaryfile, rpath, opt) then + break + end + end +end + +-- remove all rpath +function remove_all(binaryfile, opt) + for _, rpath in ipairs(list(binaryfile, opt)) do + remove(binaryfile, rpath, opt) + end +end -- cgit v1.3.1 From 142e3da88a41ef9519e2482b9c198d8bfeeaec6e Mon Sep 17 00:00:00 2001 From: ruki Date: Tue, 16 Jul 2024 23:55:53 +0800 Subject: insert rpath for macho --- xmake/modules/utils/binary/rpath.lua | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) (limited to 'xmake/modules/utils/binary/rpath.lua') diff --git a/xmake/modules/utils/binary/rpath.lua b/xmake/modules/utils/binary/rpath.lua index 55abad900..510b5efb5 100644 --- a/xmake/modules/utils/binary/rpath.lua +++ b/xmake/modules/utils/binary/rpath.lua @@ -151,6 +151,20 @@ function _get_rpath_list_by_otool(binaryfile, opt) return list end +-- install_name_tool -add_rpath binaryfile +function _insert_rpath_by_install_name_tool(binaryfile, rpath, 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 false + end + local ok = try { function () + os.vrunv("install_name_tool", {"-add_rpath", rpath, binaryfile}) + return true + end } + return ok +end + -- install_name_tool -delete_rpath binaryfile function _remove_rpath_by_install_name_tool(binaryfile, rpath, opt) local plat = opt.plat or os.host() @@ -183,6 +197,20 @@ function list(binaryfile, opt) end end +-- insert rpath +function insert(binaryfile, rpath, opt) + opt = opt or {} + local ops = {} + if is_host("macosx") then + table.insert(ops, 1, _insert_rpath_by_install_name_tool) + end + for _, op in ipairs(ops) do + if op(binaryfile, rpath, opt) then + break + end + end +end + -- remove rpath function remove(binaryfile, rpath, opt) opt = opt or {} -- cgit v1.3.1 From 4c983a4dc236397c6bee9cf6e06f089d12a9f259 Mon Sep 17 00:00:00 2001 From: ruki Date: Tue, 16 Jul 2024 23:57:00 +0800 Subject: change rpath for macho --- xmake/modules/utils/binary/rpath.lua | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) (limited to 'xmake/modules/utils/binary/rpath.lua') diff --git a/xmake/modules/utils/binary/rpath.lua b/xmake/modules/utils/binary/rpath.lua index 510b5efb5..ad42970ca 100644 --- a/xmake/modules/utils/binary/rpath.lua +++ b/xmake/modules/utils/binary/rpath.lua @@ -165,6 +165,20 @@ function _insert_rpath_by_install_name_tool(binaryfile, rpath, opt) return ok end +-- install_name_tool -rpath binaryfile +function _change_rpath_by_install_name_tool(binaryfile, rpath_old, rpath_new, 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 false + end + local ok = try { function () + os.vrunv("install_name_tool", {"-rpath", rpath_old, rpath_new, binaryfile}) + return true + end } + return ok +end + -- install_name_tool -delete_rpath binaryfile function _remove_rpath_by_install_name_tool(binaryfile, rpath, opt) local plat = opt.plat or os.host() @@ -211,6 +225,20 @@ function insert(binaryfile, rpath, opt) end end +-- change rpath +function change(binaryfile, rpath_old, rpath_new, opt) + opt = opt or {} + local ops = {} + if is_host("macosx") then + table.insert(ops, 1, _change_rpath_by_install_name_tool) + end + for _, op in ipairs(ops) do + if op(binaryfile, rpath_old, rpath_new, opt) then + break + end + end +end + -- remove rpath function remove(binaryfile, rpath, opt) opt = opt or {} -- cgit v1.3.1 From 10df5c458fcf66832c0ef437157c7397f2283b18 Mon Sep 17 00:00:00 2001 From: ruki Date: Wed, 17 Jul 2024 00:53:43 +0800 Subject: install rpath --- tests/actions/install/xmake.lua | 1 + xmake/modules/target/action/install/main.lua | 25 +++++++++++++++++++++++++ xmake/modules/utils/binary/rpath.lua | 16 ++++++++++++++++ 3 files changed, 42 insertions(+) (limited to 'xmake/modules/utils/binary/rpath.lua') diff --git a/tests/actions/install/xmake.lua b/tests/actions/install/xmake.lua index 8dc12f176..18617c971 100644 --- a/tests/actions/install/xmake.lua +++ b/tests/actions/install/xmake.lua @@ -16,6 +16,7 @@ target("app") set_kind("binary") add_deps("foo") add_files("src/main.cpp") + add_rpathdirs("@loader_path/../lib", {installonly = true}) -- set_prefixdir("app") includes("@builtin/xpack") diff --git a/xmake/modules/target/action/install/main.lua b/xmake/modules/target/action/install/main.lua index 82a6eea8d..6abc513b8 100644 --- a/xmake/modules/target/action/install/main.lua +++ b/xmake/modules/target/action/install/main.lua @@ -22,6 +22,7 @@ import("core.base.option") import("core.base.hashset") import("utils.binary.deplibs", {alias = "get_depend_libraries"}) +import("utils.binary.rpath", {alias = "rpath_utils"}) function _get_target_package_libfiles(target, opt) if option.get("nopkgs") then @@ -132,6 +133,29 @@ function _install_shared_libraries(target, opt) end end +-- update install rpath, we can only get and update rpathdirs with `{installonly = true}` +-- e.g. add_rpathdirs("@loader_path/../lib", {installonly = true}) +function _update_install_rpath(target, opt) + local bindir = target:bindir() + local targetfile = path.join(bindir, target:filename()) + rpath_utils.remove_all(targetfile, {plat = target:plat(), arch = target:arch()}) + if target:policy("install.rpath") then + local result, sources = target:get_from("rpathdirs", "*") + if result and sources then + for idx, rpathdirs in ipairs(result) do + local source = sources[idx] + local extraconf = target:extraconf_from("rpathdirs", source) + for _, rpathdir in ipairs(rpathdirs) do + local extra = extraconf[rpathdir] + if extra and extra.installonly then + rpath_utils.insert(targetfile, rpathdir, {plat = target:plat(), arch = target:arch()}) + end + end + end + end + end +end + -- install binary function _install_binary(target, opt) local bindir = target:bindir() @@ -139,6 +163,7 @@ function _install_binary(target, opt) os.vcp(target:targetfile(), bindir) os.trycp(target:symbolfile(), path.join(bindir, path.filename(target:symbolfile()))) _install_shared_libraries(target, opt) + _update_install_rpath(target, opt) end -- install shared library diff --git a/xmake/modules/utils/binary/rpath.lua b/xmake/modules/utils/binary/rpath.lua index ad42970ca..c47f7c768 100644 --- a/xmake/modules/utils/binary/rpath.lua +++ b/xmake/modules/utils/binary/rpath.lua @@ -22,6 +22,18 @@ import("core.base.option") import("lib.detect.find_tool") +function _replace_rpath_vars(rpath, opt) + local plat = opt.plat or os.host() + local arch = opt.arch or os.arch() + if plat == "macosx" or plat == "iphoneos" or plat == "appletvos" or plat == "watchos" then + rpath = rpath:gsub("@loader_path", "$ORIGIN") + rpath = rpath:gsub("@executable_path", "$ORIGIN") + else + rpath = rpath:gsub("%$ORIGIN", "%loader_path") + end + return rpath +end + function _get_rpath_list_by_objdump(binaryfile, opt) local list local plat = opt.plat or os.host() @@ -218,6 +230,7 @@ function insert(binaryfile, rpath, opt) if is_host("macosx") then table.insert(ops, 1, _insert_rpath_by_install_name_tool) end + rpath = _replace_rpath_vars(rpath, opt) for _, op in ipairs(ops) do if op(binaryfile, rpath, opt) then break @@ -232,6 +245,8 @@ function change(binaryfile, rpath_old, rpath_new, opt) if is_host("macosx") then table.insert(ops, 1, _change_rpath_by_install_name_tool) end + rpath_old = _replace_rpath_vars(rpath_old, opt) + rpath_new = _replace_rpath_vars(rpath_new, opt) for _, op in ipairs(ops) do if op(binaryfile, rpath_old, rpath_new, opt) then break @@ -246,6 +261,7 @@ function remove(binaryfile, rpath, opt) if is_host("macosx") then table.insert(ops, 1, _remove_rpath_by_install_name_tool) end + rpath = _replace_rpath_vars(rpath, opt) for _, op in ipairs(ops) do if op(binaryfile, rpath, opt) then break -- cgit v1.3.1 From ad8a223ce684cd394179aca49fbea9c7b2e0d4c0 Mon Sep 17 00:00:00 2001 From: ruki Date: Wed, 17 Jul 2024 00:57:22 +0800 Subject: add rpath for xpack --- xmake/modules/private/utils/batchcmds.lua | 51 +++++++++++++++++++++------- xmake/modules/target/action/install/main.lua | 5 ++- xmake/modules/utils/binary/rpath.lua | 4 +-- xmake/plugins/pack/batchcmds.lua | 28 +++++++++++++++ 4 files changed, 73 insertions(+), 15 deletions(-) (limited to 'xmake/modules/utils/binary/rpath.lua') diff --git a/xmake/modules/private/utils/batchcmds.lua b/xmake/modules/private/utils/batchcmds.lua index 6c3742b9f..3ea49ea8d 100644 --- a/xmake/modules/private/utils/batchcmds.lua +++ b/xmake/modules/private/utils/batchcmds.lua @@ -29,6 +29,7 @@ import("core.tool.linker") import("core.tool.compiler") import("core.language.language") import("utils.progress", {alias = "progress_utils"}) +import("utils.binary.rpath", {alias = "rpath_utils"}) -- define module local batchcmds = batchcmds or object { _init = {"_TARGET", "_CMDS", "_DEPINFO", "_tip"}} @@ -173,6 +174,20 @@ function _runcmd_ln(cmd, opt) end end +-- run command: clean rpath +function _runcmd_clean_rpath(cmd, opt) + if not opt.dryrun then + rpath_utils.clean(cmd.filepath, opt.opt) + end +end + +-- run command: insert rpath +function _runcmd_insert_rpath(cmd, opt) + if not opt.dryrun then + rpath_utils.insert(cmd.filepath, cmd.rpath, opt.opt) + end +end + -- run command function _runcmd(cmd, opt) local kind = cmd.kind @@ -180,18 +195,20 @@ function _runcmd(cmd, opt) if not maps then maps = { - show = _runcmd_show, - runv = _runcmd_runv, - vrunv = _runcmd_vrunv, - execv = _runcmd_execv, - vexecv = _runcmd_vexecv, - mkdir = _runcmd_mkdir, - rmdir = _runcmd_rmdir, - cd = _runcmd_cd, - rm = _runcmd_rm, - cp = _runcmd_cp, - mv = _runcmd_mv, - ln = _runcmd_ln + show = _runcmd_show, + runv = _runcmd_runv, + vrunv = _runcmd_vrunv, + execv = _runcmd_execv, + vexecv = _runcmd_vexecv, + mkdir = _runcmd_mkdir, + rmdir = _runcmd_rmdir, + cd = _runcmd_cd, + rm = _runcmd_rm, + cp = _runcmd_cp, + mv = _runcmd_mv, + ln = _runcmd_ln, + clean_rpath = _runcmd_clean_rpath, + insert_rpath = _runcmd_insert_rpath } _g.maps = maps end @@ -389,6 +406,16 @@ function batchcmds:show(format, ...) table.insert(self:cmds(), {kind = "show", showtext = showtext}) end +-- add command: clean rpath +function batchcmds:clean_rpath(filepath, opt) + table.insert(self:cmds(), {kind = "clean_rpath", filepath = filepath, opt = opt}) +end + +-- add command: insert rpath +function batchcmds:insert_rpath(filepath, rpath, opt) + table.insert(self:cmds(), {kind = "insert_rpath", filepath = filepath, rpath = rpath, opt = opt}) +end + -- add raw command for the specific generator or xpack format function batchcmds:rawcmd(kind, rawstr) table.insert(self:cmds(), {kind = kind, rawstr = rawstr}) diff --git a/xmake/modules/target/action/install/main.lua b/xmake/modules/target/action/install/main.lua index 6abc513b8..aaa99c4f2 100644 --- a/xmake/modules/target/action/install/main.lua +++ b/xmake/modules/target/action/install/main.lua @@ -136,9 +136,12 @@ end -- update install rpath, we can only get and update rpathdirs with `{installonly = true}` -- e.g. add_rpathdirs("@loader_path/../lib", {installonly = true}) function _update_install_rpath(target, opt) + if target:is_plat("windows", "mingw") then + return + end local bindir = target:bindir() local targetfile = path.join(bindir, target:filename()) - rpath_utils.remove_all(targetfile, {plat = target:plat(), arch = target:arch()}) + rpath_utils.clean(targetfile, {plat = target:plat(), arch = target:arch()}) if target:policy("install.rpath") then local result, sources = target:get_from("rpathdirs", "*") if result and sources then diff --git a/xmake/modules/utils/binary/rpath.lua b/xmake/modules/utils/binary/rpath.lua index c47f7c768..016ff5133 100644 --- a/xmake/modules/utils/binary/rpath.lua +++ b/xmake/modules/utils/binary/rpath.lua @@ -269,8 +269,8 @@ function remove(binaryfile, rpath, opt) end end --- remove all rpath -function remove_all(binaryfile, opt) +-- clean rpath +function clean(binaryfile, opt) for _, rpath in ipairs(list(binaryfile, opt)) do remove(binaryfile, rpath, opt) end diff --git a/xmake/plugins/pack/batchcmds.lua b/xmake/plugins/pack/batchcmds.lua index e745cd19d..6245a345c 100644 --- a/xmake/plugins/pack/batchcmds.lua +++ b/xmake/plugins/pack/batchcmds.lua @@ -100,6 +100,33 @@ function _copy_file_with_symlinks(batchcmds_, srcfile, outputdir) end end +-- update install rpath, we can only get and update rpathdirs with `{installonly = true}` +-- e.g. add_rpathdirs("@loader_path/../lib", {installonly = true}) +function _update_target_install_rpath(target, batchcmds_, opt) + if target:is_plat("windows", "mingw") then + return + end + local package = opt.package + local bindir = _get_target_bindir(package, target) + local targetfile = path.join(bindir, target:filename()) + batchcmds_:clean_rpath(targetfile, {plat = target:plat(), arch = target:arch()}) + if target:policy("install.rpath") then + local result, sources = target:get_from("rpathdirs", "*") + if result and sources then + for idx, rpathdirs in ipairs(result) do + local source = sources[idx] + local extraconf = target:extraconf_from("rpathdirs", source) + for _, rpathdir in ipairs(rpathdirs) do + local extra = extraconf[rpathdir] + if extra and extra.installonly then + batchcmds_:insert_rpath(targetfile, rpathdir, {plat = target:plat(), arch = target:arch()}) + end + end + end + end + end +end + -- install target files function _install_target_files(target, batchcmds_, opt) local package = opt.package @@ -233,6 +260,7 @@ function _on_target_installcmd_binary(target, batchcmds_, opt) batchcmds_:cp(target:symbolfile(), path.join(bindir, path.filename(target:symbolfile()))) end _install_target_shared_libraries(target, batchcmds_, opt) + _update_target_install_rpath(target, batchcmds_, opt) end -- on install shared target command -- cgit v1.3.1 From 68751ccc25332dff6c35ab5e92243cf8f2bfbc26 Mon Sep 17 00:00:00 2001 From: ruki Date: Wed, 17 Jul 2024 22:40:28 +0800 Subject: fix replace rpath --- xmake/modules/utils/binary/rpath.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'xmake/modules/utils/binary/rpath.lua') diff --git a/xmake/modules/utils/binary/rpath.lua b/xmake/modules/utils/binary/rpath.lua index 016ff5133..cdf87d580 100644 --- a/xmake/modules/utils/binary/rpath.lua +++ b/xmake/modules/utils/binary/rpath.lua @@ -29,7 +29,7 @@ function _replace_rpath_vars(rpath, opt) rpath = rpath:gsub("@loader_path", "$ORIGIN") rpath = rpath:gsub("@executable_path", "$ORIGIN") else - rpath = rpath:gsub("%$ORIGIN", "%loader_path") + rpath = rpath:gsub("%$ORIGIN", "@loader_path") end return rpath end -- cgit v1.3.1 From e1590a09bb6fb17bc25b35d871e9eaec8f894050 Mon Sep 17 00:00:00 2001 From: ruki Date: Wed, 17 Jul 2024 22:55:38 +0800 Subject: fix rpath --- tests/actions/install/xmake.lua | 2 +- xmake/modules/target/action/install/main.lua | 16 ++++++++++++---- xmake/modules/utils/binary/rpath.lua | 4 ++-- 3 files changed, 15 insertions(+), 7 deletions(-) (limited to 'xmake/modules/utils/binary/rpath.lua') diff --git a/tests/actions/install/xmake.lua b/tests/actions/install/xmake.lua index 84f567239..814ce51a5 100644 --- a/tests/actions/install/xmake.lua +++ b/tests/actions/install/xmake.lua @@ -11,12 +11,12 @@ target("foo") add_headerfiles("src/foo.h", {public = true}) add_installfiles("src/foo.txt", {prefixdir = "assets", public = true}) set_prefixdir("/", {bindir = "foo_bin", libdir = "foo_lib"}) + add_rpathdirs("@loader_path/../../foo_lib", {installonly = true, public = true}) target("app") set_kind("binary") add_deps("foo") add_files("src/main.cpp") - add_rpathdirs("@loader_path/../lib", {installonly = true}) set_prefixdir("app") includes("@builtin/xpack") diff --git a/xmake/modules/target/action/install/main.lua b/xmake/modules/target/action/install/main.lua index 0b5ac126e..9e5e0c54c 100644 --- a/xmake/modules/target/action/install/main.lua +++ b/xmake/modules/target/action/install/main.lua @@ -29,12 +29,13 @@ function _get_target_package_libfiles(target, opt) return {} end local libfiles = {} + local bindir = target:is_plat("windows", "mingw") and target:bindir() or target:libdir() for _, pkg in ipairs(target:orderpkgs(opt)) do if pkg:enabled() and pkg:get("libfiles") then for _, libfile in ipairs(table.wrap(pkg:get("libfiles"))) do local filename = path.filename(libfile) if filename:endswith(".dll") or filename:endswith(".so") or filename:find("%.so%.%d+$") or filename:endswith(".dylib") then - table.insert(libfiles, libfile) + table.insert(libfiles, path.joinenv({libfile, bindir})) end end end @@ -47,7 +48,10 @@ function _get_target_package_libfiles(target, opt) for _, libfile in ipairs(depend_libraries) do depends:insert(path.filename(libfile)) end - table.remove_if(libfiles, function (_, libfile) return not depends:has(path.filename(libfile)) end) + table.remove_if(libfiles, function (_, libfile) + libfile = path.splitenv(libfile)[1] + return not depends:has(path.filename(libfile)) + end) end return libfiles end @@ -104,15 +108,15 @@ end -- install shared libraries function _install_shared_libraries(target, opt) - local bindir = target:is_plat("windows", "mingw") and target:bindir() or target:libdir() -- get all dependent shared libraries local libfiles = {} for _, dep in ipairs(target:orderdeps()) do + local bindir = dep:is_plat("windows", "mingw") and dep:bindir() or dep:libdir() if dep:kind() == "shared" then local depfile = dep:targetfile() if os.isfile(depfile) then - table.insert(libfiles, depfile) + table.insert(libfiles, path.joinenv({depfile, bindir})) end end table.join2(libfiles, _get_target_package_libfiles(dep, {interface = true})) @@ -124,6 +128,10 @@ function _install_shared_libraries(target, opt) -- do install for _, libfile in ipairs(libfiles) do + local splitinfo = path.splitenv(libfile) + libfile = splitinfo[1] + local bindir = splitinfo[2] + assert(libfile and bindir) local filename = path.filename(libfile) local filepath = path.join(bindir, filename) if os.isfile(filepath) and hash.sha256(filepath) ~= hash.sha256(libfile) then diff --git a/xmake/modules/utils/binary/rpath.lua b/xmake/modules/utils/binary/rpath.lua index cdf87d580..674a9edf0 100644 --- a/xmake/modules/utils/binary/rpath.lua +++ b/xmake/modules/utils/binary/rpath.lua @@ -26,10 +26,10 @@ function _replace_rpath_vars(rpath, opt) local plat = opt.plat or os.host() local arch = opt.arch or os.arch() if plat == "macosx" or plat == "iphoneos" or plat == "appletvos" or plat == "watchos" then + rpath = rpath:gsub("%$ORIGIN", "@loader_path") + else rpath = rpath:gsub("@loader_path", "$ORIGIN") rpath = rpath:gsub("@executable_path", "$ORIGIN") - else - rpath = rpath:gsub("%$ORIGIN", "@loader_path") end return rpath end -- cgit v1.3.1