1
0

FindSDL.cmake 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310
  1. # Distributed under the OSI-approved BSD 3-Clause License. See accompanying
  2. # file LICENSE.rst or https://cmake.org/licensing for details.
  3. #[=======================================================================[.rst:
  4. FindSDL
  5. -------
  6. Finds the SDL (Simple DirectMedia Layer) library:
  7. .. code-block:: cmake
  8. find_package(SDL [<version>] [...])
  9. SDL is a cross-platform library for developing multimedia software, such as
  10. games and emulators.
  11. .. note::
  12. This module is specifically intended for SDL version 1. Starting with version
  13. 2, SDL provides a CMake package configuration file when built with CMake and
  14. should be found using ``find_package(SDL2)``. Similarly, SDL version 3 can be
  15. found using ``find_package(SDL3)``. These newer versions provide separate
  16. :ref:`Imported Targets` that encapsulate usage requirements. Refer to the
  17. official SDL documentation for more information.
  18. Note that the include path for the SDL header has changed in recent SDL 1
  19. versions from ``SDL/SDL.h`` to simply ``SDL.h``. This change aligns with SDL's
  20. convention of using ``#include "SDL.h"`` for portability, as not all systems
  21. install the headers in a ``SDL/`` subdirectory (e.g., FreeBSD).
  22. When targeting macOS and using the SDL framework, be sure to include both
  23. ``SDLmain.h`` and ``SDLmain.m`` in the project. For other platforms, the
  24. ``SDLmain`` library is typically linked using ``-lSDLmain``, which this module
  25. will attempt to locate automatically. Additionally, for macOS, this module will
  26. add the ``-framework Cocoa`` flag as needed.
  27. Imported Targets
  28. ^^^^^^^^^^^^^^^^
  29. This module provides the following :ref:`Imported Targets`:
  30. ``SDL::SDL``
  31. .. versionadded:: 3.19
  32. Target encapsulating the SDL library usage requirements, available if SDL is
  33. found.
  34. Result Variables
  35. ^^^^^^^^^^^^^^^^
  36. This module defines the following variables:
  37. ``SDL_FOUND``
  38. Boolean indicating whether the (requested version of) SDL is found.
  39. ``SDL_VERSION``
  40. .. versionadded:: 3.19
  41. The human-readable string containing the version of SDL found.
  42. ``SDL_VERSION_MAJOR``
  43. .. versionadded:: 3.19
  44. The major version of SDL found.
  45. ``SDL_VERSION_MINOR``
  46. .. versionadded:: 3.19
  47. The minor version of SDL found.
  48. ``SDL_VERSION_PATCH``
  49. .. versionadded:: 3.19
  50. The patch version of SDL found.
  51. ``SDL_INCLUDE_DIRS``
  52. .. versionadded:: 3.19
  53. Include directories needed to use SDL.
  54. ``SDL_LIBRARIES``
  55. .. versionadded:: 3.19
  56. Libraries needed to link against to use SDL.
  57. Cache Variables
  58. ^^^^^^^^^^^^^^^
  59. These variables may optionally be set to help this module find the correct
  60. files:
  61. ``SDL_INCLUDE_DIR``
  62. The directory containing the ``SDL.h`` header file.
  63. ``SDL_LIBRARY``
  64. A list of libraries containing the path to the SDL library and libraries
  65. needed to link against to use SDL.
  66. Hints
  67. ^^^^^
  68. This module accepts the following variables:
  69. ``SDL_BUILDING_LIBRARY``
  70. When set to boolean true, the ``SDL_main`` library will be excluded from
  71. linking, as it is not required when building the SDL library itself (only
  72. applications need ``main()`` function). If not set, this module assumes an
  73. application is being built and attempts to locate and include the appropriate
  74. ``SDL_main`` link flags in the returned ``SDL_LIBRARY`` variable.
  75. ``SDLDIR``
  76. Environment variable that can be set to help locate an SDL library installed
  77. in a custom location. It should point to the installation destination that
  78. was used when configuring, building, and installing SDL library:
  79. ``./configure --prefix=$SDLDIR``.
  80. On macOS, setting this variable will prefer the Framework version (if found)
  81. over others. In this case, the cache value of ``SDL_LIBRARY`` would need to
  82. be manually changed to override this selection or set the
  83. :variable:`CMAKE_INCLUDE_PATH` variable to modify the search paths.
  84. Troubleshooting
  85. ^^^^^^^^^^^^^^^
  86. In case the SDL library is not found automatically, the ``SDL_LIBRARY_TEMP``
  87. variable may be empty, and ``SDL_LIBRARY`` will not be set. This typically
  88. means that CMake could not locate the SDL library (e.g., ``SDL.dll``,
  89. ``libSDL.so``, ``SDL.framework``, etc.). To resolve this, manually set
  90. ``SDL_LIBRARY_TEMP`` to the correct path and reconfigure the project.
  91. Similarly, if ``SDLMAIN_LIBRARY`` is unset, it may also need to be specified
  92. manually. These variables are used to construct the final ``SDL_LIBRARY``
  93. value. If they are not set, ``SDL_LIBRARY`` will remain undefined.
  94. Deprecated Variables
  95. ^^^^^^^^^^^^^^^^^^^^
  96. The following variables are provided for backward compatibility:
  97. ``SDL_VERSION_STRING``
  98. .. deprecated:: 3.19
  99. Superseded by the ``SDL_VERSION`` with the same value.
  100. The human-readable string containing the version of SDL if found.
  101. Examples
  102. ^^^^^^^^
  103. Finding SDL library and linking it to a project target:
  104. .. code-block:: cmake
  105. find_package(SDL)
  106. target_link_libraries(project_target PRIVATE SDL::SDL)
  107. When working with SDL version 2, the upstream package provides the
  108. ``SDL2::SDL2`` imported target directly. It can be used in a project without
  109. using this module:
  110. .. code-block:: cmake
  111. find_package(SDL2)
  112. target_link_libraries(project_target PRIVATE SDL2::SDL2)
  113. Similarly, for SDL version 3:
  114. .. code-block:: cmake
  115. find_package(SDL3)
  116. target_link_libraries(project_target PRIVATE SDL3::SDL3)
  117. See Also
  118. ^^^^^^^^
  119. * The :module:`FindSDL_gfx` module to find the SDL_gfx library.
  120. * The :module:`FindSDL_image` module to find the SDL_image library.
  121. * The :module:`FindSDL_mixer` module to find the SDL_mixer library.
  122. * The :module:`FindSDL_net` module to find the SDL_net library.
  123. * The :module:`FindSDL_sound` module to find the SDL_sound library.
  124. * The :module:`FindSDL_ttf` module to find the SDL_ttf library.
  125. #]=======================================================================]
  126. cmake_policy(PUSH)
  127. cmake_policy(SET CMP0159 NEW) # file(STRINGS) with REGEX updates CMAKE_MATCH_<n>
  128. find_path(SDL_INCLUDE_DIR SDL.h
  129. HINTS
  130. ENV SDLDIR
  131. PATH_SUFFIXES SDL SDL12 SDL11
  132. # path suffixes to search inside ENV{SDLDIR}
  133. include/SDL include/SDL12 include/SDL11 include
  134. )
  135. if(CMAKE_SIZEOF_VOID_P EQUAL 8)
  136. set(VC_LIB_PATH_SUFFIX lib/x64)
  137. else()
  138. set(VC_LIB_PATH_SUFFIX lib/x86)
  139. endif()
  140. # SDL-1.1 is the name used by FreeBSD ports...
  141. # don't confuse it for the version number.
  142. find_library(SDL_LIBRARY_TEMP
  143. NAMES SDL SDL-1.1
  144. HINTS
  145. ENV SDLDIR
  146. PATH_SUFFIXES lib ${VC_LIB_PATH_SUFFIX}
  147. )
  148. # Hide this cache variable from the user, it's an internal implementation
  149. # detail. The documented library variable for the user is SDL_LIBRARY
  150. # which is derived from SDL_LIBRARY_TEMP further below.
  151. set_property(CACHE SDL_LIBRARY_TEMP PROPERTY TYPE INTERNAL)
  152. if(NOT SDL_BUILDING_LIBRARY)
  153. if(NOT SDL_INCLUDE_DIR MATCHES ".framework")
  154. # Non-OS X framework versions expect you to also dynamically link to
  155. # SDLmain. This is mainly for Windows and OS X. Other (Unix) platforms
  156. # seem to provide SDLmain for compatibility even though they don't
  157. # necessarily need it.
  158. find_library(SDLMAIN_LIBRARY
  159. NAMES SDLmain SDLmain-1.1
  160. HINTS
  161. ENV SDLDIR
  162. PATH_SUFFIXES lib ${VC_LIB_PATH_SUFFIX}
  163. PATHS
  164. /opt
  165. )
  166. endif()
  167. endif()
  168. # SDL may require threads on your system.
  169. # The Apple build may not need an explicit flag because one of the
  170. # frameworks may already provide it.
  171. # But for non-OSX systems, I will use the CMake Threads package.
  172. if(NOT APPLE)
  173. find_package(Threads)
  174. endif()
  175. # MinGW needs an additional link flag, -mwindows
  176. # It's total link flags should look like -lmingw32 -lSDLmain -lSDL -mwindows
  177. if(MINGW)
  178. set(MINGW32_LIBRARY mingw32 "-mwindows" CACHE STRING "link flags for MinGW")
  179. endif()
  180. if(SDL_LIBRARY_TEMP)
  181. # For SDLmain
  182. if(SDLMAIN_LIBRARY AND NOT SDL_BUILDING_LIBRARY)
  183. list(FIND SDL_LIBRARY_TEMP "${SDLMAIN_LIBRARY}" _SDL_MAIN_INDEX)
  184. if(_SDL_MAIN_INDEX EQUAL -1)
  185. set(SDL_LIBRARY_TEMP "${SDLMAIN_LIBRARY}" ${SDL_LIBRARY_TEMP})
  186. endif()
  187. unset(_SDL_MAIN_INDEX)
  188. endif()
  189. # For OS X, SDL uses Cocoa as a backend so it must link to Cocoa.
  190. # CMake doesn't display the -framework Cocoa string in the UI even
  191. # though it actually is there if I modify a preused variable.
  192. # I think it has something to do with the CACHE STRING.
  193. # So I use a temporary variable until the end so I can set the
  194. # "real" variable in one-shot.
  195. if(APPLE)
  196. set(SDL_LIBRARY_TEMP ${SDL_LIBRARY_TEMP} "-framework Cocoa")
  197. endif()
  198. # For threads, as mentioned Apple doesn't need this.
  199. # In fact, there seems to be a problem if I used the Threads package
  200. # and try using this line, so I'm just skipping it entirely for OS X.
  201. if(NOT APPLE)
  202. set(SDL_LIBRARY_TEMP ${SDL_LIBRARY_TEMP} ${CMAKE_THREAD_LIBS_INIT})
  203. endif()
  204. # For MinGW library
  205. if(MINGW)
  206. set(SDL_LIBRARY_TEMP ${MINGW32_LIBRARY} ${SDL_LIBRARY_TEMP})
  207. endif()
  208. # Set the final string here so the GUI reflects the final state.
  209. set(SDL_LIBRARY ${SDL_LIBRARY_TEMP} CACHE STRING "Where the SDL Library can be found")
  210. endif()
  211. if(SDL_INCLUDE_DIR AND EXISTS "${SDL_INCLUDE_DIR}/SDL_version.h")
  212. file(STRINGS "${SDL_INCLUDE_DIR}/SDL_version.h" SDL_VERSION_MAJOR_LINE REGEX "^#define[ \t]+SDL_MAJOR_VERSION[ \t]+[0-9]+$")
  213. file(STRINGS "${SDL_INCLUDE_DIR}/SDL_version.h" SDL_VERSION_MINOR_LINE REGEX "^#define[ \t]+SDL_MINOR_VERSION[ \t]+[0-9]+$")
  214. file(STRINGS "${SDL_INCLUDE_DIR}/SDL_version.h" SDL_VERSION_PATCH_LINE REGEX "^#define[ \t]+SDL_PATCHLEVEL[ \t]+[0-9]+$")
  215. string(REGEX REPLACE "^#define[ \t]+SDL_MAJOR_VERSION[ \t]+([0-9]+)$" "\\1" SDL_VERSION_MAJOR "${SDL_VERSION_MAJOR_LINE}")
  216. string(REGEX REPLACE "^#define[ \t]+SDL_MINOR_VERSION[ \t]+([0-9]+)$" "\\1" SDL_VERSION_MINOR "${SDL_VERSION_MINOR_LINE}")
  217. string(REGEX REPLACE "^#define[ \t]+SDL_PATCHLEVEL[ \t]+([0-9]+)$" "\\1" SDL_VERSION_PATCH "${SDL_VERSION_PATCH_LINE}")
  218. unset(SDL_VERSION_MAJOR_LINE)
  219. unset(SDL_VERSION_MINOR_LINE)
  220. unset(SDL_VERSION_PATCH_LINE)
  221. set(SDL_VERSION ${SDL_VERSION_MAJOR}.${SDL_VERSION_MINOR}.${SDL_VERSION_PATCH})
  222. set(SDL_VERSION_STRING ${SDL_VERSION})
  223. endif()
  224. include(FindPackageHandleStandardArgs)
  225. find_package_handle_standard_args(SDL
  226. REQUIRED_VARS SDL_LIBRARY SDL_INCLUDE_DIR
  227. VERSION_VAR SDL_VERSION)
  228. if(SDL_FOUND)
  229. set(SDL_LIBRARIES ${SDL_LIBRARY})
  230. set(SDL_INCLUDE_DIRS ${SDL_INCLUDE_DIR})
  231. if(NOT TARGET SDL::SDL)
  232. add_library(SDL::SDL INTERFACE IMPORTED)
  233. set_target_properties(SDL::SDL PROPERTIES
  234. INTERFACE_INCLUDE_DIRECTORIES "${SDL_INCLUDE_DIR}"
  235. INTERFACE_LINK_LIBRARIES "${SDL_LIBRARY}")
  236. endif()
  237. endif()
  238. cmake_policy(POP)