Files
coffee_crisis/CMakeLists.txt

230 lines
7.9 KiB
CMake

# CMakeLists.txt
cmake_minimum_required(VERSION 3.10)
project(coffee_crisis VERSION 1.00)
# Tipus de build per defecte (Debug) si no se n'ha especificat cap
if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
set(CMAKE_BUILD_TYPE Debug CACHE STRING "" FORCE)
endif()
# Configuración de compilador para MinGW en Windows
if(WIN32 AND NOT CMAKE_CXX_COMPILER_ID MATCHES "MSVC")
set(CMAKE_CXX_COMPILER "g++")
set(CMAKE_C_COMPILER "gcc")
endif()
# Establecer estándar de C++
set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED True)
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
# Configuración global de flags de compilación
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall")
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -Os -ffunction-sections -fdata-sections")
# Define el directorio de los archivos fuente
set(DIR_SOURCES "${CMAKE_SOURCE_DIR}/source")
# Cargar todos los archivos fuente en DIR_SOURCES
file(GLOB SOURCES "${DIR_SOURCES}/*.cpp")
# Verificar si se encontraron archivos fuente
if(NOT SOURCES)
message(FATAL_ERROR "No se encontraron archivos fuente en ${DIR_SOURCES}.")
endif()
# Configuración de SDL3
if(EMSCRIPTEN)
# En Emscripten, SDL3 se compila desde source con FetchContent
include(FetchContent)
FetchContent_Declare(
SDL3
GIT_REPOSITORY https://github.com/libsdl-org/SDL.git
GIT_TAG release-3.4.4
GIT_SHALLOW TRUE
)
set(SDL_SHARED OFF CACHE BOOL "" FORCE)
set(SDL_STATIC ON CACHE BOOL "" FORCE)
set(SDL_TEST_LIBRARY OFF CACHE BOOL "" FORCE)
FetchContent_MakeAvailable(SDL3)
message(STATUS "SDL3 compilado desde source para Emscripten")
else()
find_package(SDL3 REQUIRED CONFIG REQUIRED COMPONENTS SDL3)
message(STATUS "SDL3 encontrado: ${SDL3_INCLUDE_DIRS}")
endif()
# Añadir ejecutable principal
add_executable(${PROJECT_NAME} ${SOURCES})
# Configuración de salida: el ejecutable principal va a la raíz del proyecto.
# Per-target (no global) perquè `pack_resources` acabe a `build/` com la resta
# de projectes.
if(NOT EMSCRIPTEN)
set_target_properties(${PROJECT_NAME} PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR})
endif()
# Añadir definiciones de compilación dependiendo del tipo de build
target_compile_definitions(${PROJECT_NAME} PRIVATE
$<$<CONFIG:DEBUG>:DEBUG PAUSE>
$<$<CONFIG:RELEASE>:RELEASE_BUILD>
)
# Enlazar bibliotecas
target_link_libraries(${PROJECT_NAME} PRIVATE SDL3::SDL3)
# Configuración específica para cada plataforma
if(WIN32)
target_compile_definitions(${PROJECT_NAME} PRIVATE WINDOWS_BUILD)
target_link_libraries(${PROJECT_NAME} PRIVATE ws2_32 mingw32 gdi32 winmm imm32 ole32 version)
elseif(APPLE)
target_compile_definitions(${PROJECT_NAME} PRIVATE MACOS_BUILD)
target_compile_options(${PROJECT_NAME} PRIVATE -Wno-deprecated)
if(NOT CMAKE_OSX_ARCHITECTURES)
set(CMAKE_OSX_ARCHITECTURES "arm64")
endif()
if(MACOS_BUNDLE)
target_compile_definitions(${PROJECT_NAME} PRIVATE MACOS_BUNDLE)
target_link_options(${PROJECT_NAME} PRIVATE
-framework SDL3
-F ${CMAKE_SOURCE_DIR}/release/macos/frameworks/SDL3.xcframework/macos-arm64_x86_64
-rpath @executable_path/../Frameworks/
)
endif()
elseif(EMSCRIPTEN)
target_compile_definitions(${PROJECT_NAME} PRIVATE EMSCRIPTEN_BUILD)
# En wasm NO empaquetamos un resources.pack: el propio --preload-file de
# emscripten ya hace el mismo trabajo (bundle del directorio en un .data),
# así que metemos directamente 'data' y dejamos que el Resource lea por
# filesystem (MEMFS). Evita doble empaquetado y el uso de memoria extra.
target_link_options(${PROJECT_NAME} PRIVATE
"SHELL:--preload-file ${CMAKE_SOURCE_DIR}/data@/data"
"SHELL:--preload-file ${CMAKE_SOURCE_DIR}/gamecontrollerdb.txt@/gamecontrollerdb.txt"
-sALLOW_MEMORY_GROWTH=1
-sMAX_WEBGL_VERSION=2
)
set_target_properties(${PROJECT_NAME} PROPERTIES SUFFIX ".html")
elseif(UNIX AND NOT APPLE)
target_compile_definitions(${PROJECT_NAME} PRIVATE LINUX_BUILD)
target_link_options(${PROJECT_NAME} PRIVATE -Wl,--gc-sections)
endif()
# ==============================================================================
# STATIC ANALYSIS TARGETS
# ==============================================================================
find_program(CLANG_TIDY_EXE NAMES clang-tidy)
find_program(CLANG_FORMAT_EXE NAMES clang-format)
find_program(CPPCHECK_EXE NAMES cppcheck)
# Recopilar todos los archivos fuente para analisis
file(GLOB_RECURSE ALL_SOURCE_FILES
"${CMAKE_SOURCE_DIR}/source/*.cpp"
"${CMAKE_SOURCE_DIR}/source/*.h"
)
set(CLANG_TIDY_SOURCES ${ALL_SOURCE_FILES})
set(FORMAT_SOURCES ${ALL_SOURCE_FILES})
# Para cppcheck, pasar solo .cpp (los headers se procesan transitivamente).
set(CPPCHECK_SOURCES ${ALL_SOURCE_FILES})
list(FILTER CPPCHECK_SOURCES INCLUDE REGEX ".*\\.cpp$")
list(FILTER CPPCHECK_SOURCES EXCLUDE REGEX ".*/source/external/.*")
# Targets de clang-tidy
if(CLANG_TIDY_EXE)
add_custom_target(tidy
COMMAND ${CLANG_TIDY_EXE}
-p ${CMAKE_BINARY_DIR}
${CLANG_TIDY_SOURCES}
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
COMMENT "Running clang-tidy..."
)
add_custom_target(tidy-fix
COMMAND ${CLANG_TIDY_EXE}
-p ${CMAKE_BINARY_DIR}
--fix
${CLANG_TIDY_SOURCES}
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
COMMENT "Running clang-tidy with fixes..."
)
else()
message(STATUS "clang-tidy no encontrado - targets 'tidy' y 'tidy-fix' no disponibles")
endif()
# Targets de clang-format
if(CLANG_FORMAT_EXE)
add_custom_target(format
COMMAND ${CLANG_FORMAT_EXE}
-i
${FORMAT_SOURCES}
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
COMMENT "Running clang-format..."
)
add_custom_target(format-check
COMMAND ${CLANG_FORMAT_EXE}
--dry-run
--Werror
${FORMAT_SOURCES}
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
COMMENT "Checking clang-format..."
)
else()
message(STATUS "clang-format no encontrado - targets 'format' y 'format-check' no disponibles")
endif()
# Target de cppcheck
if(CPPCHECK_EXE)
add_custom_target(cppcheck
COMMAND ${CPPCHECK_EXE}
--enable=warning,style,performance,portability
--std=c++20
--language=c++
--inline-suppr
--suppress=missingIncludeSystem
--suppress=toomanyconfigs
--quiet
-I ${CMAKE_SOURCE_DIR}/source
${CPPCHECK_SOURCES}
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
COMMENT "Running cppcheck..."
)
else()
message(STATUS "cppcheck no encontrado - target 'cppcheck' no disponible")
endif()
# --- EINA STANDALONE: pack_resources ---
# Executable auxiliar que empaqueta `data/` a `resources.pack`.
# No es compila per defecte (EXCLUDE_FROM_ALL). Build explícit:
# cmake --build build --target pack_resources
# Després executar: ./build/pack_resources data resources.pack
if(NOT EMSCRIPTEN)
add_executable(pack_resources EXCLUDE_FROM_ALL
tools/pack_resources/pack_resources.cpp
source/resource_pack.cpp
)
target_include_directories(pack_resources PRIVATE "${CMAKE_SOURCE_DIR}/source")
target_compile_options(pack_resources PRIVATE -Wall)
# Regeneració automàtica de resources.pack en cada build si canvia data/.
file(GLOB_RECURSE DATA_FILES CONFIGURE_DEPENDS "${CMAKE_SOURCE_DIR}/data/*")
set(RESOURCE_PACK "${CMAKE_SOURCE_DIR}/resources.pack")
add_custom_command(
OUTPUT ${RESOURCE_PACK}
COMMAND $<TARGET_FILE:pack_resources>
"${CMAKE_SOURCE_DIR}/data"
"${RESOURCE_PACK}"
DEPENDS pack_resources ${DATA_FILES}
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
COMMENT "Empaquetant data/ → resources.pack"
VERBATIM
)
add_custom_target(resource_pack ALL DEPENDS ${RESOURCE_PACK})
add_dependencies(${PROJECT_NAME} resource_pack)
endif()