From 2ae6ada73e544bba9f547b022393f1e3c5093ec6 Mon Sep 17 00:00:00 2001 From: ruki Date: Fri, 12 Jul 2024 00:52:16 +0800 Subject: add set_prefixdir --- xmake/core/project/target.lua | 45 ++++++++++++++++++++++++++++++++++++++----- xmake/plugins/pack/xpack.lua | 6 +++--- 2 files changed, 43 insertions(+), 8 deletions(-) diff --git a/xmake/core/project/target.lua b/xmake/core/project/target.lua index 0ed7465d4..fb7801f3c 100644 --- a/xmake/core/project/target.lua +++ b/xmake/core/project/target.lua @@ -1623,20 +1623,54 @@ function _instance:rundir() return baseoption.get("workdir") or self:get("rundir") or path.directory(self:targetfile()) end --- get install directory -function _instance:installdir() +-- get prefix directory +function _instance:prefixdir() + return self:get("prefixdir") +end + +-- get the installed binary directory +function _instance:bindir() + local bindir = self:extraconf("prefixdir", self:prefixdir(), "bindir") + if bindir == nil then + bindir = "bin" + end + return self:installdir(bindir) +end + +-- get the installed library directory +function _instance:libdir() + local libdir = self:extraconf("prefixdir", self:prefixdir(), "libdir") + if libdir == nil then + libdir = "lib" + end + return self:installdir(libdir) +end - -- get it from the cache +-- get the installed include directory +function _instance:includedir() + local includedir = self:extraconf("prefixdir", self:prefixdir(), "includedir") + if includedir == nil then + includedir = "include" + end + return self:installdir(includedir) +end + +-- get install directory +function _instance:installdir(...) + opt = opt or {} local installdir = baseoption.get("installdir") if not installdir then - -- DESTDIR: be compatible with https://www.gnu.org/prep/standards/html_node/DESTDIR.html installdir = self:get("installdir") or os.getenv("INSTALLDIR") or os.getenv("PREFIX") or os.getenv("DESTDIR") or platform.get("installdir") if installdir then installdir = installdir:trim() end end - return installdir + local prefixdir = self:prefixdir() + if prefixdir then + installdir = path.join(installdir, prefixdir) + end + return path.normalize(path.join(installdir, ...)) end -- get package directory @@ -2737,6 +2771,7 @@ function target.apis() , "target.set_runargs" , "target.set_exceptions" , "target.set_encodings" + , "target.set_prefixdir" -- target.add_xxx , "target.add_deps" , "target.add_rules" diff --git a/xmake/plugins/pack/xpack.lua b/xmake/plugins/pack/xpack.lua index 89ee5a54b..203fcbe6d 100644 --- a/xmake/plugins/pack/xpack.lua +++ b/xmake/plugins/pack/xpack.lua @@ -453,7 +453,7 @@ end -- get the binary directory function xpack:bindir() - local bindir = self:get("bindir") + local bindir = self:get("bindir") or self:extraconf("prefixdir", self:prefixdir(), "bindir") if bindir == nil then bindir = "bin" end @@ -462,7 +462,7 @@ end -- get the library directory function xpack:libdir() - local libdir = self:get("libdir") + local libdir = self:get("libdir") or self:extraconf("prefixdir", self:prefixdir(), "libdir") if libdir == nil then libdir = "lib" end @@ -471,7 +471,7 @@ end -- get the include directory function xpack:includedir() - local includedir = self:get("includedir") + local includedir = self:get("includedir") or self:extraconf("prefixdir", self:prefixdir(), "includedir") if includedir == nil then includedir = "include" end -- cgit v1.3.1 From 370950a092310a934b37bc853fe0587286422159 Mon Sep 17 00:00:00 2001 From: ruki Date: Fri, 12 Jul 2024 00:54:47 +0800 Subject: improve install dir --- xmake/core/project/target.lua | 10 ++++++---- xmake/modules/target/action/install/unix.lua | 10 +++++----- xmake/modules/target/action/install/windows.lua | 18 +++++++----------- 3 files changed, 18 insertions(+), 20 deletions(-) diff --git a/xmake/core/project/target.lua b/xmake/core/project/target.lua index fb7801f3c..a404f04bd 100644 --- a/xmake/core/project/target.lua +++ b/xmake/core/project/target.lua @@ -1666,11 +1666,13 @@ function _instance:installdir(...) installdir = installdir:trim() end end - local prefixdir = self:prefixdir() - if prefixdir then - installdir = path.join(installdir, prefixdir) + if installdir then + local prefixdir = self:prefixdir() + if prefixdir then + installdir = path.join(installdir, prefixdir) + end + return path.normalize(path.join(installdir, ...)) end - return path.normalize(path.join(installdir, ...)) end -- get package directory diff --git a/xmake/modules/target/action/install/unix.lua b/xmake/modules/target/action/install/unix.lua index 71a6df42b..5b4507622 100644 --- a/xmake/modules/target/action/install/unix.lua +++ b/xmake/modules/target/action/install/unix.lua @@ -23,7 +23,7 @@ import("core.base.option") -- install headers function _install_headers(target, opt) - local includedir = path.join(target:installdir(), opt and opt.includedir or "include") + local includedir = target:includedir() os.mkdir(includedir) local srcheaders, dstheaders = target:headerfiles(includedir, {installonly = true}) if srcheaders and dstheaders then @@ -81,12 +81,12 @@ end function install_binary(target, opt) -- install binary - local binarydir = path.join(target:installdir(), opt and opt.bindir or "bin") + local binarydir = target:bindir() os.mkdir(binarydir) os.vcp(target:targetfile(), binarydir) -- install libraries - local librarydir = path.join(target:installdir(), opt and opt.libdir or "lib") + local librarydir = target:libdir() os.mkdir(librarydir) -- install the dependent shared (*.so) target @@ -110,7 +110,7 @@ end function install_shared(target, opt) -- install libraries - local librarydir = path.join(target:installdir(), opt and opt.libdir or "lib") + local librarydir = target:libdir() os.mkdir(librarydir) local targetfile = target:targetfile() if os.islink(targetfile) then @@ -142,7 +142,7 @@ end function install_static(target, opt) -- install libraries - local librarydir = path.join(target:installdir(), opt and opt.libdir or "lib") + local librarydir = target:libdir() os.mkdir(librarydir) os.vcp(target:targetfile(), librarydir) diff --git a/xmake/modules/target/action/install/windows.lua b/xmake/modules/target/action/install/windows.lua index d7b71387c..7474f1411 100644 --- a/xmake/modules/target/action/install/windows.lua +++ b/xmake/modules/target/action/install/windows.lua @@ -22,16 +22,14 @@ import("core.base.option") import("lib.detect.find_file") --- get install directory -function _get_installdir(target) - local installdir = assert(target:installdir(), "please use `xmake install -o installdir` or `set_installdir` to set install directory on windows.") - return installdir +-- check install directory +function _check_installdir(installdir) + return assert(installdir, "please use `xmake install -o installdir` or `set_installdir` to set install directory on windows.") end -- install headers function _install_headers(target, opt) - local installdir = _get_installdir(target) - local includedir = path.join(installdir, opt and opt.includedir or "include") + local includedir = _check_installdir(target:includedir()) os.mkdir(includedir) local srcheaders, dstheaders = target:headerfiles(includedir, {installonly = true}) if srcheaders and dstheaders then @@ -115,8 +113,7 @@ end function install_shared(target, opt) -- install dll library to the binary directory - local installdir = _get_installdir(target) - local binarydir = path.join(installdir, opt and opt.bindir or "bin") + local binarydir = _check_installdir(target:bindir()) os.mkdir(binarydir) os.vcp(target:targetfile(), binarydir) os.trycp(target:symbolfile(), binarydir) @@ -124,7 +121,7 @@ function install_shared(target, opt) -- install *.lib for shared/windows (*.dll) target -- @see https://github.com/xmake-io/xmake/issues/714 local targetfile = target:targetfile() - local librarydir = path.join(target:installdir(), opt and opt.libdir or "lib") + local librarydir = _check_installdir(target:libdir()) local targetfile_lib = path.join(path.directory(targetfile), path.basename(targetfile) .. (target:is_plat("mingw") and ".dll.a" or ".lib")) if os.isfile(targetfile_lib) then os.mkdir(librarydir) @@ -142,8 +139,7 @@ end function install_static(target, opt) -- install library - local installdir = _get_installdir(target) - local librarydir = path.join(installdir, opt and opt.libdir or "lib") + local librarydir = _check_installdir(target:libdir()) os.mkdir(librarydir) os.vcp(target:targetfile(), librarydir) os.trycp(target:symbolfile(), librarydir) -- cgit v1.3.1 From fd5e83fd340b9d610392d6432cd652813819c7d3 Mon Sep 17 00:00:00 2001 From: ruki Date: Fri, 12 Jul 2024 00:55:12 +0800 Subject: improve uninstall dir --- xmake/modules/target/action/uninstall/unix.lua | 10 +++++----- xmake/modules/target/action/uninstall/windows.lua | 10 +++++----- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/xmake/modules/target/action/uninstall/unix.lua b/xmake/modules/target/action/uninstall/unix.lua index ce14c2c7b..835197228 100644 --- a/xmake/modules/target/action/uninstall/unix.lua +++ b/xmake/modules/target/action/uninstall/unix.lua @@ -23,7 +23,7 @@ import("private.action.clean.remove_files") -- uninstall headers function _uninstall_headers(target, opt) - local includedir = path.join(target:installdir(), opt and opt.includedir or "include") + local includedir = target:includedir() local _, dstheaders = target:headerfiles(includedir, {installonly = true}) for _, dstheader in ipairs(dstheaders) do remove_files(dstheader, {emptydir = true}) @@ -69,12 +69,12 @@ end function uninstall_binary(target, opt) -- remove the target file - local binarydir = path.join(target:installdir(), opt and opt.bindir or "bin") + local binarydir = target:bindir() os.vrm(path.join(binarydir, path.filename(target:targetfile()))) -- remove the dependent shared (*.so) target -- @see https://github.com/xmake-io/xmake/issues/961 - local librarydir = path.join(target:installdir(), opt and opt.libdir or "lib") + local librarydir = target:libdir() for _, dep in ipairs(target:orderdeps()) do if dep:kind() == "shared" then os.vrm(path.join(librarydir, path.filename(dep:targetfile()))) @@ -90,7 +90,7 @@ end function uninstall_shared(target, opt) -- remove the target file - local librarydir = path.join(target:installdir(), opt and opt.libdir or "lib") + local librarydir = target:libdir() local targetfile = path.join(librarydir, path.filename(target:targetfile())) if os.islink(targetfile) then local targetfile_with_soname = os.readlink(targetfile) @@ -119,7 +119,7 @@ end function uninstall_static(target, opt) -- remove the target file - local librarydir = path.join(target:installdir(), opt and opt.libdir or "lib") + local librarydir = target:libdir() os.vrm(path.join(librarydir, path.filename(target:targetfile()))) -- remove headers from the include directory diff --git a/xmake/modules/target/action/uninstall/windows.lua b/xmake/modules/target/action/uninstall/windows.lua index 338f8c707..5dcc01b5e 100644 --- a/xmake/modules/target/action/uninstall/windows.lua +++ b/xmake/modules/target/action/uninstall/windows.lua @@ -20,7 +20,7 @@ -- uninstall headers function _uninstall_headers(target, opt) - local includedir = path.join(target:installdir(), opt and opt.includedir or "include") + local includedir = target:includedir() local _, dstheaders = target:headerfiles(includedir, {installonly = true}) for _, dstheader in ipairs(dstheaders) do os.vrm(dstheader) @@ -54,7 +54,7 @@ end function uninstall_binary(target, opt) -- remove the target file - local binarydir = path.join(target:installdir(), opt and opt.bindir or "bin") + local binarydir = target:bindir() os.vrm(path.join(binarydir, path.filename(target:targetfile()))) os.tryrm(path.join(binarydir, path.filename(target:symbolfile()))) @@ -75,14 +75,14 @@ end function uninstall_shared(target, opt) -- remove the target file - local binarydir = path.join(target:installdir(), opt and opt.bindir or "bin") + local binarydir = target:bindir() os.vrm(path.join(binarydir, path.filename(target:targetfile()))) os.tryrm(path.join(binarydir, path.filename(target:symbolfile()))) -- remove *.lib for shared/windows (*.dll) target -- @see https://github.com/xmake-io/xmake/issues/714 local targetfile = target:targetfile() - local librarydir = path.join(target:installdir(), opt and opt.libdir or "lib") + local librarydir = target:libdir() os.vrm(path.join(librarydir, path.basename(targetfile) .. (target:is_plat("mingw") and ".dll.a" or ".lib"))) -- remove headers from the include directory @@ -96,7 +96,7 @@ end function uninstall_static(target, opt) -- remove the target file - local librarydir = path.join(target:installdir(), opt and opt.libdir or "lib") + local librarydir = target:libdir() os.vrm(path.join(librarydir, path.filename(target:targetfile()))) os.tryrm(path.join(librarydir, path.filename(target:symbolfile()))) -- cgit v1.3.1 From 30f574369dd606d4eb03e10d35f972d725ad074d Mon Sep 17 00:00:00 2001 From: ruki Date: Fri, 12 Jul 2024 00:55:55 +0800 Subject: rename var name --- xmake/modules/target/action/install/unix.lua | 36 ++++++++++----------- xmake/modules/target/action/install/windows.lua | 38 +++++++++++------------ xmake/modules/target/action/uninstall/unix.lua | 26 ++++++++-------- xmake/modules/target/action/uninstall/windows.lua | 30 +++++++++--------- 4 files changed, 65 insertions(+), 65 deletions(-) diff --git a/xmake/modules/target/action/install/unix.lua b/xmake/modules/target/action/install/unix.lua index 5b4507622..dc1354519 100644 --- a/xmake/modules/target/action/install/unix.lua +++ b/xmake/modules/target/action/install/unix.lua @@ -81,13 +81,13 @@ end function install_binary(target, opt) -- install binary - local binarydir = target:bindir() - os.mkdir(binarydir) - os.vcp(target:targetfile(), binarydir) + local bindir = target:bindir() + os.mkdir(bindir) + os.vcp(target:targetfile(), bindir) -- install libraries - local librarydir = target:libdir() - os.mkdir(librarydir) + local libdir = target:libdir() + os.mkdir(libdir) -- install the dependent shared (*.so) target -- @see https://github.com/xmake-io/xmake/issues/961 @@ -95,23 +95,23 @@ function install_binary(target, opt) if dep:kind() == "shared" then local depfile = dep:targetfile() if os.isfile(depfile) then - os.vcp(depfile, librarydir) + os.vcp(depfile, libdir) end end -- install all shared libraries in packages in all deps - _install_shared_for_packages(dep, librarydir) + _install_shared_for_packages(dep, libdir) end -- install shared libraries for all packages - _install_shared_for_packages(target, librarydir) + _install_shared_for_packages(target, libdir) end -- install shared library function install_shared(target, opt) -- install libraries - local librarydir = target:libdir() - os.mkdir(librarydir) + local libdir = target:libdir() + os.mkdir(libdir) local targetfile = target:targetfile() if os.islink(targetfile) then local targetfile_with_soname = os.readlink(targetfile) @@ -123,16 +123,16 @@ function install_shared(target, opt) if not path.is_absolute(targetfile_with_version) then targetfile_with_version = path.join(target:targetdir(), targetfile_with_version) end - os.vcp(targetfile_with_version, librarydir, {symlink = true, force = true}) + os.vcp(targetfile_with_version, libdir, {symlink = true, force = true}) end - os.vcp(targetfile_with_soname, librarydir, {symlink = true, force = true}) - os.vcp(targetfile, librarydir, {symlink = true, force = true}) + os.vcp(targetfile_with_soname, libdir, {symlink = true, force = true}) + os.vcp(targetfile, libdir, {symlink = true, force = true}) else - os.vcp(targetfile, librarydir) + os.vcp(targetfile, libdir) end -- install shared libraries for all packages - _install_shared_for_packages(target, librarydir) + _install_shared_for_packages(target, libdir) -- install headers _install_headers(target, opt) @@ -142,9 +142,9 @@ end function install_static(target, opt) -- install libraries - local librarydir = target:libdir() - os.mkdir(librarydir) - os.vcp(target:targetfile(), librarydir) + local libdir = target:libdir() + os.mkdir(libdir) + os.vcp(target:targetfile(), libdir) -- install headers _install_headers(target, opt) diff --git a/xmake/modules/target/action/install/windows.lua b/xmake/modules/target/action/install/windows.lua index 7474f1411..c52c1c934 100644 --- a/xmake/modules/target/action/install/windows.lua +++ b/xmake/modules/target/action/install/windows.lua @@ -83,10 +83,10 @@ function install_binary(target, opt) -- install binary local installdir = _get_installdir(target) - local binarydir = path.join(installdir, opt and opt.bindir or "bin") - os.mkdir(binarydir) - os.vcp(target:targetfile(), binarydir) - os.trycp(target:symbolfile(), binarydir) + local bindir = path.join(installdir, opt and opt.bindir or "bin") + os.mkdir(bindir) + os.vcp(target:targetfile(), bindir) + os.trycp(target:symbolfile(), bindir) -- install the dependent shared/windows (*.dll) target -- @see https://github.com/xmake-io/xmake/issues/961 @@ -96,40 +96,40 @@ function install_binary(target, opt) local depfile = dep:targetfile() if os.isfile(depfile) then if not _g.installed_dllfiles[depfile] then - os.vcp(depfile, binarydir) + os.vcp(depfile, bindir) _g.installed_dllfiles[depfile] = true end end end -- install all shared libraries in packages in all deps - _install_shared_for_packages(dep, binarydir) + _install_shared_for_packages(dep, bindir) end -- install shared libraries for all packages - _install_shared_for_packages(target, binarydir) + _install_shared_for_packages(target, bindir) end -- install shared library function install_shared(target, opt) -- install dll library to the binary directory - local binarydir = _check_installdir(target:bindir()) - os.mkdir(binarydir) - os.vcp(target:targetfile(), binarydir) - os.trycp(target:symbolfile(), binarydir) + local bindir = _check_installdir(target:bindir()) + os.mkdir(bindir) + os.vcp(target:targetfile(), bindir) + os.trycp(target:symbolfile(), bindir) -- install *.lib for shared/windows (*.dll) target -- @see https://github.com/xmake-io/xmake/issues/714 local targetfile = target:targetfile() - local librarydir = _check_installdir(target:libdir()) + local libdir = _check_installdir(target:libdir()) local targetfile_lib = path.join(path.directory(targetfile), path.basename(targetfile) .. (target:is_plat("mingw") and ".dll.a" or ".lib")) if os.isfile(targetfile_lib) then - os.mkdir(librarydir) - os.vcp(targetfile_lib, librarydir) + os.mkdir(libdir) + os.vcp(targetfile_lib, libdir) end -- install shared libraries for all packages - _install_shared_for_packages(target, binarydir) + _install_shared_for_packages(target, bindir) -- install headers _install_headers(target, opt) @@ -139,10 +139,10 @@ end function install_static(target, opt) -- install library - local librarydir = _check_installdir(target:libdir()) - os.mkdir(librarydir) - os.vcp(target:targetfile(), librarydir) - os.trycp(target:symbolfile(), librarydir) + local libdir = _check_installdir(target:libdir()) + os.mkdir(libdir) + os.vcp(target:targetfile(), libdir) + os.trycp(target:symbolfile(), libdir) -- install headers _install_headers(target, opt) diff --git a/xmake/modules/target/action/uninstall/unix.lua b/xmake/modules/target/action/uninstall/unix.lua index 835197228..4615be820 100644 --- a/xmake/modules/target/action/uninstall/unix.lua +++ b/xmake/modules/target/action/uninstall/unix.lua @@ -69,38 +69,38 @@ end function uninstall_binary(target, opt) -- remove the target file - local binarydir = target:bindir() - os.vrm(path.join(binarydir, path.filename(target:targetfile()))) + local bindir = target:bindir() + os.vrm(path.join(bindir, path.filename(target:targetfile()))) -- remove the dependent shared (*.so) target -- @see https://github.com/xmake-io/xmake/issues/961 - local librarydir = target:libdir() + local libdir = target:libdir() for _, dep in ipairs(target:orderdeps()) do if dep:kind() == "shared" then - os.vrm(path.join(librarydir, path.filename(dep:targetfile()))) + os.vrm(path.join(libdir, path.filename(dep:targetfile()))) end - _uninstall_shared_for_packages(dep, librarydir) + _uninstall_shared_for_packages(dep, libdir) end -- uninstall shared libraries for packages - _uninstall_shared_for_packages(target, librarydir) + _uninstall_shared_for_packages(target, libdir) end -- uninstall shared library function uninstall_shared(target, opt) -- remove the target file - local librarydir = target:libdir() - local targetfile = path.join(librarydir, path.filename(target:targetfile())) + local libdir = target:libdir() + local targetfile = path.join(libdir, path.filename(target:targetfile())) if os.islink(targetfile) then local targetfile_with_soname = os.readlink(targetfile) if not path.is_absolute(targetfile_with_soname) then - targetfile_with_soname = path.join(librarydir, targetfile_with_soname) + targetfile_with_soname = path.join(libdir, targetfile_with_soname) end if os.islink(targetfile_with_soname) then local targetfile_with_version = os.readlink(targetfile_with_soname) if not path.is_absolute(targetfile_with_version) then - targetfile_with_version = path.join(librarydir, targetfile_with_version) + targetfile_with_version = path.join(libdir, targetfile_with_version) end os.vrm(targetfile_with_version) end @@ -112,15 +112,15 @@ function uninstall_shared(target, opt) _uninstall_headers(target, opt) -- uninstall shared libraries for packages - _uninstall_shared_for_packages(target, librarydir) + _uninstall_shared_for_packages(target, libdir) end -- uninstall static library function uninstall_static(target, opt) -- remove the target file - local librarydir = target:libdir() - os.vrm(path.join(librarydir, path.filename(target:targetfile()))) + local libdir = target:libdir() + os.vrm(path.join(libdir, path.filename(target:targetfile()))) -- remove headers from the include directory _uninstall_headers(target, opt) diff --git a/xmake/modules/target/action/uninstall/windows.lua b/xmake/modules/target/action/uninstall/windows.lua index 5dcc01b5e..2982bbee1 100644 --- a/xmake/modules/target/action/uninstall/windows.lua +++ b/xmake/modules/target/action/uninstall/windows.lua @@ -54,51 +54,51 @@ end function uninstall_binary(target, opt) -- remove the target file - local binarydir = target:bindir() - os.vrm(path.join(binarydir, path.filename(target:targetfile()))) - os.tryrm(path.join(binarydir, path.filename(target:symbolfile()))) + local bindir = target:bindir() + os.vrm(path.join(bindir, path.filename(target:targetfile()))) + os.tryrm(path.join(bindir, path.filename(target:symbolfile()))) -- remove the dependent shared/windows (*.dll) target -- @see https://github.com/xmake-io/xmake/issues/961 for _, dep in ipairs(target:orderdeps()) do if dep:kind() == "shared" then - os.vrm(path.join(binarydir, path.filename(dep:targetfile()))) + os.vrm(path.join(bindir, path.filename(dep:targetfile()))) end - _uninstall_shared_for_packages(dep, binarydir) + _uninstall_shared_for_packages(dep, bindir) end -- uninstall shared libraries for packages - _uninstall_shared_for_packages(target, binarydir) + _uninstall_shared_for_packages(target, bindir) end -- uninstall shared library function uninstall_shared(target, opt) -- remove the target file - local binarydir = target:bindir() - os.vrm(path.join(binarydir, path.filename(target:targetfile()))) - os.tryrm(path.join(binarydir, path.filename(target:symbolfile()))) + local bindir = target:bindir() + os.vrm(path.join(bindir, path.filename(target:targetfile()))) + os.tryrm(path.join(bindir, path.filename(target:symbolfile()))) -- remove *.lib for shared/windows (*.dll) target -- @see https://github.com/xmake-io/xmake/issues/714 local targetfile = target:targetfile() - local librarydir = target:libdir() - os.vrm(path.join(librarydir, path.basename(targetfile) .. (target:is_plat("mingw") and ".dll.a" or ".lib"))) + local libdir = target:libdir() + os.vrm(path.join(libdir, path.basename(targetfile) .. (target:is_plat("mingw") and ".dll.a" or ".lib"))) -- remove headers from the include directory _uninstall_headers(target, opt) -- uninstall shared libraries for packages - _uninstall_shared_for_packages(target, binarydir) + _uninstall_shared_for_packages(target, bindir) end -- uninstall static library function uninstall_static(target, opt) -- remove the target file - local librarydir = target:libdir() - os.vrm(path.join(librarydir, path.filename(target:targetfile()))) - os.tryrm(path.join(librarydir, path.filename(target:symbolfile()))) + local libdir = target:libdir() + os.vrm(path.join(libdir, path.filename(target:targetfile()))) + os.tryrm(path.join(libdir, path.filename(target:symbolfile()))) -- remove headers from the include directory _uninstall_headers(target, opt) -- cgit v1.3.1 From 6e801fdf314b2ee16e08e8bb8da8aa70c362eb88 Mon Sep 17 00:00:00 2001 From: ruki Date: Fri, 12 Jul 2024 22:41:16 +0800 Subject: improve xpack installdir --- xmake/plugins/pack/batchcmds.lua | 55 ++++++++++++++++++++++++++++++---------- 1 file changed, 41 insertions(+), 14 deletions(-) diff --git a/xmake/plugins/pack/batchcmds.lua b/xmake/plugins/pack/batchcmds.lua index 8091134b2..fe3af9cc4 100644 --- a/xmake/plugins/pack/batchcmds.lua +++ b/xmake/plugins/pack/batchcmds.lua @@ -23,6 +23,33 @@ import("core.base.option") import("utils.archive") import("private.utils.batchcmds") +function _get_target_bindir(package, target) + local bindir = package:bindir() + local prefixdir = target:prefixdir() + if prefixdir then + bindir = path.join(package:install_rootdir(), prefixdir, target:extraconf("prefixdir", prefixdir, "bindir")) + end + return path.normalize(bindir) +end + +function _get_target_libdir(package, target) + local libdir = package:libdir() + local prefixdir = target:prefixdir() + if prefixdir then + libdir = path.join(package:install_rootdir(), prefixdir, target:extraconf("prefixdir", prefixdir, "libdir")) + end + return path.normalize(libdir) +end + +function _get_target_includedir(package, target) + local includedir = package:includedir() + local prefixdir = target:prefixdir() + if prefixdir then + includedir = path.join(package:install_rootdir(), prefixdir, target:extraconf("prefixdir", prefixdir, "includedir")) + end + return path.normalize(includedir) +end + -- install headers function _install_headers(target, batchcmds_, includedir) local srcheaders, dstheaders = target:headerfiles(includedir, {installonly = true}) @@ -100,7 +127,7 @@ end -- on install binary target command function _on_target_installcmd_binary(target, batchcmds_, opt) local package = opt.package - local bindir = package:bindir() + local bindir = _get_target_bindir(package, target) -- install target file batchcmds_:cp(target:targetfile(), path.join(bindir, target:filename())) @@ -132,9 +159,9 @@ end -- on install shared target command function _on_target_installcmd_shared(target, batchcmds_, opt) local package = opt.package - local bindir = package:bindir() - local libdir = package:libdir() - local includedir = package:includedir() + local bindir = _get_target_bindir(package, target) + local libdir = _get_target_libdir(package, target) + local includedir = _get_target_includedir(package, target) -- install target file batchcmds_:cp(target:targetfile(), path.join(bindir, target:filename())) @@ -161,8 +188,8 @@ end -- on install static target command function _on_target_installcmd_static(target, batchcmds_, opt) local package = opt.package - local libdir = package:libdir() - local includedir = package:includedir() + local libdir = _get_target_libdir(package, target) + local includedir = _get_target_includedir(package, target) -- install target file batchcmds_:cp(target:targetfile(), path.join(libdir, target:filename())) @@ -177,7 +204,7 @@ end -- on install headeronly target command function _on_target_installcmd_headeronly(target, batchcmds_, opt) local package = opt.package - local includedir = package:includedir() + local includedir = _get_target_includedir(package, target) -- install headers _install_headers(target, batchcmds_, includedir) @@ -225,7 +252,7 @@ end -- on uninstall binary target command function _on_target_uninstallcmd_binary(target, batchcmds_, opt) local package = opt.package - local bindir = package:bindir() + local bindir = _get_target_bindir(package, target) -- uninstall target file batchcmds_:rm(path.join(bindir, target:filename()), {emptydirs = true}) @@ -247,9 +274,9 @@ end -- on uninstall shared target command function _on_target_uninstallcmd_shared(target, batchcmds_, opt) local package = opt.package - local bindir = package:bindir() - local libdir = package:libdir() - local includedir = package:includedir() + local bindir = _get_target_bindir(package, target) + local libdir = _get_target_libdir(package, target) + local includedir = _get_target_includedir(package, target) -- uninstall target file batchcmds_:rm(path.join(bindir, target:filename()), {emptydirs = true}) @@ -270,8 +297,8 @@ end -- on uninstall static target command function _on_target_uninstallcmd_static(target, batchcmds_, opt) local package = opt.package - local libdir = package:libdir() - local includedir = package:includedir() + local libdir = _get_target_libdir(package, target) + local includedir = _get_target_includedir(package, target) -- uninstall target file batchcmds_:rm(path.join(libdir, target:filename()), {emptydirs = true}) @@ -284,7 +311,7 @@ end -- on uninstall headeronly target command function _on_target_uninstallcmd_headeronly(target, batchcmds_, opt) local package = opt.package - local includedir = package:includedir() + local includedir = _get_target_includedir(package, target) _uninstall_headers(target, batchcmds_, includedir) end -- cgit v1.3.1 From a4898abe2815b402d9b299c002fe20834488561b Mon Sep 17 00:00:00 2001 From: ruki Date: Fri, 12 Jul 2024 22:42:18 +0800 Subject: fix xpack archive --- xmake/plugins/pack/archive.lua | 1 + 1 file changed, 1 insertion(+) diff --git a/xmake/plugins/pack/archive.lua b/xmake/plugins/pack/archive.lua index dd1861ca4..5d59c05fb 100644 --- a/xmake/plugins/pack/archive.lua +++ b/xmake/plugins/pack/archive.lua @@ -55,6 +55,7 @@ function _pack_archive(package) local oldir = os.cd(rootdir) local archivefiles = os.files("**") os.cd(oldir) + os.tryrm(package:outputfile()) archive.archive(path.absolute(package:outputfile()), archivefiles, {curdir = rootdir, compress = "best"}) end -- cgit v1.3.1 From 7f93559f094dbb4eea62d1ea30c4728b9f2b24af Mon Sep 17 00:00:00 2001 From: ruki Date: Fri, 12 Jul 2024 22:45:15 +0800 Subject: fix headerfile outputdir --- xmake/core/project/target.lua | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/xmake/core/project/target.lua b/xmake/core/project/target.lua index a404f04bd..62cf2061c 100644 --- a/xmake/core/project/target.lua +++ b/xmake/core/project/target.lua @@ -2052,13 +2052,12 @@ function _instance:headerfiles(outputdir, opt) return end - local headerdir = outputdir - if not headerdir then - if self:installdir() then - headerdir = path.join(self:installdir(), "include") + if not outputdir then + if self:includedir() then + outputdir = self:includedir() end end - return match_copyfiles(self, "headerfiles", headerdir, {copyfiles = headerfiles}) + return match_copyfiles(self, "headerfiles", outputdir, {copyfiles = headerfiles}) end -- get the configuration files -- cgit v1.3.1 From 98950182b26e2a52b3eb8d6aea318d26f04d7e79 Mon Sep 17 00:00:00 2001 From: ruki Date: Fri, 12 Jul 2024 22:49:32 +0800 Subject: improve to install files --- xmake/core/project/target.lua | 7 ++-- xmake/plugins/pack/batchcmds.lua | 82 ++++++++++++++++++++++++++++------------ 2 files changed, 61 insertions(+), 28 deletions(-) diff --git a/xmake/core/project/target.lua b/xmake/core/project/target.lua index 62cf2061c..e19ea07c5 100644 --- a/xmake/core/project/target.lua +++ b/xmake/core/project/target.lua @@ -2036,7 +2036,7 @@ end -- get the header files function _instance:headerfiles(outputdir, opt) opt = opt or {} - local headerfiles = self:get("headerfiles") + local headerfiles = self:get("headerfiles", opt) or {} -- add_headerfiles("src/*.h", {install = false}) -- @see https://github.com/xmake-io/xmake/issues/2577 if opt.installonly then @@ -2071,8 +2071,9 @@ function _instance:configfiles(outputdir) end -- get the install files -function _instance:installfiles(outputdir) - return match_copyfiles(self, "installfiles", outputdir or self:installdir()) +function _instance:installfiles(outputdir, opt) + local installfiles = self:get("installfiles", opt) or {} + return match_copyfiles(self, "installfiles", outputdir or self:installdir(), {copyfiles = installfiles}) end -- get the extra files diff --git a/xmake/plugins/pack/batchcmds.lua b/xmake/plugins/pack/batchcmds.lua index fe3af9cc4..0c2b07b9a 100644 --- a/xmake/plugins/pack/batchcmds.lua +++ b/xmake/plugins/pack/batchcmds.lua @@ -27,7 +27,7 @@ function _get_target_bindir(package, target) local bindir = package:bindir() local prefixdir = target:prefixdir() if prefixdir then - bindir = path.join(package:install_rootdir(), prefixdir, target:extraconf("prefixdir", prefixdir, "bindir")) + bindir = path.join(package:installdir(), prefixdir, target:extraconf("prefixdir", prefixdir, "bindir")) end return path.normalize(bindir) end @@ -36,7 +36,7 @@ function _get_target_libdir(package, target) local libdir = package:libdir() local prefixdir = target:prefixdir() if prefixdir then - libdir = path.join(package:install_rootdir(), prefixdir, target:extraconf("prefixdir", prefixdir, "libdir")) + libdir = path.join(package:installdir(), prefixdir, target:extraconf("prefixdir", prefixdir, "libdir")) end return path.normalize(libdir) end @@ -45,14 +45,24 @@ function _get_target_includedir(package, target) local includedir = package:includedir() local prefixdir = target:prefixdir() if prefixdir then - includedir = path.join(package:install_rootdir(), prefixdir, target:extraconf("prefixdir", prefixdir, "includedir")) + includedir = path.join(package:installdir(), prefixdir, target:extraconf("prefixdir", prefixdir, "includedir")) end return path.normalize(includedir) end +function _get_target_installdir(package, target) + local installdir = package:installdir() + local prefixdir = target:prefixdir() + if prefixdir then + installdir = path.join(package:installdir(), prefixdir) + end + return path.normalize(installdir) +end + -- install headers -function _install_headers(target, batchcmds_, includedir) - local srcheaders, dstheaders = target:headerfiles(includedir, {installonly = true}) +function _install_headers(target, batchcmds_, opt) + local package = opt.package + local srcheaders, dstheaders = target:headerfiles(_get_target_includedir(package, target), {installonly = true}) if srcheaders and dstheaders then local i = 1 for _, srcheader in ipairs(srcheaders) do @@ -63,6 +73,19 @@ function _install_headers(target, batchcmds_, includedir) i = i + 1 end end + for _, dep in ipairs(target:orderdeps()) do + local srcheaders, dstheaders = dep:headerfiles(_get_target_includedir(package, dep), {installonly = true, interface = true}) + if srcheaders and dstheaders then + local i = 1 + for _, srcheader in ipairs(srcheaders) do + local dstheader = dstheaders[i] + if dstheader then + batchcmds_:cp(srcheader, dstheader) + end + i = i + 1 + end + end + end end -- install shared libraries for package @@ -94,11 +117,18 @@ function _install_shared_for_packages(target, batchcmds_, outputdir) end -- uninstall headers -function _uninstall_headers(target, batchcmds_, includedir) - local _, dstheaders = target:headerfiles(includedir, {installonly = true}) +function _uninstall_headers(target, batchcmds_, opt) + local package = opt.package + local _, dstheaders = target:headerfiles(_get_target_includedir(package, target), {installonly = true}) for _, dstheader in ipairs(dstheaders) do batchcmds_:rm(dstheader, {emptydirs = true}) end + for _, dep in ipairs(target:orderdeps()) do + local _, dstheaders = dep:headerfiles(_get_target_includedir(package, dep), {installonly = true, interface = true}) + for _, dstheader in ipairs(dstheaders) do + batchcmds_:rm(dstheader, {emptydirs = true}) + end + end end -- uninstall shared libraries for package @@ -161,7 +191,6 @@ function _on_target_installcmd_shared(target, batchcmds_, opt) local package = opt.package local bindir = _get_target_bindir(package, target) local libdir = _get_target_libdir(package, target) - local includedir = _get_target_includedir(package, target) -- install target file batchcmds_:cp(target:targetfile(), path.join(bindir, target:filename())) @@ -182,14 +211,13 @@ function _on_target_installcmd_shared(target, batchcmds_, opt) _install_shared_for_packages(target, batchcmds_, bindir) -- install headers - _install_headers(target, batchcmds_, includedir) + _install_headers(target, batchcmds_, opt) end -- on install static target command function _on_target_installcmd_static(target, batchcmds_, opt) local package = opt.package local libdir = _get_target_libdir(package, target) - local includedir = _get_target_includedir(package, target) -- install target file batchcmds_:cp(target:targetfile(), path.join(libdir, target:filename())) @@ -198,16 +226,12 @@ function _on_target_installcmd_static(target, batchcmds_, opt) end -- install headers - _install_headers(target, batchcmds_, includedir) + _install_headers(target, batchcmds_, opt) end -- on install headeronly target command function _on_target_installcmd_headeronly(target, batchcmds_, opt) - local package = opt.package - local includedir = _get_target_includedir(package, target) - - -- install headers - _install_headers(target, batchcmds_, includedir) + _install_headers(target, batchcmds_, opt) end -- on install source target command @@ -243,10 +267,16 @@ function _on_target_installcmd(target, batchcmds_, opt) end -- install target files - local srcfiles, dstfiles = target:installfiles(package:installdir()) + local srcfiles, dstfiles = target:installfiles(_get_target_installdir(package, target)) for idx, srcfile in ipairs(srcfiles) do batchcmds_:cp(srcfile, dstfiles[idx]) end + for _, dep in ipairs(target:orderdeps()) do + local srcfiles, dstfiles = dep:installfiles(_get_target_installdir(package, dep), {interface = true}) + for idx, srcfile in ipairs(srcfiles) do + batchcmds_:cp(srcfile, dstfiles[idx]) + end + end end -- on uninstall binary target command @@ -276,7 +306,6 @@ function _on_target_uninstallcmd_shared(target, batchcmds_, opt) local package = opt.package local bindir = _get_target_bindir(package, target) local libdir = _get_target_libdir(package, target) - local includedir = _get_target_includedir(package, target) -- uninstall target file batchcmds_:rm(path.join(bindir, target:filename()), {emptydirs = true}) @@ -288,7 +317,7 @@ function _on_target_uninstallcmd_shared(target, batchcmds_, opt) batchcmds_:rm(path.join(libdir, path.basename(targetfile) .. (target:is_plat("mingw") and ".dll.a" or ".lib")), {emptydirs = true}) -- remove headers from the include directory - _uninstall_headers(target, batchcmds_, includedir) + _uninstall_headers(target, batchcmds_, opt) -- uninstall shared libraries for packages _uninstall_shared_for_packages(target, batchcmds_, bindir) @@ -298,21 +327,18 @@ end function _on_target_uninstallcmd_static(target, batchcmds_, opt) local package = opt.package local libdir = _get_target_libdir(package, target) - local includedir = _get_target_includedir(package, target) -- uninstall target file batchcmds_:rm(path.join(libdir, target:filename()), {emptydirs = true}) batchcmds_:rm(path.join(libdir, path.filename(target:symbolfile())), {emptydirs = true}) -- remove headers from the include directory - _uninstall_headers(target, batchcmds_, includedir) + _uninstall_headers(target, batchcmds_, opt) end -- on uninstall headeronly target command function _on_target_uninstallcmd_headeronly(target, batchcmds_, opt) - local package = opt.package - local includedir = _get_target_includedir(package, target) - _uninstall_headers(target, batchcmds_, includedir) + _uninstall_headers(target, batchcmds_, opt) end -- on uninstall source target command @@ -341,10 +367,16 @@ function _on_target_uninstallcmd(target, batchcmds_, opt) end -- uninstall target files - local _, dstfiles = target:installfiles(package:installdir()) + local _, dstfiles = target:installfiles(_get_target_installdir(package, target)) for _, dstfile in ipairs(dstfiles) do batchcmds_:rm(dstfile, {emptydirs = true}) end + for _, dep in ipairs(target:orderdeps()) do + local _, dstfiles = dep:installfiles(_get_target_installdir(package, dep), {interface = true}) + for _, dstfile in ipairs(dstfiles) do + batchcmds_:rm(dstfile, {emptydirs = true}) + end + end end -- get build commands from targets -- cgit v1.3.1 From aa6f60ff715cfa2e4b22345b54bd5ddc31ebef08 Mon Sep 17 00:00:00 2001 From: ruki Date: Fri, 12 Jul 2024 22:51:24 +0800 Subject: rename funcs --- xmake/plugins/pack/batchcmds.lua | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/xmake/plugins/pack/batchcmds.lua b/xmake/plugins/pack/batchcmds.lua index 0c2b07b9a..552f978cd 100644 --- a/xmake/plugins/pack/batchcmds.lua +++ b/xmake/plugins/pack/batchcmds.lua @@ -60,7 +60,7 @@ function _get_target_installdir(package, target) end -- install headers -function _install_headers(target, batchcmds_, opt) +function _install_target_headers(target, batchcmds_, opt) local package = opt.package local srcheaders, dstheaders = target:headerfiles(_get_target_includedir(package, target), {installonly = true}) if srcheaders and dstheaders then @@ -117,7 +117,7 @@ function _install_shared_for_packages(target, batchcmds_, outputdir) end -- uninstall headers -function _uninstall_headers(target, batchcmds_, opt) +function _uninstall_target_headers(target, batchcmds_, opt) local package = opt.package local _, dstheaders = target:headerfiles(_get_target_includedir(package, target), {installonly = true}) for _, dstheader in ipairs(dstheaders) do @@ -211,7 +211,7 @@ function _on_target_installcmd_shared(target, batchcmds_, opt) _install_shared_for_packages(target, batchcmds_, bindir) -- install headers - _install_headers(target, batchcmds_, opt) + _install_target_headers(target, batchcmds_, opt) end -- on install static target command @@ -226,12 +226,12 @@ function _on_target_installcmd_static(target, batchcmds_, opt) end -- install headers - _install_headers(target, batchcmds_, opt) + _install_target_headers(target, batchcmds_, opt) end -- on install headeronly target command function _on_target_installcmd_headeronly(target, batchcmds_, opt) - _install_headers(target, batchcmds_, opt) + _install_target_headers(target, batchcmds_, opt) end -- on install source target command @@ -317,7 +317,7 @@ function _on_target_uninstallcmd_shared(target, batchcmds_, opt) batchcmds_:rm(path.join(libdir, path.basename(targetfile) .. (target:is_plat("mingw") and ".dll.a" or ".lib")), {emptydirs = true}) -- remove headers from the include directory - _uninstall_headers(target, batchcmds_, opt) + _uninstall_target_headers(target, batchcmds_, opt) -- uninstall shared libraries for packages _uninstall_shared_for_packages(target, batchcmds_, bindir) @@ -333,12 +333,12 @@ function _on_target_uninstallcmd_static(target, batchcmds_, opt) batchcmds_:rm(path.join(libdir, path.filename(target:symbolfile())), {emptydirs = true}) -- remove headers from the include directory - _uninstall_headers(target, batchcmds_, opt) + _uninstall_target_headers(target, batchcmds_, opt) end -- on uninstall headeronly target command function _on_target_uninstallcmd_headeronly(target, batchcmds_, opt) - _uninstall_headers(target, batchcmds_, opt) + _uninstall_target_headers(target, batchcmds_, opt) end -- on uninstall source target command -- cgit v1.3.1 From d116ef1a1c49549bb75549700744d72954845888 Mon Sep 17 00:00:00 2001 From: ruki Date: Sat, 13 Jul 2024 08:15:45 +0800 Subject: remove old install codes --- xmake/plugins/pack/batchcmds.lua | 106 ++++++++------------------------------- 1 file changed, 22 insertions(+), 84 deletions(-) diff --git a/xmake/plugins/pack/batchcmds.lua b/xmake/plugins/pack/batchcmds.lua index 552f978cd..fbbc933c3 100644 --- a/xmake/plugins/pack/batchcmds.lua +++ b/xmake/plugins/pack/batchcmds.lua @@ -21,6 +21,7 @@ -- imports import("core.base.option") import("utils.archive") +import("utils.symbols.depend", {alias = "get_depend_libraries"}) import("private.utils.batchcmds") function _get_target_bindir(package, target) @@ -88,32 +89,14 @@ function _install_target_headers(target, batchcmds_, opt) end end --- install shared libraries for package -function _install_shared_for_package(target, pkg, batchcmds_, outputdir) - _g.installed_dllfiles = _g.installed_dllfiles or {} - for _, dllpath in ipairs(table.wrap(pkg:get("libfiles"))) do - if dllpath:endswith(".dll") then - -- prevent packages using the same libfiles from overwriting each other - if not _g.installed_dllfiles[dllpath] then - local dllname = path.filename(dllpath) - batchcmds_:cp(dllpath, path.join(outputdir, dllname)) - _g.installed_dllfiles[dllpath] = true - end - end - end -end - --- install shared libraries for packages -function _install_shared_for_packages(target, batchcmds_, outputdir) - _g.installed_packages = _g.installed_packages or {} - for _, pkg in ipairs(target:orderpkgs()) do - if not _g.installed_packages[pkg:name()] then - if pkg:enabled() and pkg:get("libfiles") then - _install_shared_for_package(target, pkg, batchcmds_, outputdir) - end - _g.installed_packages[pkg:name()] = true - end - end +-- install target shared libraries +function _install_target_shared_libraries(target, batchcmds_, opt) + local package = opt.package + local bindir = _get_target_bindir(package, target) + local targetfile = target:targetfile() + local depend_libraries = get_depend_libraries(targetfile, {plat = target:plat(), arch = target:arch()}) + print(targetfile) + print(depend_libraries) end -- uninstall headers @@ -131,27 +114,8 @@ function _uninstall_target_headers(target, batchcmds_, opt) end end --- uninstall shared libraries for package -function _uninstall_shared_for_package(target, pkg, batchcmds_, outputdir) - for _, dllpath in ipairs(table.wrap(pkg:get("libfiles"))) do - if dllpath:endswith(".dll") then - local dllname = path.filename(dllpath) - batchcmds_:rm(path.join(outputdir, dllname), {emptydirs = true}) - end - end -end - --- uninstall shared libraries for packages -function _uninstall_shared_for_packages(target, batchcmds_, outputdir) - _g.uninstalled_packages = _g.uninstalled_packages or {} - for _, pkg in ipairs(target:orderpkgs()) do - if not _g.uninstalled_packages[pkg:name()] then - if pkg:enabled() and pkg:get("libfiles") then - _uninstall_shared_for_package(target, pkg, batchcmds_, outputdir) - end - _g.uninstalled_packages[pkg:name()] = true - end - end +-- uninstall target shared libraries +function _uninstall_target_shared_libraries(target, batchcmds_, opt) end -- on install binary target command @@ -165,25 +129,8 @@ function _on_target_installcmd_binary(target, batchcmds_, opt) batchcmds_:cp(target:symbolfile(), path.join(bindir, path.filename(target:symbolfile()))) end - -- install the dependent shared/windows (*.dll) target - -- @see https://github.com/xmake-io/xmake/issues/961 - _g.installed_dllfiles = _g.installed_dllfiles or {} - for _, dep in ipairs(target:orderdeps()) do - if dep:kind() == "shared" then - local depfile = dep:targetfile() - if os.isfile(depfile) then - if not _g.installed_dllfiles[depfile] then - batchcmds_:cp(depfile, path.join(bindir, path.filename(depfile))) - _g.installed_dllfiles[depfile] = true - end - end - end - -- install all shared libraries in packages in all deps - _install_shared_for_packages(dep, batchcmds_, bindir) - end - - -- install shared libraries for all packages - _install_shared_for_packages(target, batchcmds_, bindir) + -- install target shared libraries + _install_target_shared_libraries(target, batchcmds_, opt) end -- on install shared target command @@ -207,11 +154,11 @@ function _on_target_installcmd_shared(target, batchcmds_, opt) batchcmds_:cp(targetfile_lib, path.join(libdir, path.filename(targetfile_lib))) end - -- install shared libraries for all packages - _install_shared_for_packages(target, batchcmds_, bindir) - -- install headers _install_target_headers(target, batchcmds_, opt) + + -- install target shared libraries + _install_target_shared_libraries(target, batchcmds_, opt) end -- on install static target command @@ -288,17 +235,8 @@ function _on_target_uninstallcmd_binary(target, batchcmds_, opt) batchcmds_:rm(path.join(bindir, target:filename()), {emptydirs = true}) batchcmds_:rm(path.join(bindir, path.filename(target:symbolfile())), {emptydirs = true}) - -- remove the dependent shared/windows (*.dll) target - -- @see https://github.com/xmake-io/xmake/issues/961 - for _, dep in ipairs(target:orderdeps()) do - if dep:is_shared() then - batchcmds_:rm(path.join(bindir, path.filename(dep:targetfile())), {emptydirs = true}) - end - _uninstall_shared_for_packages(dep, batchcmds_, bindir) - end - - -- uninstall shared libraries for packages - _uninstall_shared_for_packages(target, batchcmds_, bindir) + -- uninstall target shared libraries + _uninstall_target_shared_libraries(target, batchcmds_, opt) end -- on uninstall shared target command @@ -311,16 +249,16 @@ function _on_target_uninstallcmd_shared(target, batchcmds_, opt) batchcmds_:rm(path.join(bindir, target:filename()), {emptydirs = true}) batchcmds_:rm(path.join(bindir, path.filename(target:symbolfile())), {emptydirs = true}) - -- remove *.lib for shared/windows (*.dll) target + -- uninstall *.lib for shared/windows (*.dll) target -- @see https://github.com/xmake-io/xmake/issues/714 local targetfile = target:targetfile() batchcmds_:rm(path.join(libdir, path.basename(targetfile) .. (target:is_plat("mingw") and ".dll.a" or ".lib")), {emptydirs = true}) - -- remove headers from the include directory + -- uninstall target headers _uninstall_target_headers(target, batchcmds_, opt) - -- uninstall shared libraries for packages - _uninstall_shared_for_packages(target, batchcmds_, bindir) + -- uninstall target shared libraries + _uninstall_target_shared_libraries(target, batchcmds_, opt) end -- on uninstall static target command -- cgit v1.3.1 From 89911e567bac54cc107cdb8620fb1dc296faaf24 Mon Sep 17 00:00:00 2001 From: ruki Date: Sat, 13 Jul 2024 23:14:53 +0800 Subject: improve to dump depends --- xmake/modules/utils/symbols/depend.lua | 103 ++++++--------------------------- 1 file changed, 19 insertions(+), 84 deletions(-) diff --git a/xmake/modules/utils/symbols/depend.lua b/xmake/modules/utils/symbols/depend.lua index 94ca4c7e1..c9101f6d0 100644 --- a/xmake/modules/utils/symbols/depend.lua +++ b/xmake/modules/utils/symbols/depend.lua @@ -38,16 +38,8 @@ function _get_all_depends_by_dumpbin(binaryfile, opt) for _, line in ipairs(result:split("\n")) do line = line:trim() if line:endswith(".dll") then - local dependfile - if os.isfile(line) then - dependfile = line - elseif os.isfile(path.join(binarydir, line)) then - dependfile = path.join(binarydir, line) - end - if dependfile then - depends = depends or {} - table.insert(depends, path.absolute(dependfile)) - end + depends = depends or {} + table.insert(depends, line) end end end @@ -76,51 +68,22 @@ function _get_all_depends_by_objdump(binaryfile, opt) if line:startswith("DLL Name:") then local filename = line:split(":")[2]:trim() if filename:endswith(".dll") then - local dependfile - if os.isfile(filename) then - dependfile = filename - elseif os.isfile(path.join(binarydir, filename)) then - dependfile = path.join(binarydir, filename) - end - if dependfile then - depends = depends or {} - table.insert(depends, path.absolute(dependfile)) - end + 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 - local dependfile - if os.exists(filename) then - dependfile = filename - elseif os.exists(path.join(binarydir, filename)) then - dependfile = path.join(binarydir, filename) - elseif filename:startswith("@rpath/") then -- TODO - filename = filename:sub(8) - if os.exists(path.join(binarydir, filename)) then - dependfile = path.join(binarydir, filename) - end - end - if dependfile then - depends = depends or {} - table.insert(depends, path.absolute(dependfile)) - end + 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 - local dependfile - if os.isfile(filename) then - dependfile = filename - elseif os.isfile(path.join(binarydir, filename)) then - dependfile = path.join(binarydir, filename) - end - if dependfile then - depends = depends or {} - table.insert(depends, path.absolute(dependfile)) - end + depends = depends or {} + table.insert(depends, filename) end end end @@ -153,21 +116,16 @@ function _get_all_depends_by_ldd(binaryfile, opt) local result = try { function () return os.iorunv(ldd.program, {binaryfile}) end } if result then for _, line in ipairs(result:split("\n")) do - line = line:split("=>")[2] or line + 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 - filename = filename:trim() - local dependfile - if os.isfile(filename) then - dependfile = filename - elseif os.isfile(path.join(binarydir, filename)) then - dependfile = path.join(binarydir, filename) - end - if dependfile then - depends = depends or {} - table.insert(depends, path.absolute(dependfile)) - end + depends = depends or {} + table.insert(depends, filename:trim()) end end end @@ -202,17 +160,8 @@ function _get_all_depends_by_readelf(binaryfile, opt) if line:find("NEEDED", 1, true) then local filename = line:match("Shared library: %[(.-)%]") if filename then - filename = filename:trim() - local dependfile - if os.isfile(filename) then - dependfile = filename - elseif os.isfile(path.join(binarydir, filename)) then - dependfile = path.join(binarydir, filename) - end - if dependfile then - depends = depends or {} - table.insert(depends, path.absolute(dependfile)) - end + depends = depends or {} + table.insert(depends, filename:trim()) end end end @@ -245,22 +194,8 @@ function _get_all_depends_by_otool(binaryfile, opt) for _, line in ipairs(result:split("\n")) do local filename = line:match(".-%.dylib") or line:match(".-%.framework") if filename then - filename = filename:trim() - local dependfile - if os.exists(filename) then - dependfile = filename - elseif os.exists(path.join(binarydir, filename)) then - dependfile = path.join(binarydir, filename) - elseif filename:startswith("@rpath/") then -- TODO - filename = filename:sub(8) - if os.exists(path.join(binarydir, filename)) then - dependfile = path.join(binarydir, filename) - end - end - if dependfile then - depends = depends or {} - table.insert(depends, path.absolute(dependfile)) - end + depends = depends or {} + table.insert(depends, filename:trim()) end end end -- cgit v1.3.1 From 1642d2209b46006ce083f5f45c943ab12f74339c Mon Sep 17 00:00:00 2001 From: ruki Date: Sun, 14 Jul 2024 00:01:51 +0800 Subject: improve to install libfiles in xpack --- xmake/plugins/pack/batchcmds.lua | 52 ++++++++++++++++++++++++++++++++++++---- 1 file changed, 48 insertions(+), 4 deletions(-) diff --git a/xmake/plugins/pack/batchcmds.lua b/xmake/plugins/pack/batchcmds.lua index fbbc933c3..5519658b3 100644 --- a/xmake/plugins/pack/batchcmds.lua +++ b/xmake/plugins/pack/batchcmds.lua @@ -20,6 +20,7 @@ -- imports import("core.base.option") +import("core.base.hashset") import("utils.archive") import("utils.symbols.depend", {alias = "get_depend_libraries"}) import("private.utils.batchcmds") @@ -89,14 +90,57 @@ function _install_target_headers(target, batchcmds_, opt) end end +function _get_target_package_libfiles(target, opt) + local libfiles = {} + 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) + end + end + end + end + -- we can only reserve used libraries + if target:is_binary() or target:is_shared() then + local depends = hashset.new() + local targetfile = target:targetfile() + local depend_libraries = get_depend_libraries(targetfile, {plat = target:plat(), arch = target:arch()}) + 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) + end + return libfiles +end + -- install target shared libraries function _install_target_shared_libraries(target, batchcmds_, opt) local package = opt.package local bindir = _get_target_bindir(package, target) - local targetfile = target:targetfile() - local depend_libraries = get_depend_libraries(targetfile, {plat = target:plat(), arch = target:arch()}) - print(targetfile) - print(depend_libraries) + + -- get all dependent shared libraries + local libfiles = {} + for _, dep in ipairs(target:orderdeps()) do + if dep:kind() == "shared" then + local depfile = dep:targetfile() + if os.isfile(depfile) then + table.insert(libfiles, depfile) + end + end + table.join2(libfiles, _get_target_package_libfiles(dep, {interface = true})) + end + table.join2(libfiles, _get_target_package_libfiles(target)) + + -- deduplicate libfiles, prevent packages using the same libfiles from overwriting each other + libfiles = table.unique(libfiles) + + -- do install + for _, libfile in ipairs(libfiles) do + local filename = path.filename(libfile) + batchcmds_:cp(libfile, path.join(bindir, filename)) + end end -- uninstall headers -- cgit v1.3.1 From c58ab2c62721a69b81a127578b88ab678f5dc112 Mon Sep 17 00:00:00 2001 From: ruki Date: Sun, 14 Jul 2024 00:06:45 +0800 Subject: improve uninstall in xpack --- xmake/plugins/pack/batchcmds.lua | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/xmake/plugins/pack/batchcmds.lua b/xmake/plugins/pack/batchcmds.lua index 5519658b3..08216b15e 100644 --- a/xmake/plugins/pack/batchcmds.lua +++ b/xmake/plugins/pack/batchcmds.lua @@ -160,6 +160,30 @@ end -- uninstall target shared libraries function _uninstall_target_shared_libraries(target, batchcmds_, opt) + local package = opt.package + local bindir = _get_target_bindir(package, target) + + -- get all dependent shared libraries + local libfiles = {} + for _, dep in ipairs(target:orderdeps()) do + if dep:kind() == "shared" then + local depfile = dep:targetfile() + if os.isfile(depfile) then + table.insert(libfiles, depfile) + end + end + table.join2(libfiles, _get_target_package_libfiles(dep, {interface = true})) + end + table.join2(libfiles, _get_target_package_libfiles(target)) + + -- deduplicate libfiles, prevent packages using the same libfiles from overwriting each other + libfiles = table.unique(libfiles) + + -- do uninstall + for _, libfile in ipairs(libfiles) do + local filename = path.filename(libfile) + batchcmds_:rm(libfile, path.join(bindir, filename), {emptydirs = true}) + end end -- on install binary target command -- cgit v1.3.1 From 6fd249647eb5cf6a44982c35e0564c7733da5457 Mon Sep 17 00:00:00 2001 From: ruki Date: Sun, 14 Jul 2024 22:39:14 +0800 Subject: rewrite install --- xmake/modules/target/action/install/main.lua | 170 ++++++++++++++++++++++-- xmake/modules/target/action/install/unix.lua | 161 ---------------------- xmake/modules/target/action/install/windows.lua | 159 ---------------------- xmake/plugins/pack/batchcmds.lua | 68 ++++------ 4 files changed, 188 insertions(+), 370 deletions(-) delete mode 100644 xmake/modules/target/action/install/unix.lua delete mode 100644 xmake/modules/target/action/install/windows.lua diff --git a/xmake/modules/target/action/install/main.lua b/xmake/modules/target/action/install/main.lua index c115e836e..07089c60e 100644 --- a/xmake/modules/target/action/install/main.lua +++ b/xmake/modules/target/action/install/main.lua @@ -18,6 +18,36 @@ -- @file main.lua -- +-- imports +import("core.base.option") +import("core.base.hashset") +import("utils.symbols.depend", {alias = "get_depend_libraries"}) + +function _get_target_package_libfiles(target, opt) + local libfiles = {} + 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) + end + end + end + end + -- we can only reserve used libraries + if target:is_binary() or target:is_shared() then + local depends = hashset.new() + local targetfile = target:targetfile() + local depend_libraries = get_depend_libraries(targetfile, {plat = target:plat(), arch = target:arch()}) + 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) + end + return libfiles +end + -- install files function _install_files(target) local srcfiles, dstfiles = target:installfiles() @@ -33,25 +63,143 @@ function _install_files(target) end end --- the builtin install main entry -function main(target, opt) +-- install headers +function _install_headers(target, opt) + local includedir = target:includedir() + os.mkdir(includedir) + local srcheaders, dstheaders = target:headerfiles(includedir, {installonly = true}) + if srcheaders and dstheaders then + local i = 1 + for _, srcheader in ipairs(srcheaders) do + local dstheader = dstheaders[i] + if dstheader then + os.vcp(srcheader, dstheader) + end + i = i + 1 + end + end +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 + if dep:kind() == "shared" then + local depfile = dep:targetfile() + if os.isfile(depfile) then + table.insert(libfiles, depfile) + end + end + table.join2(libfiles, _get_target_package_libfiles(dep, {interface = true})) + end + table.join2(libfiles, _get_target_package_libfiles(target)) + + -- deduplicate libfiles, prevent packages using the same libfiles from overwriting each other + libfiles = table.unique(libfiles) + + -- do install + for _, libfile in ipairs(libfiles) do + local filename = path.filename(libfile) + local filepath = path.join(bindir, filename) + if os.isfile(filepath) then + wprint("'%s' already exists in install dir, we are copying '%s' to overwrite it.", filepath, libfile) + end + os.cp(libfile, filepath) + end +end + +-- install binary +function _install_binary(target, opt) + local bindir = target:bindir() + os.mkdir(bindir) + os.vcp(target:targetfile(), bindir) + os.trycp(target:symbolfile(), path.join(bindir, path.filename(target:symbolfile()))) + _install_shared_libraries(target, opt) +end + +-- install shared library +function _install_shared(target, opt) + local bindir = target:is_plat("windows", "mingw") and target:bindir() or target:libdir() + os.mkdir(bindir) + local targetfile = target:targetfile() + + if target:is_plat("windows", "mingw") then + -- install *.lib for shared/windows (*.dll) target + -- @see https://github.com/xmake-io/xmake/issues/714 + os.vcp(target:targetfile(), bindir) + local libdir = target:libdir() + local targetfile_lib = path.join(path.directory(targetfile), path.basename(targetfile) .. (target:is_plat("mingw") and ".dll.a" or ".lib")) + if os.isfile(targetfile_lib) then + os.mkdir(libdir) + os.vcp(targetfile_lib, libdir) + end + else + -- install target with soname and symlink + if os.islink(targetfile) then + local targetfile_with_soname = os.readlink(targetfile) + if not path.is_absolute(targetfile_with_soname) then + targetfile_with_soname = path.join(target:targetdir(), targetfile_with_soname) + end + if os.islink(targetfile_with_soname) then + local targetfile_with_version = os.readlink(targetfile_with_soname) + if not path.is_absolute(targetfile_with_version) then + targetfile_with_version = path.join(target:targetdir(), targetfile_with_version) + end + os.vcp(targetfile_with_version, bindir, {symlink = true, force = true}) + end + os.vcp(targetfile_with_soname, bindir, {symlink = true, force = true}) + os.vcp(targetfile, bindir, {symlink = true, force = true}) + else + os.vcp(targetfile, bindir) + end + end + os.trycp(target:symbolfile(), path.join(bindir, path.filename(target:symbolfile()))) + + _install_headers(target, opt) + _install_shared_libraries(target, opt) +end - -- get install directory +-- install static library +function _install_static(target, opt) + local libdir = target:libdir() + os.mkdir(libdir) + os.vcp(target:targetfile(), libdir) + os.trycp(target:symbolfile(), path.join(libdir, path.filename(target:symbolfile()))) + _install_headers(target, opt) +end + +-- install headeronly library +function _install_headeronly(target, opt) + _install_headers(target, opt) +end + +-- install moduleonly library +function _install_moduleonly(target, opt) + _install_headers(target, opt) +end + +function main(target, opt) local installdir = target:installdir() if not installdir then + wprint("please use `xmake install -o installdir` or `set_installdir` to set install directory.") return end - - -- trace print("installing %s to %s ..", target:name(), installdir) - -- call script - local install_style = target:is_plat("windows", "mingw") and "windows" or "unix" - local script = import(install_style, {anonymous = true})["install_" .. target:kind()] - if script then - script(target, opt) + if target:is_binary() then + _install_binary(target, opt) + elseif target:is_shared() then + _install_shared(target, opt) + elseif target:is_static() then + _install_static(target, opt) + elseif target:is_headeronly() then + _install_headeronly(target, opt) + elseif target:is_moduleonly() then + _install_moduleonly(target, opt) end - -- install other files _install_files(target) end diff --git a/xmake/modules/target/action/install/unix.lua b/xmake/modules/target/action/install/unix.lua deleted file mode 100644 index dc1354519..000000000 --- a/xmake/modules/target/action/install/unix.lua +++ /dev/null @@ -1,161 +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 unix.lua --- - --- imports -import("core.base.option") - --- install headers -function _install_headers(target, opt) - local includedir = target:includedir() - os.mkdir(includedir) - local srcheaders, dstheaders = target:headerfiles(includedir, {installonly = true}) - if srcheaders and dstheaders then - local i = 1 - for _, srcheader in ipairs(srcheaders) do - local dstheader = dstheaders[i] - if dstheader then - os.vcp(srcheader, dstheader) - end - i = i + 1 - end - end -end - --- install shared libraries for package -function _install_shared_for_package(target, pkg, outputdir) - _g.installed_libfiles = _g.installed_libfiles or {} - for _, sopath in ipairs(table.wrap(pkg:get("libfiles"))) do - if sopath:endswith(".so") or sopath:match(".+%.so%..+$") or sopath:endswith(".dylib") then - -- prevent packages using the same system libfiles from overwriting each other - if not _g.installed_libfiles[sopath] then - local soname = path.filename(sopath) - local targetname = path.join(outputdir, soname) - if os.isfile(targetname) then - wprint("'%s' already exists in install dir, overwriting it from package(%s).", soname, pkg:name()) - -- rm because symlink cannot overwrite existing file - os.rm(targetname) - end - -- we need to reserve symlink - -- @see https://github.com/xmake-io/xmake/issues/1582 - os.vcp(sopath, outputdir, {symlink = true, force = true}) - _g.installed_libfiles[sopath] = true - end - end - end -end - --- install shared libraries for packages -function _install_shared_for_packages(target, outputdir) - if option.get("nopkgs") then - return - end - _g.installed_packages = _g.installed_packages or {} - for _, pkg in ipairs(target:orderpkgs()) do - if not _g.installed_packages[pkg:name()] then - if pkg:enabled() and pkg:get("libfiles") then - _install_shared_for_package(target, pkg, outputdir) - end - _g.installed_packages[pkg:name()] = true - end - end -end - --- install binary -function install_binary(target, opt) - - -- install binary - local bindir = target:bindir() - os.mkdir(bindir) - os.vcp(target:targetfile(), bindir) - - -- install libraries - local libdir = target:libdir() - os.mkdir(libdir) - - -- install the dependent shared (*.so) target - -- @see https://github.com/xmake-io/xmake/issues/961 - for _, dep in ipairs(target:orderdeps()) do - if dep:kind() == "shared" then - local depfile = dep:targetfile() - if os.isfile(depfile) then - os.vcp(depfile, libdir) - end - end - -- install all shared libraries in packages in all deps - _install_shared_for_packages(dep, libdir) - end - - -- install shared libraries for all packages - _install_shared_for_packages(target, libdir) -end - --- install shared library -function install_shared(target, opt) - - -- install libraries - local libdir = target:libdir() - os.mkdir(libdir) - local targetfile = target:targetfile() - if os.islink(targetfile) then - local targetfile_with_soname = os.readlink(targetfile) - if not path.is_absolute(targetfile_with_soname) then - targetfile_with_soname = path.join(target:targetdir(), targetfile_with_soname) - end - if os.islink(targetfile_with_soname) then - local targetfile_with_version = os.readlink(targetfile_with_soname) - if not path.is_absolute(targetfile_with_version) then - targetfile_with_version = path.join(target:targetdir(), targetfile_with_version) - end - os.vcp(targetfile_with_version, libdir, {symlink = true, force = true}) - end - os.vcp(targetfile_with_soname, libdir, {symlink = true, force = true}) - os.vcp(targetfile, libdir, {symlink = true, force = true}) - else - os.vcp(targetfile, libdir) - end - - -- install shared libraries for all packages - _install_shared_for_packages(target, libdir) - - -- install headers - _install_headers(target, opt) -end - --- install static library -function install_static(target, opt) - - -- install libraries - local libdir = target:libdir() - os.mkdir(libdir) - os.vcp(target:targetfile(), libdir) - - -- install headers - _install_headers(target, opt) -end - --- install headeronly library -function install_headeronly(target, opt) - _install_headers(target, opt) -end - --- install moduleonly library -function install_moduleonly(target, opt) - _install_headers(target, opt) -end diff --git a/xmake/modules/target/action/install/windows.lua b/xmake/modules/target/action/install/windows.lua deleted file mode 100644 index c52c1c934..000000000 --- a/xmake/modules/target/action/install/windows.lua +++ /dev/null @@ -1,159 +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 windows.lua --- - --- imports -import("core.base.option") -import("lib.detect.find_file") - --- check install directory -function _check_installdir(installdir) - return assert(installdir, "please use `xmake install -o installdir` or `set_installdir` to set install directory on windows.") -end - --- install headers -function _install_headers(target, opt) - local includedir = _check_installdir(target:includedir()) - os.mkdir(includedir) - local srcheaders, dstheaders = target:headerfiles(includedir, {installonly = true}) - if srcheaders and dstheaders then - local i = 1 - for _, srcheader in ipairs(srcheaders) do - local dstheader = dstheaders[i] - if dstheader then - os.vcp(srcheader, dstheader) - end - i = i + 1 - end - end -end - --- install shared libraries for package -function _install_shared_for_package(target, pkg, outputdir) - _g.installed_dllfiles = _g.installed_dllfiles or {} - for _, dllpath in ipairs(table.wrap(pkg:get("libfiles"))) do - if dllpath:endswith(".dll") then - -- prevent packages using the same libfiles from overwriting each other - if not _g.installed_dllfiles[dllpath] then - local dllname = path.filename(dllpath) - if os.isfile(path.join(outputdir, dllname)) then - wprint("'%s' already exists in install dir, overwriting it from package(%s).", dllname, pkg:name()) - end - os.vcp(dllpath, outputdir) - _g.installed_dllfiles[dllpath] = true - end - end - end -end - --- install shared libraries for packages -function _install_shared_for_packages(target, outputdir) - if option.get("nopkgs") then - return - end - _g.installed_packages = _g.installed_packages or {} - for _, pkg in ipairs(target:orderpkgs()) do - if not _g.installed_packages[pkg:name()] then - if pkg:enabled() and pkg:get("libfiles") then - _install_shared_for_package(target, pkg, outputdir) - end - _g.installed_packages[pkg:name()] = true - end - end -end - --- install binary -function install_binary(target, opt) - - -- install binary - local installdir = _get_installdir(target) - local bindir = path.join(installdir, opt and opt.bindir or "bin") - os.mkdir(bindir) - os.vcp(target:targetfile(), bindir) - os.trycp(target:symbolfile(), bindir) - - -- install the dependent shared/windows (*.dll) target - -- @see https://github.com/xmake-io/xmake/issues/961 - _g.installed_dllfiles = _g.installed_dllfiles or {} - for _, dep in ipairs(target:orderdeps()) do - if dep:kind() == "shared" then - local depfile = dep:targetfile() - if os.isfile(depfile) then - if not _g.installed_dllfiles[depfile] then - os.vcp(depfile, bindir) - _g.installed_dllfiles[depfile] = true - end - end - end - -- install all shared libraries in packages in all deps - _install_shared_for_packages(dep, bindir) - end - - -- install shared libraries for all packages - _install_shared_for_packages(target, bindir) -end - --- install shared library -function install_shared(target, opt) - - -- install dll library to the binary directory - local bindir = _check_installdir(target:bindir()) - os.mkdir(bindir) - os.vcp(target:targetfile(), bindir) - os.trycp(target:symbolfile(), bindir) - - -- install *.lib for shared/windows (*.dll) target - -- @see https://github.com/xmake-io/xmake/issues/714 - local targetfile = target:targetfile() - local libdir = _check_installdir(target:libdir()) - local targetfile_lib = path.join(path.directory(targetfile), path.basename(targetfile) .. (target:is_plat("mingw") and ".dll.a" or ".lib")) - if os.isfile(targetfile_lib) then - os.mkdir(libdir) - os.vcp(targetfile_lib, libdir) - end - - -- install shared libraries for all packages - _install_shared_for_packages(target, bindir) - - -- install headers - _install_headers(target, opt) -end - --- install static library -function install_static(target, opt) - - -- install library - local libdir = _check_installdir(target:libdir()) - os.mkdir(libdir) - os.vcp(target:targetfile(), libdir) - os.trycp(target:symbolfile(), libdir) - - -- install headers - _install_headers(target, opt) -end - --- install headeronly -function install_headeronly(target, opt) - _install_headers(target, opt) -end - --- install moduleonly -function install_moduleonly(target, opt) - _install_headers(target, opt) -end diff --git a/xmake/plugins/pack/batchcmds.lua b/xmake/plugins/pack/batchcmds.lua index 08216b15e..ff20729eb 100644 --- a/xmake/plugins/pack/batchcmds.lua +++ b/xmake/plugins/pack/batchcmds.lua @@ -61,6 +61,31 @@ function _get_target_installdir(package, target) return path.normalize(installdir) end +function _get_target_package_libfiles(target, opt) + local libfiles = {} + 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) + end + end + end + end + -- we can only reserve used libraries + if target:is_binary() or target:is_shared() then + local depends = hashset.new() + local targetfile = target:targetfile() + local depend_libraries = get_depend_libraries(targetfile, {plat = target:plat(), arch = target:arch()}) + 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) + end + return libfiles +end + -- install headers function _install_target_headers(target, batchcmds_, opt) local package = opt.package @@ -90,35 +115,10 @@ function _install_target_headers(target, batchcmds_, opt) end end -function _get_target_package_libfiles(target, opt) - local libfiles = {} - 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) - end - end - end - end - -- we can only reserve used libraries - if target:is_binary() or target:is_shared() then - local depends = hashset.new() - local targetfile = target:targetfile() - local depend_libraries = get_depend_libraries(targetfile, {plat = target:plat(), arch = target:arch()}) - 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) - end - return libfiles -end - -- install target shared libraries function _install_target_shared_libraries(target, batchcmds_, opt) local package = opt.package - local bindir = _get_target_bindir(package, target) + local bindir = target:is_plat("windows", "mingw") and _get_target_bindir(package, target) or _get_target_libdir(package, target) -- get all dependent shared libraries local libfiles = {} @@ -161,7 +161,7 @@ end -- uninstall target shared libraries function _uninstall_target_shared_libraries(target, batchcmds_, opt) local package = opt.package - local bindir = _get_target_bindir(package, target) + local bindir = target:is_plat("windows", "mingw") and _get_target_bindir(package, target) or _get_target_libdir(package, target) -- get all dependent shared libraries local libfiles = {} @@ -190,24 +190,19 @@ end function _on_target_installcmd_binary(target, batchcmds_, opt) local package = opt.package local bindir = _get_target_bindir(package, target) - - -- install target file batchcmds_:cp(target:targetfile(), path.join(bindir, target:filename())) if os.isfile(target:symbolfile()) then batchcmds_:cp(target:symbolfile(), path.join(bindir, path.filename(target:symbolfile()))) end - - -- install target shared libraries _install_target_shared_libraries(target, batchcmds_, opt) end -- on install shared target command function _on_target_installcmd_shared(target, batchcmds_, opt) local package = opt.package - local bindir = _get_target_bindir(package, target) + local bindir = target:is_plat("windows", "mingw") and _get_target_bindir(package, target) or _get_target_libdir(package, target) local libdir = _get_target_libdir(package, target) - -- install target file batchcmds_:cp(target:targetfile(), path.join(bindir, target:filename())) if os.isfile(target:symbolfile()) then batchcmds_:cp(target:symbolfile(), path.join(bindir, path.filename(target:symbolfile()))) @@ -222,10 +217,7 @@ function _on_target_installcmd_shared(target, batchcmds_, opt) batchcmds_:cp(targetfile_lib, path.join(libdir, path.filename(targetfile_lib))) end - -- install headers _install_target_headers(target, batchcmds_, opt) - - -- install target shared libraries _install_target_shared_libraries(target, batchcmds_, opt) end @@ -234,13 +226,11 @@ function _on_target_installcmd_static(target, batchcmds_, opt) local package = opt.package local libdir = _get_target_libdir(package, target) - -- install target file batchcmds_:cp(target:targetfile(), path.join(libdir, target:filename())) if os.isfile(target:symbolfile()) then batchcmds_:cp(target:symbolfile(), path.join(libdir, path.filename(target:symbolfile()))) end - -- install headers _install_target_headers(target, batchcmds_, opt) end @@ -310,7 +300,7 @@ end -- on uninstall shared target command function _on_target_uninstallcmd_shared(target, batchcmds_, opt) local package = opt.package - local bindir = _get_target_bindir(package, target) + local bindir = target:is_plat("windows", "mingw") and _get_target_bindir(package, target) or _get_target_libdir(package, target) local libdir = _get_target_libdir(package, target) -- uninstall target file -- cgit v1.3.1 From e128b029dbfa5e3ab5156afd12a7a412c2bb6aad Mon Sep 17 00:00:00 2001 From: ruki Date: Sun, 14 Jul 2024 23:02:23 +0800 Subject: rewrite uninstall --- xmake/modules/target/action/install/main.lua | 2 +- xmake/modules/target/action/uninstall/main.lua | 162 +++++++++++++++++++--- xmake/modules/target/action/uninstall/unix.lua | 137 ------------------ xmake/modules/target/action/uninstall/windows.lua | 115 --------------- 4 files changed, 141 insertions(+), 275 deletions(-) delete mode 100644 xmake/modules/target/action/uninstall/unix.lua delete mode 100644 xmake/modules/target/action/uninstall/windows.lua diff --git a/xmake/modules/target/action/install/main.lua b/xmake/modules/target/action/install/main.lua index 07089c60e..09deaabdb 100644 --- a/xmake/modules/target/action/install/main.lua +++ b/xmake/modules/target/action/install/main.lua @@ -100,7 +100,7 @@ function _install_shared_libraries(target, opt) -- deduplicate libfiles, prevent packages using the same libfiles from overwriting each other libfiles = table.unique(libfiles) - -- do install + -- do install, TODO soname and symlinks for _, libfile in ipairs(libfiles) do local filename = path.filename(libfile) local filepath = path.join(bindir, filename) diff --git a/xmake/modules/target/action/uninstall/main.lua b/xmake/modules/target/action/uninstall/main.lua index daa23917c..41f074640 100644 --- a/xmake/modules/target/action/uninstall/main.lua +++ b/xmake/modules/target/action/uninstall/main.lua @@ -18,45 +18,163 @@ -- @file main.lua -- +-- imports +import("core.base.option") +import("core.base.hashset") +import("utils.symbols.depend", {alias = "get_depend_libraries"}) +import("private.action.clean.remove_files") + +function _get_target_package_libfiles(target, opt) + local libfiles = {} + 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) + end + end + end + end + -- we can only reserve used libraries + if target:is_binary() or target:is_shared() then + local depends = hashset.new() + local targetfile = target:targetfile() + local depend_libraries = get_depend_libraries(targetfile, {plat = target:plat(), arch = target:arch()}) + 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) + end + return libfiles +end + -- uninstall files function _uninstall_files(target) local _, dstfiles = target:installfiles() for _, dstfile in ipairs(dstfiles) do - os.vrm(dstfile) + remove_files(dstfile, {emptydir = true}) end end --- uninstall modules -function _uninstall_modules(target, opt) - local moduledir = path.join(target:installdir(), opt and opt.moduledir or "modules") - os.vrm(moduledir) +-- uninstall headers +function _uninstall_headers(target, opt) + local includedir = target:includedir() + local _, dstheaders = target:headerfiles(includedir, {installonly = true}) + for _, dstheader in ipairs(dstheaders) do + remove_files(dstheader, {emptydir = true}) + end end --- the builtin uninstall main entry -function main(target, opt) +-- uninstall shared libraries +function _uninstall_shared_libraries(target, opt) + local bindir = target:is_plat("windows", "mingw") and target:bindir() or target:libdir() - -- get install directory - local installdir = target:installdir() - if not installdir then - return + -- get all dependent shared libraries + local libfiles = {} + for _, dep in ipairs(target:orderdeps()) do + if dep:kind() == "shared" then + local depfile = dep:targetfile() + if os.isfile(depfile) then + table.insert(libfiles, depfile) + end + end + table.join2(libfiles, _get_target_package_libfiles(dep, {interface = true})) end + table.join2(libfiles, _get_target_package_libfiles(target)) + + -- deduplicate libfiles, prevent packages using the same libfiles from overwriting each other + libfiles = table.unique(libfiles) + + -- do uninstall + for _, libfile in ipairs(libfiles) do + local filename = path.filename(libfile) + local filepath = path.join(bindir, filename) + remove_files(filepath, {emptydir = true}) + end +end - -- trace - print("uninstalling %s from %s ..", target:name(), installdir) +-- uninstall binary +function _uninstall_binary(target, opt) + local bindir = target:bindir() + remove_files(path.join(bindir, path.filename(target:targetfile())), {emptydir = true}) + remove_files(path.join(bindir, path.filename(target:symbolfile())), {emptydir = true}) + _uninstall_shared_libraries(target, opt) +end + +-- uninstall shared library +function _uninstall_shared(target, opt) + local bindir = target:is_plat("windows", "mingw") and target:bindir() or target:libdir() - -- call script - if not target:is_phony() then - local install_style = target:is_plat("windows", "mingw") and "windows" or "unix" - local script = import(install_style, {anonymous = true})["uninstall_" .. target:kind()] - if script then - script(target, opt) + if target:is_plat("windows", "mingw") then + -- uninstall *.lib for shared/windows (*.dll) target + -- @see https://github.com/xmake-io/xmake/issues/714 + local libdir = target:libdir() + local targetfile = target:targetfile() + remove_files(path.join(bindir, path.filename(targetfile)), {emptydir = true}) + remove_files(path.join(libdir, path.basename(targetfile) .. (target:is_plat("mingw") and ".dll.a" or ".lib")), {emptydir = true}) + else + local targetfile = path.join(bindir, path.filename(target:targetfile())) + if os.islink(targetfile) then + local targetfile_with_soname = os.readlink(targetfile) + if not path.is_absolute(targetfile_with_soname) then + targetfile_with_soname = path.join(bindir, targetfile_with_soname) + end + if os.islink(targetfile_with_soname) then + local targetfile_with_version = os.readlink(targetfile_with_soname) + if not path.is_absolute(targetfile_with_version) then + targetfile_with_version = path.join(bindir, targetfile_with_version) + end + remove_files(targetfile_with_version, {emptydir = true}) + end + remove_files(targetfile_with_soname, {emptydir = true}) end + remove_files(targetfile, {emptydir = true}) end + remove_files(path.join(bindir, path.filename(target:symbolfile())), {emptydir = true}) - -- remove modules - _uninstall_modules(target, opt) + _uninstall_headers(target, opt) + _uninstall_shared_libraries(target, opt) +end + +-- uninstall static library +function _uninstall_static(target, opt) + local libdir = target:libdir() + remove_files(path.join(libdir, path.filename(target:targetfile())), {emptydir = true}) + remove_files(path.join(libdir, path.filename(target:symbolfile())), {emptydir = true}) + _uninstall_headers(target, opt) +end + +-- uninstall headeronly library +function _uninstall_headeronly(target, opt) + _uninstall_headers(target, opt) +end + +-- uninstall moduleonly library +function _uninstall_moduleonly(target, opt) + _uninstall_headers(target, opt) +end + +function main(target, opt) + local installdir = target:installdir() + if not installdir then + wprint("please use `xmake install -o installdir` or `set_installdir` to set install directory.") + return + end + print("uninstalling %s to %s ..", target:name(), installdir) + + if target:is_binary() then + _uninstall_binary(target, opt) + elseif target:is_shared() then + _uninstall_shared(target, opt) + elseif target:is_static() then + _uninstall_static(target, opt) + elseif target:is_headeronly() then + _uninstall_headeronly(target, opt) + elseif target:is_moduleonly() then + _uninstall_moduleonly(target, opt) + end - -- uninstall the other files _uninstall_files(target) end diff --git a/xmake/modules/target/action/uninstall/unix.lua b/xmake/modules/target/action/uninstall/unix.lua deleted file mode 100644 index 4615be820..000000000 --- a/xmake/modules/target/action/uninstall/unix.lua +++ /dev/null @@ -1,137 +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 unix.lua --- - --- imports -import("private.action.clean.remove_files") - --- uninstall headers -function _uninstall_headers(target, opt) - local includedir = target:includedir() - local _, dstheaders = target:headerfiles(includedir, {installonly = true}) - for _, dstheader in ipairs(dstheaders) do - remove_files(dstheader, {emptydir = true}) - end -end - --- uninstall shared libraries for package -function _uninstall_shared_for_package(target, pkg, outputdir) - for _, sopath in ipairs(table.wrap(pkg:get("libfiles"))) do - if sopath:endswith(".so") or sopath:match(".+%.so%..+$") or sopath:endswith(".dylib") then - local soname = path.filename(sopath) - local filepath = path.join(outputdir, soname) - -- https://github.com/xmake-io/xmake/issues/2665#issuecomment-1209619081 - if os.islink(filepath) then - -- relative link? e.g. libxx.so -> libxx.4.so - local realitem = os.readlink(filepath) - if realitem and not path.is_absolute(realitem) then - local realpath = path.join(outputdir, realitem) - if os.isfile(realpath) then - os.vrm(realpath) - end - end - end - remove_files(filepath, {emptydir = true}) - end - end -end - --- uninstall shared libraries for packages -function _uninstall_shared_for_packages(target, outputdir) - _g.uninstalled_packages = _g.uninstalled_packages or {} - for _, pkg in ipairs(target:orderpkgs()) do - if not _g.uninstalled_packages[pkg:name()] then - if pkg:enabled() and pkg:get("libfiles") then - _uninstall_shared_for_package(target, pkg, outputdir) - end - _g.uninstalled_packages[pkg:name()] = true - end - end -end - --- uninstall binary -function uninstall_binary(target, opt) - - -- remove the target file - local bindir = target:bindir() - os.vrm(path.join(bindir, path.filename(target:targetfile()))) - - -- remove the dependent shared (*.so) target - -- @see https://github.com/xmake-io/xmake/issues/961 - local libdir = target:libdir() - for _, dep in ipairs(target:orderdeps()) do - if dep:kind() == "shared" then - os.vrm(path.join(libdir, path.filename(dep:targetfile()))) - end - _uninstall_shared_for_packages(dep, libdir) - end - - -- uninstall shared libraries for packages - _uninstall_shared_for_packages(target, libdir) -end - --- uninstall shared library -function uninstall_shared(target, opt) - - -- remove the target file - local libdir = target:libdir() - local targetfile = path.join(libdir, path.filename(target:targetfile())) - if os.islink(targetfile) then - local targetfile_with_soname = os.readlink(targetfile) - if not path.is_absolute(targetfile_with_soname) then - targetfile_with_soname = path.join(libdir, targetfile_with_soname) - end - if os.islink(targetfile_with_soname) then - local targetfile_with_version = os.readlink(targetfile_with_soname) - if not path.is_absolute(targetfile_with_version) then - targetfile_with_version = path.join(libdir, targetfile_with_version) - end - os.vrm(targetfile_with_version) - end - os.vrm(targetfile_with_soname) - end - os.vrm(targetfile) - - -- remove headers from the include directory - _uninstall_headers(target, opt) - - -- uninstall shared libraries for packages - _uninstall_shared_for_packages(target, libdir) -end - --- uninstall static library -function uninstall_static(target, opt) - - -- remove the target file - local libdir = target:libdir() - os.vrm(path.join(libdir, path.filename(target:targetfile()))) - - -- remove headers from the include directory - _uninstall_headers(target, opt) -end - --- uninstall headeronly library -function uninstall_headeronly(target, opt) - _uninstall_headers(target, opt) -end - --- uninstall moduleonly library -function uninstall_moduleonly(target, opt) - _uninstall_headers(target, opt) -end diff --git a/xmake/modules/target/action/uninstall/windows.lua b/xmake/modules/target/action/uninstall/windows.lua deleted file mode 100644 index 2982bbee1..000000000 --- a/xmake/modules/target/action/uninstall/windows.lua +++ /dev/null @@ -1,115 +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 windows.lua --- - --- uninstall headers -function _uninstall_headers(target, opt) - local includedir = target:includedir() - local _, dstheaders = target:headerfiles(includedir, {installonly = true}) - for _, dstheader in ipairs(dstheaders) do - os.vrm(dstheader) - end -end - --- uninstall shared libraries for package -function _uninstall_shared_for_package(target, pkg, outputdir) - for _, dllpath in ipairs(table.wrap(pkg:get("libfiles"))) do - if dllpath:endswith(".dll") then - local dllname = path.filename(dllpath) - os.vrm(path.join(outputdir, dllname)) - end - end -end - --- uninstall shared libraries for packages -function _uninstall_shared_for_packages(target, outputdir) - _g.uninstalled_packages = _g.uninstalled_packages or {} - for _, pkg in ipairs(target:orderpkgs()) do - if not _g.uninstalled_packages[pkg:name()] then - if pkg:enabled() and pkg:get("libfiles") then - _uninstall_shared_for_package(target, pkg, outputdir) - end - _g.uninstalled_packages[pkg:name()] = true - end - end -end - --- uninstall binary -function uninstall_binary(target, opt) - - -- remove the target file - local bindir = target:bindir() - os.vrm(path.join(bindir, path.filename(target:targetfile()))) - os.tryrm(path.join(bindir, path.filename(target:symbolfile()))) - - -- remove the dependent shared/windows (*.dll) target - -- @see https://github.com/xmake-io/xmake/issues/961 - for _, dep in ipairs(target:orderdeps()) do - if dep:kind() == "shared" then - os.vrm(path.join(bindir, path.filename(dep:targetfile()))) - end - _uninstall_shared_for_packages(dep, bindir) - end - - -- uninstall shared libraries for packages - _uninstall_shared_for_packages(target, bindir) -end - --- uninstall shared library -function uninstall_shared(target, opt) - - -- remove the target file - local bindir = target:bindir() - os.vrm(path.join(bindir, path.filename(target:targetfile()))) - os.tryrm(path.join(bindir, path.filename(target:symbolfile()))) - - -- remove *.lib for shared/windows (*.dll) target - -- @see https://github.com/xmake-io/xmake/issues/714 - local targetfile = target:targetfile() - local libdir = target:libdir() - os.vrm(path.join(libdir, path.basename(targetfile) .. (target:is_plat("mingw") and ".dll.a" or ".lib"))) - - -- remove headers from the include directory - _uninstall_headers(target, opt) - - -- uninstall shared libraries for packages - _uninstall_shared_for_packages(target, bindir) -end - --- uninstall static library -function uninstall_static(target, opt) - - -- remove the target file - local libdir = target:libdir() - os.vrm(path.join(libdir, path.filename(target:targetfile()))) - os.tryrm(path.join(libdir, path.filename(target:symbolfile()))) - - -- remove headers from the include directory - _uninstall_headers(target, opt) -end - --- uninstall headeronly library -function uninstall_headeronly(target, opt) - _uninstall_headers(target, opt) -end - --- uninstall moduleonly library -function uninstall_moduleonly(target, opt) - _uninstall_headers(target, opt) -end -- cgit v1.3.1 From d151aaa50441d159a2980ceefc55f1db45f4d9b0 Mon Sep 17 00:00:00 2001 From: ruki Date: Mon, 15 Jul 2024 22:50:39 +0800 Subject: improve to install sofiles --- xmake/modules/target/action/install/main.lua | 38 ++++++++++++-------------- xmake/modules/target/action/uninstall/main.lua | 30 ++++++++++---------- 2 files changed, 32 insertions(+), 36 deletions(-) diff --git a/xmake/modules/target/action/install/main.lua b/xmake/modules/target/action/install/main.lua index 09deaabdb..5a0bec7ab 100644 --- a/xmake/modules/target/action/install/main.lua +++ b/xmake/modules/target/action/install/main.lua @@ -48,6 +48,20 @@ function _get_target_package_libfiles(target, opt) return libfiles end +-- copy file with symlinks +function _copyfile_with_symlinks(srcfile, outputdir) + if os.islink(srcfile) then + local srcfile_symlink = os.readlink(srcfile) + if not path.is_absolute(srcfile_symlink) then + srcfile_symlink = path.join(path.directory(srcfile), srcfile_symlink) + end + _copyfile_with_symlinks(srcfile_symlink, outputdir) + os.vcp(srcfile, outputdir, {symlink = true, force = true}) + else + os.vcp(srcfile, outputdir) + end +end + -- install files function _install_files(target) local srcfiles, dstfiles = target:installfiles() @@ -100,14 +114,14 @@ function _install_shared_libraries(target, opt) -- deduplicate libfiles, prevent packages using the same libfiles from overwriting each other libfiles = table.unique(libfiles) - -- do install, TODO soname and symlinks + -- do install for _, libfile in ipairs(libfiles) do local filename = path.filename(libfile) local filepath = path.join(bindir, filename) - if os.isfile(filepath) then + if os.isfile(filepath) and hash.sha256(filepath) ~= hash.sha256(libfile) then wprint("'%s' already exists in install dir, we are copying '%s' to overwrite it.", filepath, libfile) end - os.cp(libfile, filepath) + _copyfile_with_symlinks(libfile, bindir) end end @@ -138,23 +152,7 @@ function _install_shared(target, opt) end else -- install target with soname and symlink - if os.islink(targetfile) then - local targetfile_with_soname = os.readlink(targetfile) - if not path.is_absolute(targetfile_with_soname) then - targetfile_with_soname = path.join(target:targetdir(), targetfile_with_soname) - end - if os.islink(targetfile_with_soname) then - local targetfile_with_version = os.readlink(targetfile_with_soname) - if not path.is_absolute(targetfile_with_version) then - targetfile_with_version = path.join(target:targetdir(), targetfile_with_version) - end - os.vcp(targetfile_with_version, bindir, {symlink = true, force = true}) - end - os.vcp(targetfile_with_soname, bindir, {symlink = true, force = true}) - os.vcp(targetfile, bindir, {symlink = true, force = true}) - else - os.vcp(targetfile, bindir) - end + _copyfile_with_symlinks(targetfile, bindir) end os.trycp(target:symbolfile(), path.join(bindir, path.filename(target:symbolfile()))) diff --git a/xmake/modules/target/action/uninstall/main.lua b/xmake/modules/target/action/uninstall/main.lua index 41f074640..9a0c791cd 100644 --- a/xmake/modules/target/action/uninstall/main.lua +++ b/xmake/modules/target/action/uninstall/main.lua @@ -49,6 +49,18 @@ function _get_target_package_libfiles(target, opt) return libfiles end +-- remove file with symbols +function _remove_file_with_symbols(filepath) + if os.islink(filepath) then + local filepath_symlink = os.readlink(filepath) + if not path.is_absolute(filepath_symlink) then + filepath_symlink = path.join(path.directory(filepath), filepath_symlink) + end + _remove_file_with_symbols(filepath_symlink) + end + remove_files(filepath, {emptydir = true}) +end + -- uninstall files function _uninstall_files(target) local _, dstfiles = target:installfiles() @@ -90,7 +102,7 @@ function _uninstall_shared_libraries(target, opt) for _, libfile in ipairs(libfiles) do local filename = path.filename(libfile) local filepath = path.join(bindir, filename) - remove_files(filepath, {emptydir = true}) + _remove_file_with_symbols(filepath) end end @@ -115,21 +127,7 @@ function _uninstall_shared(target, opt) remove_files(path.join(libdir, path.basename(targetfile) .. (target:is_plat("mingw") and ".dll.a" or ".lib")), {emptydir = true}) else local targetfile = path.join(bindir, path.filename(target:targetfile())) - if os.islink(targetfile) then - local targetfile_with_soname = os.readlink(targetfile) - if not path.is_absolute(targetfile_with_soname) then - targetfile_with_soname = path.join(bindir, targetfile_with_soname) - end - if os.islink(targetfile_with_soname) then - local targetfile_with_version = os.readlink(targetfile_with_soname) - if not path.is_absolute(targetfile_with_version) then - targetfile_with_version = path.join(bindir, targetfile_with_version) - end - remove_files(targetfile_with_version, {emptydir = true}) - end - remove_files(targetfile_with_soname, {emptydir = true}) - end - remove_files(targetfile, {emptydir = true}) + _remove_file_with_symbols(targetfile) end remove_files(path.join(bindir, path.filename(target:symbolfile())), {emptydir = true}) -- cgit v1.3.1 From 729a9c2602a64f4d2fa5151355e8c63ff1a326ab Mon Sep 17 00:00:00 2001 From: ruki Date: Mon, 15 Jul 2024 22:55:08 +0800 Subject: improve batchcmds --- xmake/modules/target/action/install/main.lua | 12 ++++++------ xmake/plugins/pack/batchcmds.lua | 18 ++++++++++++++++-- 2 files changed, 22 insertions(+), 8 deletions(-) diff --git a/xmake/modules/target/action/install/main.lua b/xmake/modules/target/action/install/main.lua index 5a0bec7ab..b78c8bb54 100644 --- a/xmake/modules/target/action/install/main.lua +++ b/xmake/modules/target/action/install/main.lua @@ -49,16 +49,16 @@ function _get_target_package_libfiles(target, opt) end -- copy file with symlinks -function _copyfile_with_symlinks(srcfile, outputdir) +function _copy_file_with_symlinks(srcfile, outputdir) if os.islink(srcfile) then local srcfile_symlink = os.readlink(srcfile) if not path.is_absolute(srcfile_symlink) then srcfile_symlink = path.join(path.directory(srcfile), srcfile_symlink) end - _copyfile_with_symlinks(srcfile_symlink, outputdir) - os.vcp(srcfile, outputdir, {symlink = true, force = true}) + _copy_file_with_symlinks(srcfile_symlink, outputdir) + os.vcp(srcfile, path.join(outputdir, path.filename(srcfile)), {symlink = true, force = true}) else - os.vcp(srcfile, outputdir) + os.vcp(srcfile, path.join(outputdir, path.filename(srcfile))) end end @@ -121,7 +121,7 @@ function _install_shared_libraries(target, opt) if os.isfile(filepath) and hash.sha256(filepath) ~= hash.sha256(libfile) then wprint("'%s' already exists in install dir, we are copying '%s' to overwrite it.", filepath, libfile) end - _copyfile_with_symlinks(libfile, bindir) + _copy_file_with_symlinks(libfile, bindir) end end @@ -152,7 +152,7 @@ function _install_shared(target, opt) end else -- install target with soname and symlink - _copyfile_with_symlinks(targetfile, bindir) + _copy_file_with_symlinks(targetfile, bindir) end os.trycp(target:symbolfile(), path.join(bindir, path.filename(target:symbolfile()))) diff --git a/xmake/plugins/pack/batchcmds.lua b/xmake/plugins/pack/batchcmds.lua index ff20729eb..320afaf72 100644 --- a/xmake/plugins/pack/batchcmds.lua +++ b/xmake/plugins/pack/batchcmds.lua @@ -86,6 +86,20 @@ function _get_target_package_libfiles(target, opt) return libfiles end +-- copy file with symlinks +function _copy_file_with_symlinks(batchcmds_, srcfile, outputdir) + if os.islink(srcfile) then + local srcfile_symlink = os.readlink(srcfile) + if not path.is_absolute(srcfile_symlink) then + srcfile_symlink = path.join(path.directory(srcfile), srcfile_symlink) + end + _copy_file_with_symlinks(batchcmds_, srcfile_symlink, outputdir) + batchcmds_:cp(srcfile, path.join(outputdir, path.filename(srcfile)), {symlink = true, force = true}) + else + batchcmds_:cp(srcfile, path.join(outputdir, path.filename(srcfile))) + end +end + -- install headers function _install_target_headers(target, batchcmds_, opt) local package = opt.package @@ -139,7 +153,7 @@ function _install_target_shared_libraries(target, batchcmds_, opt) -- do install for _, libfile in ipairs(libfiles) do local filename = path.filename(libfile) - batchcmds_:cp(libfile, path.join(bindir, filename)) + _copy_file_with_symlinks(batchcmds_, libfile, bindir) end end @@ -203,7 +217,7 @@ function _on_target_installcmd_shared(target, batchcmds_, opt) local bindir = target:is_plat("windows", "mingw") and _get_target_bindir(package, target) or _get_target_libdir(package, target) local libdir = _get_target_libdir(package, target) - batchcmds_:cp(target:targetfile(), path.join(bindir, target:filename())) + _copy_file_with_symlinks(batchcmds_, target:targetfile(), bindir) if os.isfile(target:symbolfile()) then batchcmds_:cp(target:symbolfile(), path.join(bindir, path.filename(target:symbolfile()))) end -- cgit v1.3.1 From 28e075556101cd683f38e010229ea04dad3decf1 Mon Sep 17 00:00:00 2001 From: ruki Date: Mon, 15 Jul 2024 22:55:46 +0800 Subject: enable nopkgs --- xmake/modules/target/action/install/main.lua | 3 +++ 1 file changed, 3 insertions(+) diff --git a/xmake/modules/target/action/install/main.lua b/xmake/modules/target/action/install/main.lua index b78c8bb54..4308a525f 100644 --- a/xmake/modules/target/action/install/main.lua +++ b/xmake/modules/target/action/install/main.lua @@ -24,6 +24,9 @@ import("core.base.hashset") import("utils.symbols.depend", {alias = "get_depend_libraries"}) function _get_target_package_libfiles(target, opt) + if option.get("nopkgs") then + return {} + end local libfiles = {} for _, pkg in ipairs(target:orderpkgs(opt)) do if pkg:enabled() and pkg:get("libfiles") then -- cgit v1.3.1 From c9a3da04855dc7e757b2a95a269c94f64d7ff681 Mon Sep 17 00:00:00 2001 From: ruki Date: Mon, 15 Jul 2024 23:06:50 +0800 Subject: fix uninstall/remove_files --- xmake/modules/private/action/clean/remove_files.lua | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/xmake/modules/private/action/clean/remove_files.lua b/xmake/modules/private/action/clean/remove_files.lua index 3d62c6b78..6609d0766 100644 --- a/xmake/modules/private/action/clean/remove_files.lua +++ b/xmake/modules/private/action/clean/remove_files.lua @@ -25,6 +25,9 @@ import("core.base.option") function main(filedirs, opt) opt = opt or {} for _, filedir in ipairs(filedirs) do - os.tryrm(filedir, {emptydirs = option.get("all") or opt.emptydir}) + if os.exists(filedir) then + -- we cannot use os.tryrm, because we need raise exception if remove failed with `uninstall --admin` + os.rm(filedir, {emptydirs = option.get("all") or opt.emptydir}) + end end end -- cgit v1.3.1 From 1cf160a75f0f03e114c09af4f78416762663b904 Mon Sep 17 00:00:00 2001 From: ruki Date: Mon, 15 Jul 2024 23:07:11 +0800 Subject: improve remove files --- xmake/modules/private/action/clean/remove_files.lua | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/xmake/modules/private/action/clean/remove_files.lua b/xmake/modules/private/action/clean/remove_files.lua index 6609d0766..8ec7dca77 100644 --- a/xmake/modules/private/action/clean/remove_files.lua +++ b/xmake/modules/private/action/clean/remove_files.lua @@ -25,7 +25,8 @@ import("core.base.option") function main(filedirs, opt) opt = opt or {} for _, filedir in ipairs(filedirs) do - if os.exists(filedir) then + -- os.exists will return false if symlink -> not found, but we need still remove this symlink + if os.exists(filedir) or os.islink(filedir) then -- we cannot use os.tryrm, because we need raise exception if remove failed with `uninstall --admin` os.rm(filedir, {emptydirs = option.get("all") or opt.emptydir}) end -- cgit v1.3.1 From 0dc0148b8bd4d48bec1b6aefdd59761c31361a93 Mon Sep 17 00:00:00 2001 From: ruki Date: Mon, 15 Jul 2024 23:18:06 +0800 Subject: add install test --- tests/actions/install/.gitignore | 8 ++++++++ tests/actions/install/src/foo.cpp | 5 +++++ tests/actions/install/src/foo.h | 17 +++++++++++++++++ tests/actions/install/src/main.cpp | 7 +++++++ tests/actions/install/xmake.lua | 22 ++++++++++++++++++++++ 5 files changed, 59 insertions(+) create mode 100644 tests/actions/install/.gitignore create mode 100644 tests/actions/install/src/foo.cpp create mode 100644 tests/actions/install/src/foo.h create mode 100644 tests/actions/install/src/main.cpp create mode 100644 tests/actions/install/xmake.lua diff --git a/tests/actions/install/.gitignore b/tests/actions/install/.gitignore new file mode 100644 index 000000000..152105761 --- /dev/null +++ b/tests/actions/install/.gitignore @@ -0,0 +1,8 @@ +# Xmake cache +.xmake/ +build/ + +# MacOS Cache +.DS_Store + + diff --git a/tests/actions/install/src/foo.cpp b/tests/actions/install/src/foo.cpp new file mode 100644 index 000000000..1a1fb3425 --- /dev/null +++ b/tests/actions/install/src/foo.cpp @@ -0,0 +1,5 @@ +#include "foo.h" + +int add(int a, int b) { + return a + b; +} diff --git a/tests/actions/install/src/foo.h b/tests/actions/install/src/foo.h new file mode 100644 index 000000000..20df0baa4 --- /dev/null +++ b/tests/actions/install/src/foo.h @@ -0,0 +1,17 @@ +#ifdef __cplusplus +extern "C" { +#endif + +#if defined(_WIN32) +# define __export __declspec(dllexport) +#elif defined(__GNUC__) && ((__GNUC__ >= 4) || (__GNUC__ == 3 && __GNUC_MINOR__ >= 3)) +# define __export __attribute__((visibility("default"))) +#else +# define __export +#endif + +__export int add(int a, int b); + +#ifdef __cplusplus +} +#endif diff --git a/tests/actions/install/src/main.cpp b/tests/actions/install/src/main.cpp new file mode 100644 index 000000000..d55d4d342 --- /dev/null +++ b/tests/actions/install/src/main.cpp @@ -0,0 +1,7 @@ +#include "foo.h" +#include + +int main(int argc, char** argv) { + std::cout << "add(1, 2) = " << add(1, 2) << std::endl; + return 0; +} diff --git a/tests/actions/install/xmake.lua b/tests/actions/install/xmake.lua new file mode 100644 index 000000000..d8a37ad48 --- /dev/null +++ b/tests/actions/install/xmake.lua @@ -0,0 +1,22 @@ +add_rules("mode.debug", "mode.release") + +set_version("1.0.1", {soname = true}) + +add_requires("libplist", {system = false, configs = {shared = true}}) + +target("foo") + set_kind("shared") + add_files("src/foo.cpp") + add_packages("libplist", {public = true}) + +target("test5") + set_kind("binary") + add_deps("foo") + add_files("src/main.cpp") + +includes("@builtin/xpack") + +xpack("test") + add_targets("test5") + set_formats("zip") + -- cgit v1.3.1 From 2f4526310f5b04506f9f528fcd3b8e629ad220ab Mon Sep 17 00:00:00 2001 From: ruki Date: Tue, 16 Jul 2024 00:42:46 +0800 Subject: update install test --- tests/actions/install/src/foo.txt | 0 tests/actions/install/xmake.lua | 6 ++++-- 2 files changed, 4 insertions(+), 2 deletions(-) create mode 100644 tests/actions/install/src/foo.txt diff --git a/tests/actions/install/src/foo.txt b/tests/actions/install/src/foo.txt new file mode 100644 index 000000000..e69de29bb diff --git a/tests/actions/install/xmake.lua b/tests/actions/install/xmake.lua index d8a37ad48..025889da8 100644 --- a/tests/actions/install/xmake.lua +++ b/tests/actions/install/xmake.lua @@ -8,8 +8,10 @@ target("foo") set_kind("shared") add_files("src/foo.cpp") add_packages("libplist", {public = true}) + add_installfiles("src/foo.txt", {prefixdir = "assets", public = true}) + set_prefixdir("/", {bindir = "foo_bin", libdir = "foo_lib"}) -target("test5") +target("app") set_kind("binary") add_deps("foo") add_files("src/main.cpp") @@ -17,6 +19,6 @@ target("test5") includes("@builtin/xpack") xpack("test") - add_targets("test5") + add_targets("app") set_formats("zip") -- cgit v1.3.1 From 91401d48f5bfb1dd7b7624c7c7d8fea44bd9e07a Mon Sep 17 00:00:00 2001 From: ruki Date: Tue, 16 Jul 2024 00:43:09 +0800 Subject: update install test --- tests/actions/install/xmake.lua | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/actions/install/xmake.lua b/tests/actions/install/xmake.lua index 025889da8..3061cab86 100644 --- a/tests/actions/install/xmake.lua +++ b/tests/actions/install/xmake.lua @@ -15,6 +15,7 @@ target("app") set_kind("binary") add_deps("foo") add_files("src/main.cpp") + set_prefixdir("app") includes("@builtin/xpack") -- cgit v1.3.1 From c29298c7573bc18ff0e7f78277fd64781751a4ba Mon Sep 17 00:00:00 2001 From: ruki Date: Tue, 16 Jul 2024 00:43:24 +0800 Subject: only install specific target --- xmake/actions/install/install.lua | 2 -- xmake/actions/uninstall/uninstall.lua | 2 -- 2 files changed, 4 deletions(-) diff --git a/xmake/actions/install/install.lua b/xmake/actions/install/install.lua index ae9857ed3..95f634fe6 100644 --- a/xmake/actions/install/install.lua +++ b/xmake/actions/install/install.lua @@ -110,13 +110,11 @@ function main(targetname, group_pattern) local targets = {} if targetname and not targetname:startswith("__") then local target = project.target(targetname) - table.join2(targets, target:orderdeps()) table.insert(targets, target) else for _, target in ipairs(project.ordertargets()) do local group = target:get("group") if (target:is_default() and not group_pattern) or targetname == "__all" or (group_pattern and group and group:match(group_pattern)) then - table.join2(targets, target:orderdeps()) table.insert(targets, target) end end diff --git a/xmake/actions/uninstall/uninstall.lua b/xmake/actions/uninstall/uninstall.lua index 5aade0313..76feafd56 100644 --- a/xmake/actions/uninstall/uninstall.lua +++ b/xmake/actions/uninstall/uninstall.lua @@ -110,13 +110,11 @@ function main(targetname) local targets = {} if targetname and not targetname:startswith("__") then local target = project.target(targetname) - table.join2(targets, target:orderdeps()) table.insert(targets, target) else for _, target in ipairs(project.ordertargets()) do local group = target:get("group") if (target:is_default() and not group_pattern) or targetname == "__all" or (group_pattern and group and group:match(group_pattern)) then - table.join2(targets, target:orderdeps()) table.insert(targets, target) end end -- cgit v1.3.1 From 14bae7271790d31e8af2f1b7ea45533f923f4a35 Mon Sep 17 00:00:00 2001 From: ruki Date: Tue, 16 Jul 2024 00:44:39 +0800 Subject: fix batchcmds bindir --- xmake/plugins/pack/batchcmds.lua | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/xmake/plugins/pack/batchcmds.lua b/xmake/plugins/pack/batchcmds.lua index 320afaf72..b75ec2e41 100644 --- a/xmake/plugins/pack/batchcmds.lua +++ b/xmake/plugins/pack/batchcmds.lua @@ -29,7 +29,7 @@ function _get_target_bindir(package, target) local bindir = package:bindir() local prefixdir = target:prefixdir() if prefixdir then - bindir = path.join(package:installdir(), prefixdir, target:extraconf("prefixdir", prefixdir, "bindir")) + bindir = path.join(package:installdir(), prefixdir, target:extraconf("prefixdir", prefixdir, "bindir") or "bin") end return path.normalize(bindir) end @@ -38,7 +38,7 @@ function _get_target_libdir(package, target) local libdir = package:libdir() local prefixdir = target:prefixdir() if prefixdir then - libdir = path.join(package:installdir(), prefixdir, target:extraconf("prefixdir", prefixdir, "libdir")) + libdir = path.join(package:installdir(), prefixdir, target:extraconf("prefixdir", prefixdir, "libdir") or "lib") end return path.normalize(libdir) end @@ -47,7 +47,7 @@ function _get_target_includedir(package, target) local includedir = package:includedir() local prefixdir = target:prefixdir() if prefixdir then - includedir = path.join(package:installdir(), prefixdir, target:extraconf("prefixdir", prefixdir, "includedir")) + includedir = path.join(package:installdir(), prefixdir, target:extraconf("prefixdir", prefixdir, "includedir") or "include") end return path.normalize(includedir) end -- cgit v1.3.1 From 2396ca21342a288b9f0d972f479763847709d3a3 Mon Sep 17 00:00:00 2001 From: ruki Date: Tue, 16 Jul 2024 00:46:52 +0800 Subject: improve install files --- xmake/modules/target/action/install/main.lua | 15 ++++--- xmake/modules/target/action/uninstall/main.lua | 6 +++ xmake/plugins/pack/batchcmds.lua | 56 ++++++++++++++++---------- 3 files changed, 47 insertions(+), 30 deletions(-) diff --git a/xmake/modules/target/action/install/main.lua b/xmake/modules/target/action/install/main.lua index 4308a525f..a8acaf5a7 100644 --- a/xmake/modules/target/action/install/main.lua +++ b/xmake/modules/target/action/install/main.lua @@ -68,14 +68,13 @@ end -- install files function _install_files(target) local srcfiles, dstfiles = target:installfiles() - if srcfiles and dstfiles then - local i = 1 - for _, srcfile in ipairs(srcfiles) do - local dstfile = dstfiles[i] - if dstfile then - os.vcp(srcfile, dstfile) - end - i = i + 1 + for idx, srcfile in ipairs(srcfiles) do + os.vcp(srcfile, dstfiles[idx]) + end + for _, dep in ipairs(target:orderdeps()) do + local srcfiles, dstfiles = dep:installfiles(dep:installdir(), {interface = true}) + for idx, srcfile in ipairs(srcfiles) do + os.vcp(srcfile, dstfiles[idx]) end end end diff --git a/xmake/modules/target/action/uninstall/main.lua b/xmake/modules/target/action/uninstall/main.lua index 9a0c791cd..d3fa34585 100644 --- a/xmake/modules/target/action/uninstall/main.lua +++ b/xmake/modules/target/action/uninstall/main.lua @@ -67,6 +67,12 @@ function _uninstall_files(target) for _, dstfile in ipairs(dstfiles) do remove_files(dstfile, {emptydir = true}) end + for _, dep in ipairs(target:orderdeps()) do + local _, dstfiles = dep:installfiles(dep:installdir(), {interface = true}) + for _, dstfile in ipairs(dstfiles) do + remove_files(dstfile, {emptydir = true}) + end + end end -- uninstall headers diff --git a/xmake/plugins/pack/batchcmds.lua b/xmake/plugins/pack/batchcmds.lua index b75ec2e41..b1721bf10 100644 --- a/xmake/plugins/pack/batchcmds.lua +++ b/xmake/plugins/pack/batchcmds.lua @@ -100,7 +100,22 @@ function _copy_file_with_symlinks(batchcmds_, srcfile, outputdir) end end --- install headers +-- install target files +function _install_target_files(target, batchcmds_, opt) + local package = opt.package + local srcfiles, dstfiles = target:installfiles(_get_target_installdir(package, target)) + for idx, srcfile in ipairs(srcfiles) do + batchcmds_:cp(srcfile, dstfiles[idx]) + end + for _, dep in ipairs(target:orderdeps()) do + local srcfiles, dstfiles = dep:installfiles(_get_target_installdir(package, dep), {interface = true}) + for idx, srcfile in ipairs(srcfiles) do + batchcmds_:cp(srcfile, dstfiles[idx]) + end + end +end + +-- install target headers function _install_target_headers(target, batchcmds_, opt) local package = opt.package local srcheaders, dstheaders = target:headerfiles(_get_target_includedir(package, target), {installonly = true}) @@ -157,7 +172,22 @@ function _install_target_shared_libraries(target, batchcmds_, opt) end end --- uninstall headers +-- uninstall target files +function _uninstall_target_files(target, batchcmds_, opt) + local package = opt.package + local _, dstfiles = target:installfiles(_get_target_installdir(package, target)) + for _, dstfile in ipairs(dstfiles) do + batchcmds_:rm(dstfile, {emptydirs = true}) + end + for _, dep in ipairs(target:orderdeps()) do + local _, dstfiles = dep:installfiles(_get_target_installdir(package, dep), {interface = true}) + for _, dstfile in ipairs(dstfiles) do + batchcmds_:rm(dstfile, {emptydirs = true}) + end + end +end + +-- uninstall target headers function _uninstall_target_headers(target, batchcmds_, opt) local package = opt.package local _, dstheaders = target:headerfiles(_get_target_includedir(package, target), {installonly = true}) @@ -286,16 +316,7 @@ function _on_target_installcmd(target, batchcmds_, opt) end -- install target files - local srcfiles, dstfiles = target:installfiles(_get_target_installdir(package, target)) - for idx, srcfile in ipairs(srcfiles) do - batchcmds_:cp(srcfile, dstfiles[idx]) - end - for _, dep in ipairs(target:orderdeps()) do - local srcfiles, dstfiles = dep:installfiles(_get_target_installdir(package, dep), {interface = true}) - for idx, srcfile in ipairs(srcfiles) do - batchcmds_:cp(srcfile, dstfiles[idx]) - end - end + _install_target_files(target, batchcmds_, opt) end -- on uninstall binary target command @@ -377,16 +398,7 @@ function _on_target_uninstallcmd(target, batchcmds_, opt) end -- uninstall target files - local _, dstfiles = target:installfiles(_get_target_installdir(package, target)) - for _, dstfile in ipairs(dstfiles) do - batchcmds_:rm(dstfile, {emptydirs = true}) - end - for _, dep in ipairs(target:orderdeps()) do - local _, dstfiles = dep:installfiles(_get_target_installdir(package, dep), {interface = true}) - for _, dstfile in ipairs(dstfiles) do - batchcmds_:rm(dstfile, {emptydirs = true}) - end - end + _uninstall_target_files(target, batchcmds_, opt) end -- get build commands from targets -- cgit v1.3.1 From 81640975b434a293cabed7d758c599a2668a6efe Mon Sep 17 00:00:00 2001 From: ruki Date: Tue, 16 Jul 2024 00:48:07 +0800 Subject: improve to install headerfiles --- tests/actions/install/xmake.lua | 1 + xmake/modules/target/action/install/main.lua | 31 +++++++++++++++----------- xmake/modules/target/action/uninstall/main.lua | 9 ++++++-- xmake/plugins/pack/batchcmds.lua | 30 ++++++++++--------------- 4 files changed, 38 insertions(+), 33 deletions(-) diff --git a/tests/actions/install/xmake.lua b/tests/actions/install/xmake.lua index 3061cab86..b774e9e27 100644 --- a/tests/actions/install/xmake.lua +++ b/tests/actions/install/xmake.lua @@ -8,6 +8,7 @@ target("foo") set_kind("shared") add_files("src/foo.cpp") add_packages("libplist", {public = true}) + add_headerfiles("src/foo.h", {public = true}) add_installfiles("src/foo.txt", {prefixdir = "assets", public = true}) set_prefixdir("/", {bindir = "foo_bin", libdir = "foo_lib"}) diff --git a/xmake/modules/target/action/install/main.lua b/xmake/modules/target/action/install/main.lua index a8acaf5a7..3c1a12a8e 100644 --- a/xmake/modules/target/action/install/main.lua +++ b/xmake/modules/target/action/install/main.lua @@ -68,30 +68,35 @@ end -- install files function _install_files(target) local srcfiles, dstfiles = target:installfiles() - for idx, srcfile in ipairs(srcfiles) do - os.vcp(srcfile, dstfiles[idx]) + if srcfiles and dstfiles then + for idx, srcfile in ipairs(srcfiles) do + os.vcp(srcfile, dstfiles[idx]) + end end for _, dep in ipairs(target:orderdeps()) do local srcfiles, dstfiles = dep:installfiles(dep:installdir(), {interface = true}) - for idx, srcfile in ipairs(srcfiles) do - os.vcp(srcfile, dstfiles[idx]) + if srcfiles and dstfiles then + for idx, srcfile in ipairs(srcfiles) do + os.vcp(srcfile, dstfiles[idx]) + end end end end -- install headers function _install_headers(target, opt) - local includedir = target:includedir() - os.mkdir(includedir) - local srcheaders, dstheaders = target:headerfiles(includedir, {installonly = true}) + local srcheaders, dstheaders = target:headerfiles(target:includedir(), {installonly = true}) if srcheaders and dstheaders then - local i = 1 - for _, srcheader in ipairs(srcheaders) do - local dstheader = dstheaders[i] - if dstheader then - os.vcp(srcheader, dstheader) + for idx, srcheader in ipairs(srcheaders) do + os.vcp(srcheader, dstheaders[idx]) + end + end + for _, dep in ipairs(target:orderdeps()) do + local srcfiles, dstfiles = dep:headerfiles(dep:includedir(), {installonly = true, interface = true}) + if srcfiles and dstfiles then + for idx, srcfile in ipairs(srcfiles) do + os.vcp(srcfile, dstfiles[idx]) end - i = i + 1 end end end diff --git a/xmake/modules/target/action/uninstall/main.lua b/xmake/modules/target/action/uninstall/main.lua index d3fa34585..73c28f02c 100644 --- a/xmake/modules/target/action/uninstall/main.lua +++ b/xmake/modules/target/action/uninstall/main.lua @@ -77,11 +77,16 @@ end -- uninstall headers function _uninstall_headers(target, opt) - local includedir = target:includedir() - local _, dstheaders = target:headerfiles(includedir, {installonly = true}) + local _, dstheaders = target:headerfiles(target:includedir(), {installonly = true}) for _, dstheader in ipairs(dstheaders) do remove_files(dstheader, {emptydir = true}) end + for _, dep in ipairs(target:orderdeps()) do + local _, dstfiles = dep:headerfiles(dep:includedir(), {installonly = true, interface = true}) + for _, dstfile in ipairs(dstfiles) do + remove_files(dstfile, {emptydir = true}) + end + end end -- uninstall shared libraries diff --git a/xmake/plugins/pack/batchcmds.lua b/xmake/plugins/pack/batchcmds.lua index b1721bf10..26ab4f7b0 100644 --- a/xmake/plugins/pack/batchcmds.lua +++ b/xmake/plugins/pack/batchcmds.lua @@ -104,13 +104,17 @@ end function _install_target_files(target, batchcmds_, opt) local package = opt.package local srcfiles, dstfiles = target:installfiles(_get_target_installdir(package, target)) - for idx, srcfile in ipairs(srcfiles) do - batchcmds_:cp(srcfile, dstfiles[idx]) + if srcfiles and dstfiles then + for idx, srcfile in ipairs(srcfiles) do + batchcmds_:cp(srcfile, dstfiles[idx]) + end end for _, dep in ipairs(target:orderdeps()) do local srcfiles, dstfiles = dep:installfiles(_get_target_installdir(package, dep), {interface = true}) - for idx, srcfile in ipairs(srcfiles) do - batchcmds_:cp(srcfile, dstfiles[idx]) + if srcfiles and dstfiles then + for idx, srcfile in ipairs(srcfiles) do + batchcmds_:cp(srcfile, dstfiles[idx]) + end end end end @@ -120,25 +124,15 @@ function _install_target_headers(target, batchcmds_, opt) local package = opt.package local srcheaders, dstheaders = target:headerfiles(_get_target_includedir(package, target), {installonly = true}) if srcheaders and dstheaders then - local i = 1 - for _, srcheader in ipairs(srcheaders) do - local dstheader = dstheaders[i] - if dstheader then - batchcmds_:cp(srcheader, dstheader) - end - i = i + 1 + for idx, srcheader in ipairs(srcheaders) do + batchcmds_:cp(srcheader, dstheaders[idx]) end end for _, dep in ipairs(target:orderdeps()) do local srcheaders, dstheaders = dep:headerfiles(_get_target_includedir(package, dep), {installonly = true, interface = true}) if srcheaders and dstheaders then - local i = 1 - for _, srcheader in ipairs(srcheaders) do - local dstheader = dstheaders[i] - if dstheader then - batchcmds_:cp(srcheader, dstheader) - end - i = i + 1 + for idx, srcheader in ipairs(srcheaders) do + batchcmds_:cp(srcheader, dstheaders[idx]) end end end -- cgit v1.3.1 From 79fffb69b3bff30eacc42e0547c53041b207c75d Mon Sep 17 00:00:00 2001 From: ruki Date: Tue, 16 Jul 2024 00:53:26 +0800 Subject: add test.lua for install --- tests/actions/install/test.lua | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 tests/actions/install/test.lua diff --git a/tests/actions/install/test.lua b/tests/actions/install/test.lua new file mode 100644 index 000000000..78173bac7 --- /dev/null +++ b/tests/actions/install/test.lua @@ -0,0 +1,8 @@ +function main(t) + if is_host("windows", "linux", "macosx") and os.arch():startswith("x") then + os.vrun("xmake -y") + os.vrun("xmake run app") + os.vrun("xmake install -o build/usr") + os.vrun("./build/usr/app/bin/app" .. (is_host("windows") and ".exe" or "")) + end +end -- cgit v1.3.1 From 47b8220c696df2fe33e8e24590d871feedfabf2a Mon Sep 17 00:00:00 2001 From: ruki Date: Tue, 16 Jul 2024 22:46:29 +0800 Subject: fix install/uninstall with admin --- tests/actions/install/xmake.lua | 6 +++--- xmake/actions/install/install_admin.lua | 21 ++++++--------------- xmake/actions/install/main.lua | 5 ++++- xmake/actions/uninstall/main.lua | 5 ++++- xmake/actions/uninstall/uninstall_admin.lua | 18 +++--------------- 5 files changed, 20 insertions(+), 35 deletions(-) diff --git a/tests/actions/install/xmake.lua b/tests/actions/install/xmake.lua index b774e9e27..8dc12f176 100644 --- a/tests/actions/install/xmake.lua +++ b/tests/actions/install/xmake.lua @@ -1,6 +1,6 @@ add_rules("mode.debug", "mode.release") -set_version("1.0.1", {soname = true}) +--set_version("1.0.1", {soname = true}) add_requires("libplist", {system = false, configs = {shared = true}}) @@ -10,13 +10,13 @@ target("foo") add_packages("libplist", {public = true}) add_headerfiles("src/foo.h", {public = true}) add_installfiles("src/foo.txt", {prefixdir = "assets", public = true}) - set_prefixdir("/", {bindir = "foo_bin", libdir = "foo_lib"}) +-- set_prefixdir("/", {bindir = "foo_bin", libdir = "foo_lib"}) target("app") set_kind("binary") add_deps("foo") add_files("src/main.cpp") - set_prefixdir("app") +-- set_prefixdir("app") includes("@builtin/xpack") diff --git a/xmake/actions/install/install_admin.lua b/xmake/actions/install/install_admin.lua index ba5101324..93fbf5beb 100644 --- a/xmake/actions/install/install_admin.lua +++ b/xmake/actions/install/install_admin.lua @@ -25,39 +25,30 @@ import("core.project.project") import("core.platform.platform") import("install") --- install function main(targetname, group_pattern, installdir, prefix) - local verbose = option.get("verbose") + if group_pattern and #group_pattern == 0 then + group_pattern = nil + end + if installdir and #installdir == 0 then + installdir = nil + end - -- enter project directory os.cd(project.directory()) - - -- load config config.load() - - -- load platform platform.load(config.plat()) -- save the current option and push a new option context option.save() - - -- preserve verbose option option.set("verbose", verbose) - - -- pass installdir to option if installdir then option.set("installdir", installdir) end - - -- pass prefix to option if prefix then option.set("prefix", prefix) end -- install target install(targetname, group_pattern) - - -- restore the previous option context option.restore() end diff --git a/xmake/actions/install/main.lua b/xmake/actions/install/main.lua index 1d9f8b1c1..24081f874 100644 --- a/xmake/actions/install/main.lua +++ b/xmake/actions/install/main.lua @@ -116,7 +116,10 @@ function main() if sudo.has() and option.get("admin") then -- install target with administrator permission - sudo.execl(path.join(os.scriptdir(), "install_admin.lua"), {targetname or (option.get("all") and "__all" or "__def"), group_pattern, option.get("installdir"), option.get("prefix")}) + sudo.execl(path.join(os.scriptdir(), "install_admin.lua"), { + targetname or (option.get("all") and "__all" or "__def"), + group_pattern or "", option.get("installdir") or "", + option.get("prefix")}) cprint("${color.success}install ok!") ok = true end diff --git a/xmake/actions/uninstall/main.lua b/xmake/actions/uninstall/main.lua index 5c403b85e..f2ae59eb9 100644 --- a/xmake/actions/uninstall/main.lua +++ b/xmake/actions/uninstall/main.lua @@ -68,7 +68,10 @@ function main() if sudo.has() and option.get("admin") then -- uninstall target with administrator permission - sudo.execl(path.join(os.scriptdir(), "uninstall_admin.lua"), {targetname or "__all", option.get("installdir"), option.get("prefix")}) + sudo.execl(path.join(os.scriptdir(), "uninstall_admin.lua"), { + targetname or "__all", + option.get("installdir") or "", + option.get("prefix")}) -- trace cprint("${color.success}uninstall ok!") diff --git a/xmake/actions/uninstall/uninstall_admin.lua b/xmake/actions/uninstall/uninstall_admin.lua index f597dea11..68b496d87 100644 --- a/xmake/actions/uninstall/uninstall_admin.lua +++ b/xmake/actions/uninstall/uninstall_admin.lua @@ -25,39 +25,27 @@ import("core.project.project") import("core.platform.platform") import("uninstall") --- uninstall function main(targetname, installdir, prefix) - local verbose = option.get("verbose") + if installdir and #installdir == 0 then + installdir = nil + end - -- enter project directory os.cd(project.directory()) - - -- load config config.load() - - -- load platform platform.load(config.plat()) -- save the current option and push a new option context option.save() - - -- preserve verbose option option.set("verbose", verbose) - - -- pass installdir to option if installdir then option.set("installdir", installdir) end - - -- pass prefix to option if prefix then option.set("prefix", prefix) end -- uninstall target uninstall(targetname ~= "__all" and targetname or nil) - - -- restore the previous option context option.restore() end -- cgit v1.3.1 From d888f279d4a370e8dc913c43ba8f61596873d927 Mon Sep 17 00:00:00 2001 From: ruki Date: Tue, 16 Jul 2024 22:56:29 +0800 Subject: add build.rpath and install.rpath policies --- xmake/core/project/policy.lua | 4 ++++ xmake/rules/utils/inherit_links/inherit_links.lua | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/xmake/core/project/policy.lua b/xmake/core/project/policy.lua index 4b5ef9dae..74801d7eb 100644 --- a/xmake/core/project/policy.lua +++ b/xmake/core/project/policy.lua @@ -68,6 +68,8 @@ function policy.policies() ["build.sanitizer.leak"] = {description = "Enable leak sanitizer for c/c++ building.", type = "boolean"}, -- Enable undefined sanitizer for c/c++ building. ["build.sanitizer.undefined"] = {description = "Enable undefined sanitizer for c/c++ building.", type = "boolean"}, + -- Enable build rpath + ["build.rpath"] = {description = "Enable build rpath.", default = true, type = "boolean"}, -- Enable C++ modules for C++ building, even if no .mpp is involved in the compilation ["build.c++.modules"] = {description = "Enable C++ modules for C++ building.", type = "boolean"}, -- Enable std module @@ -94,6 +96,8 @@ function policy.policies() ["windows.manifest.uac.ui"] = {description = "Enable windows manifest UAC.", type = "boolean"}, -- Automatically build before running ["run.autobuild"] = {description = "Automatically build before running.", type = "boolean"}, + -- Enable install rpath + ["install.rpath"] = {description = "Enable install rpath.", default = true, type = "boolean"}, -- Preprocessor configuration for ccache/distcc, we can disable linemarkers to speed up preprocess ["preprocessor.linemarkers"] = {description = "Enable linemarkers for preprocessor.", default = true, type = "boolean"}, -- Preprocessor configuration for ccache/distcc, we can disable it to avoid cache object file with __DATE__, __TIME__ diff --git a/xmake/rules/utils/inherit_links/inherit_links.lua b/xmake/rules/utils/inherit_links/inherit_links.lua index b235c8bff..a128e1cb7 100644 --- a/xmake/rules/utils/inherit_links/inherit_links.lua +++ b/xmake/rules/utils/inherit_links/inherit_links.lua @@ -104,7 +104,7 @@ function main(target) end -- export rpathdirs for all shared library - if target:is_binary() then + if target:is_binary() and target:policy("build.rpath") then local targetdir = target:targetdir() for _, dep in ipairs(target:orderdeps({inherit = true})) do if dep:kind() == "shared" then -- cgit v1.3.1 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 From 0e8641f8886e53f307f3df7ce80040d98ab73466 Mon Sep 17 00:00:00 2001 From: ruki Date: Tue, 16 Jul 2024 23:07:21 +0800 Subject: add change_rpath.lua stub --- xmake/modules/utils/binary/change_rpath.lua | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 xmake/modules/utils/binary/change_rpath.lua diff --git a/xmake/modules/utils/binary/change_rpath.lua b/xmake/modules/utils/binary/change_rpath.lua new file mode 100644 index 000000000..199c7d107 --- /dev/null +++ b/xmake/modules/utils/binary/change_rpath.lua @@ -0,0 +1,24 @@ +--!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 change_rpath.lua +-- + +-- imports +import("core.base.option") +import("lib.detect.find_tool") + -- cgit v1.3.1 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/change_rpath.lua | 24 ---- xmake/modules/utils/binary/rpath.lua | 170 ++++++++++++++++++++++++++++ 2 files changed, 170 insertions(+), 24 deletions(-) delete mode 100644 xmake/modules/utils/binary/change_rpath.lua create mode 100644 xmake/modules/utils/binary/rpath.lua diff --git a/xmake/modules/utils/binary/change_rpath.lua b/xmake/modules/utils/binary/change_rpath.lua deleted file mode 100644 index 199c7d107..000000000 --- a/xmake/modules/utils/binary/change_rpath.lua +++ /dev/null @@ -1,24 +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 change_rpath.lua --- - --- imports -import("core.base.option") -import("lib.detect.find_tool") - 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(-) 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(+) 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(+) 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(+) 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(-) 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 61325d912523d963241467a3dc5a2e20fe63ef42 Mon Sep 17 00:00:00 2001 From: ruki Date: Wed, 17 Jul 2024 00:57:56 +0800 Subject: improve batchcmds --- xmake/modules/private/utils/batchcmds.lua | 28 +++++++++++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/xmake/modules/private/utils/batchcmds.lua b/xmake/modules/private/utils/batchcmds.lua index 3ea49ea8d..97f414c77 100644 --- a/xmake/modules/private/utils/batchcmds.lua +++ b/xmake/modules/private/utils/batchcmds.lua @@ -188,6 +188,20 @@ function _runcmd_insert_rpath(cmd, opt) end end +-- run command: remove rpath +function _runcmd_remove_rpath(cmd, opt) + if not opt.dryrun then + rpath_utils.remove(cmd.filepath, cmd.rpath, opt.opt) + end +end + +-- run command: change rpath +function _runcmd_change_rpath(cmd, opt) + if not opt.dryrun then + rpath_utils.change(cmd.filepath, cmd.rpath_old, cmd.rpath_new, opt.opt) + end +end + -- run command function _runcmd(cmd, opt) local kind = cmd.kind @@ -208,7 +222,9 @@ function _runcmd(cmd, opt) mv = _runcmd_mv, ln = _runcmd_ln, clean_rpath = _runcmd_clean_rpath, - insert_rpath = _runcmd_insert_rpath + insert_rpath = _runcmd_insert_rpath, + remove_rpath = _runcmd_remove_rpath, + change_rpath = _runcmd_change_rpath } _g.maps = maps end @@ -416,6 +432,16 @@ function batchcmds:insert_rpath(filepath, rpath, opt) table.insert(self:cmds(), {kind = "insert_rpath", filepath = filepath, rpath = rpath, opt = opt}) end +-- add command: remove rpath +function batchcmds:remove_rpath(filepath, rpath, opt) + table.insert(self:cmds(), {kind = "remove_rpath", filepath = filepath, rpath = rpath, opt = opt}) +end + +-- add command: change rpath +function batchcmds:change_rpath(filepath, rpath_old, rpath_new, opt) + table.insert(self:cmds(), {kind = "change_rpath", filepath = filepath, rpath_old = rpath_old, rpath_new = rpath_new, 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}) -- cgit v1.3.1 From df131f5ad79bc1e1da43ef796ce5e398c101059f Mon Sep 17 00:00:00 2001 From: ruki Date: Wed, 17 Jul 2024 21:01:24 +0800 Subject: enable soname --- tests/actions/install/xmake.lua | 2 +- xmake/modules/target/action/install/main.lua | 2 +- xmake/plugins/pack/batchcmds.lua | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/actions/install/xmake.lua b/tests/actions/install/xmake.lua index 18617c971..b12cb5dcd 100644 --- a/tests/actions/install/xmake.lua +++ b/tests/actions/install/xmake.lua @@ -1,6 +1,6 @@ add_rules("mode.debug", "mode.release") ---set_version("1.0.1", {soname = true}) +set_version("1.0.1", {soname = true}) add_requires("libplist", {system = false, configs = {shared = true}}) diff --git a/xmake/modules/target/action/install/main.lua b/xmake/modules/target/action/install/main.lua index aaa99c4f2..f8acc0e81 100644 --- a/xmake/modules/target/action/install/main.lua +++ b/xmake/modules/target/action/install/main.lua @@ -141,8 +141,8 @@ function _update_install_rpath(target, opt) end local bindir = target:bindir() local targetfile = path.join(bindir, target:filename()) - rpath_utils.clean(targetfile, {plat = target:plat(), arch = target:arch()}) if target:policy("install.rpath") then + rpath_utils.clean(targetfile, {plat = target:plat(), arch = target:arch()}) local result, sources = target:get_from("rpathdirs", "*") if result and sources then for idx, rpathdirs in ipairs(result) do diff --git a/xmake/plugins/pack/batchcmds.lua b/xmake/plugins/pack/batchcmds.lua index 6245a345c..767f86d75 100644 --- a/xmake/plugins/pack/batchcmds.lua +++ b/xmake/plugins/pack/batchcmds.lua @@ -109,8 +109,8 @@ function _update_target_install_rpath(target, batchcmds_, opt) 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 + batchcmds_:clean_rpath(targetfile, {plat = target:plat(), arch = target:arch()}) local result, sources = target:get_from("rpathdirs", "*") if result and sources then for idx, rpathdirs in ipairs(result) do -- cgit v1.3.1 From 168053862fba19e9db24ad9d1efa1091a084a8d8 Mon Sep 17 00:00:00 2001 From: ruki Date: Wed, 17 Jul 2024 22:35:58 +0800 Subject: fix extraconf --- xmake/modules/target/action/install/main.lua | 10 ++++++---- xmake/plugins/pack/batchcmds.lua | 10 ++++++---- 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/xmake/modules/target/action/install/main.lua b/xmake/modules/target/action/install/main.lua index f8acc0e81..0b5ac126e 100644 --- a/xmake/modules/target/action/install/main.lua +++ b/xmake/modules/target/action/install/main.lua @@ -148,10 +148,12 @@ function _update_install_rpath(target, opt) 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()}) + if extraconf then + 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 diff --git a/xmake/plugins/pack/batchcmds.lua b/xmake/plugins/pack/batchcmds.lua index 767f86d75..c41efb89d 100644 --- a/xmake/plugins/pack/batchcmds.lua +++ b/xmake/plugins/pack/batchcmds.lua @@ -116,10 +116,12 @@ function _update_target_install_rpath(target, batchcmds_, opt) 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()}) + if extraconf then + 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 -- 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(-) 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 5f5164528ab628cbd688782b9057e898f9a27cfe Mon Sep 17 00:00:00 2001 From: ruki Date: Wed, 17 Jul 2024 22:52:47 +0800 Subject: update test.lua for install --- tests/actions/install/test.lua | 4 +++- tests/actions/install/xmake.lua | 4 ++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/tests/actions/install/test.lua b/tests/actions/install/test.lua index 78173bac7..4edc90275 100644 --- a/tests/actions/install/test.lua +++ b/tests/actions/install/test.lua @@ -3,6 +3,8 @@ function main(t) os.vrun("xmake -y") os.vrun("xmake run app") os.vrun("xmake install -o build/usr") - os.vrun("./build/usr/app/bin/app" .. (is_host("windows") and ".exe" or "")) + if not is_host("linux") then -- TODO, change rpath has been not supported yet on linux. + os.vrun("./build/usr/app/bin/app" .. (is_host("windows") and ".exe" or "")) + end end end diff --git a/tests/actions/install/xmake.lua b/tests/actions/install/xmake.lua index b12cb5dcd..84f567239 100644 --- a/tests/actions/install/xmake.lua +++ b/tests/actions/install/xmake.lua @@ -10,14 +10,14 @@ target("foo") add_packages("libplist", {public = true}) add_headerfiles("src/foo.h", {public = true}) add_installfiles("src/foo.txt", {prefixdir = "assets", public = true}) --- set_prefixdir("/", {bindir = "foo_bin", libdir = "foo_lib"}) + set_prefixdir("/", {bindir = "foo_bin", libdir = "foo_lib"}) target("app") set_kind("binary") add_deps("foo") add_files("src/main.cpp") add_rpathdirs("@loader_path/../lib", {installonly = true}) --- set_prefixdir("app") + set_prefixdir("app") includes("@builtin/xpack") -- 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(-) 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 From 7f3f3a626757f7b9eb0f2334de2ae3ad43d16b99 Mon Sep 17 00:00:00 2001 From: ruki Date: Wed, 17 Jul 2024 22:56:13 +0800 Subject: improve uninstall path --- xmake/modules/target/action/uninstall/main.lua | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/xmake/modules/target/action/uninstall/main.lua b/xmake/modules/target/action/uninstall/main.lua index 8b8662f90..1c8b80ae9 100644 --- a/xmake/modules/target/action/uninstall/main.lua +++ b/xmake/modules/target/action/uninstall/main.lua @@ -25,13 +25,17 @@ import("utils.binary.deplibs", {alias = "get_depend_libraries"}) import("private.action.clean.remove_files") function _get_target_package_libfiles(target, opt) + if option.get("nopkgs") then + 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 @@ -44,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 @@ -91,15 +98,15 @@ end -- uninstall shared libraries function _uninstall_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})) @@ -111,6 +118,10 @@ function _uninstall_shared_libraries(target, opt) -- do uninstall 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) _remove_file_with_symbols(filepath) -- cgit v1.3.1 From f1b9376d8dcdddee617bff0b6a245f106238f813 Mon Sep 17 00:00:00 2001 From: ruki Date: Wed, 17 Jul 2024 22:56:58 +0800 Subject: improve install prefix for xpack --- xmake/plugins/pack/batchcmds.lua | 32 +++++++++++++++++++++++--------- 1 file changed, 23 insertions(+), 9 deletions(-) diff --git a/xmake/plugins/pack/batchcmds.lua b/xmake/plugins/pack/batchcmds.lua index c41efb89d..f810b934c 100644 --- a/xmake/plugins/pack/batchcmds.lua +++ b/xmake/plugins/pack/batchcmds.lua @@ -61,14 +61,15 @@ function _get_target_installdir(package, target) return path.normalize(installdir) end -function _get_target_package_libfiles(target, opt) +function _get_target_package_libfiles(package, target, opt) local libfiles = {} + local bindir = target:is_plat("windows", "mingw") and _get_target_bindir(package, target) or _get_target_libdir(package, target) 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 @@ -81,7 +82,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 @@ -170,26 +174,31 @@ end -- install target shared libraries function _install_target_shared_libraries(target, batchcmds_, opt) local package = opt.package - local bindir = target:is_plat("windows", "mingw") and _get_target_bindir(package, target) or _get_target_libdir(package, target) -- get all dependent shared libraries local libfiles = {} for _, dep in ipairs(target:orderdeps()) do + local bindir = dep:is_plat("windows", "mingw") and _get_target_bindir(package, dep) or _get_target_libdir(package, dep) 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})) + table.join2(libfiles, _get_target_package_libfiles(package, dep, {interface = true})) end - table.join2(libfiles, _get_target_package_libfiles(target)) + table.join2(libfiles, _get_target_package_libfiles(package, target)) -- deduplicate libfiles, prevent packages using the same libfiles from overwriting each other libfiles = table.unique(libfiles) -- 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) _copy_file_with_symlinks(batchcmds_, libfile, bindir) end @@ -228,15 +237,15 @@ end -- uninstall target shared libraries function _uninstall_target_shared_libraries(target, batchcmds_, opt) local package = opt.package - local bindir = target:is_plat("windows", "mingw") and _get_target_bindir(package, target) or _get_target_libdir(package, target) -- get all dependent shared libraries local libfiles = {} for _, dep in ipairs(target:orderdeps()) do + local bindir = dep:is_plat("windows", "mingw") and _get_target_bindir(package, dep) or _get_target_libdir(package, dep) 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})) @@ -248,6 +257,11 @@ function _uninstall_target_shared_libraries(target, batchcmds_, opt) -- do uninstall 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) batchcmds_:rm(libfile, path.join(bindir, filename), {emptydirs = true}) end -- cgit v1.3.1 From a6eb7d056ca136aa532abc39c9fdf78d6f8f4ebd Mon Sep 17 00:00:00 2001 From: ruki Date: Wed, 17 Jul 2024 22:58:45 +0800 Subject: use libzip as test --- tests/actions/install/xmake.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/actions/install/xmake.lua b/tests/actions/install/xmake.lua index 814ce51a5..6bab6d471 100644 --- a/tests/actions/install/xmake.lua +++ b/tests/actions/install/xmake.lua @@ -2,12 +2,12 @@ add_rules("mode.debug", "mode.release") set_version("1.0.1", {soname = true}) -add_requires("libplist", {system = false, configs = {shared = true}}) +add_requires("libzip", {system = false, configs = {shared = true}}) target("foo") set_kind("shared") add_files("src/foo.cpp") - add_packages("libplist", {public = true}) + add_packages("libzip", {public = true}) add_headerfiles("src/foo.h", {public = true}) add_installfiles("src/foo.txt", {prefixdir = "assets", public = true}) set_prefixdir("/", {bindir = "foo_bin", libdir = "foo_lib"}) -- cgit v1.3.1 From 95c8f8615eb91de863c1eebeb27bb5c1c5e409a7 Mon Sep 17 00:00:00 2001 From: ruki Date: Wed, 17 Jul 2024 23:08:15 +0800 Subject: fix bindir for test --- tests/actions/install/xmake.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/actions/install/xmake.lua b/tests/actions/install/xmake.lua index 6bab6d471..f21deb5db 100644 --- a/tests/actions/install/xmake.lua +++ b/tests/actions/install/xmake.lua @@ -10,7 +10,7 @@ target("foo") add_packages("libzip", {public = true}) add_headerfiles("src/foo.h", {public = true}) add_installfiles("src/foo.txt", {prefixdir = "assets", public = true}) - set_prefixdir("/", {bindir = "foo_bin", libdir = "foo_lib"}) + set_prefixdir("/", {libdir = "foo_lib"}) add_rpathdirs("@loader_path/../../foo_lib", {installonly = true, public = true}) target("app") -- cgit v1.3.1 From 9310167ec7254b065e687cba9740902939c005fd Mon Sep 17 00:00:00 2001 From: ruki Date: Wed, 17 Jul 2024 23:51:28 +0800 Subject: revert bindir --- tests/actions/install/xmake.lua | 4 ++-- xmake/modules/target/action/install/main.lua | 16 ++++--------- xmake/modules/target/action/uninstall/main.lua | 8 ++----- xmake/plugins/pack/batchcmds.lua | 32 ++++++++------------------ 4 files changed, 17 insertions(+), 43 deletions(-) diff --git a/tests/actions/install/xmake.lua b/tests/actions/install/xmake.lua index f21deb5db..652857116 100644 --- a/tests/actions/install/xmake.lua +++ b/tests/actions/install/xmake.lua @@ -11,13 +11,13 @@ target("foo") add_headerfiles("src/foo.h", {public = true}) add_installfiles("src/foo.txt", {prefixdir = "assets", public = true}) set_prefixdir("/", {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") - set_prefixdir("app") + set_prefixdir("app", {libdir = "app_lib"}) + add_rpathdirs("@loader_path/../app_lib", {installonly = true}) includes("@builtin/xpack") diff --git a/xmake/modules/target/action/install/main.lua b/xmake/modules/target/action/install/main.lua index 9e5e0c54c..0b5ac126e 100644 --- a/xmake/modules/target/action/install/main.lua +++ b/xmake/modules/target/action/install/main.lua @@ -29,13 +29,12 @@ 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, path.joinenv({libfile, bindir})) + table.insert(libfiles, libfile) end end end @@ -48,10 +47,7 @@ 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) - libfile = path.splitenv(libfile)[1] - return not depends:has(path.filename(libfile)) - end) + table.remove_if(libfiles, function (_, libfile) return not depends:has(path.filename(libfile)) end) end return libfiles end @@ -108,15 +104,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, path.joinenv({depfile, bindir})) + table.insert(libfiles, depfile) end end table.join2(libfiles, _get_target_package_libfiles(dep, {interface = true})) @@ -128,10 +124,6 @@ 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/target/action/uninstall/main.lua b/xmake/modules/target/action/uninstall/main.lua index 1c8b80ae9..2b082d3cb 100644 --- a/xmake/modules/target/action/uninstall/main.lua +++ b/xmake/modules/target/action/uninstall/main.lua @@ -98,15 +98,15 @@ end -- uninstall shared libraries function _uninstall_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, path.joinenv({depfile, bindir})) + table.insert(libfiles, depfile) end end table.join2(libfiles, _get_target_package_libfiles(dep, {interface = true})) @@ -118,10 +118,6 @@ function _uninstall_shared_libraries(target, opt) -- do uninstall 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) _remove_file_with_symbols(filepath) diff --git a/xmake/plugins/pack/batchcmds.lua b/xmake/plugins/pack/batchcmds.lua index f810b934c..c41efb89d 100644 --- a/xmake/plugins/pack/batchcmds.lua +++ b/xmake/plugins/pack/batchcmds.lua @@ -61,15 +61,14 @@ function _get_target_installdir(package, target) return path.normalize(installdir) end -function _get_target_package_libfiles(package, target, opt) +function _get_target_package_libfiles(target, opt) local libfiles = {} - local bindir = target:is_plat("windows", "mingw") and _get_target_bindir(package, target) or _get_target_libdir(package, target) 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, path.joinenv({libfile, bindir})) + table.insert(libfiles, libfile) end end end @@ -82,10 +81,7 @@ function _get_target_package_libfiles(package, target, opt) for _, libfile in ipairs(depend_libraries) do depends:insert(path.filename(libfile)) end - table.remove_if(libfiles, function (_, libfile) - libfile = path.splitenv(libfile)[1] - return not depends:has(path.filename(libfile)) - end) + table.remove_if(libfiles, function (_, libfile) return not depends:has(path.filename(libfile)) end) end return libfiles end @@ -174,31 +170,26 @@ end -- install target shared libraries function _install_target_shared_libraries(target, batchcmds_, opt) local package = opt.package + local bindir = target:is_plat("windows", "mingw") and _get_target_bindir(package, target) or _get_target_libdir(package, target) -- get all dependent shared libraries local libfiles = {} for _, dep in ipairs(target:orderdeps()) do - local bindir = dep:is_plat("windows", "mingw") and _get_target_bindir(package, dep) or _get_target_libdir(package, dep) if dep:kind() == "shared" then local depfile = dep:targetfile() if os.isfile(depfile) then - table.insert(libfiles, path.joinenv({depfile, bindir})) + table.insert(libfiles, depfile) end end - table.join2(libfiles, _get_target_package_libfiles(package, dep, {interface = true})) + table.join2(libfiles, _get_target_package_libfiles(dep, {interface = true})) end - table.join2(libfiles, _get_target_package_libfiles(package, target)) + table.join2(libfiles, _get_target_package_libfiles(target)) -- deduplicate libfiles, prevent packages using the same libfiles from overwriting each other libfiles = table.unique(libfiles) -- 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) _copy_file_with_symlinks(batchcmds_, libfile, bindir) end @@ -237,15 +228,15 @@ end -- uninstall target shared libraries function _uninstall_target_shared_libraries(target, batchcmds_, opt) local package = opt.package + local bindir = target:is_plat("windows", "mingw") and _get_target_bindir(package, target) or _get_target_libdir(package, target) -- get all dependent shared libraries local libfiles = {} for _, dep in ipairs(target:orderdeps()) do - local bindir = dep:is_plat("windows", "mingw") and _get_target_bindir(package, dep) or _get_target_libdir(package, dep) if dep:kind() == "shared" then local depfile = dep:targetfile() if os.isfile(depfile) then - table.insert(libfiles, path.joinenv({depfile, bindir})) + table.insert(libfiles, depfile) end end table.join2(libfiles, _get_target_package_libfiles(dep, {interface = true})) @@ -257,11 +248,6 @@ function _uninstall_target_shared_libraries(target, batchcmds_, opt) -- do uninstall 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) batchcmds_:rm(libfile, path.join(bindir, filename), {emptydirs = true}) end -- cgit v1.3.1 From 6a405fa54114a513213c4000de3ca88dd1a4f337 Mon Sep 17 00:00:00 2001 From: ruki Date: Thu, 18 Jul 2024 00:56:51 +0800 Subject: fix os.rm --- xmake/core/base/os.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/xmake/core/base/os.lua b/xmake/core/base/os.lua index b0545afc8..9160aa534 100644 --- a/xmake/core/base/os.lua +++ b/xmake/core/base/os.lua @@ -503,7 +503,7 @@ function os.rm(filepath, opt) return false, errors end if opt.emptydirs then - ok, errors = os._rm_empty_parentdirs(filepath) + ok, errors = os._rm_empty_parentdirs(_filepath) if not ok then return false, errors end -- cgit v1.3.1 From 5169dfdf8677bad2aaf1b74b73176578f8b390af Mon Sep 17 00:00:00 2001 From: ruki Date: Fri, 19 Jul 2024 22:37:49 +0800 Subject: fix clean all --- xmake/actions/clean/main.lua | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/xmake/actions/clean/main.lua b/xmake/actions/clean/main.lua index 6470208d5..4d149584e 100644 --- a/xmake/actions/clean/main.lua +++ b/xmake/actions/clean/main.lua @@ -104,16 +104,16 @@ end -- clean target function _clean(targetname) - - -- clean the given target if targetname then local target = project.target(targetname) _clean_target(target) else _clean_targets(project.ordertargets()) end +end - -- remove the configure directory if remove all +-- clean configuration cache +function _clean_configs() if option.get("all") then remove_files(config.directory()) end @@ -142,7 +142,6 @@ function _try_clean() end end --- main function main() -- try cleaning it using third-party buildsystem if xmake.lua not exists @@ -176,6 +175,9 @@ function main() -- unlock the whole project project.unlock() + -- we must call it after unlocking project because it will remove project lockfile + _clean_configs() + -- leave project directory os.cd(oldir) end -- cgit v1.3.1 From 835d8e7bc6e5488c5e9fcb88b8fa56f4f4694e38 Mon Sep 17 00:00:00 2001 From: ruki Date: Fri, 19 Jul 2024 22:58:13 +0800 Subject: fix os.rm and uninstall modules --- xmake/core/sandbox/modules/os.lua | 16 ++++++++-------- .../c++/modules/modules_support/compiler_support.lua | 2 +- xmake/rules/c++/modules/xmake.lua | 9 ++++++++- 3 files changed, 17 insertions(+), 10 deletions(-) diff --git a/xmake/core/sandbox/modules/os.lua b/xmake/core/sandbox/modules/os.lua index 9004f66ee..d626d0372 100644 --- a/xmake/core/sandbox/modules/os.lua +++ b/xmake/core/sandbox/modules/os.lua @@ -102,21 +102,21 @@ function sandbox_os.cp(srcpath, dstpath, opt) end -- move file or directory -function sandbox_os.mv(srcpath, dstpath) +function sandbox_os.mv(srcpath, dstpath, opt) assert(srcpath and dstpath) srcpath = tostring(srcpath) dstpath = tostring(dstpath) - local ok, errors = os.mv(vformat(srcpath), vformat(dstpath)) + local ok, errors = os.mv(vformat(srcpath), vformat(dstpath), opt) if not ok then os.raise(errors) end end -- remove files or directories -function sandbox_os.rm(filepath) +function sandbox_os.rm(filepath, opt) assert(filepath) filepath = tostring(filepath) - local ok, errors = os.rm(vformat(filepath)) + local ok, errors = os.rm(vformat(filepath), opt) if not ok then os.raise(errors) end @@ -161,12 +161,12 @@ function sandbox_os.vrm(filepath, opt) end -- link file or directory with the verbose info -function sandbox_os.vln(srcpath, dstpath) +function sandbox_os.vln(srcpath, dstpath, opt) assert(srcpath and dstpath) if option.get("verbose") then utils.cprint("${dim}> link %s to %s", srcpath, dstpath) end - return sandbox_os.ln(srcpath, dstpath) + return sandbox_os.ln(srcpath, dstpath, opt) end -- try to copy file or directory @@ -176,9 +176,9 @@ function sandbox_os.trycp(srcpath, dstpath, opt) end -- try to move file or directory -function sandbox_os.trymv(srcpath, dstpath) +function sandbox_os.trymv(srcpath, dstpath, opt) assert(srcpath and dstpath) - return os.mv(vformat(srcpath), vformat(dstpath)) + return os.mv(vformat(srcpath), vformat(dstpath), opt) end -- try to remove files or directories diff --git a/xmake/rules/c++/modules/modules_support/compiler_support.lua b/xmake/rules/c++/modules/modules_support/compiler_support.lua index 72e7b93fd..a005dc80d 100644 --- a/xmake/rules/c++/modules/modules_support/compiler_support.lua +++ b/xmake/rules/c++/modules/modules_support/compiler_support.lua @@ -293,7 +293,7 @@ function get_provided_module(module) return name, provide, cppfile end -function install_module_target(target) +function add_installfiles_for_modules(target) local sourcebatch = target:sourcebatches()["c++.build.modules.install"] if sourcebatch and sourcebatch.sourcefiles then for _, sourcefile in ipairs(sourcebatch.sourcefiles) do diff --git a/xmake/rules/c++/modules/xmake.lua b/xmake/rules/c++/modules/xmake.lua index 90ba66c81..d658815aa 100644 --- a/xmake/rules/c++/modules/xmake.lua +++ b/xmake/rules/c++/modules/xmake.lua @@ -227,6 +227,13 @@ rule("c++.build.modules.install") local modules = compiler_support.localcache():get2(target:name(), "c++.modules") builder.generate_metadata(target, modules) - compiler_support.install_module_target(target) + compiler_support.add_installfiles_for_modules(target) + end + end) + + before_uninstall(function (target) + import("modules_support.compiler_support") + if compiler_support.contains_modules(target) then + compiler_support.add_installfiles_for_modules(target) end end) -- cgit v1.3.1 From 621441fbd2f0f1792aa2fb03aa7c485793003820 Mon Sep 17 00:00:00 2001 From: ruki Date: Fri, 19 Jul 2024 23:43:37 +0800 Subject: fix clean -a --- xmake/actions/clean/main.lua | 2 ++ 1 file changed, 2 insertions(+) diff --git a/xmake/actions/clean/main.lua b/xmake/actions/clean/main.lua index 4d149584e..413a3121e 100644 --- a/xmake/actions/clean/main.lua +++ b/xmake/actions/clean/main.lua @@ -115,6 +115,8 @@ end -- clean configuration cache function _clean_configs() if option.get("all") then + -- we need to close it first after removing file lock + project.filelock():close() remove_files(config.directory()) end end -- cgit v1.3.1 From 7aaf46f34749b39067bf9c70ba08138ec2708497 Mon Sep 17 00:00:00 2001 From: ruki Date: Mon, 22 Jul 2024 23:59:34 +0800 Subject: improve to find dll --- xmake/modules/package/manager/xmake/find_package.lua | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/xmake/modules/package/manager/xmake/find_package.lua b/xmake/modules/package/manager/xmake/find_package.lua index 0d5336fe4..e3aed1294 100644 --- a/xmake/modules/package/manager/xmake/find_package.lua +++ b/xmake/modules/package/manager/xmake/find_package.lua @@ -167,6 +167,13 @@ function _find_package_from_repo(name, opt) result.shared = true table.insert(libfiles, file) end + -- @see https://github.com/xmake-io/xmake/issues/5325#issuecomment-2242513463 + if not result.shared then + for _, file in ipairs(os.files(path.join(installdir, "**.dll"))) do + result.shared = true + table.insert(libfiles, file) + end + end end -- add root link directories -- cgit v1.3.1 From 56ca5adad669d45f400198b0c99a1d20f546970c Mon Sep 17 00:00:00 2001 From: ruki Date: Tue, 23 Jul 2024 00:41:48 +0800 Subject: improve to get deplibs --- xmake/modules/target/action/install/main.lua | 26 ++++++++++++++++---- xmake/modules/target/action/uninstall/main.lua | 33 ++++++++++++++++++-------- xmake/plugins/pack/batchcmds.lua | 26 ++++++++++++++++---- 3 files changed, 65 insertions(+), 20 deletions(-) diff --git a/xmake/modules/target/action/install/main.lua b/xmake/modules/target/action/install/main.lua index 0b5ac126e..6eecfaba4 100644 --- a/xmake/modules/target/action/install/main.lua +++ b/xmake/modules/target/action/install/main.lua @@ -24,6 +24,26 @@ import("core.base.hashset") import("utils.binary.deplibs", {alias = "get_depend_libraries"}) import("utils.binary.rpath", {alias = "rpath_utils"}) +-- we need to get all deplibs, e.g. app -> libfoo.so -> libbar.so ... +-- @see https://github.com/xmake-io/xmake/issues/5325#issuecomment-2242597732 +function _get_target_package_deplibs(target, depends, libfiles, binaryfile) + local deplibs = get_depend_libraries(binaryfile, {plat = target:plat(), arch = target:arch()}) + local depends_new = hashset.new() + for _, deplib in ipairs(deplibs) do + local libname = path.filename(deplib) + if not depends:has(libname) then + depends:insert(libname) + depends_new:insert(libname) + end + end + for _, libfile in ipairs(libfiles) do + local libname = path.filename(libfile) + if depends_new:has(libname) then + _get_target_package_deplibs(target, depends, libfiles, libfile) + end + end +end + function _get_target_package_libfiles(target, opt) if option.get("nopkgs") then return {} @@ -42,11 +62,7 @@ function _get_target_package_libfiles(target, opt) -- we can only reserve used libraries if target:is_binary() or target:is_shared() then local depends = hashset.new() - local targetfile = target:targetfile() - local depend_libraries = get_depend_libraries(targetfile, {plat = target:plat(), arch = target:arch()}) - for _, libfile in ipairs(depend_libraries) do - depends:insert(path.filename(libfile)) - end + _get_target_package_deplibs(target, depends, libfiles, target:targetfile()) table.remove_if(libfiles, function (_, libfile) return not depends:has(path.filename(libfile)) end) end return libfiles diff --git a/xmake/modules/target/action/uninstall/main.lua b/xmake/modules/target/action/uninstall/main.lua index 2b082d3cb..ab2333207 100644 --- a/xmake/modules/target/action/uninstall/main.lua +++ b/xmake/modules/target/action/uninstall/main.lua @@ -24,6 +24,26 @@ import("core.base.hashset") import("utils.binary.deplibs", {alias = "get_depend_libraries"}) import("private.action.clean.remove_files") +-- we need to get all deplibs, e.g. app -> libfoo.so -> libbar.so ... +-- @see https://github.com/xmake-io/xmake/issues/5325#issuecomment-2242597732 +function _get_target_package_deplibs(target, depends, libfiles, binaryfile) + local deplibs = get_depend_libraries(binaryfile, {plat = target:plat(), arch = target:arch()}) + local depends_new = hashset.new() + for _, deplib in ipairs(deplibs) do + local libname = path.filename(deplib) + if not depends:has(libname) then + depends:insert(libname) + depends_new:insert(libname) + end + end + for _, libfile in ipairs(libfiles) do + local libname = path.filename(libfile) + if depends_new:has(libname) then + _get_target_package_deplibs(target, depends, libfiles, libfile) + end + end +end + function _get_target_package_libfiles(target, opt) if option.get("nopkgs") then return {} @@ -35,7 +55,7 @@ function _get_target_package_libfiles(target, opt) 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, path.joinenv({libfile, bindir})) + table.insert(libfiles, libfile) end end end @@ -43,15 +63,8 @@ function _get_target_package_libfiles(target, opt) -- we can only reserve used libraries if target:is_binary() or target:is_shared() then local depends = hashset.new() - local targetfile = target:targetfile() - local depend_libraries = get_depend_libraries(targetfile, {plat = target:plat(), arch = target:arch()}) - for _, libfile in ipairs(depend_libraries) do - depends:insert(path.filename(libfile)) - end - table.remove_if(libfiles, function (_, libfile) - libfile = path.splitenv(libfile)[1] - return not depends:has(path.filename(libfile)) - end) + _get_target_package_deplibs(target, depends, libfiles, target:targetfile()) + table.remove_if(libfiles, function (_, libfile) return not depends:has(path.filename(libfile)) end) end return libfiles end diff --git a/xmake/plugins/pack/batchcmds.lua b/xmake/plugins/pack/batchcmds.lua index c41efb89d..4017ed175 100644 --- a/xmake/plugins/pack/batchcmds.lua +++ b/xmake/plugins/pack/batchcmds.lua @@ -61,6 +61,26 @@ function _get_target_installdir(package, target) return path.normalize(installdir) end +-- we need to get all deplibs, e.g. app -> libfoo.so -> libbar.so ... +-- @see https://github.com/xmake-io/xmake/issues/5325#issuecomment-2242597732 +function _get_target_package_deplibs(target, depends, libfiles, binaryfile) + local deplibs = get_depend_libraries(binaryfile, {plat = target:plat(), arch = target:arch()}) + local depends_new = hashset.new() + for _, deplib in ipairs(deplibs) do + local libname = path.filename(deplib) + if not depends:has(libname) then + depends:insert(libname) + depends_new:insert(libname) + end + end + for _, libfile in ipairs(libfiles) do + local libname = path.filename(libfile) + if depends_new:has(libname) then + _get_target_package_deplibs(target, depends, libfiles, libfile) + end + end +end + function _get_target_package_libfiles(target, opt) local libfiles = {} for _, pkg in ipairs(target:orderpkgs(opt)) do @@ -76,11 +96,7 @@ function _get_target_package_libfiles(target, opt) -- we can only reserve used libraries if target:is_binary() or target:is_shared() then local depends = hashset.new() - local targetfile = target:targetfile() - local depend_libraries = get_depend_libraries(targetfile, {plat = target:plat(), arch = target:arch()}) - for _, libfile in ipairs(depend_libraries) do - depends:insert(path.filename(libfile)) - end + _get_target_package_deplibs(target, depends, libfiles, target:targetfile()) table.remove_if(libfiles, function (_, libfile) return not depends:has(path.filename(libfile)) end) end return libfiles -- cgit v1.3.1