]> git.xonotic.org Git - xonotic/darkplaces.git/blob - buildsys/module/FindSDL2.cmake
cmake: Initial working implementation of cmake build system
[xonotic/darkplaces.git] / buildsys / module / FindSDL2.cmake
1 # Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
2 # file Copyright.txt or https://cmake.org/licensing for details.
3
4 #  Copyright 2019 Amine Ben Hassouna <amine.benhassouna@gmail.com>
5 #  Copyright 2000-2019 Kitware, Inc. and Contributors
6 #  All rights reserved.
7
8 #  Redistribution and use in source and binary forms, with or without
9 #  modification, are permitted provided that the following conditions
10 #  are met:
11
12 #  * Redistributions of source code must retain the above copyright
13 #    notice, this list of conditions and the following disclaimer.
14
15 #  * Redistributions in binary form must reproduce the above copyright
16 #    notice, this list of conditions and the following disclaimer in the
17 #    documentation and/or other materials provided with the distribution.
18
19 #  * Neither the name of Kitware, Inc. nor the names of Contributors
20 #    may be used to endorse or promote products derived from this
21 #    software without specific prior written permission.
22
23 #  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
24 #  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
25 #  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
26 #  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
27 #  HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
28 #  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
29 #  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
30 #  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
31 #  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
32 #  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
33 #  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34
35 #[=======================================================================[.rst:
36 FindSDL2
37 --------
38
39 Locate SDL2 library
40
41 This module defines the following 'IMPORTED' targets:
42
43 ::
44
45   SDL2::Core
46     The SDL2 library, if found.
47     Libraries should link to SDL2::Core
48
49   SDL2::Main
50     The SDL2main library, if found.
51     Applications should link to SDL2::Main instead of SDL2::Core
52
53
54
55 This module will set the following variables in your project:
56
57 ::
58
59   SDL2_LIBRARIES, the name of the library to link against
60   SDL2_INCLUDE_DIRS, where to find SDL.h
61   SDL2_FOUND, if false, do not try to link to SDL2
62   SDL2MAIN_FOUND, if false, do not try to link to SDL2main
63   SDL2_VERSION_STRING, human-readable string containing the version of SDL2
64
65
66
67 This module responds to the following cache variables:
68
69 ::
70
71   SDL2_PATH
72     Set a custom SDL2 Library path (default: empty)
73
74   SDL2_NO_DEFAULT_PATH
75     Disable search SDL2 Library in default path.
76       If SDL2_PATH (default: ON)
77       Else (default: OFF)
78
79   SDL2_INCLUDE_DIR
80     SDL2 headers path.
81
82   SDL2_LIBRARY
83     SDL2 Library (.dll, .so, .a, etc) path.
84
85   SDL2MAIN_LIBRAY
86     SDL2main Library (.a) path.
87
88   SDL2_BUILDING_LIBRARY
89     This flag is useful only when linking to SDL2_LIBRARIES insead of
90     SDL2::Main. It is required only when building a library that links to
91     SDL2_LIBRARIES, because only applications need main() (No need to also
92     link to SDL2main).
93     If this flag is defined, then no SDL2main will be added to SDL2_LIBRARIES
94     and no SDL2::Main target will be created.
95
96
97 Don't forget to include SDLmain.h and SDLmain.m in your project for the
98 OS X framework based version. (Other versions link to -lSDL2main which
99 this module will try to find on your behalf.) Also for OS X, this
100 module will automatically add the -framework Cocoa on your behalf.
101
102
103 Additional Note: If you see an empty SDL2_LIBRARY in your project
104 configuration, it means CMake did not find your SDL2 library
105 (SDL2.dll, libsdl2.so, SDL2.framework, etc). Set SDL2_LIBRARY to point
106 to your SDL2 library, and  configure again. Similarly, if you see an
107 empty SDL2MAIN_LIBRARY, you should set this value as appropriate. These
108 values are used to generate the final SDL2_LIBRARIES variable and the
109 SDL2::Core and SDL2::Main targets, but when these values are unset,
110 SDL2_LIBRARIES, SDL2::Core and SDL2::Main does not get created.
111
112
113 $SDL2DIR is an environment variable that would correspond to the
114 ./configure --prefix=$SDL2DIR used in building SDL2.  l.e.galup 9-20-02
115
116
117
118 Created by Amine Ben Hassouna:
119   Adapt FindSDL.cmake to SDL2 (FindSDL2.cmake).
120   Add cache variables for more flexibility:
121     SDL2_PATH, SDL2_NO_DEFAULT_PATH (for details, see doc above).
122   Mark 'Threads' as a required dependency for non-OSX systems.
123   Modernize the FindSDL2.cmake module by creating specific targets:
124     SDL2::Core and SDL2::Main (for details, see doc above).
125
126
127 Original FindSDL.cmake module:
128   Modified by Eric Wing.  Added code to assist with automated building
129   by using environmental variables and providing a more
130   controlled/consistent search behavior.  Added new modifications to
131   recognize OS X frameworks and additional Unix paths (FreeBSD, etc).
132   Also corrected the header search path to follow "proper" SDL
133   guidelines.  Added a search for SDLmain which is needed by some
134   platforms.  Added a search for threads which is needed by some
135   platforms.  Added needed compile switches for MinGW.
136
137 On OSX, this will prefer the Framework version (if found) over others.
138 People will have to manually change the cache value of SDL2_LIBRARY to
139 override this selection or set the SDL2_PATH variable or the CMake
140 environment CMAKE_INCLUDE_PATH to modify the search paths.
141
142 Note that the header path has changed from SDL/SDL.h to just SDL.h
143 This needed to change because "proper" SDL convention is #include
144 "SDL.h", not <SDL/SDL.h>.  This is done for portability reasons
145 because not all systems place things in SDL/ (see FreeBSD).
146 #]=======================================================================]
147
148 # Define options for searching SDL2 Library in a custom path
149
150 set(SDL2_PATH "" CACHE STRING "Custom SDL2 Library path")
151
152 set(_SDL2_NO_DEFAULT_PATH OFF)
153 if(SDL2_PATH)
154         set(_SDL2_NO_DEFAULT_PATH ON)
155 endif()
156
157 set(SDL2_NO_DEFAULT_PATH ${_SDL2_NO_DEFAULT_PATH} CACHE BOOL "Disable search SDL2 Library in default path")
158 unset(_SDL2_NO_DEFAULT_PATH)
159
160 set(SDL2_NO_DEFAULT_PATH_CMD)
161 if(SDL2_NO_DEFAULT_PATH)
162         set(SDL2_NO_DEFAULT_PATH_CMD NO_DEFAULT_PATH)
163 endif()
164
165 # Search for the SDL2 include directory
166 find_path(SDL2_INCLUDE_DIR SDL.h
167           HINTS
168           ENV SDL2DIR
169           ${SDL2_NO_DEFAULT_PATH_CMD}
170           PATH_SUFFIXES SDL2 include/SDL2 include # path suffixes to search inside ENV{SDL2DIR}
171           PATHS ${SDL2_PATH}
172           DOC "Where the SDL2 headers can be found"
173 )
174
175 set(SDL2_INCLUDE_DIRS "${SDL2_INCLUDE_DIR}")
176
177 if(CMAKE_SIZEOF_VOID_P EQUAL 8)
178         set(VC_LIB_PATH_SUFFIX lib/x64)
179 else()
180         set(VC_LIB_PATH_SUFFIX lib/x86)
181 endif()
182
183 # SDL-2.0 is the name used by FreeBSD ports...
184 # don't confuse it for the version number.
185 find_library(SDL2_LIBRARY
186              NAMES SDL2 SDL-2.0
187              HINTS ENV SDL2DIR ${SDL2_NO_DEFAULT_PATH_CMD}
188              PATH_SUFFIXES lib ${VC_LIB_PATH_SUFFIX}
189              PATHS ${SDL2_PATH}
190              DOC "Where the SDL2 Library can be found"
191 )
192
193 find_library(SDL2_STATIC_LIBRARY
194              NAMES "${CMAKE_STATIC_LIBRARY_PREFIX}SDL2${CMAKE_STATIC_LIBRARY_SUFFIX}" "${CMAKE_STATIC_LIBRARY_PREFIX}SDL-2.0${CMAKE_STATIC_LIBRARY_SUFFIX}"
195              HINTS ENV SDL2DIR ${SDL2_NO_DEFAULT_PATH_CMD}
196              PATH_SUFFIXES lib ${VC_LIB_PATH_SUFFIX}
197              PATHS ${SDL2_PATH}
198              DOC "Where the static SDL2 Library can be found"
199 )
200
201 set(SDL2_LIBRARIES "${SDL2_LIBRARY}")
202
203 if(NOT SDL2_BUILDING_LIBRARY)
204         if(NOT SDL2_INCLUDE_DIR MATCHES ".framework")
205                 # Non-OS X framework versions expect you to also dynamically link to
206                 # SDL2main. This is mainly for Windows and OS X. Other (Unix) platforms
207                 # seem to provide SDL2main for compatibility even though they don't
208                 # necessarily need it.
209
210                 if(SDL2_PATH)
211                         set(SDL2MAIN_LIBRARY_PATHS "${SDL2_PATH}")
212                 endif()
213
214                 if(NOT SDL2_NO_DEFAULT_PATH)
215                         set(SDL2MAIN_LIBRARY_PATHS
216                             /sw
217                             /opt/local
218                             /opt/csw
219                             /opt
220                             "${SDL2MAIN_LIBRARY_PATHS}"
221                         )
222                 endif()
223
224                 find_library(SDL2MAIN_LIBRARY
225                              NAMES SDL2main
226                              HINTS ENV SDL2DIR ${SDL2_NO_DEFAULT_PATH_CMD}
227                              PATH_SUFFIXES lib ${VC_LIB_PATH_SUFFIX}
228                              PATHS ${SDL2MAIN_LIBRARY_PATHS}
229                              DOC "Where the SDL2main library can be found"
230                 )
231                 unset(SDL2MAIN_LIBRARY_PATHS)
232         endif()
233 endif()
234
235 # SDL2 may require threads on your system.
236 # The Apple build may not need an explicit flag because one of the
237 # frameworks may already provide it.
238 # But for non-OSX systems, I will use the CMake Threads package.
239 if(NOT APPLE)
240         find_package(Threads QUIET)
241         if(NOT Threads_FOUND)
242                 set(SDL2_THREADS_NOT_FOUND "Could NOT find Threads (Threads is required by SDL2).")
243                 if(SDL2_FIND_REQUIRED)
244                         message(FATAL_ERROR ${SDL2_THREADS_NOT_FOUND})
245                 else()
246                         if(NOT SDL2_FIND_QUIETLY)
247                                 message(STATUS ${SDL2_THREADS_NOT_FOUND})
248                         endif()
249                         return()
250                 endif()
251                 unset(SDL2_THREADS_NOT_FOUND)
252         endif()
253 endif()
254
255 # MinGW needs an additional link flag, -mwindows
256 # It's total link flags should look like -lmingw32 -lSDL2main -lSDL2 -mwindows
257 if(MINGW)
258         set(MINGW32_LIBRARY mingw32 "-mwindows" CACHE STRING "link flags for MinGW")
259 endif()
260
261 if(SDL2_LIBRARY)
262         # For SDL2main
263         if(SDL2MAIN_LIBRARY AND NOT SDL2_BUILDING_LIBRARY)
264                 list(FIND SDL2_LIBRARIES "${SDL2MAIN_LIBRARY}" _SDL2_MAIN_INDEX)
265                 if(_SDL2_MAIN_INDEX EQUAL -1)
266                         set(SDL2_LIBRARIES "${SDL2MAIN_LIBRARY}" ${SDL2_LIBRARIES})
267                 endif()
268                 unset(_SDL2_MAIN_INDEX)
269         endif()
270
271         # For OS X, SDL2 uses Cocoa as a backend so it must link to Cocoa.
272         # CMake doesn't display the -framework Cocoa string in the UI even
273         # though it actually is there if I modify a pre-used variable.
274         # I think it has something to do with the CACHE STRING.
275         # So I use a temporary variable until the end so I can set the
276         # "real" variable in one-shot.
277         if(APPLE)
278                 set(SDL2_LIBRARIES ${SDL2_LIBRARIES} -framework Cocoa)
279         endif()
280
281         # For threads, as mentioned Apple doesn't need this.
282         # In fact, there seems to be a problem if I used the Threads package
283         # and try using this line, so I'm just skipping it entirely for OS X.
284         if(NOT APPLE)
285                 set(SDL2_LIBRARIES ${SDL2_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT})
286         endif()
287
288         # For MinGW library
289         if(MINGW)
290                 set(SDL2_LIBRARIES ${MINGW32_LIBRARY} ${SDL2_LIBRARIES})
291         endif()
292
293 endif()
294
295 # Read SDL2 version
296 if(SDL2_INCLUDE_DIR AND EXISTS "${SDL2_INCLUDE_DIR}/SDL_version.h")
297         file(STRINGS "${SDL2_INCLUDE_DIR}/SDL_version.h" SDL2_VERSION_MAJOR_LINE REGEX "^#define[ \t]+SDL_MAJOR_VERSION[ \t]+[0-9]+$")
298         file(STRINGS "${SDL2_INCLUDE_DIR}/SDL_version.h" SDL2_VERSION_MINOR_LINE REGEX "^#define[ \t]+SDL_MINOR_VERSION[ \t]+[0-9]+$")
299         file(STRINGS "${SDL2_INCLUDE_DIR}/SDL_version.h" SDL2_VERSION_PATCH_LINE REGEX "^#define[ \t]+SDL_PATCHLEVEL[ \t]+[0-9]+$")
300         string(REGEX REPLACE "^#define[ \t]+SDL_MAJOR_VERSION[ \t]+([0-9]+)$" "\\1" SDL2_VERSION_MAJOR "${SDL2_VERSION_MAJOR_LINE}")
301         string(REGEX REPLACE "^#define[ \t]+SDL_MINOR_VERSION[ \t]+([0-9]+)$" "\\1" SDL2_VERSION_MINOR "${SDL2_VERSION_MINOR_LINE}")
302         string(REGEX REPLACE "^#define[ \t]+SDL_PATCHLEVEL[ \t]+([0-9]+)$" "\\1" SDL2_VERSION_PATCH "${SDL2_VERSION_PATCH_LINE}")
303         set(SDL2_VERSION_STRING ${SDL2_VERSION_MAJOR}.${SDL2_VERSION_MINOR}.${SDL2_VERSION_PATCH})
304         unset(SDL2_VERSION_MAJOR_LINE)
305         unset(SDL2_VERSION_MINOR_LINE)
306         unset(SDL2_VERSION_PATCH_LINE)
307         unset(SDL2_VERSION_MAJOR)
308         unset(SDL2_VERSION_MINOR)
309         unset(SDL2_VERSION_PATCH)
310 endif()
311
312 include(FindPackageHandleStandardArgs)
313
314 FIND_PACKAGE_HANDLE_STANDARD_ARGS(SDL2
315                                   REQUIRED_VARS SDL2_LIBRARY SDL2_INCLUDE_DIR
316                                   VERSION_VAR SDL2_VERSION_STRING)
317
318 if(SDL2MAIN_LIBRARY)
319         FIND_PACKAGE_HANDLE_STANDARD_ARGS(SDL2main
320                                           REQUIRED_VARS SDL2MAIN_LIBRARY SDL2_INCLUDE_DIR
321                                           VERSION_VAR SDL2_VERSION_STRING)
322 endif()
323
324 if(SDL2_STATIC_LIBRARY)
325         FIND_PACKAGE_HANDLE_STANDARD_ARGS(SDL2_static
326                                           REQUIRED_VARS SDL2_STATIC_LIBRARY SDL2_INCLUDE_DIR
327                                           VERSION_VAR SDL2_VERSION_STRING)
328 endif()
329
330 mark_as_advanced(SDL2_PATH
331                  SDL2_NO_DEFAULT_PATH
332                  SDL2_LIBRARY
333                  SDL2MAIN_LIBRARY
334                  SDL2_STATIC_LIBRARY
335                  SDL2_INCLUDE_DIR
336                  SDL2_BUILDING_LIBRARY
337 )
338
339 # SDL2:: targets (SDL2::Core and SDL2::Main)
340 if(SDL2_FOUND)
341
342         # SDL2::Core target
343         if(SDL2_LIBRARY AND NOT TARGET SDL2::Core)
344                 add_library(SDL2::Core UNKNOWN IMPORTED)
345                 set_target_properties(SDL2::Core PROPERTIES
346                                       IMPORTED_LOCATION "${SDL2_LIBRARY}"
347                                       INTERFACE_INCLUDE_DIRECTORIES "${SDL2_INCLUDE_DIR}")
348
349                 if(APPLE)
350                         # For OS X, SDL2 uses Cocoa as a backend so it must link to Cocoa.
351                         # For more details, please see above.
352                         set_property(TARGET SDL2::Core APPEND PROPERTY
353                                      INTERFACE_LINK_OPTIONS -framework Cocoa)
354                 else()
355                         # For threads, as mentioned Apple doesn't need this.
356                         # For more details, please see above.
357                         set_property(TARGET SDL2::Core APPEND PROPERTY
358                                      INTERFACE_LINK_LIBRARIES Threads::Threads)
359                 endif()
360         endif()
361
362         if(PKG_CONFIG_FOUND AND SDL2_STATIC_LIBRARY AND NOT TARGET SDL2::CoreStatic)
363                 add_library(SDL2::CoreStatic UNKNOWN IMPORTED)
364                 set_target_properties(SDL2::CoreStatic PROPERTIES
365                                       IMPORTED_LOCATION "${SDL2_STATIC_LIBRARY}"
366                                       INTERFACE_INCLUDE_DIRECTORIES "${SDL2_INCLUDE_DIR}")
367         endif()
368         # SDL2::Main target
369         # Applications should link to SDL2::Main instead of SDL2::Core
370         # For more details, please see above.
371         if(NOT SDL2_BUILDING_LIBRARY AND NOT TARGET SDL2::Main)
372
373                 if(SDL2_INCLUDE_DIR MATCHES ".framework" OR NOT SDL2MAIN_LIBRARY)
374                         add_library(SDL2::Main INTERFACE IMPORTED)
375                         set_property(TARGET SDL2::Main PROPERTY
376                                      INTERFACE_LINK_LIBRARIES SDL2::Core)
377                 elseif(SDL2MAIN_LIBRARY)
378                         # MinGW requires that the mingw32 library is specified before the
379                         # libSDL2main.a static library when linking.
380                         # The SDL2::MainInternal target is used internally to make sure that
381                         # CMake respects this condition.
382                         add_library(SDL2::MainInternal UNKNOWN IMPORTED)
383                         set_property(TARGET SDL2::MainInternal PROPERTY
384                                      IMPORTED_LOCATION "${SDL2MAIN_LIBRARY}")
385                         set_property(TARGET SDL2::MainInternal PROPERTY
386                                      INTERFACE_LINK_LIBRARIES SDL2::Core)
387
388                         add_library(SDL2::Main INTERFACE IMPORTED)
389
390                         if(MINGW)
391                                 # MinGW needs an additional link flag '-mwindows' and link to mingw32
392                                 set_property(TARGET SDL2::Main PROPERTY
393                                              INTERFACE_LINK_LIBRARIES "mingw32" "-mwindows")
394                         endif()
395
396                         set_property(TARGET SDL2::Main APPEND PROPERTY
397                                      INTERFACE_LINK_LIBRARIES SDL2::MainInternal)
398                 endif()
399         endif()
400 endif()