Skip to content

Commit c416c65

Browse files
committed
(llvm) add runtime dirs to runenvs (for asan and libunwind)
1 parent 6b98095 commit c416c65

File tree

4 files changed

+81
-65
lines changed

4 files changed

+81
-65
lines changed

xmake/modules/core/tools/clang.lua

Lines changed: 1 addition & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -227,16 +227,7 @@ function nf_runtime(self, runtime, opt)
227227
-- @see https://discourse.llvm.org/t/improve-autolinking-of-compiler-rt-and-libc-on-windows-with-lld-link/71392/10
228228
-- and need manual setting of libc++ headerdirectory
229229
-- @see https://github.com/llvm/llvm-project/issues/79647
230-
local llvm_dirs = toolchain_utils.get_llvm_dirs(self)
231-
232-
if self:is_plat("windows") and runtime == "c++_shared" then
233-
if llvm_dirs.bin then
234-
self:add("runenvs", "PATHS", llvm_dirs.bin)
235-
end
236-
if llvm_dirs.rt then
237-
self:add("runenvs", "PATHS", llvm_dirs.rt)
238-
end
239-
end
230+
local llvm_dirs = toolchain_utils.get_llvm_dirs(self:toolchain())
240231

241232
-- we will set runtimes in android ndk toolchain
242233
if not self:is_plat("android") then
@@ -277,20 +268,10 @@ function nf_runtime(self, runtime, opt)
277268
if llvm_dirs.lib then
278269
maps["c++_static"] = table.join(maps["c++_static"], nf_linkdir(self, llvm_dirs.lib))
279270
maps["c++_shared"] = table.join(maps["c++_shared"], nf_linkdir(self, llvm_dirs.lib))
280-
maps["c++_shared"] = table.join(maps["c++_shared"], nf_rpathdir(self, llvm_dirs.lib))
281271
-- sometimes llvm c++ runtimes are located in c++ subfolder (e.g homebrew llvm)
282272
if llvm_dirs.cxxlib then
283273
maps["c++_static"] = table.join(maps["c++_static"], nf_linkdir(self, llvm_dirs.cxxlib))
284274
maps["c++_shared"] = table.join(maps["c++_shared"], nf_linkdir(self, llvm_dirs.cxxlib))
285-
maps["c++_shared"] = table.join(maps["c++_shared"], nf_rpathdir(self, llvm_dirs.cxxlib))
286-
end
287-
if llvm_dirs.rt then
288-
maps["c++_shared"] = table.join(maps["c++_shared"], nf_rpathdir(self, llvm_dirs.rt))
289-
end
290-
-- add rpath to avoid the user need to set LD_LIBRARY_PATH by hand
291-
if target.is_shared and target:is_shared() and target.filename and self:is_plat("macosx", "iphoneos", "watchos") then
292-
maps["c++_shared"] = table.join(maps["c++_shared"], "-install_name")
293-
maps["c++_shared"] = table.join(maps["c++_shared"], "@rpath/" .. target:filename())
294275
end
295276
end
296277
if runtime:endswith("_static") and _has_static_libstdcxx(self) then

xmake/modules/private/utils/toolchain.lua

Lines changed: 76 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -183,25 +183,25 @@ end
183183

184184
-- get llvm sdk resource directory
185185
function _get_llvm_resourcedir(toolchain)
186-
local llvm_resourcedir = _g._LLVM_resourceDIR
186+
local llvm_resourcedir = _g._LLVM_RESOURCE_DIR
187187
if llvm_resourcedir == nil then
188-
local outdata = try { function() return os.iorunv(toolchain:get("cc"), {"-print-resource-dir"}, {envs = toolchain:runenvs()}) end }
188+
local outdata = try { function() return os.iorunv(toolchain:tool("cc"), {"-print-resource-dir"}) end }
189189
if outdata then
190190
llvm_resourcedir = path.normalize(outdata:trim())
191191
if not os.isdir(llvm_resourcedir) then
192192
llvm_resourcedir = nil
193193
end
194194
end
195-
_g._LLVM_resourceDIR = llvm_resourcedir or false
195+
_g._LLVM_RESOURCE_DIR = llvm_resourcedir or false
196196
end
197197
return llvm_resourcedir or nil
198198
end
199199

200200
-- get llvm sdk root directory
201-
function _get_llvm_rootdir(self)
201+
function _get_llvm_rootdir(toolchain)
202202
local llvm_rootdir = _g._LLVM_ROOTDIR
203203
if llvm_rootdir == nil then
204-
local resourcedir = _get_llvm_resourcedir(self)
204+
local resourcedir = _get_llvm_resourcedir(toolchain)
205205
if resourcedir then
206206
llvm_rootdir = path.normalize(path.join(resourcedir, "..", "..", ".."))
207207
if not os.isdir(llvm_rootdir) then
@@ -214,40 +214,50 @@ function _get_llvm_rootdir(self)
214214
end
215215

216216
-- find compiler-rt dir
217-
function _get_llvm_compiler_win_rtdir_and_link(self, target)
217+
function _get_llvm_compiler_rtdir_and_link(toolchain)
218218
import("lib.detect.find_tool")
219219

220-
local cc = self:get("cc")
220+
local cc = toolchain:tool("cc")
221221
local cc_tool = find_tool(cc, {version = true})
222222
if cc_tool and cc_tool.version then
223-
local resdir = _get_llvm_resourcedir(self)
223+
local resdir = _get_llvm_resourcedir(toolchain)
224224
if resdir then
225225
local res_libdir = path.join(resdir, "lib")
226226
-- when -DLLVM_ENABLE_TARGET_RUNTIME_DIR=OFF rtdir is windows/ and rtlink is clang_rt.builtinsi_<arch>.lib
227227
-- when ON rtdir is windows/<target-triple> and rtlink is clang_rt.builtins.lib
228-
local target_triple = _get_llvm_target_triple(self)
228+
local target_triple = _get_llvm_target_triple(toolchain)
229229
local arch = target_triple and target_triple:split("-")[1]
230230

231+
local plat
232+
if toolchain:is_plat("windows") then
233+
plat = "windows"
234+
elseif toolchain:is_plat("linux") then
235+
plat = "linux"
236+
elseif toolchain:is_plat("macosx", "ios", "watchos", "appletvos", "applexros") then
237+
plat = "darwin"
238+
end
239+
240+
231241
local tripletdir = target_triple and path.join(res_libdir, "windows", target_triple)
232242
tripletdir = os.isdir(tripletdir) or nil
233243

234-
local rtdir = tripletdir and path.join("windows", target_triple) or "windows"
235-
if os.isdir(path.join(res_libdir, rtdir)) then
244+
local rtdir = tripletdir and path.join(plat, target_triple) or plat
245+
if os.isdir(path.join(res_libdir, rtdir)) and toolchain:is_plat("windows") then
236246
local rtlink = "clang_rt.builtins" .. (tripletdir and ".lib" or ("-" .. arch .. ".lib"))
237247
if os.isfile(path.join(res_libdir, rtdir, rtlink)) then
238-
return res_libdir, path.join(rtdir, rtlink)
248+
return res_libdir, path.join(rtdir, rtlink), path.join(res_libdir, rtdir)
239249
end
240250
end
241-
return res_libdir
251+
return res_libdir, nil, path.join(res_libdir, rtdir)
242252
end
243253
end
244254
end
245255

246256
-- get llvm target triple
247-
function _get_llvm_target_triple(self)
257+
function _get_llvm_target_triple(toolchain)
248258
local llvm_targettriple = _g._LLVM_TARGETTRIPLE
249259
if llvm_targettriple == nil then
250-
local outdata = try { function() return os.iorunv(self:program(), {"-print-target-triple"}, {envs = self:runenvs()}) end }
260+
local outdata = try { function() return os.iorunv(toolchain:tool("cc"), {"-print-target-triple"}) end }
251261
if outdata then
252262
llvm_targettriple = outdata:trim()
253263
end
@@ -268,50 +278,75 @@ function get_llvm_dirs(toolchain)
268278
local bindir, libdir, cxxlibdir, includedir, cxxincludedir, resdir, rtdir, rtlink
269279
if rootdir then
270280
bindir = path.join(rootdir, "bin")
271-
if bindir then
272-
bindir = os.isdir(bindir) and bindir or nil
273-
end
281+
bindir = os.isdir(bindir) and bindir or nil
274282

275283
libdir = path.join(rootdir, "lib")
276-
if libdir then
277-
libdir = os.isdir(libdir) and libdir or nil
278-
end
284+
libdir = os.isdir(libdir) and libdir or nil
279285

280286
if libdir then
281-
cxxlibdir = libdir and path.join(libdir, "c++")
282-
if cxxlibdir then
287+
cxxlibdir = path.join(libdir, "c++")
288+
cxxlibdir = os.isdir(cxxlibdir) and cxxlibdir or nil
289+
if not cxxlibdir then
290+
cxxlibdir = path.join(libdir, _get_llvm_target_triple(toolchain))
283291
cxxlibdir = os.isdir(cxxlibdir) and cxxlibdir or nil
284292
end
285293
end
286294

287295
includedir = path.join(rootdir, "include")
288-
if includedir then
289-
includedir = os.isdir(includedir) and includedir or nil
290-
end
296+
includedir = os.isdir(includedir) and includedir or nil
291297

292298
if includedir then
293-
cxxincludedir = includedir and path.join(includedir, "c++", "v1") or nil
294-
if cxxincludedir then
295-
cxxincludedir = os.isdir(cxxincludedir) and cxxincludedir or nil
296-
end
299+
cxxincludedir = path.join(includedir, "c++", "v1")
300+
cxxincludedir = os.isdir(cxxincludedir) and cxxincludedir or nil
297301
end
298302

299303
resdir = _get_llvm_resourcedir(toolchain)
300-
if toolchain:is_plat("windows") then
301-
rtdir, rtlink = _get_llvm_compiler_win_rtdir_and_link(toolchain)
302-
end
304+
rtdir, rtlink, rtlib = _get_llvm_compiler_rtdir_and_link(toolchain)
303305
end
304306

305307
llvm_dirs = {root = rootdir,
306-
bin = bindir,
307-
lib = libdir,
308-
cxxlib = cxxlibdir,
309-
include = includedir,
310-
cxxinclude = cxxincludedir,
311-
res = resdir,
312-
rt = rtdir,
313-
rtlink = rtlink }
308+
bin = bindir,
309+
lib = libdir,
310+
cxxlib = cxxlibdir,
311+
include = includedir,
312+
cxxinclude = cxxincludedir,
313+
res = resdir,
314+
rt = rtdir,
315+
rtlib = rtlib,
316+
rtlink = rtlink }
314317
_g.llvm_dirs = llvm_dirs
315318
end
316319
return llvm_dirs
317320
end
321+
322+
-- set runenvs for llvm
323+
function set_llvm_runenvs(toolchain)
324+
local pathname = "PATH"
325+
if toolchain:is_plat("windows") then
326+
local curenvs = os.getenvs()
327+
for k, _ in pairs(curenvs) do
328+
if pathname:lower() == k:lower() then
329+
pathname = k
330+
break
331+
end
332+
end
333+
end
334+
335+
local dirs = get_llvm_dirs(toolchain)
336+
if dirs then
337+
if dirs.bin then
338+
toolchain:add("runenvs", pathname, dirs.bin)
339+
end
340+
for _, dir in ipairs({dirs.lib or false, dirs.cxxlib or false, dirs.rtlib or false}) do
341+
if dir then
342+
if toolchain:is_plat("windows") then
343+
toolchain:add("runenvs", pathname, dir)
344+
elseif toolchain:is_plat("linux", "bsd", "android") then
345+
toolchain:add("runenvs", "LD_LIBRARY_PATH", dir)
346+
elseif toolchain:is_plat("macosx", "ios", "appletvos", "applexros", "watchos") then
347+
toolchain:add("runenvs", "DYLD_LIBRARY_PATH", dir)
348+
end
349+
end
350+
end
351+
end
352+
end

xmake/toolchains/clang/load.lua

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
import("detect.sdks.find_vstudio")
2222
import("detect.sdks.find_mingw")
2323
import("core.project.config")
24+
import("private.utils.toolchain", {alias = "toolchain_utils"})
2425

2526
-- add the given vs environment
2627
function _add_vsenv(toolchain, name, curenvs)
@@ -66,6 +67,8 @@ function main(toolchain, suffix)
6667
target = "armv7"
6768
end
6869

70+
toolchain_utils.set_llvm_runenvs(toolchain)
71+
6972
if toolchain:is_plat("windows") then
7073
target = target .. "-windows-msvc"
7174

xmake/toolchains/llvm/xmake.lua

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -54,10 +54,7 @@ toolchain("llvm")
5454
toolchain:add("runtimes", "MT", "MTd", "MD", "MDd")
5555
end
5656

57-
local dirs = toolchain_utils.get_llvm_dirs(toolchain)
58-
if dirs and dirs.rt then
59-
toolchain:add("runenvs", dirs.rt)
60-
end
57+
toolchain_utils.set_llvm_runenvs(toolchain)
6158

6259
-- add target flags
6360
local target

0 commit comments

Comments
 (0)