From 8d5a11cd0137d3ad70f6b06e063ea91a776d510a Mon Sep 17 00:00:00 2001 From: Dimitry Andric Date: Wed, 18 Jun 2025 12:06:25 +0200 Subject: [PATCH] src.conf: Add WITH_LLVM_LINK_STATIC_LIBRARIES build knob In commit 2e47f35be5dc libllvm, libclang and liblldb were converted into private shared libraries. This allowed clang, lld, lldb, and other llvm tools to be linked against these shared libraries, which makes them smaller and avoids duplication. However, this also comes at the cost of some performance, since the dynamic libraries are quite large, and contain lots of long symbols (mangled C++ identifiers). Add a WITH_LLVM_LINK_STATIC_LIBRARIES build knob that can be used to go back to the previous behavior: libllvm, libclang and liblldb are built as internal static libraries, i.e. only available during buildworld, and fully linked into the various executables such as clang, lld, etc. PR: 287447 Reviewed by: emaste MFC after: 1 week Differential Revision: https://reviews.freebsd.org/D50956 --- lib/clang/libclang/Makefile | 8 ++++---- lib/clang/liblldb/Makefile | 13 ++++++++++++- lib/clang/libllvm/Makefile | 9 ++++----- share/man/man5/src.conf.5 | 9 ++++++++- share/mk/src.opts.mk | 1 + tools/build/mk/OptionalObsoleteFiles.inc | 11 ++++++++--- tools/build/options/WITH_LLVM_LINK_STATIC_LIBRARIES | 6 ++++++ usr.bin/clang/Makefile.inc | 2 +- usr.bin/clang/clang.prog.mk | 2 +- usr.bin/clang/lld/Makefile | 2 +- usr.bin/clang/lldb-server/Makefile | 5 +++++ usr.bin/clang/lldb/Makefile | 5 +++++ usr.bin/clang/llvm.prog.mk | 5 +++++ 13 files changed, 61 insertions(+), 17 deletions(-) create mode 100644 tools/build/options/WITH_LLVM_LINK_STATIC_LIBRARIES diff --git a/lib/clang/libclang/Makefile b/lib/clang/libclang/Makefile index 7eb2c99b25c..56f6fd374fe 100644 --- a/lib/clang/libclang/Makefile +++ b/lib/clang/libclang/Makefile @@ -1,8 +1,8 @@ -.include +.include .include "../clang.pre.mk" -.if defined(TOOLS_PREFIX) -# Build static library during cross-tools stage +.if defined(TOOLS_PREFIX) || ${MK_LLVM_LINK_STATIC_LIBRARIES} == "yes" +# Build static library during cross-tools stage, or when explicitly requested. LIB= clang INTERNALLIB= .else @@ -872,7 +872,7 @@ SRCS+= ${SRCS_ALL:O} LIBDEPS+= llvm -.if defined(TOOLS_PREFIX) +.if defined(TOOLS_PREFIX) || ${MK_LLVM_LINK_STATIC_LIBRARIES} == "yes" LIBPRIV= LIBEXT= a .else diff --git a/lib/clang/liblldb/Makefile b/lib/clang/liblldb/Makefile index a3ff8e36786..aa9e90b2f6f 100644 --- a/lib/clang/liblldb/Makefile +++ b/lib/clang/liblldb/Makefile @@ -1,10 +1,16 @@ -.include +.include .include "../lldb.pre.mk" +.if ${MK_LLVM_LINK_STATIC_LIBRARIES} == "yes" +# Build static library when explicitly requested. +LIB= lldb +INTERNALLIB= +.else PACKAGE= lldb SHLIB_CXX= lldb SHLIB_MAJOR= 19 PRIVATELIB= +.endif SHARED_CXXFLAGS+= -UPIC # To avoid compile errors @@ -753,8 +759,13 @@ SRCS+= Version/Version.cpp LIBDEPS+= clang LIBDEPS+= llvm +.if defined(TOOLS_PREFIX) || ${MK_LLVM_LINK_STATIC_LIBRARIES} == "yes" +LIBPRIV= +LIBEXT= a +.else LIBPRIV= private LIBEXT= so +.endif .for lib in ${LIBDEPS} DPADD+= ${OBJTOP}/lib/clang/lib${lib}/lib${LIBPRIV}${lib}.${LIBEXT} diff --git a/lib/clang/libllvm/Makefile b/lib/clang/libllvm/Makefile index a4e9c628d99..05128550827 100644 --- a/lib/clang/libllvm/Makefile +++ b/lib/clang/libllvm/Makefile @@ -1,8 +1,8 @@ -.include +.include .include "../llvm.pre.mk" -.if defined(TOOLS_PREFIX) -# Build static library during cross-tools stage +.if defined(TOOLS_PREFIX) || ${MK_LLVM_LINK_STATIC_LIBRARIES} == "yes" +# Build static library during cross-tools stage, or when explicitly requested. LIB= llvm INTERNALLIB= .else @@ -14,6 +14,7 @@ PRIVATELIB= # Work around "relocation R_PPC_GOT16 out of range" errors PICFLAG= -fPIC .endif +CFLAGS+= -DLLVM_BUILD_LLVM_DYLIB .endif SHARED_CXXFLAGS+= -UPIC # To avoid compile errors @@ -48,8 +49,6 @@ CFLAGS+= -DBLAKE3_NO_AVX512 -DBLAKE3_NO_AVX2 -DBLAKE3_NO_SSE41 \ CFLAGS+= -DBLAKE3_USE_NEON=0 .endif -CFLAGS+= -DLLVM_BUILD_LLVM_DYLIB - SRCDIR= llvm/lib # Explanation of different SRCS variants below: diff --git a/share/man/man5/src.conf.5 b/share/man/man5/src.conf.5 index c56a13652a8..1d55ab074a4 100644 --- a/share/man/man5/src.conf.5 +++ b/share/man/man5/src.conf.5 @@ -1,5 +1,5 @@ .\" DO NOT EDIT-- this file is @generated by tools/build/options/makeman. -.Dd December 15, 2025 +.Dd December 21, 2025 .Dt SRC.CONF 5 .Os .Sh NAME @@ -999,6 +999,13 @@ Install ELF Tool Chain's cxxfilt as c++filt, instead of LLVM's llvm-cxxfilt. .It Va WITH_LLVM_FULL_DEBUGINFO Generate full debug information for LLVM libraries and tools, which uses more disk space and build resources, but allows for easier debugging. +.It Va WITH_LLVM_LINK_STATIC_LIBRARIES +Link LLVM libraries (libllvm, libclang, liblldb) statically into each of +the binaries that use them. + +This means that binaries linked against these libraries, such as clang, +ld.lld and lldb will be much larger and position dependent, but will +start more quickly. .It Va WITHOUT_LLVM_TARGET_AARCH64 Do not build LLVM target support for AArch64. The diff --git a/share/mk/src.opts.mk b/share/mk/src.opts.mk index 4109edc90f2..0d806702417 100644 --- a/share/mk/src.opts.mk +++ b/share/mk/src.opts.mk @@ -213,6 +213,7 @@ __DEFAULT_NO_OPTIONS = \ LOADER_VERBOSE \ LOADER_VERIEXEC_PASS_MANIFEST \ LLVM_FULL_DEBUGINFO \ + LLVM_LINK_STATIC_LIBRARIES \ MALLOC_PRODUCTION \ OFED_EXTRA \ OPENLDAP \ diff --git a/tools/build/mk/OptionalObsoleteFiles.inc b/tools/build/mk/OptionalObsoleteFiles.inc index 0551074f0bc..f86e9d0dc19 100644 --- a/tools/build/mk/OptionalObsoleteFiles.inc +++ b/tools/build/mk/OptionalObsoleteFiles.inc @@ -892,12 +892,14 @@ OLD_FILES+=usr/share/man/man4/ccd.4.gz OLD_FILES+=usr/share/man/man8/ccdconfig.8.gz .endif -.if ${MK_CLANG} == no && ${MK_CLANG_FORMAT} == no && ${MK_LLDB} == no +.if ${MK_CLANG} == no && ${MK_CLANG_FORMAT} == no && ${MK_LLDB} == no && \ + ${MK_LLVM_LINK_STATIC_LIBRARIES} == no OLD_LIBS+=usr/lib/libprivateclang.so.19 .endif .if ${MK_CLANG_EXTRAS} == no && ${MK_CLANG} == no && ${MK_LLDB} == no && \ - ${MK_LLD} == no && ${MK_LLVM_BINUTILS} == no && ${MK_LLVM_COV} == no + ${MK_LLD} == no && ${MK_LLVM_BINUTILS} == no && ${MK_LLVM_COV} == no && \ + ${MK_LLVM_LINK_STATIC_LIBRARIES} == no OLD_LIBS+=usr/lib/libprivatellvm.so.19 .endif @@ -3868,10 +3870,13 @@ OLD_LIBS+=${DEBUG_LIB${LIBCOMPAT}_LIBS} OLD_FILES+=usr/bin/ld.lld .endif +.if ${MK_LLDB} == no && ${MK_LLVM_LINK_STATIC_LIBRARIES} == no +OLD_LIBS+=usr/lib/libprivatelldb.so.19 +.endif + .if ${MK_LLDB} == no OLD_FILES+=usr/bin/lldb OLD_FILES+=usr/bin/lldb-server -OLD_LIBS+=usr/lib/libprivatelldb.so.19 OLD_FILES+=usr/share/man/man1/lldb-server.1.gz OLD_FILES+=usr/share/man/man1/lldb.1.gz .endif diff --git a/tools/build/options/WITH_LLVM_LINK_STATIC_LIBRARIES b/tools/build/options/WITH_LLVM_LINK_STATIC_LIBRARIES new file mode 100644 index 00000000000..7860ee862b1 --- /dev/null +++ b/tools/build/options/WITH_LLVM_LINK_STATIC_LIBRARIES @@ -0,0 +1,6 @@ +Link LLVM libraries (libllvm, libclang, liblldb) statically into each of +the binaries that use them. + +This means that binaries linked against these libraries, such as clang, +ld.lld and lldb will be much larger and position dependent, but will +start more quickly. diff --git a/usr.bin/clang/Makefile.inc b/usr.bin/clang/Makefile.inc index 1e9998061cf..7ce07e2eac1 100644 --- a/usr.bin/clang/Makefile.inc +++ b/usr.bin/clang/Makefile.inc @@ -1,6 +1,6 @@ .include -.if defined(TOOLS_PREFIX) +.if defined(TOOLS_PREFIX) || ${MK_LLVM_LINK_STATIC_LIBRARIES} == "yes" MK_PIE:= no # Explicit libXXX.a references .endif diff --git a/usr.bin/clang/clang.prog.mk b/usr.bin/clang/clang.prog.mk index 3baf3d0baf0..e35425b0d28 100644 --- a/usr.bin/clang/clang.prog.mk +++ b/usr.bin/clang/clang.prog.mk @@ -18,7 +18,7 @@ LIBADD+= z LIBADD+= zstd .endif -.if defined(TOOLS_PREFIX) +.if defined(TOOLS_PREFIX) || ${MK_LLVM_LINK_STATIC_LIBRARIES} == "yes" LIBPRIV= LIBEXT= a .else diff --git a/usr.bin/clang/lld/Makefile b/usr.bin/clang/lld/Makefile index cbad6f2b3fc..588dc5a198f 100644 --- a/usr.bin/clang/lld/Makefile +++ b/usr.bin/clang/lld/Makefile @@ -81,7 +81,7 @@ SRCS+= tools/lld/lld.cpp LIBDEPS+= llvm -.if defined(TOOLS_PREFIX) +.if defined(TOOLS_PREFIX) || ${MK_LLVM_LINK_STATIC_LIBRARIES} == "yes" LIBPRIV= LIBEXT= a .else diff --git a/usr.bin/clang/lldb-server/Makefile b/usr.bin/clang/lldb-server/Makefile index 5042fa1fdf0..da4d8344505 100644 --- a/usr.bin/clang/lldb-server/Makefile +++ b/usr.bin/clang/lldb-server/Makefile @@ -22,8 +22,13 @@ LIBDEPS+= lldb LIBDEPS+= clang LIBDEPS+= llvm +.if defined(TOOLS_PREFIX) || ${MK_LLVM_LINK_STATIC_LIBRARIES} == "yes" +LIBPRIV= +LIBEXT= a +.else LIBPRIV= private LIBEXT= so +.endif .for lib in ${LIBDEPS} DPADD+= ${OBJTOP}/lib/clang/lib${lib}/lib${LIBPRIV}${lib}.${LIBEXT} diff --git a/usr.bin/clang/lldb/Makefile b/usr.bin/clang/lldb/Makefile index 452bfd23bfa..880d4de1c8f 100644 --- a/usr.bin/clang/lldb/Makefile +++ b/usr.bin/clang/lldb/Makefile @@ -15,8 +15,13 @@ LIBDEPS+= lldb LIBDEPS+= clang LIBDEPS+= llvm +.if defined(TOOLS_PREFIX) || ${MK_LLVM_LINK_STATIC_LIBRARIES} == "yes" +LIBPRIV= +LIBEXT= a +.else LIBPRIV= private LIBEXT= so +.endif .for lib in ${LIBDEPS} DPADD+= ${OBJTOP}/lib/clang/lib${lib}/lib${LIBPRIV}${lib}.${LIBEXT} diff --git a/usr.bin/clang/llvm.prog.mk b/usr.bin/clang/llvm.prog.mk index c369fe8d594..00f319a246f 100644 --- a/usr.bin/clang/llvm.prog.mk +++ b/usr.bin/clang/llvm.prog.mk @@ -14,8 +14,13 @@ LIBPRIV= LIBEXT= a .else LIBDEPS+= llvm +.if ${MK_LLVM_LINK_STATIC_LIBRARIES} == "yes" +LIBPRIV= +LIBEXT= a +.else LIBPRIV= private LIBEXT= so +.endif LIBADD+= z LIBADD+= zstd .endif