CMakeLists.txt 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297
  1. cmake_minimum_required(VERSION 3.10...3.30)
  2. # Policy configuration; this *MUST* be specified before project is defined
  3. if(POLICY CMP0091)
  4. cmake_policy(SET CMP0091 NEW) # Enables use of MSVC_RUNTIME_LIBRARY
  5. endif()
  6. project(pugixml VERSION 1.15 LANGUAGES CXX)
  7. include(CMakePackageConfigHelpers)
  8. include(CMakeDependentOption)
  9. include(GNUInstallDirs)
  10. cmake_dependent_option(PUGIXML_USE_VERSIONED_LIBDIR
  11. "Use a private subdirectory to install the headers and libraries" OFF
  12. "CMAKE_SOURCE_DIR STREQUAL PROJECT_SOURCE_DIR" OFF)
  13. cmake_dependent_option(PUGIXML_USE_POSTFIX
  14. "Use separate postfix for each configuration to make sure you can install multiple build outputs" OFF
  15. "CMAKE_SOURCE_DIR STREQUAL PROJECT_SOURCE_DIR" OFF)
  16. cmake_dependent_option(PUGIXML_STATIC_CRT
  17. "Use static MSVC RT libraries" OFF
  18. "MSVC" OFF)
  19. cmake_dependent_option(PUGIXML_BUILD_TESTS
  20. "Build pugixml tests" OFF
  21. "CMAKE_SOURCE_DIR STREQUAL PROJECT_SOURCE_DIR" OFF)
  22. # Custom build defines
  23. set(PUGIXML_BUILD_DEFINES CACHE STRING "Build defines for custom options")
  24. separate_arguments(PUGIXML_BUILD_DEFINES)
  25. # Technically not needed for this file. This is builtin CMAKE global variable.
  26. option(BUILD_SHARED_LIBS "Build shared instead of static library")
  27. # Expose option to build PUGIXML as static as well when the global BUILD_SHARED_LIBS variable is set
  28. cmake_dependent_option(PUGIXML_BUILD_SHARED_AND_STATIC_LIBS
  29. "Build both shared and static libraries" OFF
  30. "BUILD_SHARED_LIBS" OFF)
  31. # Expose options from the pugiconfig.hpp
  32. option(PUGIXML_WCHAR_MODE "Enable wchar_t mode" OFF)
  33. option(PUGIXML_COMPACT "Enable compact mode" OFF)
  34. option(PUGIXML_INSTALL "Enable installation rules" ON)
  35. # Advanced options from pugiconfig.hpp
  36. option(PUGIXML_NO_XPATH "Disable XPath" OFF)
  37. option(PUGIXML_NO_STL "Disable STL" OFF)
  38. option(PUGIXML_NO_EXCEPTIONS "Disable Exceptions" OFF)
  39. mark_as_advanced(PUGIXML_NO_XPATH PUGIXML_NO_STL PUGIXML_NO_EXCEPTIONS)
  40. if (APPLE)
  41. option(PUGIXML_BUILD_APPLE_FRAMEWORK "Build as Apple Frameworks" OFF)
  42. endif()
  43. set(PUGIXML_PUBLIC_DEFINITIONS
  44. $<$<BOOL:${PUGIXML_WCHAR_MODE}>:PUGIXML_WCHAR_MODE>
  45. $<$<BOOL:${PUGIXML_COMPACT}>:PUGIXML_COMPACT>
  46. $<$<BOOL:${PUGIXML_NO_XPATH}>:PUGIXML_NO_XPATH>
  47. $<$<BOOL:${PUGIXML_NO_STL}>:PUGIXML_NO_STL>
  48. $<$<BOOL:${PUGIXML_NO_EXCEPTIONS}>:PUGIXML_NO_EXCEPTIONS>
  49. )
  50. # This is used to backport a CMake 3.15 feature, but is also forwards compatible
  51. if (NOT DEFINED CMAKE_MSVC_RUNTIME_LIBRARY)
  52. set(CMAKE_MSVC_RUNTIME_LIBRARY
  53. MultiThreaded$<$<CONFIG:Debug>:Debug>$<$<NOT:$<BOOL:${PUGIXML_STATIC_CRT}>>:DLL>)
  54. endif()
  55. # Set the default C++ standard to C++17 if not set; CMake will automatically downgrade this if the compiler does not support it
  56. # When CMAKE_CXX_STANDARD_REQUIRED is set, we fall back to C++11 to avoid breaking older compilers
  57. if (NOT DEFINED CMAKE_CXX_STANDARD_REQUIRED AND NOT DEFINED CMAKE_CXX_STANDARD AND NOT CMAKE_VERSION VERSION_LESS 3.8)
  58. set(CMAKE_CXX_STANDARD 17)
  59. set(CMAKE_CXX_STANDARD_REQUIRED OFF)
  60. elseif (NOT DEFINED CMAKE_CXX_STANDARD)
  61. set(CMAKE_CXX_STANDARD 11)
  62. endif()
  63. if (PUGIXML_USE_POSTFIX)
  64. set(CMAKE_RELWITHDEBINFO_POSTFIX _r)
  65. set(CMAKE_MINSIZEREL_POSTFIX _m)
  66. set(CMAKE_DEBUG_POSTFIX _d)
  67. endif()
  68. if (CMAKE_VERSION VERSION_LESS 3.15)
  69. set(msvc-rt $<TARGET_PROPERTY:MSVC_RUNTIME_LIBRARY>)
  70. set(msvc-rt-mtd-shared $<STREQUAL:${msvc-rt},MultiThreadedDebugDLL>)
  71. set(msvc-rt-mtd-static $<STREQUAL:${msvc-rt},MultiThreadedDebug>)
  72. set(msvc-rt-mt-shared $<STREQUAL:${msvc-rt},MultiThreadedDLL>)
  73. set(msvc-rt-mt-static $<STREQUAL:${msvc-rt},MultiThreaded>)
  74. unset(msvc-rt)
  75. set(msvc-rt-mtd-shared $<${msvc-rt-mtd-shared}:-MDd>)
  76. set(msvc-rt-mtd-static $<${msvc-rt-mtd-static}:-MTd>)
  77. set(msvc-rt-mt-shared $<${msvc-rt-mt-shared}:-MD>)
  78. set(msvc-rt-mt-static $<${msvc-rt-mt-static}:-MT>)
  79. endif()
  80. set(versioned-dir $<$<BOOL:${PUGIXML_USE_VERSIONED_LIBDIR}>:/pugixml-${PROJECT_VERSION}>)
  81. set(libs)
  82. if (BUILD_SHARED_LIBS)
  83. add_library(pugixml-shared SHARED
  84. ${PROJECT_SOURCE_DIR}/scripts/pugixml_dll.rc
  85. ${PROJECT_SOURCE_DIR}/src/pugixml.cpp)
  86. add_library(pugixml::shared ALIAS pugixml-shared)
  87. list(APPEND libs pugixml-shared)
  88. string(CONCAT pugixml.msvc $<OR:
  89. $<STREQUAL:${CMAKE_CXX_COMPILER_FRONTEND_VARIANT},MSVC>,
  90. $<CXX_COMPILER_ID:MSVC>
  91. >)
  92. set_property(TARGET pugixml-shared PROPERTY EXPORT_NAME shared)
  93. target_include_directories(pugixml-shared
  94. PUBLIC
  95. $<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/src>)
  96. target_compile_definitions(pugixml-shared
  97. PUBLIC
  98. ${PUGIXML_BUILD_DEFINES}
  99. ${PUGIXML_PUBLIC_DEFINITIONS}
  100. PRIVATE
  101. PUGIXML_API=$<IF:${pugixml.msvc},__declspec\(dllexport\),__attribute__\(\(visibility\("default"\)\)\)>
  102. )
  103. target_compile_options(pugixml-shared
  104. PRIVATE
  105. ${msvc-rt-mtd-shared}
  106. ${msvc-rt-mtd-static}
  107. ${msvc-rt-mt-shared}
  108. ${msvc-rt-mt-static})
  109. endif()
  110. if (NOT BUILD_SHARED_LIBS OR PUGIXML_BUILD_SHARED_AND_STATIC_LIBS)
  111. add_library(pugixml-static STATIC
  112. ${PROJECT_SOURCE_DIR}/src/pugixml.cpp)
  113. add_library(pugixml::static ALIAS pugixml-static)
  114. list(APPEND libs pugixml-static)
  115. set_property(TARGET pugixml-static PROPERTY EXPORT_NAME static)
  116. target_include_directories(pugixml-static
  117. PUBLIC
  118. $<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/src>)
  119. target_compile_definitions(pugixml-static
  120. PUBLIC
  121. ${PUGIXML_BUILD_DEFINES}
  122. ${PUGIXML_PUBLIC_DEFINITIONS})
  123. target_compile_options(pugixml-static
  124. PRIVATE
  125. ${msvc-rt-mtd-shared}
  126. ${msvc-rt-mtd-static}
  127. ${msvc-rt-mt-shared}
  128. ${msvc-rt-mt-static})
  129. endif()
  130. if (BUILD_SHARED_LIBS)
  131. set(pugixml-alias pugixml-shared)
  132. else()
  133. set(pugixml-alias pugixml-static)
  134. endif()
  135. add_library(pugixml INTERFACE)
  136. target_link_libraries(pugixml INTERFACE ${pugixml-alias})
  137. add_library(pugixml::pugixml ALIAS pugixml)
  138. set_target_properties(${libs}
  139. PROPERTIES
  140. MSVC_RUNTIME_LIBRARY ${CMAKE_MSVC_RUNTIME_LIBRARY}
  141. EXCLUDE_FROM_ALL ON
  142. POSITION_INDEPENDENT_CODE ON
  143. SOVERSION ${PROJECT_VERSION_MAJOR}
  144. VERSION ${PROJECT_VERSION}
  145. OUTPUT_NAME pugixml)
  146. set_target_properties(${libs}
  147. PROPERTIES
  148. EXCLUDE_FROM_ALL OFF)
  149. set(install-targets pugixml ${libs})
  150. if (PUGIXML_BUILD_APPLE_FRAMEWORK)
  151. set_target_properties(${libs} PROPERTIES
  152. FRAMEWORK TRUE
  153. FRAMEWORK_VERSION ${PROJECT_VERSION}
  154. XCODE_ATTRIBUTE_PRODUCT_BUNDLE_IDENTIFIER com.zeux.pugixml
  155. MACOSX_FRAMEWORK_IDENTIFIER com.zeux.pugixml
  156. MACOSX_FRAMEWORK_BUNDLE_VERSION ${PROJECT_VERSION}
  157. MACOSX_FRAMEWORK_SHORT_VERSION_STRING ${PROJECT_VERSION_MAJOR})
  158. endif()
  159. configure_package_config_file(
  160. "${PROJECT_SOURCE_DIR}/scripts/pugixml-config.cmake.in"
  161. "${PROJECT_BINARY_DIR}/pugixml-config.cmake"
  162. INSTALL_DESTINATION ${CMAKE_INSTALL_LIBDIR}
  163. NO_CHECK_REQUIRED_COMPONENTS_MACRO
  164. NO_SET_AND_CHECK_MACRO)
  165. write_basic_package_version_file(
  166. "${PROJECT_BINARY_DIR}/pugixml-config-version.cmake"
  167. COMPATIBILITY SameMajorVersion)
  168. if (PUGIXML_USE_POSTFIX)
  169. if(CMAKE_BUILD_TYPE MATCHES RelWithDebInfo)
  170. set(LIB_POSTFIX ${CMAKE_RELWITHDEBINFO_POSTFIX})
  171. elseif(CMAKE_BUILD_TYPE MATCHES MinSizeRel)
  172. set(LIB_POSTFIX ${CMAKE_MINSIZEREL_POSTFIX})
  173. elseif(CMAKE_BUILD_TYPE MATCHES Debug)
  174. set(LIB_POSTFIX ${CMAKE_DEBUG_POSTFIX})
  175. endif()
  176. endif()
  177. # Handle both relative and absolute paths (e.g. NixOS) for a relocatable package
  178. if(IS_ABSOLUTE "${CMAKE_INSTALL_INCLUDEDIR}")
  179. set(PUGIXML_PC_INCLUDEDIR "${CMAKE_INSTALL_INCLUDEDIR}")
  180. else()
  181. set(PUGIXML_PC_INCLUDEDIR "\${prefix}/${CMAKE_INSTALL_INCLUDEDIR}")
  182. endif()
  183. if(IS_ABSOLUTE "${CMAKE_INSTALL_LIBDIR}")
  184. set(PUGIXML_PC_LIBDIR "${CMAKE_INSTALL_LIBDIR}")
  185. else()
  186. set(PUGIXML_PC_LIBDIR "\${exec_prefix}/${CMAKE_INSTALL_LIBDIR}")
  187. endif()
  188. configure_file(scripts/pugixml.pc.in pugixml.pc @ONLY)
  189. export(TARGETS ${install-targets}
  190. NAMESPACE pugixml::
  191. FILE pugixml-targets.cmake)
  192. if(PUGIXML_INSTALL)
  193. if (NOT DEFINED PUGIXML_RUNTIME_COMPONENT)
  194. set(PUGIXML_RUNTIME_COMPONENT Runtime)
  195. endif()
  196. if (NOT DEFINED PUGIXML_LIBRARY_COMPONENT)
  197. set(PUGIXML_LIBRARY_COMPONENT Library)
  198. endif()
  199. if (NOT DEFINED PUGIXML_DEVELOPMENT_COMPONENT)
  200. set(PUGIXML_DEVELOPMENT_COMPONENT Development)
  201. endif()
  202. set(namelink-component)
  203. if (NOT CMAKE_VERSION VERSION_LESS 3.12)
  204. set(namelink-component NAMELINK_COMPONENT ${PUGIXML_DEVELOPMENT_COMPONENT})
  205. endif()
  206. install(TARGETS ${install-targets}
  207. EXPORT pugixml-targets
  208. RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT ${PUGIXML_RUNTIME_COMPONENT}
  209. LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT ${PUGIXML_LIBRARY_COMPONENT} ${namelink-component}
  210. ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT ${PUGIXML_DEVELOPMENT_COMPONENT}
  211. INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}${versioned-dir}
  212. FRAMEWORK DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT runtime OPTIONAL)
  213. install(EXPORT pugixml-targets
  214. NAMESPACE pugixml::
  215. DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/pugixml COMPONENT ${PUGIXML_DEVELOPMENT_COMPONENT})
  216. install(FILES
  217. "${PROJECT_BINARY_DIR}/pugixml-config-version.cmake"
  218. "${PROJECT_BINARY_DIR}/pugixml-config.cmake"
  219. DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/pugixml COMPONENT ${PUGIXML_DEVELOPMENT_COMPONENT})
  220. install(FILES ${PROJECT_BINARY_DIR}/pugixml.pc
  221. DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig COMPONENT ${PUGIXML_DEVELOPMENT_COMPONENT})
  222. install(
  223. FILES
  224. "${PROJECT_SOURCE_DIR}/src/pugiconfig.hpp"
  225. "${PROJECT_SOURCE_DIR}/src/pugixml.hpp"
  226. DESTINATION
  227. ${CMAKE_INSTALL_INCLUDEDIR}${versioned-dir} COMPONENT ${PUGIXML_DEVELOPMENT_COMPONENT})
  228. endif()
  229. if (PUGIXML_BUILD_TESTS)
  230. include(CTest)
  231. set(fuzz-pattern "tests/fuzz_*.cpp")
  232. set(test-pattern "tests/*.cpp")
  233. if (CMAKE_VERSION VERSION_GREATER 3.11)
  234. list(INSERT fuzz-pattern 0 CONFIGURE_DEPENDS)
  235. list(INSERT test-pattern 0 CONFIGURE_DEPENDS)
  236. endif()
  237. file(GLOB test-sources ${test-pattern})
  238. file(GLOB fuzz-sources ${fuzz-pattern})
  239. list(REMOVE_ITEM test-sources ${fuzz-sources})
  240. add_custom_target(check
  241. COMMAND ${CMAKE_CTEST_COMMAND} --output-on-failure)
  242. add_executable(pugixml-check ${test-sources})
  243. add_test(NAME pugixml::test
  244. COMMAND pugixml-check
  245. WORKING_DIRECTORY ${PROJECT_SOURCE_DIR})
  246. add_dependencies(check pugixml-check)
  247. target_link_libraries(pugixml-check
  248. PRIVATE
  249. pugixml::pugixml)
  250. endif()