1 # This file is copyrighted under the BSD-license for buildsystem files of KDE
2 # copyright 2010, Patrick Spendrin <ps_ml@gmx.de>
4 cmake_minimum_required(VERSION 3.1.3)
13 set(PACKAGE_BUGREPORT "expat-bugs@libexpat.org")
14 set(PACKAGE_NAME "expat")
15 set(PACKAGE_VERSION "${PROJECT_VERSION}")
16 set(PACKAGE_STRING "${PACKAGE_NAME} ${PACKAGE_VERSION}")
17 set(PACKAGE_TARNAME "${PACKAGE_NAME}")
19 include(CMakePackageConfigHelpers)
20 include(GNUInstallDirs)
23 # Configuration defaults
26 set(_EXPAT_BUILD_TOOLS_DEFAULT OFF)
28 set(_EXPAT_BUILD_TOOLS_DEFAULT ON)
30 if(MSVC OR NOT _EXPAT_BUILD_TOOLS_DEFAULT)
31 set(_EXPAT_BUILD_DOCS_DEFAULT OFF)
33 find_program(DOCBOOK_TO_MAN NAMES docbook2x-man db2x_docbook2man docbook2man docbook-to-man)
35 set(_EXPAT_BUILD_DOCS_DEFAULT ON)
37 set(_EXPAT_BUILD_DOCS_DEFAULT OFF)
44 option(EXPAT_BUILD_TOOLS "build the xmlwf tool for expat library" ${_EXPAT_BUILD_TOOLS_DEFAULT})
45 option(EXPAT_BUILD_EXAMPLES "build the examples for expat library" ON)
46 option(EXPAT_BUILD_TESTS "build the tests for expat library" ON)
47 option(EXPAT_SHARED_LIBS "build a shared expat library" ON)
48 option(EXPAT_BUILD_DOCS "build man page for xmlwf" ${_EXPAT_BUILD_DOCS_DEFAULT})
49 option(EXPAT_BUILD_FUZZERS "build fuzzers for the expat library" OFF)
50 option(EXPAT_WITH_LIBBSD "utilize libbsd (for arc4random_buf)" OFF)
51 option(EXPAT_ENABLE_INSTALL "install expat files in cmake install target" ON)
52 set(EXPAT_CONTEXT_BYTES 1024 CACHE STRING "Define to specify how much context to retain around the current parse point")
53 mark_as_advanced(EXPAT_CONTEXT_BYTES)
54 option(EXPAT_DTD "Define to make parameter entity parsing functionality available" ON)
55 mark_as_advanced(EXPAT_DTD)
56 option(EXPAT_NS "Define to make XML Namespaces functionality available" ON)
57 mark_as_advanced(EXPAT_NS)
58 option(EXPAT_WARNINGS_AS_ERRORS "Treat all compiler warnings as errors" OFF)
59 if(NOT WIN32 OR _EXPAT_HELP)
60 option(EXPAT_DEV_URANDOM "Define to include code reading entropy from `/dev/urandom'." ON)
61 set(EXPAT_WITH_GETRANDOM "AUTO" CACHE STRING
62 "Make use of getrandom function (ON|OFF|AUTO) [default=AUTO]")
63 set(EXPAT_WITH_SYS_GETRANDOM "AUTO" CACHE STRING
64 "Make use of syscall SYS_getrandom (ON|OFF|AUTO) [default=AUTO]")
65 mark_as_advanced(EXPAT_DEV_URANDOM)
67 set(EXPAT_CHAR_TYPE "char" CACHE STRING "Character type to use (char|ushort|wchar_t) [default=char]")
68 option(EXPAT_ATTR_INFO "Define to allow retrieving the byte offsets for attribute names and values" OFF)
69 mark_as_advanced(EXPAT_ATTR_INFO)
70 option(EXPAT_LARGE_SIZE "Make XML_GetCurrent* functions return <(unsigned) long long> rather than <(unsigned) long>" OFF)
71 mark_as_advanced(EXPAT_LARGE_SIZE)
72 option(EXPAT_MIN_SIZE "Get a smaller (but slower) parser (in particular avoid multiple copies of the tokenizer)" OFF)
73 mark_as_advanced(EXPAT_MIN_SIZE)
74 if(MSVC OR _EXPAT_HELP)
75 set(EXPAT_MSVC_STATIC_CRT OFF CACHE BOOL "Use /MT flag (static CRT) when compiling in MSVC")
82 find_library(LIB_BSD NAMES bsd)
84 message(SEND_ERROR "EXPAT_WITH_LIBBSD option is enabled, but libbsd was not found")
90 macro(_expat_copy_bool_int source_ref dest_ref)
99 add_definitions(-DXML_LARGE_SIZE)
103 add_definitions(-DXML_MIN_SIZE)
106 if(EXPAT_CHAR_TYPE STREQUAL "char")
107 set(_EXPAT_UNICODE OFF)
108 set(_EXPAT_UNICODE_WCHAR_T OFF)
109 elseif(EXPAT_CHAR_TYPE STREQUAL "ushort")
110 set(_EXPAT_UNICODE ON)
111 set(_EXPAT_UNICODE_WCHAR_T OFF)
112 if(EXPAT_BUILD_TOOLS)
113 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.")
115 elseif(EXPAT_CHAR_TYPE STREQUAL "wchar_t")
116 set(_EXPAT_UNICODE ON)
117 set(_EXPAT_UNICODE_WCHAR_T ON)
119 message(SEND_ERROR "Option -DEXPAT_CHAR_TYPE=(char|ushort|wchar_t) cannot be \"${EXPAT_CHAR_TYPE}\".")
123 add_definitions(-DXML_UNICODE) # for unsigned short
124 if(_EXPAT_UNICODE_WCHAR_T)
125 add_definitions(-DXML_UNICODE_WCHAR_T) # for wchar_t
129 include(${CMAKE_CURRENT_LIST_DIR}/ConfigureChecks.cmake)
131 macro(evaluate_detection_results use_ref have_ref thing_lower thing_title)
132 if(${use_ref} AND NOT (${use_ref} STREQUAL "AUTO") AND NOT ${have_ref})
134 "Use of ${thing_lower} was enforced by ${use_ref}=ON but it could not be found.")
135 elseif(NOT ${use_ref} AND ${have_ref})
136 message("${thing_title} was found but it will not be used due to ${use_ref}=OFF.")
142 evaluate_detection_results(EXPAT_WITH_GETRANDOM HAVE_GETRANDOM "function getrandom" "Function getrandom")
143 evaluate_detection_results(EXPAT_WITH_SYS_GETRANDOM HAVE_SYSCALL_GETRANDOM "syscall SYS_getrandom" "Syscall SYS_getrandom")
146 _expat_copy_bool_int(EXPAT_ATTR_INFO XML_ATTR_INFO)
147 _expat_copy_bool_int(EXPAT_DTD XML_DTD)
148 _expat_copy_bool_int(EXPAT_LARGE_SIZE XML_LARGE_SIZE)
149 _expat_copy_bool_int(EXPAT_MIN_SIZE XML_MIN_SIZE)
150 _expat_copy_bool_int(EXPAT_NS XML_NS)
152 _expat_copy_bool_int(EXPAT_DEV_URANDOM XML_DEV_URANDOM)
154 set(XML_CONTEXT_BYTES ${EXPAT_CONTEXT_BYTES})
157 if(EXPAT_ENABLE_INSTALL)
162 configure_file(expat_config.h.cmake "${CMAKE_CURRENT_BINARY_DIR}/expat_config.h")
163 add_definitions(-DHAVE_EXPAT_CONFIG_H)
164 expat_install(FILES "${CMAKE_CURRENT_BINARY_DIR}/expat_config.h" DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
167 set(EXTRA_COMPILE_FLAGS)
168 if(FLAG_NO_STRICT_ALIASING)
169 set(EXTRA_COMPILE_FLAGS "${EXTRA_COMPILE_FLAGS} -fno-strict-aliasing")
172 add_definitions(-DXML_ENABLE_VISIBILITY=1)
173 set(EXTRA_COMPILE_FLAGS "${EXTRA_COMPILE_FLAGS} -fvisibility=hidden")
174 endif(FLAG_VISIBILITY)
175 if (EXPAT_WARNINGS_AS_ERRORS)
179 set(EXTRA_COMPILE_FLAGS "${EXTRA_COMPILE_FLAGS} -Werror")
181 endif(EXPAT_WARNINGS_AS_ERRORS)
182 set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_COMPILE_FLAGS}")
183 set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${EXTRA_COMPILE_FLAGS}")
186 if (EXPAT_MSVC_STATIC_CRT)
187 message("-- Using static CRT ${EXPAT_MSVC_STATIC_CRT}")
189 CMAKE_CXX_FLAGS_DEBUG
190 CMAKE_CXX_FLAGS_RELEASE
191 CMAKE_CXX_FLAGS_MINSIZEREL
192 CMAKE_CXX_FLAGS_RELWITHDEBINFO
194 CMAKE_C_FLAGS_RELEASE
195 CMAKE_C_FLAGS_MINSIZEREL
196 CMAKE_C_FLAGS_RELWITHDEBINFO
198 string(REPLACE "/MD" "/MT" ${flag_var} "${${flag_var}}")
203 include_directories(${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/lib)
205 add_definitions(-D_CRT_SECURE_NO_WARNINGS -wd4996)
208 if(_EXPAT_UNICODE_WCHAR_T)
209 set(_POSTFIX_WIDE "w")
212 if(MSVC AND NOT EXPAT_SHARED_LIBS)
213 if(EXPAT_MSVC_STATIC_CRT)
214 set(_POSTFIX_CRT "MT")
216 set(_POSTFIX_CRT "MD")
222 CMAKE_RELEASE_POSTFIX
223 CMAKE_MINSIZEREL_POSTFIX
224 CMAKE_RELWITHDEBINFO_POSTFIX
226 if(postfix_var STREQUAL "CMAKE_DEBUG_POSTFIX")
227 set(_POSTFIX_DEBUG "d")
229 set(_POSTFIX_DEBUG "")
232 set(${postfix_var} "${_POSTFIX_WIDE}${_POSTFIX_DEBUG}${_POSTFIX_CRT}" CACHE STRING "Windows binary postfix, e.g. expat<postfix=[w][d][MD|MT]>.lib")
243 # NOTE: ISO C forbids an empty translation unit
248 if(EXPAT_SHARED_LIBS)
251 set(expat_SRCS ${expat_SRCS} lib/libexpat.def)
253 else(EXPAT_SHARED_LIBS)
256 add_definitions(-DXML_STATIC)
258 endif(EXPAT_SHARED_LIBS)
260 add_library(expat ${_SHARED} ${expat_SRCS})
261 if(EXPAT_WITH_LIBBSD)
262 target_link_libraries(expat ${LIB_BSD})
265 set(LIBCURRENT 7) # sync
266 set(LIBREVISION 10) # with
267 set(LIBAGE 6) # configure.ac!
268 math(EXPR LIBCURRENT_MINUS_AGE "${LIBCURRENT} - ${LIBAGE}")
271 set_property(TARGET expat PROPERTY VERSION ${LIBCURRENT_MINUS_AGE}.${LIBAGE}.${LIBREVISION})
272 set_property(TARGET expat PROPERTY SOVERSION ${LIBCURRENT_MINUS_AGE})
273 set_property(TARGET expat PROPERTY NO_SONAME ${NO_SONAME})
276 expat_install(TARGETS expat EXPORT expat
277 RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
278 LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
279 ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR})
281 expat_install(FILES lib/expat.h lib/expat_external.h DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
287 set(prefix ${CMAKE_INSTALL_PREFIX})
288 set(exec_prefix "\${prefix}")
289 set(libdir "\${exec_prefix}/${CMAKE_INSTALL_LIBDIR}")
290 set(includedir "\${prefix}/${CMAKE_INSTALL_INCLUDEDIR}")
291 configure_file(expat.pc.in ${CMAKE_CURRENT_BINARY_DIR}/expat.pc @ONLY)
292 expat_install(FILES ${CMAKE_CURRENT_BINARY_DIR}/expat.pc DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig)
296 # C command line tool xmlwf
298 if(EXPAT_BUILD_TOOLS)
306 add_executable(xmlwf ${xmlwf_SRCS})
307 set_property(TARGET xmlwf PROPERTY RUNTIME_OUTPUT_DIRECTORY xmlwf)
308 target_link_libraries(xmlwf expat)
309 expat_install(TARGETS xmlwf DESTINATION ${CMAKE_INSTALL_BINDIR})
311 if(MINGW AND _EXPAT_UNICODE_WCHAR_T)
312 # https://gcc.gnu.org/onlinedocs/gcc/x86-Windows-Options.html
313 set_target_properties(xmlwf PROPERTIES LINK_FLAGS -municode)
317 file(MAKE_DIRECTORY ${PROJECT_BINARY_DIR}/doc)
318 add_custom_command(TARGET expat PRE_BUILD COMMAND "${DOCBOOK_TO_MAN}" "${PROJECT_SOURCE_DIR}/doc/xmlwf.xml" && mv "XMLWF.1" "${PROJECT_BINARY_DIR}/doc/xmlwf.1")
319 expat_install(FILES "${PROJECT_BINARY_DIR}/doc/xmlwf.1" DESTINATION ${CMAKE_INSTALL_MANDIR}/man1)
326 if(EXPAT_BUILD_EXAMPLES)
327 add_executable(elements examples/elements.c)
328 set_property(TARGET elements PROPERTY RUNTIME_OUTPUT_DIRECTORY examples)
329 target_link_libraries(elements expat)
331 add_executable(outline examples/outline.c)
332 set_property(TARGET outline PROPERTY RUNTIME_OUTPUT_DIRECTORY examples)
333 target_link_libraries(outline expat)
334 endif(EXPAT_BUILD_EXAMPLES)
339 if(EXPAT_BUILD_TESTS)
340 ## these are unittests that can be run on any platform
353 set(host whatever-mingw32) # for nothing but run.sh
355 configure_file(${CMAKE_CURRENT_SOURCE_DIR}/run.sh.in run.sh @ONLY)
358 function(expat_add_test _name _file)
360 add_test(NAME ${_name} COMMAND ${_file})
362 add_test(NAME ${_name} COMMAND bash run.sh ${_file})
366 add_executable(runtests tests/runtests.c ${test_SRCS})
367 set_property(TARGET runtests PROPERTY RUNTIME_OUTPUT_DIRECTORY tests)
368 target_link_libraries(runtests expat)
369 expat_add_test(runtests $<TARGET_FILE:runtests>)
371 add_executable(runtestspp tests/runtestspp.cpp ${test_SRCS})
372 set_property(TARGET runtestspp PROPERTY RUNTIME_OUTPUT_DIRECTORY tests)
373 target_link_libraries(runtestspp expat)
374 expat_add_test(runtestspp $<TARGET_FILE:runtestspp>)
375 endif(EXPAT_BUILD_TESTS)
377 if(EXPAT_BUILD_FUZZERS)
378 if(NOT "${CMAKE_C_COMPILER_ID}" STREQUAL "Clang")
380 "Building fuzz targets without Clang (but ${CMAKE_C_COMPILER_ID}) "
381 "is not supported. Please set "
382 "-DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++.")
385 string(FIND "${CMAKE_EXE_LINKER_FLAGS}" "-fsanitize" sanitizer_present)
386 if(${sanitizer_present} EQUAL "-1")
388 "There was no sanitizer present when building the fuzz targets. "
389 "This is likely in error - consider adding "
390 "-DCMAKE_C_FLAGS='-fsanitize=<sanitizer>' and "
391 "-DCMAKE_CXX_FLAGS='-fsanitize=<sanitizer>' and "
392 "-DCMAKE_STATIC_LINKER_FLAGS='-fsanitize=<sanitizer>' and "
393 "-DCMAKE_EXE_LINKER_FLAGS='-fsanitize=<sanitizer>' to your cmake "
397 set(encoding_types UTF-16 UTF-8 ISO-8859-1 US-ASCII UTF-16BE UTF-16LE)
398 set(fuzz_targets xml_parse_fuzzer xml_parsebuffer_fuzzer)
400 add_library(fuzzpat STATIC ${expat_SRCS})
401 target_compile_options(fuzzpat PRIVATE -fsanitize=fuzzer-no-link)
403 foreach(fuzz_target ${fuzz_targets})
404 foreach(encoding_type ${encoding_types})
405 set(target_name ${fuzz_target}_${encoding_type})
406 add_executable(${target_name} fuzz/${fuzz_target}.c)
407 target_link_libraries(${target_name} fuzzpat)
408 target_compile_definitions(${target_name}
409 PRIVATE ENCODING_FOR_FUZZING=${encoding_type})
410 target_compile_options(${target_name} PRIVATE -fsanitize=fuzzer-no-link)
411 # NOTE: Avoiding target_link_options here only because it needs CMake >=3.13
412 set_target_properties(${target_name} PROPERTIES LINK_FLAGS -fsanitize=fuzzer)
414 TARGET ${target_name} PROPERTY RUNTIME_OUTPUT_DIRECTORY fuzz)
417 endif(EXPAT_BUILD_FUZZERS)
420 # Custom target "run-xmltest"
422 if(EXPAT_BUILD_TOOLS AND NOT MSVC)
426 sh -c 'test -f xmlts.zip || wget --output-document=xmlts.zip https://www.w3.org/XML/Test/xmlts20080827.zip'
435 sh -c 'test -d xmlconf || unzip -q xmlts.zip'
440 add_dependencies(xmlts-zip-extracted xmlts-zip-downloaded)
445 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'
448 add_dependencies(xmltest-sh-been-run xmlts-zip-extracted xmlwf)
453 ${CMAKE_CURRENT_SOURCE_DIR}/fix-xmltest-log.sh tests/xmltest.log
456 add_dependencies(xmltest-log-fixed xmltest-sh-been-run)
461 diff -u ${CMAKE_CURRENT_SOURCE_DIR}/tests/xmltest.log.expected tests/xmltest.log)
462 add_dependencies(xmltest-log-verified xmltest-log-fixed)
464 add_custom_target(run-xmltest)
465 add_dependencies(run-xmltest xmltest-log-verified)
471 configure_file(Changes changelog COPYONLY)
475 ${CMAKE_CURRENT_BINARY_DIR}/changelog
477 ${CMAKE_INSTALL_DOCDIR})
480 # CMake files for find_package(expat [..] CONFIG [..])
482 configure_package_config_file(
483 cmake/expat-config.cmake.in
484 cmake/expat-config.cmake
486 ${CMAKE_INSTALL_LIBDIR}/cmake/expat-${PROJECT_VERSION}/
488 write_basic_package_version_file(
489 cmake/expat-config-version.cmake
490 COMPATIBILITY SameMajorVersion # i.e. semver
496 cmake/expat-targets.cmake # not going to be installed
500 ${CMAKE_CURRENT_BINARY_DIR}/cmake/expat-config.cmake
501 ${CMAKE_CURRENT_BINARY_DIR}/cmake/expat-config-version.cmake
503 ${CMAKE_INSTALL_LIBDIR}/cmake/expat-${PROJECT_VERSION}/
509 ${CMAKE_INSTALL_LIBDIR}/cmake/expat-${PROJECT_VERSION}/
517 if(EXPAT_CHAR_TYPE STREQUAL "char")
518 set(_EXPAT_CHAR_TYPE_SUMMARY "char (UTF-8)")
519 elseif(EXPAT_CHAR_TYPE STREQUAL "ushort")
520 set(_EXPAT_CHAR_TYPE_SUMMARY "ushort (unsigned short, UTF-16)")
521 elseif(EXPAT_CHAR_TYPE STREQUAL "wchar_t")
523 set(_EXPAT_CHAR_TYPE_SUMMARY "wchar_t (UTF-16)")
525 set(_EXPAT_CHAR_TYPE_SUMMARY "wchar_t (UTF-32) // not implemented")
528 set(_EXPAT_CHAR_TYPE_SUMMARY "ERROR")
530 string(TOUPPER "${CMAKE_BUILD_TYPE}" _EXPAT_BUILD_TYPE_UPPER)
532 message(STATUS "===========================================================================")
534 message(STATUS "Configuration")
535 message(STATUS " Prefix ..................... ${CMAKE_INSTALL_PREFIX}")
536 message(STATUS " Build type ................. ${CMAKE_BUILD_TYPE}")
537 message(STATUS " Shared libraries ........... ${EXPAT_SHARED_LIBS}")
539 message(STATUS " Static CRT ................. ${EXPAT_MSVC_STATIC_CRT}")
541 message(STATUS " Character type ............. ${_EXPAT_CHAR_TYPE_SUMMARY}")
543 message(STATUS " Binary postfix ............. ${CMAKE_${_EXPAT_BUILD_TYPE_UPPER}_POSTFIX}")
546 message(STATUS " Build documentation ........ ${EXPAT_BUILD_DOCS}")
547 message(STATUS " Build examples ............. ${EXPAT_BUILD_EXAMPLES}")
548 message(STATUS " Build fuzzers .............. ${EXPAT_BUILD_FUZZERS}")
549 message(STATUS " Build tests ................ ${EXPAT_BUILD_TESTS}")
550 message(STATUS " Build tools (xmlwf) ........ ${EXPAT_BUILD_TOOLS}")
551 message(STATUS " Install files .............. ${EXPAT_ENABLE_INSTALL}")
553 message(STATUS " Features")
554 message(STATUS " // Advanced options, changes not advised")
555 message(STATUS " Attributes info .......... ${EXPAT_ATTR_INFO}")
556 message(STATUS " Context bytes ............ ${EXPAT_CONTEXT_BYTES}")
557 message(STATUS " DTD support .............. ${EXPAT_DTD}")
558 message(STATUS " Large size ............... ${EXPAT_LARGE_SIZE}")
559 message(STATUS " Minimum size ............. ${EXPAT_MIN_SIZE}")
560 message(STATUS " Namespace support ........ ${EXPAT_NS}")
562 message(STATUS " Entropy sources")
564 message(STATUS " rand_s ................... ON")
566 message(STATUS " getrandom ................ ${HAVE_GETRANDOM}")
567 message(STATUS " syscall SYS_getrandom .... ${HAVE_SYSCALL_GETRANDOM}")
568 message(STATUS " libbsd ................... ${EXPAT_WITH_LIBBSD}")
569 message(STATUS " /dev/random .............. ${EXPAT_DEV_URANDOM}")
572 if(CMAKE_GENERATOR STREQUAL "Unix Makefiles")
573 message(STATUS "Continue with")
574 message(STATUS " make")
575 if(EXPAT_BUILD_TESTS)
576 message(STATUS " make test")
578 if(EXPAT_ENABLE_INSTALL)
579 message(STATUS " sudo make install")
583 message(STATUS "===========================================================================")