From 02574e3b032b9ca0aff09059fc49a73c8588926b Mon Sep 17 00:00:00 2001 From: Petr Vana Date: Fri, 30 Sep 2022 23:11:52 +0200 Subject: [PATCH] Introduce LLD_jll as stdlib (#46455) * Introduce LLD_jll to stdlib * Add symlinks to lld to libexecdir * Allow to compile LLD from source (during LLVM compilation) + remove symlinks * Fix directory of libraries for Windows --- Make.inc | 4 +- Makefile | 3 + base/Makefile | 12 ++++ deps/Makefile | 6 +- deps/llvm.mk | 7 ++- stdlib/LLD_jll/Project.toml | 21 +++++++ stdlib/LLD_jll/src/LLD_jll.jl | 108 ++++++++++++++++++++++++++++++++ stdlib/LLD_jll/test/runtests.jl | 9 +++ stdlib/Makefile | 2 +- 9 files changed, 167 insertions(+), 5 deletions(-) create mode 100644 stdlib/LLD_jll/Project.toml create mode 100644 stdlib/LLD_jll/src/LLD_jll.jl create mode 100644 stdlib/LLD_jll/test/runtests.jl diff --git a/Make.inc b/Make.inc index 82733dd39052b..8b7f9c1c4ac32 100644 --- a/Make.inc +++ b/Make.inc @@ -66,6 +66,7 @@ USE_SYSTEM_PATCHELF:=0 USE_SYSTEM_LIBWHICH:=0 USE_SYSTEM_ZLIB:=0 USE_SYSTEM_P7ZIP:=0 +USE_SYSTEM_LLD:=0 # Link to the LLVM shared library USE_LLVM_SHLIB := 1 @@ -347,6 +348,7 @@ BUILD_LLVM_CLANG := 0 # see http://lldb.llvm.org/build.html for dependencies BUILD_LLDB := 0 BUILD_LIBCXX := 0 +BUILD_LLD := 1 # Options to enable Polly and its code-generation options USE_POLLY := 0 @@ -1151,7 +1153,7 @@ LIBGFORTRAN_VERSION := $(subst libgfortran,,$(filter libgfortran%,$(subst -,$(SP # Note: we explicitly _do not_ define `CSL` here, since it requires some more # advanced techniques to decide whether it should be installed from a BB source # or not. See `deps/csl.mk` for more detail. -BB_PROJECTS := BLASTRAMPOLINE OPENBLAS LLVM LIBSUITESPARSE OPENLIBM GMP MBEDTLS LIBSSH2 NGHTTP2 MPFR CURL LIBGIT2 PCRE LIBUV LIBUNWIND DSFMT OBJCONV ZLIB P7ZIP +BB_PROJECTS := BLASTRAMPOLINE OPENBLAS LLVM LIBSUITESPARSE OPENLIBM GMP MBEDTLS LIBSSH2 NGHTTP2 MPFR CURL LIBGIT2 PCRE LIBUV LIBUNWIND DSFMT OBJCONV ZLIB P7ZIP LLD define SET_BB_DEFAULT # First, check to see if BB is disabled on a global setting ifeq ($$(USE_BINARYBUILDER),0) diff --git a/Makefile b/Makefile index 5c0f9f74c0bad..e9941bcb33dc2 100644 --- a/Makefile +++ b/Makefile @@ -306,6 +306,9 @@ endif # Install `7z` into libexec/ $(INSTALL_M) $(build_bindir)/7z$(EXE) $(DESTDIR)$(libexecdir)/ + # Install `lld` into libexec/ + $(INSTALL_M) $(build_depsbindir)/lld$(EXE) $(DESTDIR)$(libexecdir)/ + # Copy public headers cp -R -L $(build_includedir)/julia/* $(DESTDIR)$(includedir)/julia # Copy system image diff --git a/base/Makefile b/base/Makefile index 1cc050f57fb4c..0d3e89b58de29 100644 --- a/base/Makefile +++ b/base/Makefile @@ -195,6 +195,18 @@ $(build_bindir)/7z$(EXE): rm -f "$@" && \ ln -svf "$(7Z_PATH)" "$@" +symlink_lld: $(build_bindir)/lld$(EXE) + +ifneq ($(USE_SYSTEM_LLD),0) +SYMLINK_SYSTEM_LIBRARIES += symlink_lld +LLD_PATH := $(shell which lld$(EXE)) +endif + +$(build_bindir)/lld$(EXE): + [ -e "$(LLD_PATH)" ] && \ + rm -f "$@" && \ + ln -svf "$(LLD_PATH)" "$@" + # the following excludes: libuv.a, libutf8proc.a ifneq ($(USE_SYSTEM_LIBM),0) diff --git a/deps/Makefile b/deps/Makefile index 6c0bc6de86c54..4f0cc48b01971 100644 --- a/deps/Makefile +++ b/deps/Makefile @@ -88,6 +88,10 @@ ifeq ($(USE_SYSTEM_LLVM), 0) DEP_LIBS += llvm endif +ifeq ($(USE_SYSTEM_LLD), 0) +DEP_LIBS += lld +endif + ifeq ($(USE_SYSTEM_PCRE), 0) DEP_LIBS += pcre endif @@ -168,7 +172,7 @@ endif DEP_LIBS_STAGED_ALL := llvm llvm-tools clang llvmunwind unwind libuv pcre \ openlibm dsfmt blastrampoline openblas lapack gmp mpfr patchelf utf8proc \ objconv mbedtls libssh2 nghttp2 curl libgit2 libwhich zlib p7zip csl \ - libsuitesparse + libsuitesparse lld DEP_LIBS_ALL := $(DEP_LIBS_STAGED_ALL) ifneq ($(USE_BINARYBUILDER_OPENBLAS),0) diff --git a/deps/llvm.mk b/deps/llvm.mk index f0312ed6decda..5d297b6c369bf 100644 --- a/deps/llvm.mk +++ b/deps/llvm.mk @@ -56,6 +56,9 @@ endif ifeq ($(BUILD_LIBCXX), 1) LLVM_ENABLE_RUNTIMES := $(LLVM_ENABLE_RUNTIMES);libcxx;libcxxabi endif +ifeq ($(BUILD_LLD), 1) +LLVM_ENABLE_PROJECTS := $(LLVM_ENABLE_PROJECTS);lld +endif LLVM_LIB_FILE := libLLVMCodeGen.a @@ -309,6 +312,6 @@ $(eval $(call bb-install,clang,CLANG,false,true)) $(eval $(call bb-install,lld,LLD,false,true)) $(eval $(call bb-install,llvm-tools,LLVM_TOOLS,false,true)) -install-lld install-clang install-llvm-tools: install-llvm - endif # USE_BINARYBUILDER_LLVM + +install-lld install-clang install-llvm-tools: install-llvm diff --git a/stdlib/LLD_jll/Project.toml b/stdlib/LLD_jll/Project.toml new file mode 100644 index 0000000000000..7fbb85963f798 --- /dev/null +++ b/stdlib/LLD_jll/Project.toml @@ -0,0 +1,21 @@ +name = "LLD_jll" +uuid = "d55e3150-da41-5e91-b323-ecfd1eec6109" +version = "14.0.5+3" + +[deps] +Pkg = "44cfe95a-1eb2-52ea-b672-e2afdf69b78f" +Zlib_jll = "83775a58-1f1d-513f-b197-d71354ab007a" +Libdl = "8f399da3-3557-5675-b5ff-fb832c97cbdb" +TOML = "fa267f1f-6049-4f14-aa54-33bafae1ed76" +libLLVM_jll = "8f36deef-c2a5-5394-99ed-8e07531fb29a" +Artifacts = "56f22d72-fd6d-98f1-02f0-08ddc0907c33" + +[compat] +julia = "1.9" +libLLVM_jll = "14.0.5" + +[extras] +Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40" + +[targets] +test = ["Test"] diff --git a/stdlib/LLD_jll/src/LLD_jll.jl b/stdlib/LLD_jll/src/LLD_jll.jl new file mode 100644 index 0000000000000..d14d740fc5e5b --- /dev/null +++ b/stdlib/LLD_jll/src/LLD_jll.jl @@ -0,0 +1,108 @@ + +# This file is a part of Julia. License is MIT: https://julialang.org/license + +## dummy stub for https://github.com/JuliaBinaryWrappers/LLD_jll.jl + +baremodule LLD_jll +using Base, Libdl +Base.Experimental.@compiler_options compile=min optimize=0 infer=false + +const PATH_list = String[] +const LIBPATH_list = String[] + +export lld + +# These get calculated in __init__() +const PATH = Ref("") +const LIBPATH = Ref("") +artifact_dir = "" +lld_path = "" +if Sys.iswindows() + const lld_exe = "lld.exe" +else + const lld_exe = "lld" +end + +if Sys.iswindows() + const LIBPATH_env = "PATH" + const LIBPATH_default = "" + const pathsep = ';' +elseif Sys.isapple() + const LIBPATH_env = "DYLD_FALLBACK_LIBRARY_PATH" + const LIBPATH_default = "~/lib:/usr/local/lib:/lib:/usr/lib" + const pathsep = ':' +else + const LIBPATH_env = "LD_LIBRARY_PATH" + const LIBPATH_default = "" + const pathsep = ':' +end + +function adjust_ENV!(env::Dict, PATH::String, LIBPATH::String, adjust_PATH::Bool, adjust_LIBPATH::Bool) + if adjust_LIBPATH + LIBPATH_base = get(env, LIBPATH_env, expanduser(LIBPATH_default)) + if !isempty(LIBPATH_base) + env[LIBPATH_env] = string(LIBPATH, pathsep, LIBPATH_base) + else + env[LIBPATH_env] = LIBPATH + end + end + if adjust_PATH && (LIBPATH_env != "PATH" || !adjust_LIBPATH) + if adjust_PATH + if !isempty(get(env, "PATH", "")) + env["PATH"] = string(PATH, pathsep, env["PATH"]) + else + env["PATH"] = PATH + end + end + end + return env +end + +function lld(f::Function; adjust_PATH::Bool = true, adjust_LIBPATH::Bool = true) + env = adjust_ENV!(copy(ENV), PATH[], LIBPATH[], adjust_PATH, adjust_LIBPATH) + withenv(env...) do + return f(lld_path) + end +end +function lld(; adjust_PATH::Bool = true, adjust_LIBPATH::Bool = true) + env = adjust_ENV!(copy(ENV), PATH[], LIBPATH[], adjust_PATH, adjust_LIBPATH) + return Cmd(Cmd([lld_path]); env) +end + +function init_lld_path() + # Prefer our own bundled lld, but if we don't have one, pick it up off of the PATH + # If this is an in-tree build, `lld` will live in `tools`. Otherwise, it'll be in `libexec` + for bundled_lld_path in (joinpath(Sys.BINDIR, Base.LIBEXECDIR, lld_exe), + joinpath(Sys.BINDIR, "..", "tools", lld_exe), + joinpath(Sys.BINDIR, lld_exe)) + if isfile(bundled_lld_path) + global lld_path = abspath(bundled_lld_path) + return + end + end + global lld_path = something(Sys.which(lld_exe), lld_exe) +end + +function __init__() + global artifact_dir = dirname(Sys.BINDIR) + init_lld_path() + PATH[] = dirname(lld_path) + push!(PATH_list, PATH[]) + if Sys.iswindows() + # On windows, the dynamic libraries (.dll) are in Sys.BINDIR ("usr\\bin") + append!(LIBPATH_list, [joinpath(Sys.BINDIR, Base.LIBDIR, "julia"), Sys.BINDIR]) + else + append!(LIBPATH_list, [joinpath(Sys.BINDIR, Base.LIBDIR, "julia"), joinpath(Sys.BINDIR, Base.LIBDIR)]) + end + LIBPATH[] = join(LIBPATH_list, pathsep) +end + +# JLLWrappers API compatibility shims. Note that not all of these will really make sense. +# For instance, `find_artifact_dir()` won't actually be the artifact directory, because +# there isn't one. It instead returns the overall Julia prefix. +is_available() = true +find_artifact_dir() = artifact_dir +dev_jll() = error("stdlib JLLs cannot be dev'ed") +best_wrapper = nothing + +end # module libLLD_jll diff --git a/stdlib/LLD_jll/test/runtests.jl b/stdlib/LLD_jll/test/runtests.jl new file mode 100644 index 0000000000000..f8eccfe939dce --- /dev/null +++ b/stdlib/LLD_jll/test/runtests.jl @@ -0,0 +1,9 @@ +# This file is a part of Julia. License is MIT: https://julialang.org/license + +using Test, Libdl, LLD_jll + +@testset "LLD_jll" begin + @test isfile(LLD_jll.lld_path) + flavor = Sys.isapple() ? "darwin" : (Sys.iswindows() ? "link" : "gnu") + @test success(`$(LLD_jll.lld()) -flavor $flavor --version`) +end diff --git a/stdlib/Makefile b/stdlib/Makefile index d45be468626cd..7957520c31ea3 100644 --- a/stdlib/Makefile +++ b/stdlib/Makefile @@ -20,7 +20,7 @@ $(build_datarootdir)/julia/stdlib/$(VERSDIR): JLLS = DSFMT GMP CURL LIBGIT2 LLVM LIBSSH2 LIBUV MBEDTLS MPFR NGHTTP2 \ BLASTRAMPOLINE OPENBLAS OPENLIBM P7ZIP PCRE LIBSUITESPARSE ZLIB \ - LLVMUNWIND CSL UNWIND + LLVMUNWIND CSL UNWIND LLD # Initialize this with JLLs that aren't in "deps/$(LibName).version" JLL_NAMES := MozillaCACerts_jll