Files
kichikuou_system3-sdl2/CMakeLists.txt
T
kichikuou 981c302dfc Migrate Android from SDL2 to SDL3
Make SDL3 the default and only supported SDL version for Android. Download
the official SDL3 Android AAR during Gradle configuration and expose it to
the native CMake build through Prefab. SDL_ttf 3 is built from source with
HarfBuzz and PlutoSVG disabled.
2026-09-16 09:24:40 +09:00

339 lines
11 KiB
CMake

cmake_minimum_required(VERSION 3.14)
# Enable CMAKE_MSVC_RUNTIME_LIBRARY, requires CMake >=3.15
if (POLICY CMP0091)
cmake_policy(SET CMP0091 NEW)
endif ()
project(System3 LANGUAGES CXX)
set(CMAKE_CXX_STANDARD 17)
include(CTest)
if (ANDROID)
set(_SYSTEM3_DEFAULT_SDL_VERSION "3")
else()
set(_SYSTEM3_DEFAULT_SDL_VERSION "2")
endif()
set(SYSTEM3_SDL_VERSION "${_SYSTEM3_DEFAULT_SDL_VERSION}" CACHE STRING
"SDL major version (2 or 3)")
set_property(CACHE SYSTEM3_SDL_VERSION PROPERTY STRINGS 2 3)
if (NOT SYSTEM3_SDL_VERSION STREQUAL "2" AND
NOT SYSTEM3_SDL_VERSION STREQUAL "3")
message(FATAL_ERROR "SYSTEM3_SDL_VERSION must be 2 or 3")
endif()
add_library(system3_sdl INTERFACE)
target_compile_definitions(system3_sdl INTERFACE
SYSTEM3_SDL_VERSION=${SYSTEM3_SDL_VERSION})
if (SYSTEM3_SDL_VERSION STREQUAL "2")
set(SYSTEM3_AUDIO_BACKEND src/generic/mako.cpp)
else()
set(SYSTEM3_AUDIO_BACKEND src/generic/mako_sdl3.cpp)
endif()
# Generates a static library from pkg_check_modules() result
function(add_static_library name pkg)
add_library(${name} INTERFACE)
set_target_properties(${name}
PROPERTIES
INTERFACE_INCLUDE_DIRECTORIES "${${pkg}_STATIC_INCLUDE_DIRS}"
INTERFACE_COMPILE_OPTIONS "${${pkg}_STATIC_CFLAGS_OTHER}"
INTERFACE_LINK_LIBRARIES "${${pkg}_STATIC_LIBRARIES}"
INTERFACE_LINK_OPTIONS "${${pkg}_STATIC_LDFLAGS_OTHER}")
endfunction()
if (MSVC)
# Use statically-linked runtime library.
set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>")
option(BUILD_SHARED_LIBS "Build as shared library" OFF)
endif ()
add_library(ymfm
deps/ymfm/src/ymfm_opn.cpp
deps/ymfm/src/ymfm_adpcm.cpp
deps/ymfm/src/ymfm_ssg.cpp)
target_include_directories(ymfm PUBLIC deps/ymfm/src)
# Suppress false-positive -Warray-bounds in ymfm_fm.ipp.
if (NOT MSVC)
target_compile_options(ymfm PRIVATE -Wno-array-bounds)
endif()
if (ANDROID)
if (NOT SYSTEM3_SDL_VERSION STREQUAL "3")
message(FATAL_ERROR "Android supports SDL3 only")
endif()
add_library(system3 SHARED)
target_sources(system3 PRIVATE
src/android/nact_android.cpp
${SYSTEM3_AUDIO_BACKEND}
)
find_library(ndk_log log)
target_link_libraries(system3_sdl INTERFACE SDL3::SDL3 SDL3_ttf::SDL3_ttf)
target_link_libraries(system3 PRIVATE ymfm ${ndk_log})
elseif (EMSCRIPTEN)
option(JSPI "Use JavaScript Promise Integration instead of Asyncify" OFF)
add_executable(system3)
target_sources(system3 PRIVATE
src/emscripten/nact_emscripten.cpp
src/emscripten/mako.cpp
)
set(LIBS
-sUSE_SDL=${SYSTEM3_SDL_VERSION}
-sUSE_SDL_TTF=${SYSTEM3_SDL_VERSION})
if (SYSTEM3_SDL_VERSION STREQUAL "3")
list(APPEND LIBS -Wno-experimental)
endif()
target_compile_options(system3_sdl INTERFACE ${LIBS})
target_link_options(system3_sdl INTERFACE ${LIBS})
target_link_libraries(system3 PRIVATE idbfs.js ymfm)
# Without optimizations, Asyncify generates very large code.
list(APPEND CMAKE_EXE_LINKER_FLAGS_DEBUG "-O1")
if (JSPI)
target_link_options(system3 PRIVATE -sJSPI)
else()
target_link_options(system3 PRIVATE
-sASYNCIFY=1
-sASYNCIFY_IGNORE_INDIRECT=1
-sASYNCIFY_REMOVE=SDL_Delay
"-sASYNCIFY_ADD=NACT::execute()"
)
endif()
target_link_options(system3 PRIVATE
-sENVIRONMENT=web
-sMODULARIZE=1
-sEXPORT_ES6=1
-sALLOW_MEMORY_GROWTH=1
-sNO_EXIT_RUNTIME=1
-sEXPORTED_FUNCTIONS=_main,_malloc
-sEXPORTED_RUNTIME_METHODS=FS,IDBFS,HEAPU8,HEAP16,getValue,addRunDependency,removeRunDependency,stringToUTF8OnStack
--emit-tsd=system3.d.ts
)
else() # NOT (ANDROID OR EMSCRIPTEN)
add_executable(system3)
target_link_libraries(system3 PRIVATE ymfm)
if (MSVC)
include(FetchContent)
if (SYSTEM3_SDL_VERSION STREQUAL "2")
FetchContent_Declare(sdl
URL https://github.com/libsdl-org/SDL/releases/download/release-2.32.10/SDL2-devel-2.32.10-VC.zip
URL_HASH SHA1=27f5179346a0b0db80c4dd1769c7c9d62b9a91f3)
FetchContent_MakeAvailable(sdl)
find_package(SDL2 REQUIRED CONFIG PATHS ${sdl_SOURCE_DIR}/cmake NO_DEFAULT_PATH)
set(SDL_TARGET SDL2::SDL2)
set(SDL_MAIN_TARGET SDL2::SDL2main)
FetchContent_Declare(sdl_ttf
URL https://github.com/libsdl-org/SDL_ttf/releases/download/release-2.24.0/SDL2_ttf-devel-2.24.0-VC.zip
URL_HASH SHA1=2d18b9a4fc2ec0eee80de2a946b088d4e6efd0ee)
FetchContent_MakeAvailable(sdl_ttf)
find_package(SDL2_ttf REQUIRED CONFIG PATHS ${sdl_ttf_SOURCE_DIR}/cmake NO_DEFAULT_PATH)
set(SDL_TTF_TARGET SDL2_ttf::SDL2_ttf)
else()
FetchContent_Declare(sdl
URL https://github.com/libsdl-org/SDL/releases/download/release-3.4.16/SDL3-devel-3.4.16-VC.zip
URL_HASH SHA1=edcf1f567837e7464cf80df402661b41acd78dbf)
FetchContent_MakeAvailable(sdl)
find_package(SDL3 REQUIRED CONFIG PATHS ${sdl_SOURCE_DIR}/cmake NO_DEFAULT_PATH)
set(SDL_TARGET SDL3::SDL3)
set(SDL_MAIN_TARGET "")
FetchContent_Declare(sdl_ttf
URL https://github.com/libsdl-org/SDL_ttf/releases/download/release-3.2.2/SDL3_ttf-devel-3.2.2-VC.zip
URL_HASH SHA1=3786bc016d89ca4cf9739e4d342ca29e3e29c137)
FetchContent_MakeAvailable(sdl_ttf)
find_package(SDL3_ttf REQUIRED CONFIG PATHS ${sdl_ttf_SOURCE_DIR}/cmake NO_DEFAULT_PATH)
set(SDL_TTF_TARGET SDL3_ttf::SDL3_ttf)
endif()
get_target_property(SDL_DLL ${SDL_TARGET} IMPORTED_LOCATION)
get_target_property(SDL_TTF_DLL ${SDL_TTF_TARGET} IMPORTED_LOCATION)
get_filename_component(SDL_LIBDIR ${SDL_DLL} DIRECTORY)
get_filename_component(SDL_TTF_LIBDIR ${SDL_TTF_DLL} DIRECTORY)
target_link_libraries(system3_sdl INTERFACE
${SDL_MAIN_TARGET} ${SDL_TARGET} ${SDL_TTF_TARGET})
FetchContent_Declare(rtmidi
URL https://github.com/thestk/rtmidi/archive/refs/tags/6.0.0.zip
URL_HASH SHA1=43287aff8c2c03d3b38cff4d44611763f5e149fa
EXCLUDE_FROM_ALL)
set(RTMIDI_BUILD_TESTING OFF CACHE BOOL "Build test programs" FORCE)
FetchContent_MakeAvailable(rtmidi)
set_property(TARGET rtmidi PROPERTY COMPILE_WARNING_AS_ERROR OFF)
target_compile_definitions(system3 PRIVATE USE_MIDI)
target_link_libraries(system3 PRIVATE rtmidi)
target_sources(system3 PRIVATE src/sys/mako_midi.cpp)
FetchContent_Declare(nlohmann_json
URL https://github.com/nlohmann/json/releases/download/v3.11.3/json.tar.xz
URL_HASH SHA1=886dd96952c7c8ad78fdac1a26c409f9e886377b)
FetchContent_MakeAvailable(nlohmann_json)
set(ENABLE_DEBUGGER ON)
target_link_libraries(system3 PRIVATE nlohmann_json::nlohmann_json)
target_compile_definitions(system3 PRIVATE _CRT_NONSTDC_NO_DEPRECATE _CRT_SECURE_NO_WARNINGS)
target_compile_options(system3 PRIVATE /utf-8 /wd4244)
add_custom_command(TARGET system3 POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy_if_different
"$<TARGET_FILE:${SDL_TARGET}>" "$<TARGET_FILE_DIR:system3>"
COMMAND ${CMAKE_COMMAND} -E copy_if_different
"$<TARGET_FILE:${SDL_TTF_TARGET}>" "$<TARGET_FILE_DIR:system3>"
COMMENT "Copying SDL runtime DLLs"
VERBATIM)
set_target_properties(system3 PROPERTIES
WIN32_EXECUTABLE TRUE
VS_DEBUGGER_ENVIRONMENT "PATH=${SDL_LIBDIR}$<SEMICOLON>${SDL_TTF_LIBDIR}$<SEMICOLON>$ENV{PATH}")
set_directory_properties(PROPERTIES VS_STARTUP_PROJECT system3)
install(FILES ${SDL_DLL} ${SDL_TTF_DLL} DESTINATION .)
install(TARGETS system3 RUNTIME DESTINATION .)
else()
include(FindPkgConfig)
if (SYSTEM3_SDL_VERSION STREQUAL "2")
pkg_check_modules(SDL REQUIRED IMPORTED_TARGET sdl2)
pkg_check_modules(SDLTTF REQUIRED IMPORTED_TARGET SDL2_ttf)
else()
pkg_check_modules(SDL REQUIRED IMPORTED_TARGET sdl3)
pkg_check_modules(SDLTTF REQUIRED IMPORTED_TARGET sdl3-ttf)
endif()
if (MINGW)
add_static_library(sdl SDL)
add_static_library(sdl_ttf SDLTTF)
# Workaround for linking error
set_property(TARGET sdl_ttf PROPERTY INTERFACE_LINK_LIBRARIES
$<LINK_GROUP:RESCAN,${SDLTTF_STATIC_LIBRARIES}>)
else()
add_library(sdl ALIAS PkgConfig::SDL)
add_library(sdl_ttf ALIAS PkgConfig::SDLTTF)
endif()
target_link_libraries(system3_sdl INTERFACE sdl sdl_ttf)
find_package(nlohmann_json 3.2.0)
if (nlohmann_json_FOUND)
set(ENABLE_DEBUGGER ON)
target_link_libraries(system3 PRIVATE nlohmann_json::nlohmann_json)
endif()
pkg_check_modules(RTMIDI IMPORTED_TARGET rtmidi)
if (RTMIDI_FOUND)
if (MINGW)
add_static_library(RTMIDI RTMIDI)
else()
add_library(RTMIDI ALIAS PkgConfig::RTMIDI)
endif()
target_compile_definitions(system3 PRIVATE USE_MIDI)
target_link_libraries(system3 PRIVATE RTMIDI)
target_sources(system3 PRIVATE src/sys/mako_midi.cpp)
endif()
endif()
if (CMAKE_SYSTEM_NAME STREQUAL "Windows")
target_sources(system3 PRIVATE
src/win/nact_win.cpp
src/win/resource.rc
${SYSTEM3_AUDIO_BACKEND}
)
target_compile_definitions(system3 PRIVATE NOMINMAX)
target_link_libraries(system3 PRIVATE winmm)
if (MINGW)
target_link_options(system3 PRIVATE -static)
endif()
else()
target_sources(system3 PRIVATE
src/generic/nact_generic.cpp
${SYSTEM3_AUDIO_BACKEND}
)
set(RESOURCE_PATH ${CMAKE_INSTALL_PREFIX}/share/system3/)
install(TARGETS system3 RUNTIME DESTINATION bin)
install(DIRECTORY resources/
DESTINATION share/system3
FILES_MATCHING PATTERN *.MDA PATTERN *.ttf)
endif()
endif()
target_sources(system3 PRIVATE
src/sdlmain.cpp
src/config.cpp
src/fileio.cpp
src/resource.cpp
src/encoding.cpp
src/texthook.cpp
src/fm/makofm.cpp
src/fm/mako_ymfm.cpp
src/sys/ags.cpp
src/sys/ags_cursor.cpp
src/sys/ags_draw.cpp
src/sys/ags_gl3.cpp
src/sys/ags_gm3.cpp
src/sys/ags_pms.cpp
src/sys/ags_text.cpp
src/sys/ags_vsp.cpp
src/sys/ags_vsp2l.cpp
src/sys/dri.cpp
src/sys/game_id.cpp
src/sys/msgskip.cpp
src/sys/nact.cpp
src/sys/nact_gakuenking.cpp
src/sys/nact_input.cpp
src/sys/nact_sys1.cpp
src/sys/nact_sys2.cpp
src/sys/nact_sys3.cpp
src/sys/nact_text.cpp
src/sys/nact_window.cpp
src/sys/scenario.cpp
)
if (ENABLE_DEBUGGER)
target_compile_definitions(system3 PRIVATE ENABLE_DEBUGGER)
target_sources(system3 PRIVATE
src/debugger/debug_info.cpp
src/debugger/debugger.cpp
src/debugger/cli_frontend.cpp
src/debugger/dap_frontend.cpp
)
endif()
if(NINTENDO_SWITCH)
if (SYSTEM3_SDL_VERSION STREQUAL "3")
message(FATAL_ERROR "Nintendo Switch currently supports SDL2 only")
endif()
set(RESOURCE_PATH romfs:/)
nx_generate_nacp(system3.nacp
NAME "system3"
AUTHOR "kichikuou"
VERSION "1.8.0"
)
nx_create_nro(system3
NACP system3.nacp
ICON "switch/icon.jpg"
ROMFS "resources"
)
endif()
if (NOT EMSCRIPTEN)
target_sources(system3 PRIVATE src/sys/music_decoder.cpp)
target_include_directories(system3 PRIVATE deps/dr_libs deps/stb)
# dr_mp3 and stb_vorbis are amalgamated into this translation unit; silence
# their warnings so they are not promoted to errors by WARNING_AS_ERROR.
set_source_files_properties(src/sys/music_decoder.cpp PROPERTIES
COMPILE_OPTIONS "$<IF:$<CXX_COMPILER_ID:MSVC>,/w,-w>")
endif()
target_compile_definitions(system3 PRIVATE RESOURCE_PATH="${RESOURCE_PATH}")
target_include_directories(system3 PRIVATE src src/sys)
target_link_libraries(system3 PRIVATE system3_sdl)
if (BUILD_TESTING AND NOT ANDROID AND NOT EMSCRIPTEN AND NOT NINTENDO_SWITCH)
add_subdirectory(test)
endif()