DependenciesForBackends.cmake 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169
  1. #[[
  2. Set up external dependencies required by the built-in backends.
  3. All dependencies are searched as soft dependencies so that they won't error out if the library is declared by other
  4. means. This file is not meant to be used by consumers of the library, only by the RmlUi CMake project.
  5. ]]
  6. # --- Window/input APIs ---
  7. # SDL
  8. if(RMLUI_BACKEND MATCHES "^SDL")
  9. # Although the official CMake find module is called FindSDL.cmake, the official config module provided by the SDL
  10. # package for its version 2 is called SDL2Config.cmake. Following this trend, the official SDL config files change
  11. # their name according to their major version number
  12. find_package("SDL2")
  13. #[[
  14. Current code operates using a hybrid mode by detecting either the variable or the target due to the possibility
  15. of package managers such as Conan and vcpkg of setting up SDL in their own way but always following the target
  16. naming conventions of the official SDL config files.
  17. ]]
  18. if(NOT TARGET SDL2::SDL2 AND NOT SDL2_FOUND)
  19. report_dependency_not_found("SDL2" SDL2::SDL2)
  20. endif()
  21. # Set up the detected SDL as the SDL2::SDL2 INTERFACE target if it hasn't already been created. This is done for
  22. # consistent referencing across the CMake code regardless of the CMake version used.
  23. if(NOT TARGET SDL2::SDL2)
  24. add_library(SDL2::SDL2 INTERFACE IMPORTED)
  25. set_target_properties(SDL2::SDL2 PROPERTIES
  26. INTERFACE_LINK_LIBRARIES "${SDL2_LIBRARIES}"
  27. INTERFACE_INCLUDE_DIRECTORIES "${SDL2_INCLUDE_DIRS}"
  28. )
  29. endif()
  30. # SDL_GL2 backend requires GLEW
  31. if(RMLUI_BACKEND STREQUAL "SDL_GL2" AND NOT TARGET GLEW::GLEW)
  32. find_package(GLEW)
  33. if(NOT TARGET GLEW::GLEW)
  34. report_dependency_not_found("GLEW" GLEW::GLEW)
  35. endif()
  36. endif()
  37. # Check version requirement for the SDL renderer
  38. if(RMLUI_BACKEND STREQUAL "SDL_SDLrenderer" AND SDL2_VERSION VERSION_LESS "2.0.20")
  39. message(FATAL_ERROR "SDL native renderer backend (${RMLUI_BACKEND}) requires SDL 2.0.20 (found ${SDL2_VERSION}).")
  40. endif()
  41. # List of SDL backends that require SDL_image to work with samples
  42. set(RMLUI_SDL_BACKENDS_WITH_SDLIMAGE "SDL_GL2" "SDL_GL3" "SDL_SDLrenderer")
  43. # Determine if the selected SDL backend requires SDL_image
  44. if(RMLUI_BACKEND IN_LIST RMLUI_SDL_BACKENDS_WITH_SDLIMAGE)
  45. set(RMLUI_SDLIMAGE_REQUIRED TRUE)
  46. else()
  47. set(RMLUI_SDLIMAGE_REQUIRED FALSE)
  48. endif()
  49. unset(RMLUI_SDL_BACKENDS_WITH_SDLIMAGE)
  50. # Require SDL_image if needed
  51. if(RMLUI_SDLIMAGE_REQUIRED)
  52. find_package("SDL2_image")
  53. report_dependency_found_or_error("SDL2_image" SDL2_image::SDL2_image)
  54. endif()
  55. endif()
  56. # GLFW
  57. if(RMLUI_BACKEND MATCHES "^GLFW")
  58. find_package("glfw3" "3.3")
  59. # Instead of relying on the <package_name>_FOUND variable, we check directly for the target
  60. if(NOT TARGET glfw)
  61. report_dependency_found_or_error("GLFW" glfw)
  62. endif()
  63. endif()
  64. # SFML
  65. if(RMLUI_BACKEND MATCHES "^SFML")
  66. #[[
  67. Starting with SFML 2.7, the recommended method to find the library is using
  68. the official config file which sets up targets for each module of the library.
  69. The names of the targets follow the namespaced target names convention.
  70. When one of the required modules isn't present as a SFML::<module> target,
  71. that means SFML < 2.7 is being used and we need to set up the target(s) by ourselves.
  72. In SFML 2.5 the first iteration of the SFMLConfig.cmake file was introduced, which
  73. uses a target-oriented approach to exposing the different modules of SFML but it doesn't
  74. use the same names as the config file from SFML 2.7.
  75. ]]
  76. # List of required components in capital case
  77. set(RMLUI_SFML_REQUIRED_COMPONENTS "Graphics" "Window" "System")
  78. # Run find package with component names both capitalized and lower-cased
  79. find_package("SFML" "2" COMPONENTS ${RMLUI_SFML_REQUIRED_COMPONENTS} QUIET)
  80. if(NOT SFML_FOUND)
  81. list(TRANSFORM RMLUI_SFML_REQUIRED_COMPONENTS TOLOWER OUTPUT_VARIABLE RMLUI_SFML_REQUIRED_COMPONENTS_LOWER_CASE)
  82. find_package("SFML" "2" COMPONENTS ${RMLUI_SFML_REQUIRED_COMPONENTS_LOWER_CASE} QUIET)
  83. endif()
  84. # Since we are using find_package() in basic mode, we can check the _FOUND variable
  85. if(NOT SFML_FOUND)
  86. report_dependency_not_found("SFML" SFML::SFML)
  87. endif()
  88. #[[
  89. Since the RmlUi CMake project uses the SFML 2.7 namespaced target names, if the version is lower wrappers
  90. need to be set up.
  91. Because we always require the window module, we can use it to determine which iteration of the config.
  92. ]]
  93. # If any of the mandatory SFML 2.7 targets isn't present, assume SFML < 2.7 has been found and set up wrappers
  94. if(NOT TARGET SFML::Window)
  95. #[[
  96. If sfml-window exists, then that means the version is either SFML 2.5 or 2.6 which set up
  97. module-specific CMake targets but with different names using a config file.
  98. Therefore, we need to alias the target names to match those declared by SFML 2.7 and used by RmlUi.
  99. ]]
  100. # For each SFML component the project requires
  101. foreach(rmlui_sfml_component ${RMLUI_SFML_REQUIRED_COMPONENTS})
  102. # Make the component name lowercase
  103. string(TOLOWER ${rmlui_sfml_component} rmlui_sfml_component_lower)
  104. if(TARGET sfml-${rmlui_sfml_component_lower})
  105. #[[
  106. RMLUI_CMAKE_MINIMUM_VERSION_RAISE_NOTICE:
  107. Because the target CMake version is 3.10, we can't alias non-global targets nor global imported targets.
  108. Promoting an imported target to the global scope without it being necessary can cause undesired behavior,
  109. specially when the project is consumed as a subdirectory inside another CMake project, therefore is not
  110. recommended. Instead of that, we pseudo-alias the target creating a second INTERFACE target with alias name.
  111. More info: https://cmake.org/cmake/help/latest/command/add_library.html#alias-libraries
  112. ]]
  113. # If the target exists, alias it
  114. add_library(SFML::${rmlui_sfml_component} INTERFACE IMPORTED)
  115. target_link_libraries(SFML::${rmlui_sfml_component} INTERFACE sfml-${rmlui_sfml_component_lower})
  116. endif()
  117. endforeach()
  118. endif()
  119. endif()
  120. # X11
  121. if(RMLUI_BACKEND MATCHES "^X11")
  122. find_package("X11")
  123. endif()
  124. # --- Rendering APIs ---
  125. # OpenGL
  126. # Set preferred OpenGL ABI on Linux for target OpenGL::GL
  127. # More info: https://cmake.org/cmake/help/latest/module/FindOpenGL.html#linux-specific
  128. # RMLUI_CMAKE_MINIMUM_VERSION_RAISE_NOTICE:
  129. # Can remove this with CMake 3.11 as this has become the default. See policy CMP0072.
  130. set(OpenGL_GL_PREFERENCE "GLVND")
  131. if(RMLUI_BACKEND MATCHES "GL2$")
  132. find_package("OpenGL" "2")
  133. report_dependency_found_or_error("OpenGL" OpenGL::GL)
  134. endif()
  135. if(RMLUI_BACKEND MATCHES "GL3$")
  136. find_package("OpenGL" "3")
  137. report_dependency_found_or_error("OpenGL" OpenGL::GL)
  138. endif()