# Copyright (c) 2025 Dominic Masters # # This software is released under the MIT License. # https://opensource.org/licenses/MIT # Setup cmake_minimum_required(VERSION 3.18) set(CMAKE_C_STANDARD 11) set(CMAKE_C_STANDARD_REQUIRED ON) set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_CURRENT_SOURCE_DIR}/cmake/modules) option(ENABLE_TESTS "Enable tests" OFF) # Prep cache set(DUSK_CACHE_TARGET "dusk-target") # Build variables set(DUSK_ROOT_DIR "${CMAKE_SOURCE_DIR}") set(DUSK_BUILD_DIR "${CMAKE_BINARY_DIR}") set(DUSK_SOURCES_DIR "${DUSK_ROOT_DIR}/src") set(DUSK_TEST_DIR "${DUSK_ROOT_DIR}/test") set(DUSK_TEMP_DIR "${DUSK_BUILD_DIR}/temp") set(DUSK_TOOLS_DIR "${DUSK_ROOT_DIR}/tools") set(DUSK_DATA_DIR "${DUSK_ROOT_DIR}/data") set(DUSK_ASSETS_DIR "${DUSK_ROOT_DIR}/assets") set(DUSK_BUILT_ASSETS_DIR "${DUSK_BUILD_DIR}/built_assets" CACHE INTERNAL ${DUSK_CACHE_TARGET}) set(DUSK_GENERATED_HEADERS_DIR "${DUSK_BUILD_DIR}/generated") set(DUSK_BUILD_BINARY ${DUSK_BUILD_DIR}/Dusk CACHE INTERNAL ${DUSK_CACHE_TARGET}) set(DUSK_ASSETS "" CACHE INTERNAL ${DUSK_CACHE_TARGET}) set(DUSK_LIBRARY_TARGET_NAME "DuskCore" CACHE INTERNAL ${DUSK_CACHE_TARGET}) set(DUSK_BINARY_TARGET_NAME "Dusk" CACHE INTERNAL ${DUSK_CACHE_TARGET}) set(DUSK_ASSETS_ZIP "${DUSK_BUILD_DIR}/dusk.dsk" CACHE INTERNAL ${DUSK_CACHE_TARGET}) # Create directories file(MAKE_DIRECTORY ${DUSK_GENERATED_HEADERS_DIR}) # Find packages find_package(Python3 COMPONENTS Interpreter REQUIRED) # Set target system, default to linux if not set. if(NOT DEFINED DUSK_TARGET_SYSTEM) set(DUSK_TARGET_SYSTEM "linux") endif() # Toolchains if(DUSK_TARGET_SYSTEM STREQUAL "psp") find_package(pspsdk REQUIRED) endif() if(DUSK_TARGET_SYSTEM STREQUAL "gamecube" OR DUSK_TARGET_SYSTEM STREQUAL "wii") # Override to make library and binary be the same. set(DUSK_LIBRARY_TARGET_NAME "${DUSK_LIBRARY_TARGET_NAME}.elf" CACHE INTERNAL ${DUSK_CACHE_TARGET}) endif() # Init Project. project(${DUSK_LIBRARY_TARGET_NAME} VERSION 1.0.0 LANGUAGES C ) # Either, create library and binary separately (used for tests), or make them # one in the same so all code is in the binary. if(ENABLE_TESTS) # MainLibrary add_library(${DUSK_LIBRARY_TARGET_NAME} STATIC) # Binary Executable add_executable(${DUSK_BINARY_TARGET_NAME} ${DUSK_SOURCES_DIR}/null.c) # Link library to binary target_link_libraries(${DUSK_BINARY_TARGET_NAME} PUBLIC ${DUSK_LIBRARY_TARGET_NAME} ) else() set(DUSK_LIBRARY_TARGET_NAME "${DUSK_BINARY_TARGET_NAME}" CACHE INTERNAL ${DUSK_CACHE_TARGET}) add_executable(${DUSK_BINARY_TARGET_NAME} ${DUSK_SOURCES_DIR}/null.c) endif() # Add tools add_subdirectory(tools) # Per Target Libraries and definitions if(DUSK_TARGET_SYSTEM STREQUAL "linux") find_package(SDL2 REQUIRED) find_package(OpenGL REQUIRED) target_link_libraries(${DUSK_LIBRARY_TARGET_NAME} PUBLIC SDL2 pthread OpenGL::GL GL m ) target_compile_definitions(${DUSK_LIBRARY_TARGET_NAME} PUBLIC DISPLAY_SDL2=1 DISPLAY_WINDOW_WIDTH_DEFAULT=1080 DISPLAY_WINDOW_HEIGHT_DEFAULT=810 DISPLAY_SCREEN_HEIGHT_DEFAULT=270 INPUT_SDL2=1 INPUT_KEYBOARD=1 INPUT_POINTER=1 INPUT_GAMEPAD=1 THREAD_PTHREAD=1 TIME_SDL2=1 TIME_FIXED=0 ) elseif(DUSK_TARGET_SYSTEM STREQUAL "psp") find_package(SDL2 REQUIRED) find_package(OpenGL REQUIRED) target_link_libraries(${DUSK_LIBRARY_TARGET_NAME} PUBLIC ${SDL2_LIBRARIES} SDL2 pthread OpenGL::GL zip bz2 z mbedtls mbedcrypto lzma m ) target_include_directories(${DUSK_LIBRARY_TARGET_NAME} PRIVATE ${SDL2_INCLUDE_DIRS} ) target_compile_definitions(${DUSK_LIBRARY_TARGET_NAME} PUBLIC DISPLAY_SDL2=1 DISPLAY_WINDOW_WIDTH_DEFAULT=480 DISPLAY_WINDOW_HEIGHT_DEFAULT=272 DISPLAY_WIDTH=480 DISPLAY_HEIGHT=272 DISPLAY_SIZE_DYNAMIC=0 INPUT_SDL2=1 INPUT_GAMEPAD=1 THREAD_PTHREAD=1 TIME_FIXED=1 ) elseif(DUSK_TARGET_SYSTEM STREQUAL "gamecube" OR DUSK_TARGET_SYSTEM STREQUAL "wii") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-rtti -fno-exceptions") # configure_file(opengl.pc.in opengl.pc @ONLY) find_package(PkgConfig REQUIRED) pkg_check_modules(zip IMPORTED_TARGET libzip) target_compile_definitions(${DUSK_LIBRARY_TARGET_NAME} PUBLIC DOLPHIN ) # Disable all warnings target_compile_options(${DUSK_LIBRARY_TARGET_NAME} PRIVATE -w) # Custom flags for cglm set(CGLM_SHARED OFF CACHE BOOL "Build cglm shared" FORCE) set(CGLM_STATIC ON CACHE BOOL "Build cglm static" FORCE) find_package(cglm REQUIRED) # Compile lua include(FetchContent) FetchContent_Declare( liblua URL https://www.lua.org/ftp/lua-5.5.0.tar.gz ) FetchContent_MakeAvailable(liblua) set(LUA_SRC_DIR "${liblua_SOURCE_DIR}/src") set(LUA_C_FILES lapi.c lauxlib.c lbaselib.c lcode.c lcorolib.c lctype.c ldblib.c ldebug.c ldo.c ldump.c lfunc.c lgc.c linit.c liolib.c llex.c lmathlib.c lmem.c loadlib.c lobject.c lopcodes.c loslib.c lparser.c lstate.c lstring.c lstrlib.c ltable.c ltablib.c ltm.c lundump.c lutf8lib.c lvm.c lzio.c ) list(TRANSFORM LUA_C_FILES PREPEND "${LUA_SRC_DIR}/") add_library(liblua STATIC ${LUA_C_FILES}) target_include_directories(liblua PUBLIC "${LUA_SRC_DIR}") target_compile_definitions(liblua PRIVATE LUA_USE_C89) add_library(lua::lua ALIAS liblua) set(Lua_FOUND TRUE CACHE BOOL "Lua found" FORCE) target_link_libraries(${DUSK_LIBRARY_TARGET_NAME} PRIVATE cglm liblua m fat PkgConfig::zip ) target_compile_definitions(${DUSK_LIBRARY_TARGET_NAME} PUBLIC DISPLAY_WINDOW_WIDTH_DEFAULT=640 DISPLAY_WINDOW_HEIGHT_DEFAULT=480 DISPLAY_WIDTH=640 DISPLAY_HEIGHT=480 DISPLAY_SIZE_DYNAMIC=0 INPUT_GAMEPAD=1 THREAD_PTHREAD=1 TIME_FIXED=1 ) endif() # Add code add_subdirectory(${DUSK_SOURCES_DIR}) # Include generated headers target_include_directories(${DUSK_LIBRARY_TARGET_NAME} PUBLIC ${DUSK_GENERATED_HEADERS_DIR} ) # Handle tests if(ENABLE_TESTS) enable_testing() add_subdirectory(test) endif() # Build assets file(GLOB_RECURSE DUSK_ASSET_FILES CONFIGURE_DEPENDS "${DUSK_ASSETS_DIR}/*") add_custom_command( OUTPUT "${DUSK_ASSETS_ZIP}" COMMAND ${CMAKE_COMMAND} -E make_directory "${DUSK_ASSETS_DIR}" COMMAND ${CMAKE_COMMAND} -E rm -f "${DUSK_ASSETS_ZIP}" COMMAND ${CMAKE_COMMAND} -E tar "cf" "${DUSK_ASSETS_ZIP}" --format=zip -- . WORKING_DIRECTORY "${DUSK_ASSETS_DIR}" DEPENDS ${DUSK_ASSET_FILES} VERBATIM ) add_custom_target(DUSK_ASSETS_BUILT DEPENDS "${DUSK_ASSETS_ZIP}") add_dependencies(${DUSK_LIBRARY_TARGET_NAME} DUSK_ASSETS_BUILT) # Postbuild if(DUSK_TARGET_SYSTEM STREQUAL "psp") create_pbp_file( TARGET "${DUSK_BINARY_TARGET_NAME}" ICON_PATH NULL BACKGROUND_PATH NULL PREVIEW_PATH NULL TITLE "${DUSK_BINARY_TARGET_NAME}" PSAR_PATH ${DUSK_ASSETS_ZIP} VERSION 01.00 ) elseif(DUSK_TARGET_SYSTEM STREQUAL "gamecube" OR DUSK_TARGET_SYSTEM STREQUAL "wii") set(DUSK_BINARY_TARGET_NAME_DOL "${DUSK_BUILD_DIR}/Dusk.dol") add_custom_command(TARGET ${DUSK_BINARY_TARGET_NAME} POST_BUILD COMMAND elf2dol "$" "${DUSK_BINARY_TARGET_NAME_DOL}" COMMENT "Generating ${DUSK_BINARY_TARGET_NAME_DOL} from ${DUSK_BINARY_TARGET_NAME}" ) endif()