Author: Keith Smiley
Date: 2026-04-10T13:59:32-07:00
New Revision: 11a802685043cb1e9b23e54437da011bdfbf1d61

URL: 
https://github.com/llvm/llvm-project/commit/11a802685043cb1e9b23e54437da011bdfbf1d61
DIFF: 
https://github.com/llvm/llvm-project/commit/11a802685043cb1e9b23e54437da011bdfbf1d61.diff

LOG: [cmake] Add support for statically linking libxml2 (#166867)

Dynamically depending on libxml2 results in various annoyances across
different linux distros for release artifacts. Specifically on fedora
and nixos the library has a different name than on debian, and on
arch-linux they tried to remove the old name entirely.

With this, enabled by default for releases, we don't sacrifice any
behavior changes, but no longer have these issues. For lld the binary
size impact is <1mb

This continues to use the shared libxml for lldb since otherwise
it requires linking ICU, which is off by default

macOS ignores this setting since libxml2 is part of the OS and stable
enough.

This mirrors what we do for zstd

Fixes https://github.com/llvm/llvm-project/issues/113696
Fixes https://github.com/llvm/llvm-project/issues/138225
Fixes
https://discourse.llvm.org/t/official-builds-without-libxml2-and-libtinfo/58169

Added: 
    llvm/cmake/modules/FindLibXml2.cmake

Modified: 
    clang/cmake/caches/Release.cmake
    llvm/CMakeLists.txt
    llvm/cmake/config-ix.cmake
    llvm/lib/WindowsManifest/CMakeLists.txt

Removed: 
    


################################################################################
diff  --git a/clang/cmake/caches/Release.cmake 
b/clang/cmake/caches/Release.cmake
index efe20a201dbc9..b0bc3ebfe5cb6 100644
--- a/clang/cmake/caches/Release.cmake
+++ b/clang/cmake/caches/Release.cmake
@@ -172,6 +172,10 @@ set_final_stage_var(CPACK_GENERATOR "TXZ" STRING)
 set_final_stage_var(CPACK_ARCHIVE_THREADS "0" STRING)
 
 set_final_stage_var(LLVM_USE_STATIC_ZSTD "ON" BOOL)
+if (${CMAKE_HOST_SYSTEM_NAME} MATCHES "Linux")
+  set_final_stage_var(LLVM_USE_STATIC_LIBXML2 "ON" BOOL)
+endif()
+
 if (LLVM_RELEASE_ENABLE_LTO)
   set_final_stage_var(LLVM_ENABLE_FATLTO "ON" BOOL)
   set_final_stage_var(CPACK_PRE_BUILD_SCRIPTS 
"${CMAKE_CURRENT_LIST_DIR}/release_cpack_pre_build_strip_lto.cmake" STRING)

diff  --git a/llvm/CMakeLists.txt b/llvm/CMakeLists.txt
index da012596cca93..6001928f92e37 100644
--- a/llvm/CMakeLists.txt
+++ b/llvm/CMakeLists.txt
@@ -646,6 +646,8 @@ set(LLVM_TARGET_ARCH "host"
 
 set(LLVM_ENABLE_LIBXML2 "ON" CACHE STRING "Use libxml2 if available. Can be 
ON, OFF, or FORCE_ON")
 
+set(LLVM_USE_STATIC_LIBXML2 "OFF" CACHE BOOL "Use static version of libxml2. 
Can be ON, or OFF")
+
 option(LLVM_ENABLE_LIBEDIT "Use libedit if available." ON)
 
 option(LLVM_ENABLE_LIBPFM "Use libpfm for performance counters if available." 
ON)

diff  --git a/llvm/cmake/config-ix.cmake b/llvm/cmake/config-ix.cmake
index 7a5631b1ae3b5..7eca375e29b87 100644
--- a/llvm/cmake/config-ix.cmake
+++ b/llvm/cmake/config-ix.cmake
@@ -219,14 +219,27 @@ if(LLVM_ENABLE_LIBXML2)
     # Check if libxml2 we found is usable; for example, we may have found a 
32-bit
     # library on a 64-bit system which would result in a link-time failure.
     cmake_push_check_state()
-    list(APPEND CMAKE_REQUIRED_INCLUDES ${LIBXML2_INCLUDE_DIRS})
-    list(APPEND CMAKE_REQUIRED_LIBRARIES ${LIBXML2_LIBRARIES})
-    list(APPEND CMAKE_REQUIRED_DEFINITIONS ${LIBXML2_DEFINITIONS})
+    list(APPEND CMAKE_REQUIRED_INCLUDES ${LIBXML2_INCLUDE_DIR})
+    list(APPEND CMAKE_REQUIRED_LIBRARIES ${LIBXML2_LIBRARY})
     check_symbol_exists(xmlReadMemory libxml/xmlreader.h HAVE_LIBXML2)
     cmake_pop_check_state()
     if(LLVM_ENABLE_LIBXML2 STREQUAL FORCE_ON AND NOT HAVE_LIBXML2)
       message(FATAL_ERROR "Failed to configure libxml2")
     endif()
+
+    if(LLVM_USE_STATIC_LIBXML2)
+      if(NOT TARGET LibXml2::LibXml2Static)
+        message(FATAL_ERROR "Failed to find static libxml2 library, but 
LLVM_USE_STATIC_LIBXML2=ON")
+      endif()
+      cmake_push_check_state()
+      list(APPEND CMAKE_REQUIRED_INCLUDES ${LIBXML2_INCLUDE_DIR})
+      list(APPEND CMAKE_REQUIRED_LIBRARIES ${LIBXML2_STATIC_LIBRARY} 
${LIBXML2_STATIC_DEPS})
+      check_symbol_exists(xmlReadMemory libxml/xmlreader.h HAVE_LIBXML2_STATIC)
+      cmake_pop_check_state()
+      if(NOT HAVE_LIBXML2_STATIC)
+        message(FATAL_ERROR "Failed to configure static libxml2, but 
LLVM_USE_STATIC_LIBXML2=ON")
+      endif()
+    endif()
   endif()
   set(LLVM_ENABLE_LIBXML2 "${HAVE_LIBXML2}")
 endif()

diff  --git a/llvm/cmake/modules/FindLibXml2.cmake 
b/llvm/cmake/modules/FindLibXml2.cmake
new file mode 100644
index 0000000000000..24080bb1aeab2
--- /dev/null
+++ b/llvm/cmake/modules/FindLibXml2.cmake
@@ -0,0 +1,75 @@
+# Try to find the libxml2 library
+#
+# If successful, the following variables will be defined:
+# LIBXML2_INCLUDE_DIR
+# LIBXML2_LIBRARY
+# LIBXML2_STATIC_LIBRARY
+# LibXml2_FOUND
+#
+# Additionally, the following import targets will be defined:
+# LibXml2::LibXml2
+# LibXml2::LibXml2Static (if the static library is found)
+
+find_package(PkgConfig QUIET)
+if(PkgConfig_FOUND)
+  pkg_check_modules(PC_LIBXML QUIET libxml-2.0)
+endif()
+
+find_path(LIBXML2_INCLUDE_DIR NAMES libxml/xpath.h
+  HINTS
+  ${PC_LIBXML_INCLUDEDIR}
+  ${PC_LIBXML_INCLUDE_DIRS}
+  PATH_SUFFIXES libxml2
+)
+
+if(DEFINED LIBXML2_LIBRARIES AND NOT DEFINED LIBXML2_LIBRARY)
+  set(LIBXML2_LIBRARY ${LIBXML2_LIBRARIES})
+endif()
+
+find_library(LIBXML2_LIBRARY NAMES xml2 libxml2 libxml2_a
+  HINTS
+  ${PC_LIBXML_LIBDIR}
+  ${PC_LIBXML_LIBRARY_DIRS}
+)
+
+find_library(LIBXML2_STATIC_LIBRARY NAMES
+  "${CMAKE_STATIC_LIBRARY_PREFIX}xml2${CMAKE_STATIC_LIBRARY_SUFFIX}"
+  "${CMAKE_STATIC_LIBRARY_PREFIX}libxml2${CMAKE_STATIC_LIBRARY_SUFFIX}"
+  HINTS
+  ${PC_LIBXML_LIBDIR}
+  ${PC_LIBXML_LIBRARY_DIRS}
+)
+
+include(FindPackageHandleStandardArgs)
+find_package_handle_standard_args(LibXml2
+  REQUIRED_VARS LIBXML2_LIBRARY LIBXML2_INCLUDE_DIR
+  VERSION_VAR PC_LIBXML_VERSION
+)
+
+if(LibXml2_FOUND)
+  if(NOT TARGET LibXml2::LibXml2)
+    add_library(LibXml2::LibXml2 UNKNOWN IMPORTED)
+    set_target_properties(LibXml2::LibXml2 PROPERTIES
+        INTERFACE_INCLUDE_DIRECTORIES "${LIBXML2_INCLUDE_DIR}"
+        IMPORTED_LOCATION "${LIBXML2_LIBRARY}")
+  endif()
+  if(LIBXML2_STATIC_LIBRARY AND NOT TARGET LibXml2::LibXml2Static)
+    add_library(LibXml2::LibXml2Static STATIC IMPORTED)
+    set_target_properties(LibXml2::LibXml2Static PROPERTIES
+        INTERFACE_INCLUDE_DIRECTORIES "${LIBXML2_INCLUDE_DIR}"
+        IMPORTED_LOCATION "${LIBXML2_STATIC_LIBRARY}")
+    # Static libraries need their transitive dependencies for linking.
+    set(LIBXML2_STATIC_DEPS)
+    foreach(lib IN LISTS PC_LIBXML_STATIC_LIBRARIES)
+      if(NOT lib STREQUAL "xml2")
+        list(APPEND LIBXML2_STATIC_DEPS ${lib})
+      endif()
+    endforeach()
+    if(LIBXML2_STATIC_DEPS)
+      set_target_properties(LibXml2::LibXml2Static PROPERTIES
+          INTERFACE_LINK_LIBRARIES "${LIBXML2_STATIC_DEPS}")
+    endif()
+  endif()
+endif()
+
+mark_as_advanced(LIBXML2_INCLUDE_DIR LIBXML2_LIBRARY LIBXML2_STATIC_LIBRARY)

diff  --git a/llvm/lib/WindowsManifest/CMakeLists.txt 
b/llvm/lib/WindowsManifest/CMakeLists.txt
index 910132a4c7dec..46fe3b50357b6 100644
--- a/llvm/lib/WindowsManifest/CMakeLists.txt
+++ b/llvm/lib/WindowsManifest/CMakeLists.txt
@@ -1,7 +1,11 @@
 include(GetLibraryName)
 
 if(LLVM_ENABLE_LIBXML2)
-  set(imported_libs LibXml2::LibXml2)
+  if(LLVM_USE_STATIC_LIBXML2)
+    set(imported_libs LibXml2::LibXml2Static)
+  else()
+    set(imported_libs LibXml2::LibXml2)
+  endif()
 endif()
 
 add_llvm_component_library(LLVMWindowsManifest
@@ -24,10 +28,10 @@ if(LLVM_ENABLE_LIBXML2)
   # CMAKE_BUILD_TYPE is only meaningful to single-configuration generators.
   if(CMAKE_BUILD_TYPE)
     string(TOUPPER ${CMAKE_BUILD_TYPE} build_type)
-    get_property(libxml2_library TARGET LibXml2::LibXml2 PROPERTY 
LOCATION_${build_type})
+    get_property(libxml2_library TARGET ${imported_libs} PROPERTY 
LOCATION_${build_type})
   endif()
   if(NOT libxml2_library)
-    get_property(libxml2_library TARGET LibXml2::LibXml2 PROPERTY LOCATION)
+    get_property(libxml2_library TARGET ${imported_libs} PROPERTY LOCATION)
   endif()
   get_library_name(${libxml2_library} libxml2_library)
   set_property(TARGET LLVMWindowsManifest PROPERTY LLVM_SYSTEM_LIBS 
${libxml2_library})


        
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to