|
21 | 21 | -- inherit gcc |
22 | 22 | inherit("gcc") |
23 | 23 | import("core.language.language") |
| 24 | +import("private.utils.toolchain", {alias="toolchain_utils"}) |
24 | 25 |
|
25 | 26 | -- init it |
26 | 27 | functioninit(self) |
@@ -191,76 +192,6 @@ function _has_static_libstdcxx(self) |
191 | 192 | returnhas_static_libstdcxx |
192 | 193 | end |
193 | 194 |
|
194 | | --- get llvm sdk root directory |
195 | | -function_get_llvm_rootdir(self) |
196 | | -localllvm_rootdir=_g._LLVM_ROOTDIR |
197 | | -ifllvm_rootdir==nilthen |
198 | | -localoutdata=try {function()returnos.iorunv(self:program(), {"-print-resource-dir"}, {envs=self:runenvs()})end } |
199 | | -ifoutdatathen |
200 | | -llvm_rootdir=path.normalize(path.join(outdata:trim(),"..","..","..")) |
201 | | -ifnotos.isdir(llvm_rootdir)then |
202 | | -llvm_rootdir=nil |
203 | | -end |
204 | | -end |
205 | | -_g._LLVM_ROOTDIR=llvm_rootdirorfalse |
206 | | -end |
207 | | -returnllvm_rootdirornil |
208 | | -end |
209 | | - |
210 | | --- get llvm target triple |
211 | | -function_get_llvm_target_triple(self) |
212 | | -localllvm_targettriple=_g._LLVM_TARGETTRIPLE |
213 | | -ifllvm_targettriple==nilthen |
214 | | -localoutdata=try {function()returnos.iorunv(self:program(), {"-print-target-triple"}, {envs=self:runenvs()})end } |
215 | | -ifoutdatathen |
216 | | -llvm_targettriple=outdata:trim() |
217 | | -end |
218 | | -_g._LLVM_TARGETTRIPLE=llvm_targettripleorfalse |
219 | | -end |
220 | | -returnllvm_targettripleornil |
221 | | -end |
222 | | - |
223 | | --- find compiler-rt dir |
224 | | -function_get_llvm_compiler_rtdir(self,target,llvm_rootdir) |
225 | | -import("lib.detect.find_tool") |
226 | | -import("core.base.semver") |
227 | | - |
228 | | -locallibdir=path.absolute(path.join(llvm_rootdir,"lib","clang")) |
229 | | -localtarget_triple=_get_llvm_target_triple(self) |
230 | | - |
231 | | -localcc=target:tool("cc") |
232 | | -localcc_tool=find_tool(cc, {version=true}) |
233 | | -ifcc_toolandcc_tool.versionthen |
234 | | -localversion=semver.new(cc_tool.version):major() |
235 | | -localbasedir=path.join(libdir,version,"lib") |
236 | | - |
237 | | -localcompiler_rtdir |
238 | | --- sometimes llvm is built with -DLLVM_ENABLE_PER_TARGET_RUNTIME_DIR=ON, compiler_rt is located in a target-triple subfolder |
239 | | -localtripletdir=path.join(basedir,target_triple) |
240 | | -ifos.isdir(tripletdir)then |
241 | | -compiler_rtdir=tripletdir |
242 | | -else |
243 | | --- sometimes llvm is built with -DLLVM_ENABLE_PER_TARGET_RUNTIME_DIR=OFF, compiler_rt is located in a platform name subfolder |
244 | | -iftarget:is_plat("windows")then |
245 | | -compiler_rtdir=os.isdir(path.join(basedir,"windows"))andpath.join(basedir,"windows") |
246 | | -elseiftarget:is_plat("linux")then |
247 | | -compiler_rtdir=os.isdir(path.join(basedir,"linux"))andpath.join(basedir,"linux") |
248 | | -elseiftarget:is_plat("macosx")then |
249 | | -compiler_rtdir=os.isdir(path.join(basedir,"darwin"))andpath.join(basedir,"darwin") |
250 | | -end |
251 | | -end |
252 | | - |
253 | | -ifcompiler_rtdirandtarget_triplethen |
254 | | -localarch=target_triple:split("-")[1] |
255 | | -localcompiler_rtlink="clang_rt.builtins-"..arch |
256 | | -ifos.isfile(path.join(compiler_rtdir,compiler_rtlink..".lib"))then |
257 | | -returncompiler_rtdir,path.join(compiler_rtdir,compiler_rtlink..".lib") |
258 | | -end |
259 | | -end |
260 | | -returncompiler_rtdir |
261 | | -end |
262 | | -end |
263 | | - |
264 | 195 | -- make the runtime flag |
265 | 196 | -- @see https://github.com/xmake-io/xmake/issues/3546 |
266 | 197 | functionnf_runtime(self,runtime,opt) |
@@ -291,58 +222,72 @@ function nf_runtime(self, runtime, opt) |
291 | 222 | } |
292 | 223 | end |
293 | 224 | end |
294 | | -ifnotself:is_plat("android")then-- we will set runtimes in android ndk toolchain |
295 | | -maps=mapsor {} |
296 | | -localllvm_rootdir=self:toolchain():sdkdir() |
297 | | -ifnotllvm_rootdirandself:is_plat("windows")then |
298 | | -llvm_rootdir=_get_llvm_rootdir(self) |
| 225 | +localtarget=opt.targetoropt |
| 226 | +-- llvm on windows still doesn't support autolinking of libc++ and compiler-rt builtins |
| 227 | +-- @see https://discourse.llvm.org/t/improve-autolinking-of-compiler-rt-and-libc-on-windows-with-lld-link/71392/10 |
| 228 | +-- and need manual setting of libc++ headerdirectory |
| 229 | +-- @see https://github.com/llvm/llvm-project/issues/79647 |
| 230 | +localllvm_dirs=toolchain_utils.get_llvm_dirs(self) |
| 231 | + |
| 232 | +ifself:is_plat("windows")andruntime=="c++_shared"then |
| 233 | +ifllvm_dirs.binthen |
| 234 | +self:add("runenvs","PATHS",llvm_dirs.bin) |
299 | 235 | end |
300 | | -ifkind=="cxx"then |
| 236 | +ifllvm_dirs.rtthen |
| 237 | +self:add("runenvs","PATHS",llvm_dirs.rt) |
| 238 | +end |
| 239 | +end |
| 240 | + |
| 241 | +-- we will set runtimes in android ndk toolchain |
| 242 | +ifnotself:is_plat("android")then |
| 243 | +maps=mapsor {} |
| 244 | +ifkind=="cxx"orkind=="ld"orkind=="sh"then |
301 | 245 | maps["c++_static"]="-stdlib=libc++" |
302 | 246 | maps["c++_shared"]="-stdlib=libc++" |
303 | 247 | maps["stdc++_static"]="-stdlib=libstdc++" |
304 | 248 | maps["stdc++_shared"]="-stdlib=libstdc++" |
305 | | --- clang on windows fail to add libc++ includepath when using -stdlib=libc++ so we manually add it |
306 | | --- @see https://github.com/llvm/llvm-project/issues/79647 |
307 | | -ifllvm_rootdirthen |
308 | | -maps["c++_static"]=table.join(maps["c++_static"],"-cxx-isystem"..path.join(llvm_rootdir,"include","c++","v1")) |
309 | | -maps["c++_shared"]=table.join(maps["c++_shared"],"-cxx-isystem"..path.join(llvm_rootdir,"include","c++","v1")) |
| 249 | +ifkind=="cxx"then |
| 250 | +-- force the toolchain libc++ headers to prevent clang picking the systems one |
| 251 | +ifllvm_dirs.cxxincludethen |
| 252 | +maps["c++_static"]=table.join(maps["c++_static"],"-cxx-isystem"..llvm_dirs.cxxinclude) |
| 253 | +maps["c++_shared"]=table.join(maps["c++_shared"],"-cxx-isystem"..llvm_dirs.cxxinclude) |
| 254 | +end |
310 | 255 | end |
311 | | -elseifkind=="ld"orkind=="sh"then |
312 | | -localtarget=opt.targetoropt |
313 | | -localis_cxx_or_c=targetand (target.sourcekindsandtable.contains(table.wrap(target:sourcekinds()),"cxx","cc")) |
314 | | -ifis_cxx_or_cthen |
315 | | -maps["c++_static"]="-stdlib=libc++" |
316 | | -maps["c++_shared"]="-stdlib=libc++" |
317 | | -maps["stdc++_static"]="-stdlib=libstdc++" |
318 | | -maps["stdc++_shared"]="-stdlib=libstdc++" |
319 | | --- clang on windows fail to add libc++ librarypath when using -stdlib=libc++ so we manually add it |
320 | | --- @see https://github.com/llvm/llvm-project/issues/79647 |
321 | | -ifllvm_rootdirthen |
322 | | -locallibdir=path.absolute(path.join(llvm_rootdir,"lib")) |
323 | | -maps["c++_static"]=table.join(maps["c++_static"],nf_linkdir(self,libdir)) |
324 | | -maps["c++_shared"]=table.join(maps["c++_shared"],nf_linkdir(self,libdir)) |
| 256 | +end |
| 257 | + |
| 258 | +ifself:is_plat("windows")andlanguage.sourcekinds()[kind]then |
| 259 | +-- on windows force link to compiler_rt builtins |
| 260 | +ifllvm_dirs.rtandllvm_dirs.rtlinkthen |
| 261 | +forname,_inpairs(maps)do |
| 262 | +maps[name]=table.join({"-Xclang","--dependent-lib="..llvm_dirs.rtlink},maps[name]) |
| 263 | +end |
| 264 | +end |
| 265 | +end |
| 266 | +ifkind=="ld"orkind=="sh"then |
| 267 | +ifself:is_plat("windows")andllvm_dirs.rtthen |
| 268 | +-- on windows force add compiler_rt link directories |
| 269 | +forname,_inpairs(maps)do |
| 270 | +maps[name]=table.join(nf_linkdir(self,llvm_dirs.rt),maps[name]) |
| 271 | +maps[name]=table.join("-resource-dir="..llvm_dirs.res,maps[name]) |
| 272 | +end |
| 273 | +end |
| 274 | + |
| 275 | +localis_cxx=targetand (target.sourcekindsandtable.contains(table.wrap(target:sourcekinds()),"cxx")) |
| 276 | +ifis_cxxthen |
| 277 | +ifllvm_dirs.libthen |
| 278 | +maps["c++_static"]=table.join(maps["c++_static"],nf_linkdir(self,llvm_dirs.lib)) |
| 279 | +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)) |
325 | 281 | -- sometimes llvm c++ runtimes are located in c++ subfolder (e.g homebrew llvm) |
326 | | -localcxx_libdir=path.join(libdir,"c++") |
327 | | -ifos.isdir(cxx_libdir)then |
328 | | -maps["c++_static"]=table.join(maps["c++_static"],nf_linkdir(self,cxx_libdir)) |
329 | | -maps["c++_shared"]=table.join(maps["c++_shared"],"-L"..nf_linkdir(self,cxx_libdir)) |
| 282 | +ifllvm_dirs.cxxlibthen |
| 283 | +maps["c++_static"]=table.join(maps["c++_static"],nf_linkdir(self,llvm_dirs.cxxlib)) |
| 284 | +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)) |
330 | 286 | end |
331 | | -localcompiler_rtdir,compiler_rtlink=_get_llvm_compiler_rtdir(self,target,llvm_rootdir) |
332 | | -ifcompiler_rtdirthen |
333 | | -forname,_inpairs(maps)do |
334 | | -maps[name]=table.join(nf_linkdir(self,compiler_rtdir),maps[name]) |
335 | | -ifcompiler_rtlinkthen |
336 | | -maps[name]=table.join(compiler_rtlink,maps[name]) |
337 | | -end |
338 | | -end |
| 287 | +ifllvm_dirs.rtthen |
| 288 | +maps["c++_shared"]=table.join(maps["c++_shared"],nf_rpathdir(self,llvm_dirs.rt)) |
339 | 289 | end |
340 | 290 | -- add rpath to avoid the user need to set LD_LIBRARY_PATH by hand |
341 | | -maps["c++_shared"]=table.join(maps["c++_shared"],nf_rpathdir(self,libdir)) |
342 | | -ifcompiler_rtdirthen |
343 | | -maps["c++_shared"]=table.join(maps["c++_shared"],nf_rpathdir(self,compiler_rtdir)) |
344 | | -maps["MD"]=table.join(maps["MD"],nf_rpathdir(self,compiler_rtdir)) |
345 | | -end |
346 | 291 | iftarget.is_sharedandtarget:is_shared()andtarget.filenameandself:is_plat("macosx","iphoneos","watchos")then |
347 | 292 | maps["c++_shared"]=table.join(maps["c++_shared"],"-install_name") |
348 | 293 | maps["c++_shared"]=table.join(maps["c++_shared"],"@rpath/"..target:filename()) |
|