Utilities.cmake 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192
  1. #[[
  2. Various global utility functions for RmlUi.
  3. ]]
  4. #[[
  5. Format the RmlUi version as it should normally be displayed.
  6. Output:
  7. RMLUI_VERSION_SHORT: The RmlUi version as a string
  8. ]]
  9. function(generate_rmlui_version_string)
  10. if(NOT RMLUI_VERSION_RELEASE)
  11. set(RMLUI_VERSION_SUFFIX "-dev")
  12. endif()
  13. if(PROJECT_VERSION_PATCH GREATER 0)
  14. set(RMLUI_VERSION_PATCH ".${PROJECT_VERSION_PATCH}")
  15. endif()
  16. set(RMLUI_VERSION_SHORT
  17. "${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}${RMLUI_VERSION_PATCH}${RMLUI_VERSION_SUFFIX}"
  18. PARENT_SCOPE
  19. )
  20. endfunction()
  21. #[[
  22. Stop execution and print an error message for the dependency.
  23. Arguments:
  24. - friendly_name: Friendly name of the target
  25. - target_name: Name of the CMake target the project will link against
  26. ]]
  27. function(report_dependency_not_found friendly_name target_name)
  28. message(FATAL_ERROR
  29. "${friendly_name} could not be found.\n"
  30. "Please ensure that ${friendly_name} can be found by CMake, or linked to using \"${target_name}\" as its "
  31. "target name. If you are consuming RmlUi from another CMake project, you can create an ALIAS target to "
  32. "offer an alternative name for a CMake target."
  33. )
  34. endfunction()
  35. #[[
  36. Verify that the target is found and print a message, otherwise stop execution.
  37. Arguments:
  38. - friendly_name: Friendly name of the target
  39. - target_name: Name of the CMake target the project will link against
  40. - success_message: Message to show when the target exists (optional)
  41. ]]
  42. function(report_dependency_found_or_error friendly_name target_name)
  43. if(NOT TARGET ${target_name})
  44. report_dependency_not_found(${friendly_name} ${target_name})
  45. endif()
  46. if(ARGC GREATER "2" AND ARGV2)
  47. set(success_message " - ${ARGV2}")
  48. endif()
  49. message(STATUS "Found ${target_name}${success_message}")
  50. endfunction()
  51. #[[
  52. Set compiler options and features that are common to all RmlUi targets.
  53. Arguments:
  54. - target: The name of the target to set
  55. ]]
  56. function(set_common_target_options target)
  57. target_compile_features(${target} PUBLIC cxx_std_14)
  58. set_target_properties(${target} PROPERTIES C_EXTENSIONS OFF CXX_EXTENSIONS OFF)
  59. if(RMLUI_COMPILER_OPTIONS)
  60. if(CMAKE_CXX_COMPILER_ID MATCHES "Clang" OR CMAKE_CXX_COMPILER_ID MATCHES "GNU")
  61. target_compile_options(${target} PRIVATE -Wall -Wextra -pedantic)
  62. elseif(MSVC)
  63. target_compile_options(${target} PRIVATE /W4 /w44062 /permissive-)
  64. target_compile_definitions(${target} PRIVATE _CRT_SECURE_NO_WARNINGS)
  65. if(CMAKE_GENERATOR MATCHES "Visual Studio")
  66. target_compile_options(${target} PRIVATE /MP)
  67. endif()
  68. endif()
  69. endif()
  70. if(RMLUI_WARNINGS_AS_ERRORS)
  71. if(NOT RMLUI_COMPILER_OPTIONS)
  72. message(FATAL_ERROR "Option RMLUI_WARNINGS_AS_ERRORS requires RMLUI_COMPILER_OPTIONS=ON.")
  73. endif()
  74. if(CMAKE_CXX_COMPILER_ID MATCHES "Clang" OR CMAKE_CXX_COMPILER_ID MATCHES "GNU")
  75. target_compile_options(${target} PRIVATE -Werror)
  76. elseif(MSVC)
  77. target_compile_options(${target} PRIVATE /WX)
  78. else()
  79. message(FATAL_ERROR "Unknown compiler, cannot enable option RMLUI_WARNINGS_AS_ERRORS.")
  80. endif()
  81. endif()
  82. endfunction()
  83. #[[
  84. Create installation rule for MSVC program database (PDB) files.
  85. Arguments:
  86. - target: The name of the target
  87. ]]
  88. function(install_target_pdb target)
  89. if(MSVC)
  90. if(BUILD_SHARED_LIBS)
  91. # The following only works for linker-generated PDBs, not compiler-generated PDBs produced in static builds.
  92. install(FILES "$<TARGET_PDB_FILE:${target}>"
  93. DESTINATION "${CMAKE_INSTALL_LIBDIR}"
  94. OPTIONAL
  95. )
  96. else()
  97. get_property(output_name TARGET ${target} PROPERTY OUTPUT_NAME)
  98. install(FILES "$<TARGET_FILE_DIR:${target}>/${output_name}.pdb"
  99. DESTINATION "${CMAKE_INSTALL_LIBDIR}"
  100. OPTIONAL
  101. )
  102. endif()
  103. endif()
  104. endfunction()
  105. #[[
  106. Create installation rules for sample targets.
  107. Arguments:
  108. - target: The name of the target
  109. ]]
  110. function(install_sample_target target)
  111. set(data_dirs "")
  112. foreach(dir IN ITEMS "data" "lua")
  113. if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/${dir}")
  114. list(APPEND data_dirs "${dir}")
  115. endif()
  116. endforeach()
  117. file(RELATIVE_PATH sample_path ${PROJECT_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR})
  118. install(TARGETS ${TARGET_NAME}
  119. ${RMLUI_RUNTIME_DEPENDENCY_SET_ARG}
  120. RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
  121. )
  122. set(install_dirs "src" ${data_dirs})
  123. install(DIRECTORY ${install_dirs}
  124. DESTINATION "${CMAKE_INSTALL_DATADIR}/${sample_path}"
  125. )
  126. # Set Emscripten-specific sample properties and assets.
  127. if(EMSCRIPTEN)
  128. # Make Emscripten generate the default HTML shell for the sample.
  129. set_property(TARGET ${target} PROPERTY SUFFIX ".html")
  130. # Enables Asyncify which we only need since the backend doesn't control the main loop. This enables us to yield
  131. # to the browser during the backend call to Backend::ProcessEvents(). Asyncify results in larger and slower
  132. # code, users are instead encouraged to use 'emscripten_set_main_loop()' and family.
  133. target_link_libraries(${target} PRIVATE "-sASYNCIFY")
  134. # We don't know the needed memory beforehand, allow it to grow.
  135. target_link_libraries(${target} PRIVATE "-sALLOW_MEMORY_GROWTH")
  136. # Add common assets.
  137. set(common_assets_dir "Samples/assets")
  138. target_link_libraries(${target} PRIVATE "--preload-file ${PROJECT_SOURCE_DIR}/${common_assets_dir}/@/${common_assets_dir}/")
  139. file(GLOB asset_files "${PROJECT_SOURCE_DIR}/${common_assets_dir}/*")
  140. # Add sample-specific assets.
  141. foreach(source_relative_dir IN LISTS data_dirs)
  142. set(abs_dir "${CMAKE_CURRENT_SOURCE_DIR}/${source_relative_dir}")
  143. file(RELATIVE_PATH root_relative_dir "${PROJECT_SOURCE_DIR}" "${abs_dir}")
  144. target_link_libraries(${target} PRIVATE "--preload-file ${abs_dir}/@/${root_relative_dir}/")
  145. file(GLOB sample_data_files "${abs_dir}/*")
  146. list(APPEND asset_files "${sample_data_files}")
  147. endforeach()
  148. # Add a linker dependency to all asset files, so that the linker runs again if any asset is modified.
  149. set_target_properties(${target} PROPERTIES LINK_DEPENDS "${asset_files}")
  150. endif()
  151. endfunction()
  152. #[[
  153. Enable or disable a given configuration type for multi-configuration generators.
  154. Arguments:
  155. - name: The name of the new configuration
  156. - clone_config: The name of the configuration to clone compile flags from
  157. - enable: Enable or disable configuration
  158. ]]
  159. function(enable_configuration_type name clone_config enable)
  160. if(CMAKE_CONFIGURATION_TYPES)
  161. string(TOUPPER "${name}" name_upper)
  162. string(TOUPPER "${clone_config}" clone_config_upper)
  163. if(enable)
  164. list(APPEND CMAKE_CONFIGURATION_TYPES "${name}")
  165. list(REMOVE_DUPLICATES CMAKE_CONFIGURATION_TYPES)
  166. set("CMAKE_MAP_IMPORTED_CONFIG_${name_upper}" "${name};${clone_config}" CACHE INTERNAL "" FORCE)
  167. set("CMAKE_C_FLAGS_${name_upper}" "${CMAKE_C_FLAGS_${clone_config_upper}}" CACHE INTERNAL "" FORCE)
  168. set("CMAKE_CXX_FLAGS_${name_upper}" "${CMAKE_CXX_FLAGS_${clone_config_upper}}" CACHE INTERNAL "" FORCE)
  169. set("CMAKE_EXE_LINKER_FLAGS_${name_upper}" "${CMAKE_EXE_LINKER_FLAGS_${clone_config_upper}}" CACHE INTERNAL "" FORCE)
  170. set("CMAKE_SHARED_LINKER_FLAGS_${name_upper}" "${CMAKE_SHARED_LINKER_FLAGS_${clone_config_upper}}" CACHE INTERNAL "" FORCE)
  171. else()
  172. list(REMOVE_ITEM CMAKE_CONFIGURATION_TYPES "${name}")
  173. endif()
  174. set(CMAKE_CONFIGURATION_TYPES "${CMAKE_CONFIGURATION_TYPES}" CACHE STRING "List of configurations to enable" FORCE)
  175. endif()
  176. endfunction()