CMake: iOS support added
authorDavid Ludwig <dludwig@pobox.com>
Tue, 27 Aug 2019 11:07:43 -0400
changeset 130836d31d5218c2c
parent 13082 f77988be3607
child 13084 c3880ebab198
CMake: iOS support added

When using a recent version of CMake (3.14+), this should make it possible to:
- build SDL for iOS, both static and dynamic
- build SDL test apps (as iOS .app bundles)
- generate a working SDL_config.h for iOS (using SDL_config.h.cmake as a basis)

To use, set the following CMake variables when running CMake's configuration stage:
- CMAKE_SYSTEM_NAME=iOS
- CMAKE_OSX_SYSROOT=<SDK> (examples: iphoneos, iphonesimulator, iphoneos12.4, /full/path/to/iPhoneOS.sdk, etc.)
- CMAKE_OSX_ARCHITECTURES=<semicolon-separated list of CPU architectures> (example: "arm64;armv7s")

Examples:
- for Simulator, using the latest, installed SDK:
cmake path/to/SDL -DCMAKE_SYSTEM_NAME=iOS -DCMAKE_OSX_SYSROOT=iphonesimulator -DCMAKE_OSX_ARCHITECTURES=x86_64

- for Device, using the latest, installed SDK, 64-bit only
cmake path/to/SDL -DCMAKE_SYSTEM_NAME=iOS -DCMAKE_OSX_SYSROOT=iphoneos -DCMAKE_OSX_ARCHITECTURES=arm64

- for Device, using the latest, installed SDK, mixed 32/64 bit
cmake path/to/SDL -DCMAKE_SYSTEM_NAME=iOS -DCMAKE_OSX_SYSROOT=iphoneos -DCMAKE_OSX_ARCHITECTURES="arm64;armv7s"

- for Device, using a specific SDK revision (iOS 12.4, in this example):
cmake path/to/SDL -DCMAKE_SYSTEM_NAME=iOS -DCMAKE_OSX_SYSROOT=iphoneos12.4 -DCMAKE_OSX_ARCHITECTURES=arm64

- for Simulator, using the latest, installed SDK, and building SDL test apps (as .app bundles):
cmake path/to/SDL -DSDL_TEST=1 -DCMAKE_SYSTEM_NAME=iOS -DCMAKE_OSX_SYSROOT=iphonesimulator -DCMAKE_OSX_ARCHITECTURES=x86_64
CMakeLists.txt
include/SDL_config.h.cmake
test/CMakeLists.txt
     1.1 --- a/CMakeLists.txt	Wed May 15 19:54:36 2019 +0800
     1.2 +++ b/CMakeLists.txt	Tue Aug 27 11:07:43 2019 -0400
     1.3 @@ -1453,6 +1453,7 @@
     1.4      set(SDL_FRAMEWORK_COCOA 1)
     1.5      set(SDL_FRAMEWORK_CARBON 1)
     1.6    endif()
     1.7 +  set(SDL_FRAMEWORK_FOUNDATION 1)
     1.8  
     1.9    # Requires the darwin file implementation
    1.10    if(SDL_FILE)
    1.11 @@ -1476,6 +1477,7 @@
    1.12      set(HAVE_SDL_AUDIO TRUE)
    1.13      set(SDL_FRAMEWORK_COREAUDIO 1)
    1.14      set(SDL_FRAMEWORK_AUDIOTOOLBOX 1)
    1.15 +    set(SDL_FRAMEWORK_AVFOUNDATION 1)
    1.16    endif()
    1.17  
    1.18    if(SDL_JOYSTICK)
    1.19 @@ -1483,43 +1485,49 @@
    1.20      if(HAVE_HIDAPI)
    1.21        if(IOS)
    1.22          set(SOURCE_FILES ${SOURCE_FILES} ${SDL2_SOURCE_DIR}/src/hidapi/ios/hid.m)
    1.23 +        set(SDL_FRAMEWORK_COREBLUETOOTH 1)
    1.24        endif()
    1.25      endif()
    1.26 -    set(SDL_JOYSTICK_IOKIT 1)
    1.27      if (IOS)
    1.28        file(GLOB JOYSTICK_SOURCES ${SDL2_SOURCE_DIR}/src/joystick/iphoneos/*.m ${SDL2_SOURCE_DIR}/src/joystick/steam/*.c)
    1.29 +      set(SDL_JOYSTICK_MFI 1)
    1.30 +      set(SDL_FRAMEWORK_COREMOTION 1)
    1.31 +      set(SDL_FRAMEWORK_GAMECONTROLLER 1)
    1.32 +      set(HAVE_SDL_SENSORS 1)
    1.33      else()
    1.34        file(GLOB JOYSTICK_SOURCES ${SDL2_SOURCE_DIR}/src/joystick/darwin/*.c)
    1.35 +      set(SDL_JOYSTICK_IOKIT 1)
    1.36 +      set(SDL_FRAMEWORK_IOKIT 1)
    1.37 +      set(SDL_FRAMEWORK_FF 1)
    1.38      endif()
    1.39      set(SOURCE_FILES ${SOURCE_FILES} ${JOYSTICK_SOURCES})
    1.40      set(HAVE_SDL_JOYSTICK TRUE)
    1.41 -    set(SDL_FRAMEWORK_IOKIT 1)
    1.42 -    set(SDL_FRAMEWORK_FF 1)
    1.43    endif()
    1.44  
    1.45    if(SDL_HAPTIC)
    1.46 -    set(SDL_HAPTIC_IOKIT 1)
    1.47      if (IOS)
    1.48        file(GLOB HAPTIC_SOURCES ${SDL2_SOURCE_DIR}/src/haptic/dummy/*.c)
    1.49        set(SDL_HAPTIC_DUMMY 1)
    1.50      else()
    1.51        file(GLOB HAPTIC_SOURCES ${SDL2_SOURCE_DIR}/src/haptic/darwin/*.c)
    1.52 +      set(SDL_HAPTIC_IOKIT 1)
    1.53 +      set(SDL_FRAMEWORK_IOKIT 1)
    1.54 +      set(SDL_FRAMEWORK_FF 1)
    1.55      endif()
    1.56      set(SOURCE_FILES ${SOURCE_FILES} ${HAPTIC_SOURCES})
    1.57      set(HAVE_SDL_HAPTIC TRUE)
    1.58 -    set(SDL_FRAMEWORK_IOKIT 1)
    1.59 -    set(SDL_FRAMEWORK_FF 1)
    1.60      if(NOT SDL_JOYSTICK)
    1.61        message(FATAL_ERROR "SDL_HAPTIC requires SDL_JOYSTICK to be enabled")
    1.62      endif()
    1.63    endif()
    1.64  
    1.65    if(SDL_POWER)
    1.66 -    set(SDL_POWER_MACOSX 1)
    1.67      if (IOS)
    1.68        file(GLOB POWER_SOURCES ${SDL2_SOURCE_DIR}/src/power/uikit/*.m)
    1.69 +      set(SDL_POWER_UIKIT 1)
    1.70      else()
    1.71        file(GLOB POWER_SOURCES ${SDL2_SOURCE_DIR}/src/power/macosx/*.c)
    1.72 +      set(SDL_POWER_MACOSX 1)
    1.73      endif()
    1.74      set(SOURCE_FILES ${SOURCE_FILES} ${POWER_SOURCES})
    1.75      set(HAVE_SDL_POWER TRUE)
    1.76 @@ -1542,10 +1550,24 @@
    1.77      set(HAVE_SDL_FILESYSTEM TRUE)
    1.78    endif()
    1.79  
    1.80 +  if(SDL_SENSOR)
    1.81 +    if(IOS)
    1.82 +      set(SDL_SENSOR_COREMOTION 1)
    1.83 +      set(HAVE_SDL_SENSORS TRUE)
    1.84 +      file(GLOB SENSOR_SOURCES ${SDL2_SOURCE_DIR}/src/sensor/coremotion/*.m)
    1.85 +      set(SOURCE_FILES ${SOURCE_FILES} ${SENSOR_SOURCES})
    1.86 +    endif()
    1.87 +  endif()
    1.88 +
    1.89    # iOS hack needed - http://code.google.com/p/ios-cmake/ ?
    1.90    if(SDL_VIDEO)
    1.91      if (IOS)
    1.92        set(SDL_VIDEO_DRIVER_UIKIT 1)
    1.93 +      set(SDL_FRAMEWORK_COREGRAPHICS 1)
    1.94 +      set(SDL_FRAMEWORK_QUARTZCORE 1)
    1.95 +      set(SDL_FRAMEWORK_UIKIT 1)
    1.96 +      set(SDL_IPHONE_KEYBOARD 1)
    1.97 +      set(SDL_IPHONE_LAUNCHSCREEN 1)
    1.98        file(GLOB UIKITVIDEO_SOURCES ${SDL2_SOURCE_DIR}/src/video/uikit/*.m)
    1.99        set(SOURCE_FILES ${SOURCE_FILES} ${UIKITVIDEO_SOURCES})
   1.100      else()
   1.101 @@ -1556,15 +1578,21 @@
   1.102          set(SDL_VIDEO_RENDER_OGL 1)
   1.103          set(HAVE_VIDEO_OPENGL TRUE)
   1.104        endif()
   1.105 +    endif()
   1.106  
   1.107 -      if(VIDEO_OPENGLES)
   1.108 +    if(VIDEO_OPENGLES)
   1.109 +      if(IOS)
   1.110 +        set(SDL_FRAMEWORK_OPENGLES 1)
   1.111 +        set(SDL_VIDEO_OPENGL_ES 1)
   1.112 +        set(SDL_VIDEO_RENDER_OGL_ES 1)
   1.113 +      else()
   1.114          set(SDL_VIDEO_OPENGL_EGL 1)
   1.115 -        set(SDL_VIDEO_OPENGL_ES2 1)
   1.116 -        set(SDL_VIDEO_RENDER_OGL_ES2 1)
   1.117 -        set(HAVE_VIDEO_OPENGLES TRUE)
   1.118        endif()
   1.119 +      set(SDL_VIDEO_OPENGL_ES2 1)
   1.120 +      set(SDL_VIDEO_RENDER_OGL_ES2 1)
   1.121 +      set(HAVE_VIDEO_OPENGLES TRUE)
   1.122      endif()
   1.123 -    
   1.124 +
   1.125      if(VIDEO_VULKAN OR VIDEO_METAL OR RENDER_METAL)
   1.126        set(ORIG_CMAKE_REQUIRED_FLAGS ${CMAKE_REQUIRED_FLAGS})
   1.127        set(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} -x objective-c")
   1.128 @@ -1634,6 +1662,30 @@
   1.129      find_library(AUDIOTOOLBOX AudioToolbox)
   1.130      list(APPEND EXTRA_LIBS ${AUDIOTOOLBOX})
   1.131    endif()
   1.132 +  if(SDL_FRAMEWORK_AVFOUNDATION)
   1.133 +    find_library(AVFOUNDATION AVFoundation)
   1.134 +    list(APPEND EXTRA_LIBS ${AVFOUNDATION})
   1.135 +  endif()
   1.136 +  if(SDL_FRAMEWORK_COREBLUETOOTH)
   1.137 +    find_library(COREBLUETOOTH CoreBluetooth)
   1.138 +    list(APPEND EXTRA_LIBS ${COREBLUETOOTH})
   1.139 +  endif()
   1.140 +  if(SDL_FRAMEWORK_COREGRAPHICS)
   1.141 +    find_library(COREGRAPHICS CoreGraphics)
   1.142 +    list(APPEND EXTRA_LIBS ${COREGRAPHICS})
   1.143 +  endif()
   1.144 +  if(SDL_FRAMEWORK_COREMOTION)
   1.145 +    find_library(COREMOTION CoreMotion)
   1.146 +    list(APPEND EXTRA_LIBS ${COREMOTION})
   1.147 +  endif()
   1.148 +  if(SDL_FRAMEWORK_FOUNDATION)
   1.149 +    find_library(FOUNDATION Foundation)
   1.150 +    list(APPEND EXTRA_LIBS ${FOUNDATION})
   1.151 +  endif()
   1.152 +  if(SDL_FRAMEWORK_GAMECONTROLLER)
   1.153 +    find_library(GAMECONTROLLER GameController)
   1.154 +    list(APPEND EXTRA_LIBS ${GAMECONTROLLER})
   1.155 +  endif()
   1.156    if(SDL_FRAMEWORK_METAL)
   1.157      if(IOS)
   1.158        find_library(METAL Metal)
   1.159 @@ -1642,6 +1694,10 @@
   1.160        list(APPEND EXTRA_LDFLAGS "-Wl,-weak_framework,Metal")
   1.161      endif()
   1.162    endif()
   1.163 +  if(SDL_FRAMEWORK_OPENGLES)
   1.164 +    find_library(OPENGLES OpenGLES)
   1.165 +    list(APPEND EXTRA_LIBS ${OPENGLES})
   1.166 +  endif()
   1.167    if(SDL_FRAMEWORK_QUARTZCORE)
   1.168      if(IOS)
   1.169        find_library(QUARTZCORE QuartzCore)
   1.170 @@ -1650,6 +1706,10 @@
   1.171        list(APPEND EXTRA_LDFLAGS "-Wl,-weak_framework,QuartzCore")
   1.172      endif()
   1.173    endif()
   1.174 +  if(SDL_FRAMEWORK_UIKIT)
   1.175 +    find_library(UIKIT UIKit)
   1.176 +    list(APPEND EXTRA_LIBS ${UIKIT})
   1.177 +  endif()
   1.178  
   1.179    CheckPTHREAD()
   1.180  
   1.181 @@ -1900,6 +1960,10 @@
   1.182    if (NOT ANDROID)
   1.183      set_target_properties(SDL2 PROPERTIES DEBUG_POSTFIX ${SDL_CMAKE_DEBUG_POSTFIX})
   1.184    endif()
   1.185 +  if(IOS)
   1.186 +    set_property(TARGET SDL2 APPEND_STRING PROPERTY COMPILE_FLAGS "-fobjc-arc")
   1.187 +    target_compile_definitions(SDL2 PRIVATE IOS_DYLIB=1)
   1.188 +  endif()
   1.189  endif()
   1.190  
   1.191  if(ANDROID)
   1.192 @@ -1942,6 +2006,9 @@
   1.193    if (NOT ANDROID)
   1.194      set_target_properties(SDL2-static PROPERTIES DEBUG_POSTFIX ${SDL_CMAKE_DEBUG_POSTFIX})
   1.195    endif()
   1.196 +  if(IOS)
   1.197 +    set_property(TARGET SDL2-static APPEND_STRING PROPERTY COMPILE_FLAGS "-fobjc-arc")
   1.198 +  endif()
   1.199  endif()
   1.200  
   1.201  ##### Tests #####
     2.1 --- a/include/SDL_config.h.cmake	Wed May 15 19:54:36 2019 +0800
     2.2 +++ b/include/SDL_config.h.cmake	Tue Aug 27 11:07:43 2019 -0400
     2.3 @@ -298,6 +298,7 @@
     2.4  
     2.5  /* Enable various sensor drivers */
     2.6  #cmakedefine SDL_SENSOR_ANDROID @SDL_SENSOR_ANDROID@
     2.7 +#cmakedefine SDL_SENSOR_COREMOTION @SDL_SENSOR_COREMOTION@
     2.8  #cmakedefine SDL_SENSOR_DUMMY @SDL_SENSOR_DUMMY@
     2.9  
    2.10  /* Enable various shared object loading systems */
    2.11 @@ -323,6 +324,7 @@
    2.12  #cmakedefine SDL_VIDEO_DRIVER_ANDROID @SDL_VIDEO_DRIVER_ANDROID@
    2.13  #cmakedefine SDL_VIDEO_DRIVER_HAIKU @SDL_VIDEO_DRIVER_HAIKU@
    2.14  #cmakedefine SDL_VIDEO_DRIVER_COCOA @SDL_VIDEO_DRIVER_COCOA@
    2.15 +#cmakedefine SDL_VIDEO_DRIVER_UIKIT @SDL_VIDEO_DRIVER_UIKIT@
    2.16  #cmakedefine SDL_VIDEO_DRIVER_DIRECTFB @SDL_VIDEO_DRIVER_DIRECTFB@
    2.17  #cmakedefine SDL_VIDEO_DRIVER_DIRECTFB_DYNAMIC @SDL_VIDEO_DRIVER_DIRECTFB_DYNAMIC@
    2.18  #cmakedefine SDL_VIDEO_DRIVER_DUMMY @SDL_VIDEO_DRIVER_DUMMY@
    2.19 @@ -396,6 +398,7 @@
    2.20  #cmakedefine SDL_POWER_LINUX @SDL_POWER_LINUX@
    2.21  #cmakedefine SDL_POWER_WINDOWS @SDL_POWER_WINDOWS@
    2.22  #cmakedefine SDL_POWER_MACOSX @SDL_POWER_MACOSX@
    2.23 +#cmakedefine SDL_POWER_UIKIT @SDL_POWER_UIKIT@
    2.24  #cmakedefine SDL_POWER_HAIKU @SDL_POWER_HAIKU@
    2.25  #cmakedefine SDL_POWER_EMSCRIPTEN @SDL_POWER_EMSCRIPTEN@
    2.26  #cmakedefine SDL_POWER_HARDWIRED @SDL_POWER_HARDWIRED@
    2.27 @@ -417,6 +420,9 @@
    2.28  #cmakedefine SDL_LIBSAMPLERATE_DYNAMIC @SDL_LIBSAMPLERATE_DYNAMIC@
    2.29  
    2.30  /* Platform specific definitions */
    2.31 +#cmakedefine SDL_IPHONE_KEYBOARD @SDL_IPHONE_KEYBOARD@
    2.32 +#cmakedefine SDL_IPHONE_LAUNCHSCREEN @SDL_IPHONE_LAUNCHSCREEN@
    2.33 +
    2.34  #if !defined(__WIN32__)
    2.35  #  if !defined(_STDINT_H_) && !defined(_STDINT_H) && !defined(HAVE_STDINT_H) && !defined(_HAVE_STDINT_H)
    2.36  typedef unsigned int size_t;
     3.1 --- a/test/CMakeLists.txt	Wed May 15 19:54:36 2019 +0800
     3.2 +++ b/test/CMakeLists.txt	Tue Aug 27 11:07:43 2019 -0400
     3.3 @@ -101,22 +101,52 @@
     3.4  file(COPY ${RESOURCE_FILES} DESTINATION ${CMAKE_CURRENT_BINARY_DIR})
     3.5  
     3.6  # TODO: Might be easier to make all targets depend on the resources...?
     3.7 -add_dependencies(testscale SDL2_test_resoureces)
     3.8 -add_dependencies(testrendercopyex SDL2_test_resoureces)
     3.9 -add_dependencies(controllermap SDL2_test_resoureces)
    3.10 -add_dependencies(testyuv SDL2_test_resoureces)
    3.11 -add_dependencies(testgamecontroller SDL2_test_resoureces)
    3.12 -add_dependencies(testshape SDL2_test_resoureces)
    3.13 -add_dependencies(testshader SDL2_test_resoureces)
    3.14 -add_dependencies(testnative SDL2_test_resoureces)
    3.15 -add_dependencies(testspriteminimal SDL2_test_resoureces)
    3.16 -add_dependencies(testautomation SDL2_test_resoureces)
    3.17 -add_dependencies(testcustomcursor SDL2_test_resoureces)
    3.18 -add_dependencies(testrendertarget SDL2_test_resoureces)
    3.19 -add_dependencies(testsprite2 SDL2_test_resoureces)
    3.20  
    3.21 -add_dependencies(loopwave SDL2_test_resoureces)
    3.22 -add_dependencies(loopwavequeue SDL2_test_resoureces)
    3.23 -add_dependencies(testresample SDL2_test_resoureces)
    3.24 -add_dependencies(testaudiohotplug SDL2_test_resoureces)
    3.25 -add_dependencies(testmultiaudio SDL2_test_resoureces)
    3.26 +set(NEEDS_RESOURCES
    3.27 +    testscale
    3.28 +    testrendercopyex
    3.29 +    controllermap
    3.30 +    testyuv
    3.31 +    testgamecontroller
    3.32 +    testshape
    3.33 +    testshader
    3.34 +    testnative
    3.35 +    testspriteminimal
    3.36 +    testautomation
    3.37 +    testcustomcursor
    3.38 +    testrendertarget
    3.39 +    testsprite2
    3.40 +    loopwave
    3.41 +    loopwavequeue
    3.42 +    testresample
    3.43 +    testaudiohotplug
    3.44 +    testmultiaudio
    3.45 +)
    3.46 +foreach(APP IN LISTS NEEDS_RESOURCES)
    3.47 +    add_dependencies(${APP} SDL2_test_resoureces)
    3.48 +    if(APPLE)
    3.49 +        # Make sure resource files get installed into macOS/iOS .app bundles.  
    3.50 +        target_sources(${APP} PRIVATE "${RESOURCE_FILES}")
    3.51 +        set_target_properties(${APP} PROPERTIES RESOURCE "${RESOURCE_FILES}")
    3.52 +    endif()
    3.53 +endforeach()
    3.54 +
    3.55 +# Set Apple App ID / Bundle ID.  This is needed to launch apps on some Apple
    3.56 +# platforms (iOS, for example).
    3.57 +if(APPLE)
    3.58 +    if(${CMAKE_VERSION} VERSION_LESS "3.7.0")
    3.59 +        # CMake's 'BUILDSYSTEM_TARGETS' property is only available in
    3.60 +        # CMake 3.7 and above.
    3.61 +        message(WARNING "Unable to set Bundle ID for Apple .app builds due to old CMake (pre 3.7).")
    3.62 +    else()
    3.63 +        get_property(TARGETS DIRECTORY ${CMAKE_CURRENT_LIST_DIR} PROPERTY BUILDSYSTEM_TARGETS)
    3.64 +        foreach(CURRENT_TARGET IN LISTS TARGETS)
    3.65 +            get_property(TARGET_TYPE TARGET ${CURRENT_TARGET} PROPERTY TYPE)
    3.66 +            if(TARGET_TYPE STREQUAL "EXECUTABLE")
    3.67 +                set_target_properties("${CURRENT_TARGET}" PROPERTIES
    3.68 +                    MACOSX_BUNDLE_GUI_IDENTIFIER "org.libsdl.${CURRENT_TARGET}"
    3.69 +                )
    3.70 +            endif()
    3.71 +        endforeach()
    3.72 +    endif()
    3.73 +endif()