Skip to content

Commit

Permalink
build: Add CMake option to use external expat (#134)
Browse files Browse the repository at this point in the history
Signed-off-by: Uilian Ries <[email protected]>
Co-authored-by: Filip Stenström <[email protected]>
  • Loading branch information
uilianries and filip-stenstrom authored Nov 8, 2024
1 parent d543e8e commit e871e37
Show file tree
Hide file tree
Showing 2 changed files with 91 additions and 78 deletions.
6 changes: 5 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ option(FMILIB_BUILD_STATIC_LIB "Build the library as static." ON)
option(FMILIB_BUILD_SHARED_LIB "Build the library as shared (dll/so/dylib)." ON)
option(FMILIB_INSTALL_SUBLIBS "Install sub-libraries (fmicapi. fmixml, jmutil, fmiimport, fmizip)" OFF)
option(FMILIB_FIND_PACKAGE_ZLIB "Use find_package for zlib, instead of version in FMILibrary/Thirdparty." OFF)
option(FMILIB_SYSTEM_EXPAT "Use system expat library instead of the one in FMILibrary/Thirdparty. Static builds of FMI Library will not bundle expat." OFF)
mark_as_advanced(FMILIB_FIND_PACKAGE_ZLIB)

if(NOT (WIN32 OR CYGWIN OR APPLE))
Expand Down Expand Up @@ -288,7 +289,10 @@ if(FMILIB_BUILD_TESTS)
)
endif()

set(FMILIB_SHARED_SUBLIBS fmixml fmizip fmicapi expat minizip zlib c99snprintf)
set(FMILIB_SHARED_SUBLIBS fmixml fmizip fmicapi minizip zlib c99snprintf)
if(NOT FMILIB_SYSTEM_EXPAT)
list(APPEND FMILIB_SHARED_SUBLIBS expat)
endif()
set(FMILIB_SUBLIBS fmiimport jmutils ${FMILIB_SHARED_SUBLIBS})
# XXX: Unclear why we create intermediate sublibs instead of just giving everything as source.
# Probably also wouldn't get problems with using PRIVATE/PUBLIC on linking sublibs on Windows.
Expand Down
163 changes: 86 additions & 77 deletions Config.cmake/fmixml.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -101,8 +101,6 @@ endif()

# set(DOXYFILE_EXTRA_SOURCES "${DOXYFILE_EXTRA_SOURCES} \"${FMIXMLDIR}/include\"")

set(FMIXML_EXPAT_DIR "${FMILIB_THIRDPARTYLIBS}/Expat/expat-2.5.0")

set(FMIXMLHEADERS
include/FMI/fmi_xml_context.h
src/FMI/fmi_xml_context_impl.h
Expand Down Expand Up @@ -189,91 +187,102 @@ set(FMIXMLSOURCE
src/FMI3/fmi3_xml_parser_scheme.c
)

include(ExternalProject)
if(FMILIB_SYSTEM_EXPAT)
# On success defines (at least) the following variables:
# - EXPAT_INCLUDE_DIRS
# - EXPAT_LIBRARIES
# And the following target:
# - expat
find_package(EXPAT REQUIRED)
else()
include(ExternalProject)

# The *_POSTFIX variables are set because it makes it easier to determine the name of
# the lib expat will produce at configure time. Note that Expat has some special handling
# for it for MSVC which this in effect negates. https://github.com/libexpat/libexpat/pull/316
set(EXPAT_SETTINGS
-DEXPAT_BUILD_TOOLS:BOOLEAN=OFF
-DEXPAT_BUILD_EXAMPLES:BOOLEAN=OFF
-DEXPAT_BUILD_TESTS:BOOLEAN=OFF
-DEXPAT_SHARED_LIBS:BOOLEAN=OFF
-DEXPAT_DTD:BOOLEAN=OFF
-DEXPAT_NS:BOOLEAN=OFF
-DEXPAT_MSVC_STATIC_CRT:BOOLEAN=${FMILIB_BUILD_WITH_STATIC_RTLIB}
-DEXPAT_DEBUG_POSTFIX:STRING=
-DEXPAT_RELEASE_POSTFIX:STRING=
-DEXPAT_MINSIZEREL_POSTFIX:STRING=
-DEXPAT_RELWITHDEBINFO_POSTFIX:STRING=
-DCMAKE_POSITION_INDEPENDENT_CODE:BOOLEAN=ON
-DCMAKE_BUILD_TYPE:STRING=${CMAKE_BUILD_TYPE}
-DCMAKE_EXE_LINKER_FLAGS:STRING=${CMAKE_EXE_LINKER_FLAGS}
-DCMAKE_LINK_LIBRARY_FLAG:STRING=${CMAKE_LINK_LIBRARY_FLAG}
-DCMAKE_MODULE_LINKER_FLAGS:STRING=${CMAKE_MODULE_LINKER_FLAGS}
-DCMAKE_SHARED_LINKER_FLAGS:STRING=${CMAKE_SHARED_LINKER_FLAGS}
-DCMAKE_INSTALL_PREFIX:PATH=${CMAKE_BINARY_DIR}/ExpatEx/install
)
# The *_POSTFIX variables are set because it makes it easier to determine the name of
# the lib expat will produce at configure time. Note that Expat has some special handling
# for it for MSVC which this in effect negates. https://github.com/libexpat/libexpat/pull/316
set(EXPAT_SETTINGS
-DEXPAT_BUILD_TOOLS:BOOLEAN=OFF
-DEXPAT_BUILD_EXAMPLES:BOOLEAN=OFF
-DEXPAT_BUILD_TESTS:BOOLEAN=OFF
-DEXPAT_SHARED_LIBS:BOOLEAN=OFF
-DEXPAT_DTD:BOOLEAN=OFF
-DEXPAT_NS:BOOLEAN=OFF
-DEXPAT_MSVC_STATIC_CRT:BOOLEAN=${FMILIB_BUILD_WITH_STATIC_RTLIB}
-DEXPAT_DEBUG_POSTFIX:STRING=
-DEXPAT_RELEASE_POSTFIX:STRING=
-DEXPAT_MINSIZEREL_POSTFIX:STRING=
-DEXPAT_RELWITHDEBINFO_POSTFIX:STRING=
-DCMAKE_POSITION_INDEPENDENT_CODE:BOOLEAN=ON
-DCMAKE_BUILD_TYPE:STRING=${CMAKE_BUILD_TYPE}
-DCMAKE_EXE_LINKER_FLAGS:STRING=${CMAKE_EXE_LINKER_FLAGS}
-DCMAKE_LINK_LIBRARY_FLAG:STRING=${CMAKE_LINK_LIBRARY_FLAG}
-DCMAKE_MODULE_LINKER_FLAGS:STRING=${CMAKE_MODULE_LINKER_FLAGS}
-DCMAKE_SHARED_LINKER_FLAGS:STRING=${CMAKE_SHARED_LINKER_FLAGS}
-DCMAKE_INSTALL_PREFIX:PATH=${CMAKE_BINARY_DIR}/ExpatEx/install
)

ExternalProject_Add(
expatex
PREFIX "${FMIXML_EXPAT_DIR}"
SOURCE_DIR "${FMIXML_EXPAT_DIR}"
CMAKE_CACHE_ARGS ${EXPAT_SETTINGS}
BINARY_DIR ${CMAKE_BINARY_DIR}/ExpatEx
INSTALL_DIR ${CMAKE_BINARY_DIR}/ExpatEx/install
TMP_DIR ${CMAKE_BINARY_DIR}/ExpatEx/tmp
STAMP_DIR ${CMAKE_BINARY_DIR}/ExpatEx/stamp
)
set(FMIXML_EXPAT_DIR "${FMILIB_THIRDPARTYLIBS}/Expat/expat-2.5.0")

ExternalProject_Add_Step(
expatex dependent_reconfigure
DEPENDEES configure
DEPENDERS build
COMMAND ${CMAKE_COMMAND} -E echo "Running: ${CMAKE_COMMAND} -G \"${CMAKE_GENERATOR}\" ${EXPAT_SETTINGS} ${FMIXML_EXPAT_DIR}"
COMMAND ${CMAKE_COMMAND} -G "${CMAKE_GENERATOR}" ${EXPAT_SETTINGS} "${FMIXML_EXPAT_DIR}"
DEPENDS ${CMAKE_BINARY_DIR}/CMakeCache.txt
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/ExpatEx
)
ExternalProject_Add(
expatex
PREFIX "${FMIXML_EXPAT_DIR}"
SOURCE_DIR "${FMIXML_EXPAT_DIR}"
CMAKE_CACHE_ARGS ${EXPAT_SETTINGS}
BINARY_DIR ${CMAKE_BINARY_DIR}/ExpatEx
INSTALL_DIR ${CMAKE_BINARY_DIR}/ExpatEx/install
TMP_DIR ${CMAKE_BINARY_DIR}/ExpatEx/tmp
STAMP_DIR ${CMAKE_BINARY_DIR}/ExpatEx/stamp
)

# XXX: Maybe we could use FetchContent to find targets of expat? Then we hopefully
# wouldn't need below workarounds for guessing expatlib's location and name.
# Requires CMake 3.16 though.
ExternalProject_Add_Step(
expatex dependent_reconfigure
DEPENDEES configure
DEPENDERS build
COMMAND ${CMAKE_COMMAND} -E echo "Running: ${CMAKE_COMMAND} -G \"${CMAKE_GENERATOR}\" ${EXPAT_SETTINGS} ${FMIXML_EXPAT_DIR}"
COMMAND ${CMAKE_COMMAND} -G "${CMAKE_GENERATOR}" ${EXPAT_SETTINGS} "${FMIXML_EXPAT_DIR}"
DEPENDS ${CMAKE_BINARY_DIR}/CMakeCache.txt
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/ExpatEx
)

if(MSVC)
# Expat uses special naming with MSVC, which is mirrored here.
set(EXPAT_LIB_PREFIX lib)
else()
set(EXPAT_LIB_PREFIX ${CMAKE_STATIC_LIBRARY_PREFIX})
endif()
# XXX: Maybe we could use FetchContent to find targets of expat? Then we hopefully
# wouldn't need below workarounds for guessing expatlib's location and name.
# Requires CMake 3.16 though.

if("${CMAKE_CFG_INTDIR}" STREQUAL ".")
# Ninja complains about 'ExpatEx/./libexpat.a' otherwise. Probably because
# generator expressions in mergestaticlibs give slighlty different paths.
set(expatlib "${CMAKE_BINARY_DIR}/ExpatEx/${EXPAT_LIB_PREFIX}expat${CMAKE_STATIC_LIBRARY_SUFFIX}")
else()
set(expatlib "${CMAKE_BINARY_DIR}/ExpatEx/${CMAKE_CFG_INTDIR}/${EXPAT_LIB_PREFIX}expat${CMAKE_STATIC_LIBRARY_SUFFIX}")
endif()
if(MSVC)
# Expat uses special naming with MSVC, which is mirrored here.
set(EXPAT_LIB_PREFIX lib)
else()
set(EXPAT_LIB_PREFIX ${CMAKE_STATIC_LIBRARY_PREFIX})
endif()

# Workaround to make it explicit that target 'expatex' produces 'expatlib'. (Ninja complains otherwise.)
add_custom_command(
OUTPUT "${expatlib}"
DEPENDS expatex
)
add_custom_target(tmp_expatlib DEPENDS ${expatlib})
if("${CMAKE_CFG_INTDIR}" STREQUAL ".")
# Ninja complains about 'ExpatEx/./libexpat.a' otherwise. Probably because
# generator expressions in mergestaticlibs give slighlty different paths.
set(expatlib "${CMAKE_BINARY_DIR}/ExpatEx/${EXPAT_LIB_PREFIX}expat${CMAKE_STATIC_LIBRARY_SUFFIX}")
else()
set(expatlib "${CMAKE_BINARY_DIR}/ExpatEx/${CMAKE_CFG_INTDIR}/${EXPAT_LIB_PREFIX}expat${CMAKE_STATIC_LIBRARY_SUFFIX}")
endif()

add_library(expat STATIC IMPORTED)
set_target_properties(
expat PROPERTIES
IMPORTED_LOCATION "${expatlib}"
)
add_dependencies(expat tmp_expatlib)
# Workaround to make it explicit that target 'expatex' produces 'expatlib'. (Ninja complains otherwise.)
add_custom_command(
OUTPUT "${expatlib}"
DEPENDS expatex
)
add_custom_target(tmp_expatlib DEPENDS ${expatlib})

if(FMILIB_INSTALL_SUBLIBS)
install(FILES "${expatlib}" DESTINATION lib)
endif()
add_library(expat STATIC IMPORTED)
set_target_properties(
expat PROPERTIES
IMPORTED_LOCATION "${expatlib}"
)
add_dependencies(expat tmp_expatlib)

set(EXPAT_INCLUDE_DIRS ${CMAKE_BINARY_DIR}/ExpatEx/install/include)
if(FMILIB_INSTALL_SUBLIBS)
install(FILES "${expatlib}" DESTINATION lib)
endif()

set(EXPAT_INCLUDE_DIRS ${CMAKE_BINARY_DIR}/ExpatEx/install/include)
endif()

PREFIXLIST(FMIXMLSOURCE ${FMIXMLDIR}/)
PREFIXLIST(FMIXMLHEADERS ${FMIXMLDIR}/)
Expand Down

0 comments on commit e871e37

Please sign in to comment.