From fa9ee3e5fb4a612d2314a67ab396d0c1e85196c4 Mon Sep 17 00:00:00 2001 From: Arthur LAURENT Date: Wed, 6 Mar 2024 20:02:22 +0100 Subject: fix toolchain directory for libc++ linking and enable rpath --- xmake/modules/core/tools/clang.lua | 32 ++++++++++++++++++++++++++++++-- 1 file changed, 30 insertions(+), 2 deletions(-) diff --git a/xmake/modules/core/tools/clang.lua b/xmake/modules/core/tools/clang.lua index c2bb5a72c..04c261879 100644 --- a/xmake/modules/core/tools/clang.lua +++ b/xmake/modules/core/tools/clang.lua @@ -207,6 +207,19 @@ function _get_llvm_rootdir(self) return llvm_rootdir or nil end +-- get llvm target triple +function _get_llvm_target_triple(self) + local llvm_targettriple = _g._LLVM_TARGETTRIPLE + if llvm_targettriple == nil then + local outdata = try { function() return os.iorun(self:program() .. " -print-target-triple") end } + if outdata then + llvm_targettriple = outdata:trim() + end + _g._LLVM_TARGETTRIPLE = llvm_targettriple or false + end + return llvm_targettriple or nil +end + -- make the runtime flag -- @see https://github.com/xmake-io/xmake/issues/3546 function nf_runtime(self, runtime, opt) @@ -267,8 +280,23 @@ function nf_runtime(self, runtime, opt) llvm_rootdir = _get_llvm_rootdir(self) end if llvm_rootdir then - maps["c++_static"] = table.join(maps["c++_static"], "-L" .. path.join(llvm_rootdir, "lib")) - maps["c++_shared"] = table.join(maps["c++_shared"], "-L" .. path.join(llvm_rootdir, "lib")) + local libdir = path.join(llvm_rootdir, "lib") + maps["c++_static"] = table.join(maps["c++_static"], "-L" .. libdir) + maps["c++_shared"] = table.join(maps["c++_shared"], "-L" .. libdir) + -- sometimes llvm runtimes are located in a target-triple subfolder + local target_triple = _get_llvm_target_triple(self) + local triple_libdir = (target_triple and os.isdir(path.join(libdir, target_triple))) and path.join(libdir, target_triple) + if triple_libdir then + maps["c++_static"] = table.join(maps["c++_static"], "-L" .. triple_libdir) + maps["c++_shared"] = table.join(maps["c++_shared"], "-L" .. triple_libdir) + end + -- add rpath to avoid the user need to set LD_LIBRARY_PATH by hand + if not self:is_plat("windows") and not self:is_plat("mingw") then + maps["c++_shared"] = table.join(maps["c++_shared"], "-Wl,-rpath=" .. libdir) + if triple_libdir then + maps["c++_shared"] = table.join(maps["c++_shared"], "-Wl,-rpath=" .. triple_libdir) + end + end end if runtime:endswith("_static") and _has_static_libstdcxx(self) then maps["c++_static"] = table.join(maps["c++_static"], "-static-libstdc++") -- cgit v1.3.1 From 5cdb2e09ea9a9babf430aac01397665151f9518c Mon Sep 17 00:00:00 2001 From: Arthur LAURENT Date: Wed, 6 Mar 2024 20:26:04 +0100 Subject: use absolute path for llvm runtime libdir --- xmake/modules/core/tools/clang.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/xmake/modules/core/tools/clang.lua b/xmake/modules/core/tools/clang.lua index 04c261879..5cd32ce04 100644 --- a/xmake/modules/core/tools/clang.lua +++ b/xmake/modules/core/tools/clang.lua @@ -280,7 +280,7 @@ function nf_runtime(self, runtime, opt) llvm_rootdir = _get_llvm_rootdir(self) end if llvm_rootdir then - local libdir = path.join(llvm_rootdir, "lib") + local libdir = path.absolute(path.join(llvm_rootdir, "lib")) maps["c++_static"] = table.join(maps["c++_static"], "-L" .. libdir) maps["c++_shared"] = table.join(maps["c++_shared"], "-L" .. libdir) -- sometimes llvm runtimes are located in a target-triple subfolder -- cgit v1.3.1 From 2c67c028dffe3e456e8b9ac16296ef042629b88b Mon Sep 17 00:00:00 2001 From: Arthur LAURENT Date: Wed, 6 Mar 2024 20:47:42 +0100 Subject: apply PR suggestion --- xmake/modules/core/tools/clang.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/xmake/modules/core/tools/clang.lua b/xmake/modules/core/tools/clang.lua index 5cd32ce04..9e0e23cd2 100644 --- a/xmake/modules/core/tools/clang.lua +++ b/xmake/modules/core/tools/clang.lua @@ -291,7 +291,7 @@ function nf_runtime(self, runtime, opt) maps["c++_shared"] = table.join(maps["c++_shared"], "-L" .. triple_libdir) end -- add rpath to avoid the user need to set LD_LIBRARY_PATH by hand - if not self:is_plat("windows") and not self:is_plat("mingw") then + if not self:is_plat("windows", "mingw") then maps["c++_shared"] = table.join(maps["c++_shared"], "-Wl,-rpath=" .. libdir) if triple_libdir then maps["c++_shared"] = table.join(maps["c++_shared"], "-Wl,-rpath=" .. triple_libdir) -- cgit v1.3.1 From a7a6202288ae1975bb2f9a710786912b7cceda84 Mon Sep 17 00:00:00 2001 From: Arthur LAURENT Date: Thu, 7 Mar 2024 11:28:39 +0100 Subject: use iorunv and pass runenvs to llvm triple detection --- xmake/modules/core/tools/clang.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/xmake/modules/core/tools/clang.lua b/xmake/modules/core/tools/clang.lua index 9e0e23cd2..79a274a21 100644 --- a/xmake/modules/core/tools/clang.lua +++ b/xmake/modules/core/tools/clang.lua @@ -195,7 +195,7 @@ end function _get_llvm_rootdir(self) local llvm_rootdir = _g._LLVM_ROOTDIR if llvm_rootdir == nil then - local outdata = try { function() return os.iorun(self:program() .. " -print-resource-dir") end } + local outdata = try { function() return os.iorunv(self:program(), {"-print-resource-dir"}, {envs = self:runenvs()}) end } if outdata then llvm_rootdir = path.normalize(path.join(outdata:trim(), "..", "..", "..")) if not os.isdir(llvm_rootdir) then @@ -211,7 +211,7 @@ end function _get_llvm_target_triple(self) local llvm_targettriple = _g._LLVM_TARGETTRIPLE if llvm_targettriple == nil then - local outdata = try { function() return os.iorun(self:program() .. " -print-target-triple") end } + local outdata = try { function() return os.iorunv(self:program(), {"-print-target-triple"}, {envs = self:runenvs()}) end } if outdata then llvm_targettriple = outdata:trim() end -- cgit v1.3.1 From a6b26e0f93bfaa55ec6033501437df73efca1934 Mon Sep 17 00:00:00 2001 From: Arthur LAURENT Date: Thu, 7 Mar 2024 11:36:26 +0100 Subject: handle macOS with native clang driver rpath flag --- xmake/modules/core/tools/clang.lua | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/xmake/modules/core/tools/clang.lua b/xmake/modules/core/tools/clang.lua index 79a274a21..78806fe13 100644 --- a/xmake/modules/core/tools/clang.lua +++ b/xmake/modules/core/tools/clang.lua @@ -291,11 +291,20 @@ function nf_runtime(self, runtime, opt) maps["c++_shared"] = table.join(maps["c++_shared"], "-L" .. triple_libdir) end -- add rpath to avoid the user need to set LD_LIBRARY_PATH by hand - if not self:is_plat("windows", "mingw") then - maps["c++_shared"] = table.join(maps["c++_shared"], "-Wl,-rpath=" .. libdir) + local rpath_flags + if self:has_flags("-Wl,-rpath=" .. libdir, "ldflags") then + rpath_flags = {"-Wl,-rpath=" .. libdir} if triple_libdir then - maps["c++_shared"] = table.join(maps["c++_shared"], "-Wl,-rpath=" .. triple_libdir) + table.join2(rpath_flags, "-Wl,-rpath=" .. triple_libdir) end + elseif self:has_flags("-Xlinker -rpath -Xlinker " .. libdir, "ldflags") then + rpath_flags = {"-Xlinker", "-rpath", "-Xlinker", (libdir:gsub("%$ORIGIN", "@loader_path"))} + if triple_libdir then + table.join2(rpath_flags, {"-Xlinker", "-rpath", "-Xlinker", (triple_libdir:gsub("%$ORIGIN", "@loader_path"))}) + end + end + if rpath_flags then + maps["c++_shared"] = table.join(maps["c++_shared"], rpath_flags) end end if runtime:endswith("_static") and _has_static_libstdcxx(self) then -- cgit v1.3.1 From b4c3a3eb56fe7a00a49706c37121d0125d84d09f Mon Sep 17 00:00:00 2001 From: Arthur LAURENT Date: Thu, 7 Mar 2024 12:00:04 +0100 Subject: improve rpath for clang linux --- xmake/modules/core/tools/clang.lua | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/xmake/modules/core/tools/clang.lua b/xmake/modules/core/tools/clang.lua index 78806fe13..39f90025b 100644 --- a/xmake/modules/core/tools/clang.lua +++ b/xmake/modules/core/tools/clang.lua @@ -293,9 +293,19 @@ function nf_runtime(self, runtime, opt) -- add rpath to avoid the user need to set LD_LIBRARY_PATH by hand local rpath_flags if self:has_flags("-Wl,-rpath=" .. libdir, "ldflags") then - rpath_flags = {"-Wl,-rpath=" .. libdir} + rpath_flags = {"-Wl,-rpath=" .. (libdir:gsub("@[%w_]+", function (name) + local maps = {["@loader_path"] = "$ORIGIN", ["@executable_path"] = "$ORIGIN"} + return maps[name] + end))} if triple_libdir then - table.join2(rpath_flags, "-Wl,-rpath=" .. triple_libdir) + table.join2(rpath_flags, "-Wl,-rpath=" .. (triple_libdir:gsub("@[%w_]+", function (name) + local maps = {["@loader_path"] = "$ORIGIN", ["@executable_path"] = "$ORIGIN"} + return maps[name] + end))) + end + if self:is_plat("bsd") then + -- FreeBSD ld must have "-zorigin" with "-rpath". Otherwise, $ORIGIN is not translated and it is literal. + table.insert(rpath_flags, 1, "-Wl,-zorigin") end elseif self:has_flags("-Xlinker -rpath -Xlinker " .. libdir, "ldflags") then rpath_flags = {"-Xlinker", "-rpath", "-Xlinker", (libdir:gsub("%$ORIGIN", "@loader_path"))} -- cgit v1.3.1 From c41b27e31ea3f52a9b9ae69809aeb431d6e5fe9b Mon Sep 17 00:00:00 2001 From: Arthur LAURENT Date: Thu, 7 Mar 2024 12:04:54 +0100 Subject: improve rpath support for clang macOS --- xmake/modules/core/tools/clang.lua | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/xmake/modules/core/tools/clang.lua b/xmake/modules/core/tools/clang.lua index 39f90025b..5da649779 100644 --- a/xmake/modules/core/tools/clang.lua +++ b/xmake/modules/core/tools/clang.lua @@ -314,6 +314,10 @@ function nf_runtime(self, runtime, opt) end end if rpath_flags then + if target:kind() == "shared" and self:is_plat("macosx", "iphoneos", "watchos") then + table.insert(rpath_flags, "-install_name") + table.insert(rpath_flags, "@rpath/" .. path.filename(target:filename())) + end maps["c++_shared"] = table.join(maps["c++_shared"], rpath_flags) end end -- cgit v1.3.1 From 4f712dbed258b887da87334522c0b85fa4c80381 Mon Sep 17 00:00:00 2001 From: Arthur LAURENT Date: Thu, 7 Mar 2024 12:10:39 +0100 Subject: simplify --- xmake/modules/core/tools/clang.lua | 51 ++++++++++++++++++-------------------- 1 file changed, 24 insertions(+), 27 deletions(-) diff --git a/xmake/modules/core/tools/clang.lua b/xmake/modules/core/tools/clang.lua index 5da649779..907264ce8 100644 --- a/xmake/modules/core/tools/clang.lua +++ b/xmake/modules/core/tools/clang.lua @@ -220,6 +220,24 @@ function _get_llvm_target_triple(self) return llvm_targettriple or nil end +-- make the rpathdir flag +function rpathdir(self, dir) + dir = path.translate(dir) + if self:has_flags("-Wl,-rpath=" .. dir, "ldflags") then + local flags = {"-Wl,-rpath=" .. (dir:gsub("@[%w_]+", function (name) + local maps = {["@loader_path"] = "$ORIGIN", ["@executable_path"] = "$ORIGIN"} + return maps[name] + end))} + if self:is_plat("bsd") then + -- FreeBSD ld must have "-zorigin" with "-rpath". Otherwise, $ORIGIN is not translated and it is literal. + table.insert(flags, 1, "-Wl,-zorigin") + end + return flags + elseif self:has_flags("-Xlinker -rpath -Xlinker " .. dir, "ldflags") then + return {"-Xlinker", "-rpath", "-Xlinker", (dir:gsub("%$ORIGIN", "@loader_path"))} + end +end + -- make the runtime flag -- @see https://github.com/xmake-io/xmake/issues/3546 function nf_runtime(self, runtime, opt) @@ -291,34 +309,13 @@ function nf_runtime(self, runtime, opt) maps["c++_shared"] = table.join(maps["c++_shared"], "-L" .. triple_libdir) end -- add rpath to avoid the user need to set LD_LIBRARY_PATH by hand - local rpath_flags - if self:has_flags("-Wl,-rpath=" .. libdir, "ldflags") then - rpath_flags = {"-Wl,-rpath=" .. (libdir:gsub("@[%w_]+", function (name) - local maps = {["@loader_path"] = "$ORIGIN", ["@executable_path"] = "$ORIGIN"} - return maps[name] - end))} - if triple_libdir then - table.join2(rpath_flags, "-Wl,-rpath=" .. (triple_libdir:gsub("@[%w_]+", function (name) - local maps = {["@loader_path"] = "$ORIGIN", ["@executable_path"] = "$ORIGIN"} - return maps[name] - end))) - end - if self:is_plat("bsd") then - -- FreeBSD ld must have "-zorigin" with "-rpath". Otherwise, $ORIGIN is not translated and it is literal. - table.insert(rpath_flags, 1, "-Wl,-zorigin") - end - elseif self:has_flags("-Xlinker -rpath -Xlinker " .. libdir, "ldflags") then - rpath_flags = {"-Xlinker", "-rpath", "-Xlinker", (libdir:gsub("%$ORIGIN", "@loader_path"))} - if triple_libdir then - table.join2(rpath_flags, {"-Xlinker", "-rpath", "-Xlinker", (triple_libdir:gsub("%$ORIGIN", "@loader_path"))}) - end + maps["c++_shared"] = table.join(maps["c++_shared"], rpathdir(self, libdir)) + if triple_libdir then + maps["c++_shared"] = table.join(maps["c++_shared"], rpathdir(self, triple_libdir)) end - if rpath_flags then - if target:kind() == "shared" and self:is_plat("macosx", "iphoneos", "watchos") then - table.insert(rpath_flags, "-install_name") - table.insert(rpath_flags, "@rpath/" .. path.filename(target:filename())) - end - maps["c++_shared"] = table.join(maps["c++_shared"], rpath_flags) + if target:kind() == "shared" and self:is_plat("macosx", "iphoneos", "watchos") then + table.join2(maps["c++_shared"], "-install_name") + table.join2(maps["c++_shared"], "@rpath/" .. path.filename(target:filename())) end end if runtime:endswith("_static") and _has_static_libstdcxx(self) then -- cgit v1.3.1 From 252b7e5ee70d6203715d39131e34d325e55385d2 Mon Sep 17 00:00:00 2001 From: Arthur LAURENT Date: Thu, 7 Mar 2024 12:12:13 +0100 Subject: make rpathdir clang function private --- xmake/modules/core/tools/clang.lua | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/xmake/modules/core/tools/clang.lua b/xmake/modules/core/tools/clang.lua index 907264ce8..9c30b43c3 100644 --- a/xmake/modules/core/tools/clang.lua +++ b/xmake/modules/core/tools/clang.lua @@ -221,7 +221,7 @@ function _get_llvm_target_triple(self) end -- make the rpathdir flag -function rpathdir(self, dir) +function _rpathdir(self, dir) dir = path.translate(dir) if self:has_flags("-Wl,-rpath=" .. dir, "ldflags") then local flags = {"-Wl,-rpath=" .. (dir:gsub("@[%w_]+", function (name) @@ -309,13 +309,13 @@ function nf_runtime(self, runtime, opt) maps["c++_shared"] = table.join(maps["c++_shared"], "-L" .. triple_libdir) end -- add rpath to avoid the user need to set LD_LIBRARY_PATH by hand - maps["c++_shared"] = table.join(maps["c++_shared"], rpathdir(self, libdir)) + maps["c++_shared"] = table.join(maps["c++_shared"], _rpathdir(self, libdir)) if triple_libdir then - maps["c++_shared"] = table.join(maps["c++_shared"], rpathdir(self, triple_libdir)) + maps["c++_shared"] = table.join(maps["c++_shared"], _rpathdir(self, triple_libdir)) end if target:kind() == "shared" and self:is_plat("macosx", "iphoneos", "watchos") then - table.join2(maps["c++_shared"], "-install_name") - table.join2(maps["c++_shared"], "@rpath/" .. path.filename(target:filename())) + maps["c++_shared"] = table.join(maps["c++_shared"], "-install_name") + maps["c++_shared"] = table.join(maps["c++_shared"], "@rpath/" .. path.filename(target:filename())) end end if runtime:endswith("_static") and _has_static_libstdcxx(self) then -- cgit v1.3.1 From 70e7191e99b213f0ba38a45b0b5dd0e6e852994a Mon Sep 17 00:00:00 2001 From: Arthur LAURENT Date: Thu, 7 Mar 2024 12:15:41 +0100 Subject: reuse gcc nf_rpathdir in clang tool --- xmake/modules/core/tools/clang.lua | 22 ++-------------------- 1 file changed, 2 insertions(+), 20 deletions(-) diff --git a/xmake/modules/core/tools/clang.lua b/xmake/modules/core/tools/clang.lua index 9c30b43c3..8c33fb025 100644 --- a/xmake/modules/core/tools/clang.lua +++ b/xmake/modules/core/tools/clang.lua @@ -220,24 +220,6 @@ function _get_llvm_target_triple(self) return llvm_targettriple or nil end --- make the rpathdir flag -function _rpathdir(self, dir) - dir = path.translate(dir) - if self:has_flags("-Wl,-rpath=" .. dir, "ldflags") then - local flags = {"-Wl,-rpath=" .. (dir:gsub("@[%w_]+", function (name) - local maps = {["@loader_path"] = "$ORIGIN", ["@executable_path"] = "$ORIGIN"} - return maps[name] - end))} - if self:is_plat("bsd") then - -- FreeBSD ld must have "-zorigin" with "-rpath". Otherwise, $ORIGIN is not translated and it is literal. - table.insert(flags, 1, "-Wl,-zorigin") - end - return flags - elseif self:has_flags("-Xlinker -rpath -Xlinker " .. dir, "ldflags") then - return {"-Xlinker", "-rpath", "-Xlinker", (dir:gsub("%$ORIGIN", "@loader_path"))} - end -end - -- make the runtime flag -- @see https://github.com/xmake-io/xmake/issues/3546 function nf_runtime(self, runtime, opt) @@ -309,9 +291,9 @@ function nf_runtime(self, runtime, opt) maps["c++_shared"] = table.join(maps["c++_shared"], "-L" .. triple_libdir) end -- add rpath to avoid the user need to set LD_LIBRARY_PATH by hand - maps["c++_shared"] = table.join(maps["c++_shared"], _rpathdir(self, libdir)) + maps["c++_shared"] = table.join(maps["c++_shared"], nf_rpathdir(self, libdir)) if triple_libdir then - maps["c++_shared"] = table.join(maps["c++_shared"], _rpathdir(self, triple_libdir)) + maps["c++_shared"] = table.join(maps["c++_shared"], nf_rpathdir(self, triple_libdir)) end if target:kind() == "shared" and self:is_plat("macosx", "iphoneos", "watchos") then maps["c++_shared"] = table.join(maps["c++_shared"], "-install_name") -- cgit v1.3.1 From 6da651c37e996ce3c7e303d647e8ce92ac5a3768 Mon Sep 17 00:00:00 2001 From: Arthur LAURENT Date: Thu, 7 Mar 2024 12:50:46 +0100 Subject: cleanup --- xmake/modules/core/tools/clang.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/xmake/modules/core/tools/clang.lua b/xmake/modules/core/tools/clang.lua index 8c33fb025..76f553829 100644 --- a/xmake/modules/core/tools/clang.lua +++ b/xmake/modules/core/tools/clang.lua @@ -295,9 +295,9 @@ function nf_runtime(self, runtime, opt) if triple_libdir then maps["c++_shared"] = table.join(maps["c++_shared"], nf_rpathdir(self, triple_libdir)) end - if target:kind() == "shared" and self:is_plat("macosx", "iphoneos", "watchos") then + if target:is_shared() and self:is_plat("macosx", "iphoneos", "watchos") then maps["c++_shared"] = table.join(maps["c++_shared"], "-install_name") - maps["c++_shared"] = table.join(maps["c++_shared"], "@rpath/" .. path.filename(target:filename())) + maps["c++_shared"] = table.join(maps["c++_shared"], "@rpath/" .. target:filename()) end end if runtime:endswith("_static") and _has_static_libstdcxx(self) then -- cgit v1.3.1