diff --git a/Makefile b/Makefile index 023c01aadaa2a..3d8bf5436b476 100644 --- a/Makefile +++ b/Makefile @@ -403,6 +403,10 @@ endif # Install appdata file mkdir -p $(DESTDIR)$(datarootdir)/metainfo/ $(INSTALL_F) $(JULIAHOME)/contrib/julia.appdata.xml $(DESTDIR)$(datarootdir)/metainfo/ + # Install terminal info database +ifneq ($(WITH_TERMINFO),0) + cp -R -L $(build_datarootdir)/terminfo $(DESTDIR)$(datarootdir) +endif # Update RPATH entries and JL_SYSTEM_IMAGE_PATH if $(private_libdir_rel) != $(build_private_libdir_rel) ifneq ($(private_libdir_rel),$(build_private_libdir_rel)) diff --git a/NEWS.md b/NEWS.md index 2e9b32befe342..17829f38a7182 100644 --- a/NEWS.md +++ b/NEWS.md @@ -170,6 +170,10 @@ Deprecated or removed External dependencies --------------------- +- The terminal info database, `terminfo`, is now vendored by default, providing a better + REPL user experience when `terminfo` is not available on the system. Julia can be built + without vendoring the database using the Makefile option `WITH_TERMINFO=0`. ([#55411]) + Tooling Improvements -------------------- diff --git a/base/terminfo.jl b/base/terminfo.jl index 6f1d1ca8015f0..79713f4a86aa3 100644 --- a/base/terminfo.jl +++ b/base/terminfo.jl @@ -245,7 +245,8 @@ end Locate the terminfo file for `term`, return `nothing` if none could be found. The lookup policy is described in `terminfo(5)` "Fetching Compiled -Descriptions". +Descriptions". A terminfo database is included by default with Julia and is +taken to be the first entry of `@TERMINFO_DIRS@`. """ function find_terminfo_file(term::String) isempty(term) && return @@ -261,6 +262,7 @@ function find_terminfo_file(term::String) append!(terminfo_dirs, replace(split(ENV["TERMINFO_DIRS"], ':'), "" => "/usr/share/terminfo")) + push!(terminfo_dirs, normpath(Sys.BINDIR, DATAROOTDIR, "terminfo")) Sys.isunix() && push!(terminfo_dirs, "/etc/terminfo", "/lib/terminfo", "/usr/share/terminfo") for dir in terminfo_dirs @@ -268,8 +270,15 @@ function find_terminfo_file(term::String) return joinpath(dir, chr, term) elseif isfile(joinpath(dir, chrcode, term)) return joinpath(dir, chrcode, term) + elseif isfile(joinpath(dir, lowercase(chr), lowercase(term))) + # The vendored terminfo database is fully lowercase to avoid issues on + # case-sensitive filesystems. On Unix-like systems, terminfo files with + # different cases are hard links to one another, so this is still + # correct for non-vendored terminfo, just redundant. + return joinpath(dir, lowercase(chr), lowercase(term)) end end + return nothing end """ diff --git a/deps/Makefile b/deps/Makefile index 2f9050f448d67..b87a3e1e58609 100644 --- a/deps/Makefile +++ b/deps/Makefile @@ -175,6 +175,10 @@ ifeq ($(WITH_NVTX),1) DEP_LIBS += nvtx endif +ifneq ($(WITH_TERMINFO),0) +DEP_LIBS += terminfo +endif + # Only compile standalone LAPACK if we are not using OpenBLAS. # OpenBLAS otherwise compiles LAPACK as part of its build. # This is useful where one wants to use the vendor BLAS, but @@ -197,7 +201,8 @@ DEP_LIBS_STAGED := $(DEP_LIBS) 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 \ - sanitizers libsuitesparse lld libtracyclient ittapi nvtx JuliaSyntax + sanitizers libsuitesparse lld libtracyclient ittapi nvtx JuliaSyntax \ + terminfo DEP_LIBS_ALL := $(DEP_LIBS_STAGED_ALL) ifneq ($(USE_BINARYBUILDER_OPENBLAS),0) @@ -259,6 +264,7 @@ include $(SRCDIR)/libgit2.mk include $(SRCDIR)/libwhich.mk include $(SRCDIR)/p7zip.mk include $(SRCDIR)/libtracyclient.mk +include $(SRCDIR)/terminfo.mk # vendored Julia libs include $(SRCDIR)/JuliaSyntax.mk diff --git a/deps/checksums/terminfo b/deps/checksums/terminfo new file mode 100644 index 0000000000000..bd971e72b1be8 --- /dev/null +++ b/deps/checksums/terminfo @@ -0,0 +1,2 @@ +TermInfoDB-v2023.12.9.any.tar.gz/md5/573d9b5adaf6af500e3dfae6e3d15ebf +TermInfoDB-v2023.12.9.any.tar.gz/sha512/e0a5bfe54346f9d5690a840628b329f6fac7375b0d29337bc70813ae3553a72bb397f8034d221c544289e40c4cfc685d5805777b7528f05bbe0123b5905c24a4 diff --git a/deps/terminfo.mk b/deps/terminfo.mk new file mode 100644 index 0000000000000..63194f786f566 --- /dev/null +++ b/deps/terminfo.mk @@ -0,0 +1,43 @@ +## TERMINFO-DB ## +include $(SRCDIR)/terminfo.version + +$(SRCCACHE)/TermInfoDB-v$(TERMINFO_VER).any.tar.gz: | $(SRCCACHE) + $(JLDOWNLOAD) $@ https://github.com/JuliaBinaryWrappers/TermInfoDB_jll.jl/releases/download/$(TERMINFO_TAG)/TermInfoDB.v$(TERMINFO_VER).any.tar.gz + touch -c $@ + +$(BUILDDIR)/TermInfoDB-v$(TERMINFO_VER)/source-extracted: $(SRCCACHE)/TermInfoDB-v$(TERMINFO_VER).any.tar.gz + $(JLCHECKSUM) $< + rm -rf $(dir $@) + mkdir -p $(dir $@) + $(TAR) -C $(dir $@) --strip-components 1 -xf $< + echo 1 > $@ + +checksum-terminfo: $(SRCCACHE)/TermInfoDB-v$(TERMINFO_VER).any.tar.gz + $(JLCHECKSUM) $< + +$(BUILDDIR)/TermInfoDB-v$(TERMINFO_VER)/build-compiled: $(BUILDDIR)/TermInfoDB-v$(TERMINFO_VER)/source-extracted + echo 1 > $@ + +$(BUILDDIR)/TermInfoDB-v$(TERMINFO_VER)/build-checked: $(BUILDDIR)/TermInfoDB-v$(TERMINFO_VER)/build-compiled + echo 1 > $@ + +define TERMINFO_INSTALL + mkdir -p $2/$$(build_datarootdir) + cp -R $1/terminfo $2/$$(build_datarootdir) +endef +$(eval $(call staged-install, \ + terminfo,TermInfoDB-v$(TERMINFO_VER), \ + TERMINFO_INSTALL,,,,)) + +clean-terminfo: + -rm -f $(BUILDDIR)/TermInfoDB-v$(TERMINFO_VER)/build-compiled + +distclean-terminfo: + rm -rf $(SRCCACHE)/TermInfoDB*.tar.gz $(SRCCACHE)/TermInfoDB-v$(TERMINFO_VER) $(BUILDDIR)/TermInfoDB-v$(TERMINFO_VER) + +get-terminfo: $(SRCCACHE)/TermInfoDB-v$(TERMINFO_VER).any.tar.gz +extract-terminfo: $(BUILDDIR)/TermInfoDB-v$(TERMINFO_VER)/source-extracted +configure-terminfo: extract-terminfo +compile-terminfo: $(BUILDDIR)/TermInfoDB-v$(TERMINFO_VER)/build-compiled +fastcheck-terminfo: check-terminfo +check-terminfo: $(BUILDDIR)/TermInfoDB-v$(TERMINFO_VER)/build-checked diff --git a/deps/terminfo.version b/deps/terminfo.version new file mode 100644 index 0000000000000..b7c020b830517 --- /dev/null +++ b/deps/terminfo.version @@ -0,0 +1,3 @@ +# -*- makefile -*- +TERMINFO_VER := 2023.12.9 +TERMINFO_TAG := TermInfoDB-v$(TERMINFO_VER)+0 diff --git a/stdlib/REPL/test/precompilation.jl b/stdlib/REPL/test/precompilation.jl index 228cbd212a2c1..7efcf0b5e8282 100644 --- a/stdlib/REPL/test/precompilation.jl +++ b/stdlib/REPL/test/precompilation.jl @@ -15,8 +15,11 @@ if !Sys.iswindows() @testset "No interactive startup compilation" begin f, _ = mktemp() - # start an interactive session - cmd = `$(Base.julia_cmd()[1]) --trace-compile=$f -q --startup-file=no -i` + # start an interactive session, ensuring `TERM` is unset since it can trigger + # different amounts of precompilation stemming from `base/terminfo.jl` depending + # on the value, making the test here unreliable + cmd = addenv(`$(Base.julia_cmd()[1]) --trace-compile=$f -q --startup-file=no -i`, + Dict("TERM" => "")) pts, ptm = open_fake_pty() p = run(cmd, pts, pts, pts; wait=false) Base.close_stdio(pts)