Search code examples
c++cmakestatic-librariesstatic-linkinglibxml2

How can I use CMake and FindLibXml2 to link against a static version of LibXml2 that requires no DLL


I am modernizing our CMake build system and switching to static compilation of all dependencies so I can deploy the application as single binary. One of the dependencies is LibXml2 which is statically compiled (Environment MSVC 2019 x64 Native):

cscript configure.js iconv=no compiler=msvc cruntime=/MT debug=yes static=yes prefix=libxml
nmake Makefile.msvc libxml install

This generates the DLL win32\libxml\bin\libxml2.dll and the LIB files win32\libxml\lib\libxml2.liband win32\libxml\lib\libxml2_a.lib.

My CMake file looks like this:

find_package(LibXml2 REQUIRED)

add_executable(testapp WIN32)

target_sources(testapp
    PRIVATE
        Main.cpp
)

target_include_directories(testapp PUBLIC ${LIBXML_LIBRARIES})

target_link_libraries(testapp PRIVATE LibXml2::LibXml2)

Problem: It looks like the find module FindLibXml2 picks up the relocatable shared DLL, but not the static LIB archive. Thus the application is linked against the dynamic library.

Question: How can I use the find module script, but link against the static version of LibXml2? Is this even possible or do I have to write an own find script?


Solution

  • User @alex-reinking gave the important tip: Set the cached variable before calling the find module - and not afterwards.

    Because I don't want to hardcode the path (and can't because I have a debug and release build of LibXml2), I use find_library to find the static library (Note: I added the libxml directory via CMAKE_PREFIX_PATH):

    find_library(STATIC_LIBXML2_LIBRARY NAMES libxml2_a)
    message(STATUS "Found library: ${STATIC_LIBXML2_LIBRARY}")
    set(LIBXML2_LIBRARY ${STATIC_LIBXML2_LIBRARY})
    find_package(LibXml2 REQUIRED)