1# __ __ _ 2# ___\ \/ /_ __ __ _| |_ 3# / _ \\ /| '_ \ / _` | __| 4# | __// \| |_) | (_| | |_ 5# \___/_/\_\ .__/ \__,_|\__| 6# |_| XML parser 7# 8# Copyright (c) 2010 Patrick Spendrin <ps_ml@gmx.de> 9# Copyright (c) 2012 Karl Waclawek <karl@waclawek.net> 10# Copyright (c) 2016-2022 Sebastian Pipping <sebastian@pipping.org> 11# Copyright (c) 2016 Sergei Nikulov <sergey.nikulov@gmail.com> 12# Copyright (c) 2016 Björn Lindahl <bjorn.lindahl@foi.se> 13# Copyright (c) 2016 Tobias Taschner <github@tc84.de> 14# Copyright (c) 2016 Ben Boeckel <ben.boeckel@kitware.com> 15# Copyright (c) 2017 Rhodri James <rhodri@wildebeest.org.uk> 16# Copyright (c) 2017 Rolf Eike Beer <eike@sf-mail.de> 17# Copyright (c) 2017 Stephen Groat <stephen@groat.us> 18# Copyright (c) 2017 Franek Korta <fkorta@gmail.com> 19# Copyright (c) 2018 pedro-vicente <pedro.vicente@space-research.org> 20# Copyright (c) 2018 Frank Rast <frank.rast@gefeg.com> 21# Copyright (c) 2018 userwithuid <userwithuid@gmail.com> 22# Copyright (c) 2018 Yury Gribov <tetra2005@gmail.com> 23# Copyright (c) 2019 Kishore Kunche <kishore.kunche@intel.com> 24# Copyright (c) 2019 xantares <xantares09@hotmail.com> 25# Copyright (c) 2019 Mohammed Khajapasha <mohammed.khajapasha@intel.com> 26# Copyright (c) 2019 David Loffredo <loffredo@steptools.com> 27# Copyright (c) 2019 Bhargava Shastry <bhargava.shastry@ethereum.org> 28# Copyright (c) 2020 Maciej Sroczyński <macieksroczynski@poczta.fm> 29# Copyright (c) 2020 Gulliver <gulliver@traumkristalle.net> 30# Copyright (c) 2020 Thomas Beutlich <tc@tbeu.de> 31# Copyright (c) 2021 Alex Richardson <Alexander.Richardson@cl.cam.ac.uk> 32# Copyright (c) 2022 Johnny Jazeix <jazeix@gmail.com> 33# Copyright (c) 2022 David Faure <david.faure@kdab.com> 34# Unlike most of Expat, 35# this file is copyrighted under the BSD-license for buildsystem files of KDE. 36 37cmake_minimum_required(VERSION 3.1.3) 38 39project(expat 40 VERSION 41 2.5.0 42 LANGUAGES 43 C 44) 45 46set(PACKAGE_BUGREPORT "expat-bugs@libexpat.org") 47set(PACKAGE_NAME "expat") 48set(PACKAGE_VERSION "${PROJECT_VERSION}") 49set(PACKAGE_STRING "${PACKAGE_NAME} ${PACKAGE_VERSION}") 50set(PACKAGE_TARNAME "${PACKAGE_NAME}") 51 52include(CMakePackageConfigHelpers) 53include(GNUInstallDirs) 54 55# 56# Configuration defaults 57# 58if(WINCE) 59 set(_EXPAT_BUILD_TOOLS_DEFAULT OFF) 60else() 61 set(_EXPAT_BUILD_TOOLS_DEFAULT ON) 62endif() 63if(MSVC OR NOT _EXPAT_BUILD_TOOLS_DEFAULT) 64 set(_EXPAT_BUILD_DOCS_DEFAULT OFF) 65else() 66 find_program(DOCBOOK_TO_MAN NAMES docbook2x-man db2x_docbook2man docbook2man docbook-to-man) 67 if(DOCBOOK_TO_MAN) 68 set(_EXPAT_BUILD_DOCS_DEFAULT ON) 69 else() 70 set(_EXPAT_BUILD_DOCS_DEFAULT OFF) 71 endif() 72endif() 73if(MSVC) 74 set(_EXPAT_BUILD_PKGCONFIG_DEFAULT OFF) 75else() 76 set(_EXPAT_BUILD_PKGCONFIG_DEFAULT ON) 77endif() 78if(DEFINED BUILD_SHARED_LIBS) 79 set(_EXPAT_SHARED_LIBS_DEFAULT ${BUILD_SHARED_LIBS}) 80else() 81 set(_EXPAT_SHARED_LIBS_DEFAULT ON) 82endif() 83if(NOT CMAKE_BUILD_TYPE) 84 set(CMAKE_BUILD_TYPE NoConfig) # so that accessing EXPAT_*_POSTFIX will be waterproof 85endif() 86string(TOUPPER "${CMAKE_BUILD_TYPE}" _EXPAT_BUILD_TYPE_UPPER) 87 88# 89# Configuration 90# 91 92macro(expat_shy_set var default cache type desc) 93 # Macro expat_shy_set came into life because: 94 # - Expat was previously using an inconsistent mix of CMake's native set() 95 # and option() to define public build time options. 96 # - option() is more friendly than set() with regard to configuring an 97 # external project that is pulled in by means of add_subdirectory() -- 98 # see comments in issue #597 -- so we wanted to get away from set(). 99 # - option() auto-converts non-bool values to bool when writing to the CMake 100 # cache, so we needed something that supports non-bool better and hence 101 # wanted to get away from plain option(), too. 102 # 103 # As a result, this function serves as a hybrid between CMake's regular set() 104 # and option(): from set() it takes support for non-bool types and the function 105 # name and signature whereas from option() (with policy CMP0077 mode NEW) it 106 # takes being shy when a value has previously been defined for that variable. 107 # 108 # So that resolves all need for set(.. FORCE) when pulling in Expat by means of 109 # add_subdirectory(). 110 # 111 if(NOT ${cache} STREQUAL "CACHE") 112 message(SEND_ERROR "Macro usage is: expat_shy_set(var default CACHE type desc)") 113 endif() 114 115 if(DEFINED ${var}) 116 # NOTE: The idea is to (ideally) only add to the cache if 117 # there is no cache entry, yet. "if(DEFINED CACHE{var})" 118 # requires CMake >=3.14. 119 if(CMAKE_VERSION VERSION_GREATER_EQUAL "3.14" AND NOT DEFINED "CACHE{${var}}") 120 set("${var}" "${${var}}" CACHE "${type}" "${desc}") 121 endif() 122 else() 123 set("${var}" "${default}" CACHE "${type}" "${desc}") 124 endif() 125endmacro() 126 127expat_shy_set(EXPAT_BUILD_TOOLS ${_EXPAT_BUILD_TOOLS_DEFAULT} CACHE BOOL "Build the xmlwf tool for expat library") 128expat_shy_set(EXPAT_BUILD_EXAMPLES ON CACHE BOOL "Build the examples for expat library") 129expat_shy_set(EXPAT_BUILD_TESTS ON CACHE BOOL "Build the tests for expat library") 130expat_shy_set(EXPAT_SHARED_LIBS ${_EXPAT_SHARED_LIBS_DEFAULT} CACHE BOOL "Build a shared expat library") 131expat_shy_set(EXPAT_BUILD_DOCS ${_EXPAT_BUILD_DOCS_DEFAULT} CACHE BOOL "Build man page for xmlwf") 132expat_shy_set(EXPAT_BUILD_FUZZERS OFF CACHE BOOL "Build fuzzers for the expat library") 133expat_shy_set(EXPAT_BUILD_PKGCONFIG ${_EXPAT_BUILD_PKGCONFIG_DEFAULT} CACHE BOOL "Build pkg-config file") 134expat_shy_set(EXPAT_OSSFUZZ_BUILD OFF CACHE BOOL "Build fuzzers via ossfuzz for the expat library") 135if(UNIX OR _EXPAT_HELP) 136 expat_shy_set(EXPAT_WITH_LIBBSD OFF CACHE BOOL "Utilize libbsd (for arc4random_buf)") 137endif() 138expat_shy_set(EXPAT_ENABLE_INSTALL ON CACHE BOOL "Install expat files in cmake install target") 139expat_shy_set(EXPAT_CONTEXT_BYTES 1024 CACHE STRING "Define to specify how much context to retain around the current parse point") 140mark_as_advanced(EXPAT_CONTEXT_BYTES) 141expat_shy_set(EXPAT_DTD ON CACHE BOOL "Define to make parameter entity parsing functionality available") 142mark_as_advanced(EXPAT_DTD) 143expat_shy_set(EXPAT_NS ON CACHE BOOL "Define to make XML Namespaces functionality available") 144mark_as_advanced(EXPAT_NS) 145expat_shy_set(EXPAT_WARNINGS_AS_ERRORS OFF CACHE BOOL "Treat all compiler warnings as errors") 146if(UNIX OR _EXPAT_HELP) 147 expat_shy_set(EXPAT_DEV_URANDOM ON CACHE BOOL "Define to include code reading entropy from `/dev/urandom'.") 148 expat_shy_set(EXPAT_WITH_GETRANDOM "AUTO" CACHE STRING "Make use of getrandom function (ON|OFF|AUTO) [default=AUTO]") 149 expat_shy_set(EXPAT_WITH_SYS_GETRANDOM "AUTO" CACHE STRING "Make use of syscall SYS_getrandom (ON|OFF|AUTO) [default=AUTO]") 150 mark_as_advanced(EXPAT_DEV_URANDOM) 151endif() 152expat_shy_set(EXPAT_CHAR_TYPE "char" CACHE STRING "Character type to use (char|ushort|wchar_t) [default=char]") 153expat_shy_set(EXPAT_ATTR_INFO OFF CACHE BOOL "Define to allow retrieving the byte offsets for attribute names and values") 154mark_as_advanced(EXPAT_ATTR_INFO) 155expat_shy_set(EXPAT_LARGE_SIZE OFF CACHE BOOL "Make XML_GetCurrent* functions return <(unsigned) long long> rather than <(unsigned) long>") 156mark_as_advanced(EXPAT_LARGE_SIZE) 157expat_shy_set(EXPAT_MIN_SIZE OFF CACHE BOOL "Get a smaller (but slower) parser (in particular avoid multiple copies of the tokenizer)") 158mark_as_advanced(EXPAT_MIN_SIZE) 159if(MSVC OR _EXPAT_HELP) 160 expat_shy_set(EXPAT_MSVC_STATIC_CRT OFF CACHE BOOL "Use /MT flag (static CRT) when compiling in MSVC") 161endif() 162if(NOT _EXPAT_HELP) 163 expat_shy_set(_EXPAT_M32 OFF CACHE BOOL "(Unofficial!) Produce 32bit code with -m32") 164 mark_as_advanced(_EXPAT_M32) 165endif() 166 167if(EXPAT_BUILD_TESTS) 168 # We have to call enable_language() before modifying any CMAKE_CXX_* variables 169 enable_language(CXX) 170endif() 171 172# 173# Environment checks 174# 175if(EXPAT_WITH_LIBBSD) 176 find_library(LIB_BSD NAMES bsd) 177 if(NOT LIB_BSD) 178 message(SEND_ERROR "EXPAT_WITH_LIBBSD option is enabled, but libbsd was not found") 179 else() 180 set(HAVE_LIBBSD TRUE) 181 endif() 182endif() 183 184if(MSVC) 185 # For the three types of MSVC version values, please see: 186 # - https://cmake.org/cmake/help/latest/variable/MSVC_VERSION.html 187 # - https://sourceforge.net/p/predef/wiki/Compilers/ 188 # - https://en.wikipedia.org/wiki/Microsoft_Visual_Studio#History 189 set(_EXPAT_MSVC_REQUIRED_INT 1800) # i.e. 12.0/2013/1800; see PR #426 190 set(_EXPAT_MSVC_SUPPORTED_INT 1910) 191 set(_EXPAT_MSVC_SUPPORTED_DISPLAY "Visual Studio 15.0/2017/${_EXPAT_MSVC_SUPPORTED_INT}") 192 193 if(MSVC_VERSION VERSION_LESS ${_EXPAT_MSVC_SUPPORTED_INT}) 194 if(MSVC_VERSION VERSION_LESS ${_EXPAT_MSVC_REQUIRED_INT}) 195 message(SEND_ERROR "MSVC_VERSION ${MSVC_VERSION} is TOO OLD to compile Expat without errors.") 196 message(SEND_ERROR "Please use officially supported ${_EXPAT_MSVC_SUPPORTED_DISPLAY} or later. Thank you!") 197 else() 198 message(WARNING "MSVC_VERSION ${MSVC_VERSION} is NOT OFFICIALLY SUPPORTED by Expat.") 199 message(WARNING "Please use ${_EXPAT_MSVC_SUPPORTED_DISPLAY} or later. Thank you!") 200 endif() 201 endif() 202endif() 203 204macro(_expat_copy_bool_int source_ref dest_ref) 205 if(${source_ref}) 206 set(${dest_ref} 1) 207 else() 208 set(${dest_ref} 0) 209 endif() 210endmacro() 211 212if(EXPAT_LARGE_SIZE) 213 add_definitions(-DXML_LARGE_SIZE) 214endif() 215 216if(EXPAT_MIN_SIZE) 217 add_definitions(-DXML_MIN_SIZE) 218endif() 219 220if(EXPAT_CHAR_TYPE STREQUAL "char") 221 set(_EXPAT_UNICODE OFF) 222 set(_EXPAT_UNICODE_WCHAR_T OFF) 223elseif(EXPAT_CHAR_TYPE STREQUAL "ushort") 224 set(_EXPAT_UNICODE ON) 225 set(_EXPAT_UNICODE_WCHAR_T OFF) 226 if(EXPAT_BUILD_EXAMPLES) 227 message(SEND_ERROR "Examples can not be built with option -DEXPAT_CHAR_TYPE=ushort. Please pass -DEXPAT_CHAR_TYPE=(char|wchar_t) or -DEXPAT_BUILD_EXAMPLES=OFF.") 228 endif() 229 if(EXPAT_BUILD_TESTS) 230 message(SEND_ERROR "The testsuite can not be built with option -DEXPAT_CHAR_TYPE=ushort. Please pass -DEXPAT_CHAR_TYPE=(char|wchar_t) or -DEXPAT_BUILD_TESTS=OFF.") 231 endif() 232 if(EXPAT_BUILD_TOOLS) 233 message(SEND_ERROR "The xmlwf tool can not be built with option -DEXPAT_CHAR_TYPE=ushort. Please pass -DEXPAT_CHAR_TYPE=(char|wchar_t) or -DEXPAT_BUILD_TOOLS=OFF.") 234 endif() 235elseif(EXPAT_CHAR_TYPE STREQUAL "wchar_t") 236 set(_EXPAT_UNICODE ON) 237 set(_EXPAT_UNICODE_WCHAR_T ON) 238 if(NOT WIN32) 239 string(FIND "${CMAKE_C_FLAGS}" "-fshort-wchar" _expat_short_wchar_found) 240 if(${_expat_short_wchar_found} EQUAL "-1") 241 message(SEND_ERROR "Configuration -DEXPAT_CHAR_TYPE=wchar_t requires -DCMAKE_{C,CXX}_FLAGS=-fshort-wchar (which was not found) and libc compiled with -fshort-wchar, too.") 242 endif() 243 if (EXPAT_BUILD_TOOLS) 244 message(SEND_ERROR "The xmlwf tool can not be built with option -DEXPAT_CHAR_TYPE=wchar_t outside of Windows. Please pass -DEXPAT_CHAR_TYPE=char or -DEXPAT_BUILD_TOOLS=OFF.") 245 endif() 246 endif() 247else() 248 message(SEND_ERROR "Option -DEXPAT_CHAR_TYPE=(char|ushort|wchar_t) cannot be \"${EXPAT_CHAR_TYPE}\".") 249endif() 250 251if(_EXPAT_UNICODE) 252 add_definitions(-DXML_UNICODE) # for unsigned short 253 if(_EXPAT_UNICODE_WCHAR_T) 254 add_definitions(-DXML_UNICODE_WCHAR_T) # for wchar_t 255 endif() 256endif() 257 258include(${CMAKE_CURRENT_LIST_DIR}/ConfigureChecks.cmake) 259 260macro(evaluate_detection_results use_ref have_ref thing_lower thing_title) 261 if(${use_ref} AND NOT (${use_ref} STREQUAL "AUTO") AND NOT ${have_ref}) 262 message(SEND_ERROR 263 "Use of ${thing_lower} was enforced by ${use_ref}=ON but it could not be found.") 264 elseif(NOT ${use_ref} AND ${have_ref}) 265 message("${thing_title} was found but it will not be used due to ${use_ref}=OFF.") 266 set(${have_ref} 0) 267 endif() 268endmacro() 269 270if(NOT WIN32) 271 evaluate_detection_results(EXPAT_WITH_GETRANDOM HAVE_GETRANDOM "function getrandom" "Function getrandom") 272 evaluate_detection_results(EXPAT_WITH_SYS_GETRANDOM HAVE_SYSCALL_GETRANDOM "syscall SYS_getrandom" "Syscall SYS_getrandom") 273endif() 274 275_expat_copy_bool_int(EXPAT_ATTR_INFO XML_ATTR_INFO) 276_expat_copy_bool_int(EXPAT_DTD XML_DTD) 277_expat_copy_bool_int(EXPAT_LARGE_SIZE XML_LARGE_SIZE) 278_expat_copy_bool_int(EXPAT_MIN_SIZE XML_MIN_SIZE) 279_expat_copy_bool_int(EXPAT_NS XML_NS) 280if(NOT WIN32) 281 _expat_copy_bool_int(EXPAT_DEV_URANDOM XML_DEV_URANDOM) 282endif() 283set(XML_CONTEXT_BYTES ${EXPAT_CONTEXT_BYTES}) 284 285macro(expat_install) 286 if(EXPAT_ENABLE_INSTALL) 287 install(${ARGN}) 288 endif() 289endmacro() 290 291configure_file(expat_config.h.cmake "${CMAKE_CURRENT_BINARY_DIR}/expat_config.h") 292expat_install(FILES "${CMAKE_CURRENT_BINARY_DIR}/expat_config.h" DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}) 293 294 295set(EXTRA_COMPILE_FLAGS) 296if(FLAG_NO_STRICT_ALIASING) 297 set(EXTRA_COMPILE_FLAGS "${EXTRA_COMPILE_FLAGS} -fno-strict-aliasing") 298endif() 299if(FLAG_VISIBILITY) 300 if(EXPAT_SHARED_LIBS) 301 add_definitions(-DXML_ENABLE_VISIBILITY=1) 302 endif() 303 set(EXTRA_COMPILE_FLAGS "${EXTRA_COMPILE_FLAGS} -fvisibility=hidden") 304endif() 305if(MINGW) 306 # Without __USE_MINGW_ANSI_STDIO the compiler produces a false positive 307 set(EXTRA_COMPILE_FLAGS "${EXTRA_COMPILE_FLAGS} -Wno-pedantic-ms-format") 308endif() 309if (EXPAT_WARNINGS_AS_ERRORS) 310 if(MSVC) 311 add_definitions(/WX) 312 else() 313 set(EXTRA_COMPILE_FLAGS "${EXTRA_COMPILE_FLAGS} -Werror") 314 endif() 315endif() 316set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_COMPILE_FLAGS}") 317set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${EXTRA_COMPILE_FLAGS}") 318 319if (MSVC) 320 if (EXPAT_MSVC_STATIC_CRT) 321 message("-- Using static CRT ${EXPAT_MSVC_STATIC_CRT}") 322 foreach(flag_var 323 CMAKE_CXX_FLAGS_${_EXPAT_BUILD_TYPE_UPPER} 324 CMAKE_CXX_FLAGS_DEBUG 325 CMAKE_CXX_FLAGS_RELEASE 326 CMAKE_CXX_FLAGS_MINSIZEREL 327 CMAKE_CXX_FLAGS_RELWITHDEBINFO 328 CMAKE_C_FLAGS_${_EXPAT_BUILD_TYPE_UPPER} 329 CMAKE_C_FLAGS_DEBUG 330 CMAKE_C_FLAGS_RELEASE 331 CMAKE_C_FLAGS_MINSIZEREL 332 CMAKE_C_FLAGS_RELWITHDEBINFO 333 ) 334 string(REPLACE "/MD" "/MT" ${flag_var} "${${flag_var}}") 335 endforeach() 336 endif() 337endif() 338 339if(_EXPAT_M32 AND NOT MSVC) 340 foreach(flag_var 341 CMAKE_CXX_FLAGS_${_EXPAT_BUILD_TYPE_UPPER} 342 CMAKE_CXX_FLAGS_DEBUG 343 CMAKE_CXX_FLAGS_RELEASE 344 CMAKE_CXX_FLAGS_MINSIZEREL 345 CMAKE_CXX_FLAGS_RELWITHDEBINFO 346 CMAKE_C_FLAGS_${_EXPAT_BUILD_TYPE_UPPER} 347 CMAKE_C_FLAGS_DEBUG 348 CMAKE_C_FLAGS_RELEASE 349 CMAKE_C_FLAGS_MINSIZEREL 350 CMAKE_C_FLAGS_RELWITHDEBINFO 351 ) 352 set(${flag_var} "${${flag_var}} -m32") 353 endforeach() 354endif() 355 356include_directories(${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/lib) 357if(MSVC) 358 add_definitions(-D_CRT_SECURE_NO_WARNINGS -wd4996) 359endif() 360 361# 362# C library 363# 364set(_EXPAT_C_SOURCES 365 lib/xmlparse.c 366 lib/xmlrole.c 367 lib/xmltok.c 368# NOTE: ISO C forbids an empty translation unit 369# lib/xmltok_impl.c 370# lib/xmltok_ns.c 371) 372 373if(EXPAT_SHARED_LIBS) 374 set(_SHARED SHARED) 375 if(WIN32) 376 macro(_expat_def_file_toggle source_var target_var) 377 if(${source_var}) 378 set(${target_var} " ") # i.e. not commented out, a single space 379 else() 380 set(${target_var} ";") # i.e. commented out 381 endif() 382 endmacro() 383 384 _expat_def_file_toggle(EXPAT_DTD _EXPAT_COMMENT_DTD) 385 _expat_def_file_toggle(EXPAT_ATTR_INFO _EXPAT_COMMENT_ATTR_INFO) 386 387 configure_file("${CMAKE_CURRENT_SOURCE_DIR}/lib/libexpat.def.cmake" "${CMAKE_CURRENT_BINARY_DIR}/lib/libexpat.def") 388 set(_EXPAT_EXTRA_SOURCES ${_EXPAT_EXTRA_SOURCES} "${CMAKE_CURRENT_BINARY_DIR}/lib/libexpat.def") 389 390 # Add DLL version 391 string(REPLACE "." "," _EXPAT_DLL_VERSION ${PROJECT_VERSION}.0) 392 set(_EXPAT_EXTRA_SOURCES ${_EXPAT_EXTRA_SOURCES} win32/version.rc) 393 endif() 394else() 395 set(_SHARED STATIC) 396endif() 397 398add_library(expat ${_SHARED} ${_EXPAT_C_SOURCES} ${_EXPAT_EXTRA_SOURCES}) 399if(_EXPAT_LIBM_FOUND) 400 target_link_libraries(expat m) 401endif() 402if(EXPAT_WITH_LIBBSD) 403 target_link_libraries(expat ${LIB_BSD}) 404endif() 405 406# 407# Library filename postfix 408# 409if(_EXPAT_UNICODE) 410 set(_POSTFIX_WIDE "w") 411endif() 412 413if(MSVC AND NOT EXPAT_SHARED_LIBS) 414 if(EXPAT_MSVC_STATIC_CRT) 415 set(_POSTFIX_CRT "MT") 416 else() 417 set(_POSTFIX_CRT "MD") 418 endif() 419endif() 420 421foreach(build_type_upper 422 ${_EXPAT_BUILD_TYPE_UPPER} 423 DEBUG 424 RELEASE 425 MINSIZEREL 426 RELWITHDEBINFO 427 ) 428 if(WIN32 AND build_type_upper STREQUAL "DEBUG") 429 set(_POSTFIX_DEBUG "d") 430 else() 431 set(_POSTFIX_DEBUG "") # needs a reset because of being looped 432 endif() 433 434 expat_shy_set(EXPAT_${build_type_upper}_POSTFIX "${_POSTFIX_WIDE}${_POSTFIX_DEBUG}${_POSTFIX_CRT}" CACHE STRING "Library filename postfix for build type ${build_type_upper}; yields filenames libexpat<postfix=[w][d][MD|MT]>.(dll|dylib|lib|so)") 435 mark_as_advanced(EXPAT_${build_type_upper}_POSTFIX) 436 set_property(TARGET expat PROPERTY ${build_type_upper}_POSTFIX ${EXPAT_${build_type_upper}_POSTFIX}) 437endforeach() 438 439set(LIBCURRENT 9) # sync 440set(LIBREVISION 10) # with 441set(LIBAGE 8) # configure.ac! 442math(EXPR LIBCURRENT_MINUS_AGE "${LIBCURRENT} - ${LIBAGE}") 443 444if(NOT WIN32) 445 set_property(TARGET expat PROPERTY VERSION ${LIBCURRENT_MINUS_AGE}.${LIBAGE}.${LIBREVISION}) 446 set_property(TARGET expat PROPERTY SOVERSION ${LIBCURRENT_MINUS_AGE}) 447 set_property(TARGET expat PROPERTY NO_SONAME ${NO_SONAME}) 448 449 if(APPLE) 450 if(NOT CMAKE_VERSION VERSION_GREATER_EQUAL 3.17) 451 message(FATAL_ERROR "Expat requires CMake >=3.17 on platform \"APPLE\".") 452 endif() 453 454 # NOTE: This intends to talk CMake into compatiblity with GNU Libtool 455 math(EXPR _EXPAT_MACHO_COMPATIBILITY_VERSION "${LIBCURRENT} + 1") 456 set(_EXPAT_MACHO_CURRENT_VERSION "${_EXPAT_MACHO_COMPATIBILITY_VERSION}.${LIBREVISION}") 457 set_property(TARGET expat PROPERTY MACHO_COMPATIBILITY_VERSION ${_EXPAT_MACHO_COMPATIBILITY_VERSION}) 458 set_property(TARGET expat PROPERTY MACHO_CURRENT_VERSION ${_EXPAT_MACHO_CURRENT_VERSION}) 459 endif() 460endif() 461 462if(MINGW AND EXPAT_SHARED_LIBS) 463 set_target_properties(expat PROPERTIES SUFFIX "-${LIBCURRENT_MINUS_AGE}.dll") 464endif() 465 466if(WIN32 AND NOT MINGW) 467 # NOTE: This avoids a name collision with Expat.dll of Perl's XML::Parser::Expat 468 # on Windows by resorting to filename libexpat.dll since Expat 1.95.3. 469 # Everything but MSVC is already adding prefix "lib", automatically. 470 # NOTE: "set_property(TARGET expat PROPERTY PREFIX lib)" would only affect *.dll 471 # files but not *.lib files, so we have to rely on property OUTPUT_NAME, instead. 472 # Target property <CONFIG>_POSTFIX still applies. 473 set(_EXPAT_OUTPUT_NAME libexpat) 474 set_property(TARGET expat PROPERTY OUTPUT_NAME ${_EXPAT_OUTPUT_NAME}) 475else() 476 set(_EXPAT_OUTPUT_NAME expat) 477endif() 478 479target_include_directories(expat 480 INTERFACE 481 $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/lib> 482 $<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}> 483 $<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}> 484) 485 486if(WIN32 AND EXPAT_SHARED_LIBS) 487 target_compile_definitions(expat PRIVATE VER_FILEVERSION=${_EXPAT_DLL_VERSION}) 488endif() 489 490expat_install(TARGETS expat EXPORT expat 491 RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} 492 LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} 493 ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}) 494 495expat_install(FILES lib/expat.h lib/expat_external.h DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}) 496 497# 498# pkg-config file 499# 500if(EXPAT_BUILD_PKGCONFIG) 501 if(CMAKE_INSTALL_LIBDIR MATCHES "^/") 502 set(_expat_pkgconfig_libdir "${CMAKE_INSTALL_LIBDIR}") 503 else() 504 set(_expat_pkgconfig_libdir "\${exec_prefix}/${CMAKE_INSTALL_LIBDIR}") 505 endif() 506 507 if(CMAKE_INSTALL_INCLUDEDIR MATCHES "^/") 508 set(_expat_pkgconfig_includedir "${CMAKE_INSTALL_INCLUDEDIR}") 509 else() 510 set(_expat_pkgconfig_includedir "\${prefix}/${CMAKE_INSTALL_INCLUDEDIR}") 511 endif() 512 513 set_target_properties(expat PROPERTIES 514 pkgconfig_prefix "${CMAKE_INSTALL_PREFIX}" 515 pkgconfig_exec_prefix "\${prefix}" 516 pkgconfig_libdir "${_expat_pkgconfig_libdir}" 517 pkgconfig_includedir "${_expat_pkgconfig_includedir}" 518 pkgconfig_version "${PACKAGE_VERSION}") 519 520 foreach(_build_type ${CMAKE_BUILD_TYPE} Debug Release RelWithDebInfo MinSizeRel) 521 string(TOLOWER "${_build_type}" _build_type_lower) 522 string(TOUPPER "${_build_type}" _build_type_upper) 523 set_property(TARGET expat PROPERTY "pkgconfig_${_build_type_lower}_name" "expat${EXPAT_${_build_type_upper}_POSTFIX}") 524 set_property(TARGET expat PROPERTY "pkgconfig_${_build_type_lower}_output_name" "${_EXPAT_OUTPUT_NAME}${EXPAT_${_build_type_upper}_POSTFIX}") 525 if(_EXPAT_LIBM_FOUND) 526 set_property(TARGET expat PROPERTY "pkgconfig_libm" "-lm") 527 else() 528 set_property(TARGET expat PROPERTY "pkgconfig_libm" "") 529 endif() 530 endforeach() 531 532 file(GENERATE 533 OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/$<CONFIG>/expat.pc 534 INPUT ${PROJECT_SOURCE_DIR}/expat.pc.cmake) 535 536 expat_install(FILES ${CMAKE_CURRENT_BINARY_DIR}/$<CONFIG>/expat.pc DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig) 537endif() 538 539# 540# C command line tool xmlwf 541# 542if(EXPAT_BUILD_TOOLS) 543 set(xmlwf_SRCS 544 xmlwf/xmlwf.c 545 xmlwf/xmlfile.c 546 xmlwf/codepage.c 547 xmlwf/readfilemap.c 548 ) 549 550 add_executable(xmlwf ${xmlwf_SRCS}) 551 set_property(TARGET xmlwf PROPERTY RUNTIME_OUTPUT_DIRECTORY xmlwf) 552 target_link_libraries(xmlwf expat) 553 if(_EXPAT_LIBM_FOUND) 554 target_link_libraries(xmlwf m) 555 endif() 556 expat_install(TARGETS xmlwf DESTINATION ${CMAKE_INSTALL_BINDIR}) 557 558 if(MINGW AND _EXPAT_UNICODE_WCHAR_T) 559 # https://gcc.gnu.org/onlinedocs/gcc/x86-Windows-Options.html 560 set_target_properties(xmlwf PROPERTIES LINK_FLAGS -municode) 561 endif() 562 563 if(EXPAT_BUILD_DOCS) 564 file(MAKE_DIRECTORY ${PROJECT_BINARY_DIR}/doc) 565 add_custom_target( 566 xmlwf-manpage 567 COMMAND 568 "${DOCBOOK_TO_MAN}" "${PROJECT_SOURCE_DIR}/doc/xmlwf.xml" && mv "XMLWF.1" "${PROJECT_BINARY_DIR}/doc/xmlwf.1" 569 BYPRODUCTS 570 doc/xmlwf.1) 571 add_dependencies(expat xmlwf-manpage) 572 expat_install(FILES "${PROJECT_BINARY_DIR}/doc/xmlwf.1" DESTINATION ${CMAKE_INSTALL_MANDIR}/man1) 573 elseif(EXISTS ${PROJECT_SOURCE_DIR}/doc/xmlwf.1) 574 expat_install(FILES "${PROJECT_SOURCE_DIR}/doc/xmlwf.1" DESTINATION ${CMAKE_INSTALL_MANDIR}/man1) 575 endif() 576endif() 577 578# 579# C code examples 580# 581if(EXPAT_BUILD_EXAMPLES) 582 add_executable(elements examples/elements.c) 583 add_executable(outline examples/outline.c) 584 585 foreach(_target elements outline) 586 set_property(TARGET ${_target} PROPERTY RUNTIME_OUTPUT_DIRECTORY examples) 587 target_link_libraries(${_target} expat) 588 endforeach() 589endif() 590 591# 592# C/C++ test runners 593# 594if(EXPAT_BUILD_TESTS) 595 ## these are unittests that can be run on any platform 596 enable_testing() 597 598 set(test_SRCS 599 tests/chardata.c 600 tests/memcheck.c 601 tests/minicheck.c 602 tests/structdata.c 603 ${_EXPAT_C_SOURCES} 604 ) 605 606 if(NOT MSVC) 607 if(MINGW) 608 set(host whatever-mingw32) # for nothing but run.sh 609 endif() 610 configure_file(${CMAKE_CURRENT_SOURCE_DIR}/run.sh.in run.sh @ONLY) 611 endif() 612 613 function(expat_add_test _name _file) 614 if(MSVC) 615 add_test(NAME ${_name} COMMAND ${_file}) 616 else() 617 add_test(NAME ${_name} COMMAND bash run.sh ${_file}) 618 endif() 619 endfunction() 620 621 set(_EXPAT_TEST_TARGETS runtests runtestspp) 622 add_executable(runtests tests/runtests.c ${test_SRCS}) 623 add_executable(runtestspp tests/runtestspp.cpp ${test_SRCS}) 624 625 foreach(_target ${_EXPAT_TEST_TARGETS}) 626 set_property(TARGET ${_target} PROPERTY RUNTIME_OUTPUT_DIRECTORY tests) 627 expat_add_test(${_target} $<TARGET_FILE:${_target}>) 628 629 if(_EXPAT_LIBM_FOUND) 630 target_link_libraries(${_target} m) 631 endif() 632 633 if(EXPAT_WITH_LIBBSD) 634 target_link_libraries(${_target} ${LIB_BSD}) 635 endif() 636 endforeach() 637endif() 638 639# 640# Fuzzers 641# 642if(EXPAT_BUILD_FUZZERS) 643 if(NOT "${CMAKE_C_COMPILER_ID}" STREQUAL "Clang") 644 message(SEND_ERROR 645 "Building fuzz targets without Clang (but ${CMAKE_C_COMPILER_ID}) " 646 "is not supported. Please set " 647 "-DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++.") 648 endif() 649 650 string(FIND "${CMAKE_C_FLAGS}" "-fsanitize" sanitizer_present) 651 if(${sanitizer_present} EQUAL "-1") 652 message(WARNING 653 "There was no sanitizer present when building the fuzz targets. " 654 "This is likely in error - consider adding " 655 "-DCMAKE_C_FLAGS='-fsanitize=<sanitizer>' and " 656 "-DCMAKE_CXX_FLAGS='-fsanitize=<sanitizer>' and " 657 "-DCMAKE_EXE_LINKER_FLAGS='-fsanitize=<sanitizer>' and " 658 "-DCMAKE_MODULE_LINKER_FLAGS='-fsanitize=<sanitizer>' and " 659 "-DCMAKE_SHARED_LINKER_FLAGS='-fsanitize=<sanitizer>' to your cmake " 660 "execution.") 661 endif() 662 663 if(EXPAT_OSSFUZZ_BUILD AND NOT DEFINED ENV{LIB_FUZZING_ENGINE}) 664 message(SEND_ERROR 665 "OSS-Fuzz builds require the environment variable " 666 "LIB_FUZZING_ENGINE to be set. If you are seeing this " 667 "warning, it points to a deeper problem in the ossfuzz " 668 "build setup.") 669 endif() 670 671 set(encoding_types UTF-16 UTF-8 ISO-8859-1 US-ASCII UTF-16BE UTF-16LE) 672 set(fuzz_targets xml_parse_fuzzer xml_parsebuffer_fuzzer) 673 674 add_library(fuzzpat STATIC ${_EXPAT_C_SOURCES}) 675 if(NOT EXPAT_OSSFUZZ_BUILD) 676 target_compile_options(fuzzpat PRIVATE -fsanitize=fuzzer-no-link) 677 endif() 678 679 foreach(fuzz_target ${fuzz_targets}) 680 foreach(encoding_type ${encoding_types}) 681 set(target_name ${fuzz_target}_${encoding_type}) 682 add_executable(${target_name} fuzz/${fuzz_target}.c) 683 target_link_libraries(${target_name} fuzzpat) 684 target_compile_definitions(${target_name} 685 PRIVATE ENCODING_FOR_FUZZING=${encoding_type}) 686 if(NOT EXPAT_OSSFUZZ_BUILD) 687 target_compile_options(${target_name} PRIVATE -fsanitize=fuzzer-no-link) 688 endif() 689 # NOTE: Avoiding target_link_options here only because it needs CMake >=3.13 690 if(EXPAT_OSSFUZZ_BUILD) 691 set_target_properties(${target_name} PROPERTIES LINK_FLAGS $ENV{LIB_FUZZING_ENGINE}) 692 set_target_properties(${target_name} PROPERTIES LINKER_LANGUAGE "CXX") 693 else() 694 set_target_properties(${target_name} PROPERTIES LINK_FLAGS -fsanitize=fuzzer) 695 endif() 696 set_property( 697 TARGET ${target_name} PROPERTY RUNTIME_OUTPUT_DIRECTORY fuzz) 698 endforeach() 699 endforeach() 700else() 701 if(EXPAT_OSSFUZZ_BUILD) 702 message(SEND_ERROR 703 "Attempting to perform an ossfuzz build without turning on the fuzzer build. " 704 "This is likely in error - consider adding " 705 "-DEXPAT_BUILD_FUZZERS=ON to your cmake execution.") 706 endif() 707endif() 708 709# 710# C/C++ config affecting multiple targets 711# 712if(WIN32) 713 set(_EXPAT_STATIC_TARGETS ${_EXPAT_TEST_TARGETS}) 714 if(NOT EXPAT_SHARED_LIBS) 715 list(APPEND _EXPAT_STATIC_TARGETS expat) 716 endif() 717 if(EXPAT_BUILD_FUZZERS) 718 list(APPEND _EXPAT_STATIC_TARGETS fuzzpat) 719 endif() 720 721 foreach(_target ${_EXPAT_STATIC_TARGETS}) 722 target_compile_definitions(${_target} PUBLIC -DXML_STATIC) 723 endforeach() 724endif() 725 726# 727# Custom target "run-xmltest" 728# 729if(EXPAT_BUILD_TOOLS AND NOT MSVC) 730 add_custom_target( 731 xmlts-zip-downloaded 732 COMMAND 733 sh -c 'test -f xmlts.zip || wget --output-document=xmlts.zip https://www.w3.org/XML/Test/xmlts20080827.zip' 734 BYPRODUCTS 735 tests/xmlts.zip 736 WORKING_DIRECTORY 737 tests/) 738 739 add_custom_target( 740 xmlts-zip-extracted 741 COMMAND 742 sh -c 'test -d xmlconf || unzip -q xmlts.zip' 743 BYPRODUCTS 744 tests/xmlconf 745 WORKING_DIRECTORY 746 tests/) 747 add_dependencies(xmlts-zip-extracted xmlts-zip-downloaded) 748 749 add_custom_target( 750 xmltest-sh-been-run 751 COMMAND 752 sh -c '${CMAKE_CURRENT_SOURCE_DIR}/tests/xmltest.sh "bash ${CMAKE_CURRENT_BINARY_DIR}/run.sh $<TARGET_FILE:xmlwf>" 2>&1 | tee tests/xmltest.log' 753 BYPRODUCTS 754 tests/xmltest.log) 755 add_dependencies(xmltest-sh-been-run xmlts-zip-extracted xmlwf) 756 757 add_custom_target( 758 xmltest-log-fixed 759 COMMAND 760 ${CMAKE_CURRENT_SOURCE_DIR}/fix-xmltest-log.sh tests/xmltest.log 761 DEPENDS 762 tests/xmltest.log) 763 add_dependencies(xmltest-log-fixed xmltest-sh-been-run) 764 765 add_custom_target( 766 xmltest-log-verified 767 COMMAND 768 diff -u ${CMAKE_CURRENT_SOURCE_DIR}/tests/xmltest.log.expected tests/xmltest.log) 769 add_dependencies(xmltest-log-verified xmltest-log-fixed) 770 771 add_custom_target(run-xmltest) 772 add_dependencies(run-xmltest xmltest-log-verified) 773endif() 774 775# 776# Documentation 777# 778configure_file(Changes changelog COPYONLY) 779expat_install( 780 FILES 781 AUTHORS 782 ${CMAKE_CURRENT_BINARY_DIR}/changelog 783 DESTINATION 784 ${CMAKE_INSTALL_DOCDIR}) 785 786# 787# CMake files for find_package(expat [..] CONFIG [..]) 788# 789configure_package_config_file( 790 cmake/expat-config.cmake.in 791 cmake/expat-config.cmake 792 INSTALL_DESTINATION 793 ${CMAKE_INSTALL_LIBDIR}/cmake/expat-${PROJECT_VERSION}/ 794) 795write_basic_package_version_file( 796 cmake/expat-config-version.cmake 797 COMPATIBILITY SameMajorVersion # i.e. semver 798) 799export( 800 TARGETS 801 expat 802 FILE 803 cmake/expat-targets.cmake # not going to be installed 804) 805expat_install( 806 FILES 807 ${CMAKE_CURRENT_BINARY_DIR}/cmake/expat-config.cmake 808 ${CMAKE_CURRENT_BINARY_DIR}/cmake/expat-config-version.cmake 809 DESTINATION 810 ${CMAKE_INSTALL_LIBDIR}/cmake/expat-${PROJECT_VERSION}/ 811) 812expat_install( 813 EXPORT 814 expat 815 DESTINATION 816 ${CMAKE_INSTALL_LIBDIR}/cmake/expat-${PROJECT_VERSION}/ 817 NAMESPACE 818 expat:: 819) 820 821# 822# CPack 823# 824 825# This effectively disables target "package_source". 826# That is done due to CPack's unfortunate choice of an exclusion list 827# rather than inclusion list. An exclusion list does not protect against 828# unwanted files ending up in the resulting archive in a way that's 829# safe to run from an Expat developer's machine. 830set(CPACK_SOURCE_GENERATOR '') 831 832if(WIN32) 833 set(CPACK_GENERATOR ZIP) 834else() 835 set(CPACK_GENERATOR TGZ) 836endif() 837 838include(CPack) 839 840# 841# Summary 842# 843if(EXPAT_CHAR_TYPE STREQUAL "char") 844 set(_EXPAT_CHAR_TYPE_SUMMARY "char (UTF-8)") 845elseif(EXPAT_CHAR_TYPE STREQUAL "ushort") 846 set(_EXPAT_CHAR_TYPE_SUMMARY "ushort (unsigned short, UTF-16)") 847elseif(EXPAT_CHAR_TYPE STREQUAL "wchar_t") 848 if(WIN32) 849 set(_EXPAT_CHAR_TYPE_SUMMARY "wchar_t (UTF-16)") 850 else() 851 set(_EXPAT_CHAR_TYPE_SUMMARY "wchar_t (UTF-32) // not implemented") 852 endif() 853else() 854 set(_EXPAT_CHAR_TYPE_SUMMARY "ERROR") 855endif() 856# NOTE: We're not accessing global property GENERATOR_IS_MULTI_CONFIG 857# because that would require CMake >=3.9 858if(CMAKE_CONFIGURATION_TYPES) 859 set(_EXPAT_GENERATOR_IS_MULTI_CONFIG TRUE) 860else() 861 set(_EXPAT_GENERATOR_IS_MULTI_CONFIG FALSE) 862endif() 863 864message(STATUS "===========================================================================") 865message(STATUS "") 866message(STATUS "Configuration") 867message(STATUS " Generator .................. ${CMAKE_GENERATOR}") 868if(_EXPAT_GENERATOR_IS_MULTI_CONFIG) 869 message(STATUS " Build types ................ ${CMAKE_CONFIGURATION_TYPES}") 870else() 871 message(STATUS " Build type ................. ${CMAKE_BUILD_TYPE}") 872endif() 873message(STATUS " Prefix ..................... ${CMAKE_INSTALL_PREFIX}") 874message(STATUS " Shared libraries ........... ${EXPAT_SHARED_LIBS}") 875if(MSVC) 876 message(STATUS " Static CRT ................. ${EXPAT_MSVC_STATIC_CRT}") 877endif() 878message(STATUS " Character type ............. ${_EXPAT_CHAR_TYPE_SUMMARY}") 879if(NOT _EXPAT_GENERATOR_IS_MULTI_CONFIG) 880 message(STATUS " Library name postfix ....... ${EXPAT_${_EXPAT_BUILD_TYPE_UPPER}_POSTFIX}") 881endif() 882message(STATUS "") 883message(STATUS " Build documentation ........ ${EXPAT_BUILD_DOCS}") 884message(STATUS " Build examples ............. ${EXPAT_BUILD_EXAMPLES}") 885message(STATUS " Build fuzzers .............. ${EXPAT_BUILD_FUZZERS}") 886message(STATUS " Build tests ................ ${EXPAT_BUILD_TESTS}") 887message(STATUS " Build tools (xmlwf) ........ ${EXPAT_BUILD_TOOLS}") 888message(STATUS " Build pkg-config file ...... ${EXPAT_BUILD_PKGCONFIG}") 889message(STATUS " Install files .............. ${EXPAT_ENABLE_INSTALL}") 890message(STATUS "") 891message(STATUS " Features") 892message(STATUS " // Advanced options, changes not advised") 893message(STATUS " Attributes info .......... ${EXPAT_ATTR_INFO}") 894message(STATUS " Context bytes ............ ${EXPAT_CONTEXT_BYTES}") 895message(STATUS " DTD support .............. ${EXPAT_DTD}") 896message(STATUS " Large size ............... ${EXPAT_LARGE_SIZE}") 897message(STATUS " Minimum size ............. ${EXPAT_MIN_SIZE}") 898message(STATUS " Namespace support ........ ${EXPAT_NS}") 899message(STATUS "") 900message(STATUS " Entropy sources") 901if(WIN32) 902 message(STATUS " rand_s ................... ON") 903else() 904 message(STATUS " getrandom ................ ${HAVE_GETRANDOM}") 905 message(STATUS " syscall SYS_getrandom .... ${HAVE_SYSCALL_GETRANDOM}") 906 message(STATUS " libbsd ................... ${EXPAT_WITH_LIBBSD}") 907 message(STATUS " /dev/random .............. ${EXPAT_DEV_URANDOM}") 908endif() 909message(STATUS "") 910if(CMAKE_GENERATOR STREQUAL "Unix Makefiles") 911 message(STATUS "Continue with") 912 message(STATUS " make") 913 if(EXPAT_BUILD_TESTS) 914 message(STATUS " make test") 915 endif() 916 if(EXPAT_ENABLE_INSTALL) 917 message(STATUS " sudo make install") 918 endif() 919 message(STATUS "") 920endif() 921message(STATUS "===========================================================================") 922