libexpat: building expat 2.4.8 on windows using static runtime fails

Trying to upgrade to the latest version of expat using MSVC 2022, I find it impossible to link against expat, when compiled with the static runtime options. Here my cmake variables:

  set (EXPAT_SHARED_LIBS OFF)
  set (EXPAT_BUILD_EXAMPLES OFF)
  set (EXPAT_BUILD_TESTS OFF)
  set (EXPAT_BUILD_TOOLS OFF)
  set (EXPAT_BUILD_TOOLS OFF)
  if (WITH_STATIC_RUNTIME)
    #expat is overriding this, so enforce it to be
    set(EXPAT_MSVC_STATIC_CRT ON CACHE BOOL "Use /MT flag (static CRT) when compiling in MSVC" FORCE)
  endif()

Unfortunately, when trying to link against the library, i get an undefined symbol:

libexpat.lib(xmlparse.c.obj) : error LNK2019: unresolved external symbol __imp_rand_s referenced in function generate_hash_secret_salt

additionally there are warnings, that indicate that the static runtime seems to be ignored:

LINK : warning LNK4098: defaultlib 'MSVCRT' conflicts with use of other libs; use /NODEFAULTLIB:library
LINK : warning LNK4217: symbol '_errno' defined in 'libucrt.lib(errno.obj)' is imported by 'libexpat.lib(xmlparse.c.obj)' in function 'ENTROPY_DEBUG'
LINK : warning LNK4217: symbol '__acrt_iob_func' defined in 'libucrt.lib(_file.obj)' is imported by 'libexpat.lib(xmlparse.c.obj)' in function 'ENTROPY_DEBUG'
LINK : warning LNK4217: symbol '__stdio_common_vfprintf' defined in 'libucrt.lib(output.obj)' is imported by 'libexpat.lib(xmlparse.c.obj)' in function '_vfprintf_l'
LINK : warning LNK4217: symbol 'free' defined in 'libucrt.lib(free.obj)' is imported by 'libexpat.lib(xmlparse.c.obj)' in function 'parserCreate'
LINK : warning LNK4217: symbol 'malloc' defined in 'libucrt.lib(malloc.obj)' is imported by 'libexpat.lib(xmlparse.c.obj)' in function 'parserCreate'
LINK : warning LNK4217: symbol 'realloc' defined in 'libucrt.lib(realloc.obj)' is imported by 'libexpat.lib(xmlparse.c.obj)' in function 'parserCreate'
LINK : warning LNK4217: symbol 'strtoul' defined in 'libucrt.lib(strtox.obj)' is imported by 'libexpat.lib(xmlparse.c.obj)' in function 'ENTROPY_DEBUG'
LINK : warning LNK4217: symbol 'getenv' defined in 'libucrt.lib(getenv.obj)' is imported by 'libexpat.lib(xmlparse.c.obj)' in function 'ENTROPY_DEBUG'

About this issue

  • Original URL
  • State: closed
  • Created 2 years ago
  • Comments: 27 (17 by maintainers)

Commits related to this issue

Most upvoted comments

@fbergmann How did you resolve this issue

libexpat.lib(xmlparse.c.obj) : error LNK2019: unresolved external symbol __imp_rand_s referenced in function generate_hash_secret_salt

We resolved this issue in our Expat find script, by compiling it twice, to see whether the XML_STATIC compile definition is needed:

# figure out if we need XML_STATIC flag
if (EXPAT_INCLUDE_DIR AND EXPAT_LIBRARY)
  enable_language(C)  
  set(EXPAT_EXPAT_CODE
"
#include <expat.h>
#include <stdio.h>

int 
main(void)
{
    printf(\"%s\", XML_ExpatVersion());
    return 0;
}
" 
)

set(CMAKE_REQUIRED_LIBRARIES_CACHE ${CMAKE_REQUIRED_LIBRARIES})
set(CMAKE_REQUIRED_INCLUDES_CACHE ${CMAKE_REQUIRED_INCLUDES})
set(CMAKE_REQUIRED_DEFINITIONS_CACHE ${CMAKE_REQUIRED_DEFINITIONS})

set(EXPAT_EXPAT_TEST)
set(CMAKE_REQUIRED_LIBRARIES "${EXPAT_LIBRARY}")
set(CMAKE_REQUIRED_INCLUDES "${EXPAT_INCLUDE_DIR}")
CHECK_C_SOURCE_COMPILES("${EXPAT_EXPAT_CODE}" EXPAT_EXPAT_TEST)

if (NOT EXPAT_EXPAT_TEST)
set(CMAKE_REQUIRED_LIBRARIES "${EXPAT_LIBRARY}")
set(CMAKE_REQUIRED_INCLUDES "${EXPAT_INCLUDE_DIR}")
set(CMAKE_REQUIRED_DEFINITIONS "-DXML_STATIC=1")

CHECK_C_SOURCE_COMPILES("${EXPAT_EXPAT_CODE}" EXPAT_EXPAT_TEST2)
if (EXPAT_EXPAT_TEST2)
  set_target_properties(EXPAT::EXPAT PROPERTIES
    INTERFACE_COMPILE_DEFINITIONS "XML_STATIC=1"
    )
else()
  message(FATAL_ERROR "Unable to compile a test executable against expat with
  
  EXPAT_INCLUDE_DIR = ${EXPAT_INCLUDE_DIR}
  EXPAT_LIBRARY     = ${EXPAT_LIBRARY}
  ")
endif()

endif()

full script for example here:

https://github.com/copasi/COPASI/blob/develop/CMakeModules/FindEXPAT.cmake

@hartwork Thanks for your input, yes I am using it on windows. I can switch to the recommended version