Files
advent-of-code-2025/CMakeLists.txt

130 lines
4.1 KiB
CMake
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

cmake_minimum_required(VERSION 3.22)
# -----------------------------
# Safely force Clang
# -----------------------------
if(NOT DEFINED CMAKE_C_COMPILER)
set(CMAKE_C_COMPILER clang CACHE STRING "C compiler" FORCE)
endif()
if(NOT DEFINED CMAKE_CXX_COMPILER)
set(CMAKE_CXX_COMPILER clang++ CACHE STRING "C++ compiler" FORCE)
endif()
# -----------------------------
# Project setup
# -----------------------------
project(advent-of-code
LANGUAGES CXX
VERSION 2025.12
)
set(CMAKE_CXX_STANDARD 23)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
set(CMAKE_BUILD_TYPE Release CACHE STRING "Build type")
# -----------------------------
# Dependencies
# -----------------------------
add_subdirectory(external/fmt)
add_subdirectory(external/spdlog)
set(COMMON_LIBS fmt::fmt spdlog::spdlog)
# -----------------------------
# 1. Collect ALL .cpp files under src/
# -----------------------------
file(GLOB_RECURSE ALL_CPP_FILES
RELATIVE ${CMAKE_CURRENT_SOURCE_DIR}
"src/*.cpp"
)
# -----------------------------
# 2. Separate day solution mains from everything else
# -----------------------------
set(DAY_MAIN_PATTERN "^day-[0-9]+-solution\\.cpp$")
set(DAY_MAINS "")
set(COMMON_SOURCES "")
foreach(file ${ALL_CPP_FILES})
get_filename_component(fname ${file} NAME)
if(fname MATCHES ${DAY_MAIN_PATTERN})
list(APPEND DAY_MAINS "${CMAKE_CURRENT_SOURCE_DIR}/${file}")
else()
list(APPEND COMMON_SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/${file}")
endif()
endforeach()
# -----------------------------
# 3. Include directories (all subfolders under src/)
# -----------------------------
file(GLOB_RECURSE SRC_SUBDIRS LIST_DIRECTORIES true "src/*")
set(PROJECT_INCLUDE_DIRS "")
foreach(dir ${SRC_SUBDIRS})
if(IS_DIRECTORY ${dir})
list(APPEND PROJECT_INCLUDE_DIRS ${dir})
endif()
endforeach()
# -----------------------------
# 4. Common code → object library (only if we actually have common files)
# -----------------------------
if(COMMON_SOURCES)
add_library(common_objects OBJECT ${COMMON_SOURCES})
target_include_directories(common_objects PRIVATE ${PROJECT_INCLUDE_DIRS})
target_link_libraries(common_objects PRIVATE ${COMMON_LIBS})
target_compile_features(common_objects PRIVATE cxx_std_23)
else()
# Create a dummy interface target so the rest of the script stays simple
add_library(common_objects INTERFACE)
message(STATUS "No common source files found each day will compile independently")
endif()
# -----------------------------
# 5. Build one executable per day solution
# -----------------------------
foreach(MAIN_FILE ${DAY_MAINS})
get_filename_component(MAIN_NAME ${MAIN_FILE} NAME_WE) # day-1-solution
set(EXE_NAME "aoc-${MAIN_NAME}")
add_executable(${EXE_NAME} ${MAIN_FILE})
# If we have common_objects as OBJECT library → reuse compiled objects
# Otherwise it's just an INTERFACE → nothing added
if(COMMON_SOURCES)
target_sources(${EXE_NAME} PRIVATE $<TARGET_OBJECTS:common_objects>)
endif()
target_include_directories(${EXE_NAME} PRIVATE ${PROJECT_INCLUDE_DIRS})
target_link_libraries(${EXE_NAME} PRIVATE ${COMMON_LIBS} common_objects)
target_compile_features(${EXE_NAME} PRIVATE cxx_std_23)
# Warnings + optimizations
if(CMAKE_CXX_COMPILER_ID MATCHES "Clang|GNU")
target_compile_options(${EXE_NAME} PRIVATE
-Wall -Wextra -Wpedantic -Wconversion -Wshadow -Wformat=2 -Werror=main
)
endif()
target_compile_options(${EXE_NAME} PRIVATE -O3 -march=native)
if(CMAKE_CXX_COMPILER_ID MATCHES "Clang|GNU")
target_link_options(${EXE_NAME} PRIVATE -flto=auto)
endif()
endforeach()
# -----------------------------
# Final summary
# -----------------------------
list(LENGTH DAY_MAINS DAY_COUNT)
message(STATUS "Advent of Code 2025 Building ${DAY_COUNT} solution(s):")
foreach(MAIN ${DAY_MAINS})
get_filename_component(NAME ${MAIN} NAME)
message(STATUS " • ${NAME} → aoc-${NAME_WE}")
endforeach()
if(NOT DAY_MAINS)
message(FATAL_ERROR "No files matching 'day-N-solution.cpp' found in src/ nothing to build!")
endif()