Skip to content

Commit 04e8ca2

Browse files
committed
[cmake] Add support for statically linking libxml2
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 macOS ignores this setting since libxml2 is part of the OS and stable enough. This mirrors what we do for zstd Fixes #113696 Fixes #138225 Fixes https://discourse.llvm.org/t/official-builds-without-libxml2-and-libtinfo/58169
1 parent 2d51705 commit 04e8ca2

File tree

6 files changed

+84
-25
lines changed

6 files changed

+84
-25
lines changed

clang/cmake/caches/Release.cmake

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,7 @@ set_final_stage_var(CPACK_GENERATOR "TXZ" STRING)
171171
set_final_stage_var(CPACK_ARCHIVE_THREADS "0" STRING)
172172

173173
set_final_stage_var(LLVM_USE_STATIC_ZSTD "ON" BOOL)
174+
set_final_stage_var(LLVM_USE_STATIC_LIBXML2 "ON" BOOL)
174175
if (LLVM_RELEASE_ENABLE_LTO)
175176
set_final_stage_var(LLVM_ENABLE_FATLTO "ON" BOOL)
176177
set_final_stage_var(CPACK_PRE_BUILD_SCRIPTS "${CMAKE_CURRENT_LIST_DIR}/release_cpack_pre_build_strip_lto.cmake" STRING)

lldb/source/Host/CMakeLists.txt

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -152,7 +152,7 @@ set(EXTRA_LIBS)
152152
if (CMAKE_SYSTEM_NAME MATCHES "NetBSD")
153153
list(APPEND EXTRA_LIBS kvm)
154154
endif()
155-
if (LLDB_ENABLE_LIBXML2)
155+
if (LLDB_ENABLE_LIBXML2 AND NOT LLVM_USE_STATIC_LIBXML2)
156156
list(APPEND EXTRA_LIBS LibXml2::LibXml2)
157157
endif()
158158
if (HAVE_LIBDL)
@@ -190,3 +190,8 @@ add_lldb_library(lldbHost NO_PLUGIN_DEPENDENCIES
190190
${LLDB_LIBEDIT_LIBS}
191191
)
192192

193+
if (LLDB_ENABLE_LIBXML2 AND LLVM_USE_STATIC_LIBXML2)
194+
target_link_libraries(lldbHost PRIVATE ${LIBXML2_LIBRARIES})
195+
target_include_directories(lldbHost PUBLIC ${LIBXML2_INCLUDE_DIRS})
196+
add_dependencies(lldbHost libxml2)
197+
endif()

llvm/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -605,6 +605,8 @@ set(LLVM_TARGET_ARCH "host"
605605

606606
set(LLVM_ENABLE_LIBXML2 "ON" CACHE STRING "Use libxml2 if available. Can be ON, OFF, or FORCE_ON")
607607

608+
set(LLVM_USE_STATIC_LIBXML2 "OFF" CACHE BOOL "Use static version of libxml2. Can be ON, or OFF")
609+
608610
option(LLVM_ENABLE_LIBEDIT "Use libedit if available." ON)
609611

610612
option(LLVM_ENABLE_LIBPFM "Use libpfm for performance counters if available." ON)

llvm/cmake/config-ix.cmake

Lines changed: 24 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -210,22 +210,31 @@ if(LLVM_ENABLE_ZSTD)
210210
endif()
211211

212212
if(LLVM_ENABLE_LIBXML2)
213-
if(LLVM_ENABLE_LIBXML2 STREQUAL FORCE_ON)
214-
find_package(LibXml2 REQUIRED)
215-
elseif(NOT LLVM_USE_SANITIZER MATCHES "Memory.*")
216-
find_package(LibXml2)
213+
if(APPLE)
214+
set(LLVM_USE_STATIC_LIBXML2 OFF)
217215
endif()
218-
if(LibXml2_FOUND)
219-
# Check if libxml2 we found is usable; for example, we may have found a 32-bit
220-
# library on a 64-bit system which would result in a link-time failure.
221-
cmake_push_check_state()
222-
list(APPEND CMAKE_REQUIRED_INCLUDES ${LIBXML2_INCLUDE_DIRS})
223-
list(APPEND CMAKE_REQUIRED_LIBRARIES ${LIBXML2_LIBRARIES})
224-
list(APPEND CMAKE_REQUIRED_DEFINITIONS ${LIBXML2_DEFINITIONS})
225-
check_symbol_exists(xmlReadMemory libxml/xmlreader.h HAVE_LIBXML2)
226-
cmake_pop_check_state()
227-
if(LLVM_ENABLE_LIBXML2 STREQUAL FORCE_ON AND NOT HAVE_LIBXML2)
228-
message(FATAL_ERROR "Failed to configure libxml2")
216+
217+
if(LLVM_USE_STATIC_LIBXML2)
218+
include(LibXml2)
219+
set(HAVE_LIBXML2 1)
220+
else()
221+
if(LLVM_ENABLE_LIBXML2 STREQUAL FORCE_ON)
222+
find_package(LibXml2 REQUIRED)
223+
elseif(NOT LLVM_USE_SANITIZER MATCHES "Memory.*")
224+
find_package(LibXml2)
225+
endif()
226+
if(LibXml2_FOUND)
227+
# Check if libxml2 we found is usable; for example, we may have found a 32-bit
228+
# library on a 64-bit system which would result in a link-time failure.
229+
cmake_push_check_state()
230+
list(APPEND CMAKE_REQUIRED_INCLUDES ${LIBXML2_INCLUDE_DIRS})
231+
list(APPEND CMAKE_REQUIRED_LIBRARIES ${LIBXML2_LIBRARIES})
232+
list(APPEND CMAKE_REQUIRED_DEFINITIONS ${LIBXML2_DEFINITIONS})
233+
check_symbol_exists(xmlReadMemory libxml/xmlreader.h HAVE_LIBXML2)
234+
cmake_pop_check_state()
235+
if(LLVM_ENABLE_LIBXML2 STREQUAL FORCE_ON AND NOT HAVE_LIBXML2)
236+
message(FATAL_ERROR "Failed to configure libxml2")
237+
endif()
229238
endif()
230239
endif()
231240
set(LLVM_ENABLE_LIBXML2 "${HAVE_LIBXML2}")

llvm/cmake/modules/LibXml2.cmake

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
include(ExternalProject)
2+
3+
if (NOT LIBXML2_PREFIX)
4+
set (LIBXML2_PREFIX libxml2)
5+
endif()
6+
7+
set(LIBXML2_PATH ${CMAKE_CURRENT_BINARY_DIR}/${LIBXML2_PREFIX}/src/${LIBXML2_PREFIX})
8+
set(LIBXML2_LIB_PATH ${LIBXML2_PATH}-build/libxml2.a)
9+
10+
ExternalProject_Add(${LIBXML2_PREFIX}
11+
PREFIX ${LIBXML2_PREFIX}
12+
GIT_REPOSITORY https://github.com/GNOME/libxml2.git
13+
GIT_TAG v2.15.1
14+
CMAKE_ARGS -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}
15+
-DBUILD_SHARED_LIBS=OFF
16+
-DLIBXML2_WITH_PYTHON=OFF
17+
-DLIBXML2_WITH_PROGRAMS=OFF
18+
-DLIBXML2_WITH_TESTS=OFF
19+
-DLIBXML2_WITH_LZMA=OFF
20+
-DLIBXML2_WITH_ZLIB=OFF
21+
CMAKE_CACHE_ARGS -DCMAKE_C_COMPILER:FILEPATH=${CMAKE_C_COMPILER}
22+
-DCMAKE_CXX_COMPILER:FILEPATH=${CMAKE_CXX_COMPILER}
23+
-DCMAKE_POSITION_INDEPENDENT_CODE:BOOL=ON
24+
BUILD_BYPRODUCTS ${LIBXML2_LIB_PATH}
25+
UPDATE_COMMAND ""
26+
INSTALL_COMMAND ""
27+
)
28+
29+
set(LIBXML2_INCLUDE_DIRS ${LIBXML2_PATH}/include ${LIBXML2_PATH}-build)
30+
set(LIBXML2_LIBRARIES ${LIBXML2_LIB_PATH})
31+
set(LIBXML2_DEFINITIONS "")

llvm/lib/WindowsManifest/CMakeLists.txt

Lines changed: 20 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
include(GetLibraryName)
22

3-
if(LLVM_ENABLE_LIBXML2)
3+
if(LLVM_ENABLE_LIBXML2 AND NOT LLVM_USE_STATIC_LIBXML2)
44
set(imported_libs LibXml2::LibXml2)
55
endif()
66

@@ -18,17 +18,28 @@ add_llvm_component_library(LLVMWindowsManifest
1818
Support
1919
)
2020

21+
if(LLVM_ENABLE_LIBXML2 AND LLVM_USE_STATIC_LIBXML2)
22+
target_link_libraries(LLVMWindowsManifest PRIVATE ${LIBXML2_LIBRARIES})
23+
target_include_directories(LLVMWindowsManifest PRIVATE ${LIBXML2_INCLUDE_DIRS})
24+
add_dependencies(LLVMWindowsManifest libxml2)
25+
endif()
26+
2127
# This block is only needed for llvm-config. When we deprecate llvm-config and
2228
# move to using CMake export, this block can be removed.
2329
if(LLVM_ENABLE_LIBXML2)
24-
# CMAKE_BUILD_TYPE is only meaningful to single-configuration generators.
25-
if(CMAKE_BUILD_TYPE)
26-
string(TOUPPER ${CMAKE_BUILD_TYPE} build_type)
27-
get_property(libxml2_library TARGET LibXml2::LibXml2 PROPERTY LOCATION_${build_type})
28-
endif()
29-
if(NOT libxml2_library)
30-
get_property(libxml2_library TARGET LibXml2::LibXml2 PROPERTY LOCATION)
30+
if(LLVM_USE_STATIC_LIBXML2)
31+
# When using static libxml2 built via ExternalProject, use the library path directly
32+
get_library_name(${LIBXML2_LIBRARIES} libxml2_library)
33+
else()
34+
# CMAKE_BUILD_TYPE is only meaningful to single-configuration generators.
35+
if(CMAKE_BUILD_TYPE)
36+
string(TOUPPER ${CMAKE_BUILD_TYPE} build_type)
37+
get_property(libxml2_library TARGET LibXml2::LibXml2 PROPERTY LOCATION_${build_type})
38+
endif()
39+
if(NOT libxml2_library)
40+
get_property(libxml2_library TARGET LibXml2::LibXml2 PROPERTY LOCATION)
41+
endif()
42+
get_library_name(${libxml2_library} libxml2_library)
3143
endif()
32-
get_library_name(${libxml2_library} libxml2_library)
3344
set_property(TARGET LLVMWindowsManifest PROPERTY LLVM_SYSTEM_LIBS ${libxml2_library})
3445
endif()

0 commit comments

Comments
 (0)