cmake_minimum_required(VERSION 3.16) # set the output directory for built objects. # This makes sure that the dynamic library goes into the build directory automatically. set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/$") set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/$") # prevent installing to system directories. set(CMAKE_INSTALL_PREFIX "${CMAKE_BINARY_DIR}" CACHE INTERNAL "") # Declare the project project(sdl-min) if ((APPLE AND NOT CMAKE_SYSTEM_NAME MATCHES "Darwin") OR EMSCRIPTEN) set(BUILD_SHARED_LIBS OFF CACHE INTERNAL "") # Disable shared builds on platforms where it does not make sense to use them set(SDL_SHARED OFF) else() set(SDL_SHARED ON) endif() if(MSVC) if(NOT CMAKE_GENERATOR STREQUAL "Ninja") add_definitions(/MP) # parallelize each target, unless Ninja is the generator endif() endif() # Set the name of the executable set(EXECUTABLE_NAME ${PROJECT_NAME}) # Create an executable or a shared library based on the platform and add our sources to it if (ANDROID) # The SDL java code is hardcoded to load libmain.so on android, so we need to change EXECUTABLE_NAME set(EXECUTABLE_NAME main) add_library(${EXECUTABLE_NAME} SHARED) else() add_executable(${EXECUTABLE_NAME}) endif() # Add your sources to the target target_sources(${EXECUTABLE_NAME} PRIVATE src/main.cpp src/assets/iosLaunchScreen.storyboard ) # What is iosLaunchScreen.storyboard? This file describes what Apple's mobile platforms # should show the user while the application is starting up. If you don't include one, # then you get placed in a compatibility mode that does not allow HighDPI. # This file is referenced inside Info.plist.in, where it is marked as the launch screen file. # It is also ignored on non-Apple platforms. # To get an app icon on Apple platforms, add it to your executable. # Afterward, the image file in Info.plist.in. if(APPLE) target_sources("${EXECUTABLE_NAME}" PRIVATE "src/logo.png") endif() # Set C++ version target_compile_features(${EXECUTABLE_NAME} PUBLIC cxx_std_20) # on Web targets, we need CMake to generate a HTML webpage. if(EMSCRIPTEN) set(CMAKE_EXECUTABLE_SUFFIX ".html" CACHE INTERNAL "") endif() # Configure SDL by calling its CMake file. # we use EXCLUDE_FROM_ALL so that its install targets and configs don't # pollute upwards into our configuration. add_subdirectory(SDL EXCLUDE_FROM_ALL) # If you don't want SDL_ttf, then remove this section. set(SDLTTF_VENDORED ON) # tell SDL_ttf to build its own dependencies add_subdirectory(SDL_ttf EXCLUDE_FROM_ALL) # SDL_mixer (used for playing audio) set(SDLMIXER_MIDI_NATIVE OFF) # disable formats we don't use to make the build faster and smaller. Also some of these don't work on all platforms so you'll need to do some experimentation. set(SDLMIXER_GME OFF) set(SDLMIXER_WAVPACK OFF) set(SDLMIXER_MOD OFF) set(SDLMIXER_OPUS OFF) set(SDLMIXER_VENDORED ON) # tell SDL_mixer to build its own dependencies add_subdirectory(SDL_mixer EXCLUDE_FROM_ALL) # SDL_image (used for loading various image formats) set(SDLIMAGE_VENDORED ON) set(SDLIMAGE_AVIF OFF) # disable formats we don't use to make the build faster and smaller. set(SDLIMAGE_BMP OFF) set(SDLIMAGE_JPEG OFF) set(SDLIMAGE_WEBP OFF) add_subdirectory(SDL_image EXCLUDE_FROM_ALL) # Link SDL to our executable. This also makes its include directory available to us. target_link_libraries(${EXECUTABLE_NAME} PUBLIC SDL3_ttf::SDL3_ttf # remove if you are not using SDL_ttf SDL3_mixer::SDL3_mixer # remove if you are not using SDL_mixer SDL3_image::SDL3_image # remove if you are not using SDL_image SDL3::SDL3 # If using satelite libraries, SDL must be the last item in the list. ) # SDL_Image bug: https://github.com/libsdl-org/SDL_image/issues/506 if (APPLE AND NOT BUILD_SHARED_LIBS) find_library(IO_LIB ImageIO REQUIRED) find_library(CS_LIB CoreServices REQUIRED) find_library(CT_LIB CoreText REQUIRED) find_library(CG_LIB CoreGraphics REQUIRED) find_library(CF_LIB CoreFoundation REQUIRED) target_link_libraries(${EXECUTABLE_NAME} PUBLIC ${CF_LIB} ${CT_LIB} ${IO_LIB} ${CS_LIB} ${CG_LIB}) endif() target_compile_definitions(${EXECUTABLE_NAME} PUBLIC SDL_MAIN_USE_CALLBACKS) # Dealing with assets # We have some non-code resources that our application needs in order to work. How we deal with those differs per platform. if (APPLE) # on Apple targets, the application bundle has a "resources" subfolder where we can place our assets. # SDL_GetBasePath() gives us easy access to that location. set(input_root "${CMAKE_CURRENT_LIST_DIR}/src") macro(add_resource FILE) file(RELATIVE_PATH relpath "${input_root}" "${FILE}") get_filename_component(relpath "${relpath}" DIRECTORY) target_sources(${EXECUTABLE_NAME} PRIVATE ${FILE}) set_property(SOURCE ${FILE} PROPERTY MACOSX_PACKAGE_LOCATION "Resources/${relpath}") endmacro() add_resource("${CMAKE_CURRENT_LIST_DIR}/src/Inter-VariableFont.ttf") add_resource("${CMAKE_CURRENT_LIST_DIR}/src/the_entertainer.ogg") add_resource("${CMAKE_CURRENT_LIST_DIR}/src/gs_tiger.svg") elseif(EMSCRIPTEN) # on the web, we have to put the files inside of the webassembly # somewhat unintuitively, this is done via a linker argument. target_link_libraries(${EXECUTABLE_NAME} PRIVATE "--preload-file \"${CMAKE_CURRENT_LIST_DIR}/src/Inter-VariableFont.ttf@/\"" "--preload-file \"${CMAKE_CURRENT_LIST_DIR}/src/the_entertainer.ogg@/\"" "--preload-file \"${CMAKE_CURRENT_LIST_DIR}/src/gs_tiger.svg@/\"" ) else() if (ANDROID) file(MAKE_DIRECTORY "${MOBILE_ASSETS_DIR}") # we need to create the project Assets dir otherwise CMake won't copy our assets. endif() macro(copy_helper filename) if (ANDROID) # MOBILE_ASSETS_DIR is set in the gradle file via the cmake command line and points to the Android Studio Assets folder. # when we copy assets there, the Android build pipeline knows to add them to the apk. set(outname "${MOBILE_ASSETS_DIR}/${filename}") else() # for platforms that do not have a good packaging format, all we can do is copy the assets to the process working directory. set(outname "${CMAKE_BINARY_DIR}/$/${filename}") endif() add_custom_command(POST_BUILD TARGET "${EXECUTABLE_NAME}" COMMAND ${CMAKE_COMMAND} -E copy_if_different "${CMAKE_CURRENT_LIST_DIR}/src/${filename}" "${outname}" DEPENDS "${filename}" ) endmacro() copy_helper("assets/Inter-VariableFont.ttf") copy_helper("assets/MartianMono-VariableFont.ttf") copy_helper("assets/sunset_on_the_beach.ogg") copy_helper("assets/success.ogg") copy_helper("assets/failure.ogg") copy_helper("assets/gs_tiger.svg") endif() # set some extra configs for each platform set_target_properties(${EXECUTABLE_NAME} PROPERTIES # On macOS, make a proper .app bundle instead of a bare executable MACOSX_BUNDLE TRUE # Set the Info.plist file for Apple Mobile platforms. Without this file, your app # will not launch. MACOSX_BUNDLE_INFO_PLIST "${CMAKE_CURRENT_SOURCE_DIR}/src/Info.plist.in" # in Xcode, create a Scheme in the schemes dropdown for the app. XCODE_GENERATE_SCHEME TRUE # Identification for Xcode XCODE_ATTRIBUTE_BUNDLE_IDENTIFIER "com.ravbug.sdl3-sample" XCODE_ATTRIBUTE_PRODUCT_BUNDLE_IDENTIFIER "com.ravbug.sdl3-sample" XCODE_ATTRIBUTE_CURRENTYEAR "${CURRENTYEAR}" ) # on Visual Studio, set our app as the default project set_property(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} PROPERTY VS_STARTUP_PROJECT "${EXECUTABLE_NAME}") # On macOS Platforms, ensure that the bundle is valid for distribution by calling fixup_bundle. # note that fixup_bundle does not work on iOS, so you will want to use static libraries # or manually copy dylibs and set rpaths if(CMAKE_SYSTEM_NAME MATCHES "Darwin") # tell Install about the target, otherwise fixup won't know about the transitive dependencies install(TARGETS ${EXECUTABLE_NAME} BUNDLE DESTINATION ./install COMPONENT Runtime RUNTIME DESTINATION ./install/bin COMPONENT Runtime ) set(DEP_DIR "${CMAKE_BINARY_DIR}") # where to look for dependencies when fixing up INSTALL(CODE "include(BundleUtilities) fixup_bundle(\"$\" \"\" \"${DEP_DIR}\") " ) set(CPACK_GENERATOR "DragNDrop") include(CPack) endif()