Add a CMakeLists.txt to each exercise directory, included from cmat/CMakeLists.txt, so every exercise and solution becomes a buildable target. GUI exercises link the curses-based DOS_Unix implementations on Unix-like systems; the Windows-specific DOS variants are not compiled. Exercises without a portable path or with missing dependencies (Boost) are reported as not available at configure time. Targets are excluded from the default build and built by name, e.g. `cmake --build build --target Ex11`, so intentionally buggy exercises such as Ex21 do not break the default build. Also fix two portability issues: rename Ex11bug/pole.h to Pole.h for case-sensitive filesystems and drop the extra Light:: qualification in SolutionEx71A/Light.h. Document build commands and layout in AGENTS.md. Co-authored-by: Qwen 3.8 27B <qwen3.8_27b-q3_k_xl@lmstudio.local>
146 lines
5.7 KiB
CMake
146 lines
5.7 KiB
CMake
# ==============================================================================
|
|
# Course Material (cmat)
|
|
# ==============================================================================
|
|
# Exercises copied from 397. Each exercise directory holds its own
|
|
# CMakeLists.txt (included below) and defines one executable target with the
|
|
# directory's name via cmat_add_exercise().
|
|
#
|
|
# Targets are excluded from the default build; build one by name:
|
|
# cmake --build build --target Ex11
|
|
#
|
|
# Some exercises intentionally contain bugs that students fix during the
|
|
# course. Those targets fail to compile (or misbehave at runtime) until the
|
|
# bug is fixed, which is expected.
|
|
|
|
# ------------------------------------------------------------------------------
|
|
# Compile options
|
|
# ------------------------------------------------------------------------------
|
|
# Legacy course material: keep the project's warning flags but drop -Werror;
|
|
# these old sources produce warnings that must not block the build.
|
|
set(CMAT_OPTIONS "")
|
|
foreach (opt IN LISTS BASE_OPTIONS)
|
|
if (NOT opt STREQUAL "-Werror" AND NOT opt STREQUAL "/WX")
|
|
list(APPEND CMAT_OPTIONS "${opt}")
|
|
endif()
|
|
endforeach()
|
|
|
|
# ------------------------------------------------------------------------------
|
|
# Keyboard/Screen support (DOS_Unix/)
|
|
# ------------------------------------------------------------------------------
|
|
# GUI exercises use the Keyboard/Screen abstraction from DOS_Unix/. The DOS
|
|
# variants (Keyboard_DOS.cpp, Screen_DOS.cpp) are Windows-specific and are not
|
|
# compiled. On Unix-like systems the curses variants provide the same
|
|
# interface instead.
|
|
|
|
set(CMAT_GUI_LIB "")
|
|
if (IS_LINUX OR IS_MACOS)
|
|
find_package(Curses QUIET)
|
|
if (Curses_FOUND)
|
|
add_library(dos_unix STATIC
|
|
DOS_Unix/CursesObj.cpp
|
|
DOS_Unix/Keyboard_Unix.cpp
|
|
DOS_Unix/Screen_Unix.cpp
|
|
)
|
|
set_target_properties(dos_unix PROPERTIES EXCLUDE_FROM_ALL TRUE)
|
|
target_include_directories(dos_unix PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/DOS_Unix")
|
|
if (CURSES_INCLUDE_DIRS)
|
|
target_include_directories(dos_unix SYSTEM PUBLIC ${CURSES_INCLUDE_DIRS})
|
|
endif()
|
|
target_link_libraries(dos_unix PUBLIC ${CURSES_LIBRARIES})
|
|
set(CMAT_GUI_LIB dos_unix)
|
|
else()
|
|
message(STATUS "Curses not found; GUI exercises are unavailable")
|
|
endif()
|
|
else()
|
|
# Windows: only the DOS keyboard/screen implementations exist, which are
|
|
# Windows-specific; there is nothing portable to build with.
|
|
endif()
|
|
|
|
# Exercises using Boost.Serialization (system install; not fetched). CONFIG
|
|
# mode uses Boost's own CMake package, since the FindBoost module was removed
|
|
# in CMake 4.
|
|
find_package(Boost CONFIG QUIET COMPONENTS serialization)
|
|
|
|
# ------------------------------------------------------------------------------
|
|
# Target helpers
|
|
# ------------------------------------------------------------------------------
|
|
# cmat_add_exercise(<name> [GUI] [BOOST] <sources>...)
|
|
#
|
|
# Creates an executable target from the given sources. GUI links the
|
|
# Keyboard/Screen support library; BOOST links Boost.Serialization. If a
|
|
# required dependency is missing, the exercise is reported as not available
|
|
# and no target is created.
|
|
function(cmat_add_exercise name)
|
|
cmake_parse_arguments(ARG "GUI;BOOST" "" "SOURCES" ${ARGN})
|
|
if (ARG_GUI AND NOT CMAT_GUI_LIB)
|
|
cmat_unavailable(${name} "requires the Keyboard/Screen abstraction, which is Windows-specific (DOS_Unix/)")
|
|
return()
|
|
endif()
|
|
if (ARG_BOOST AND NOT Boost_FOUND)
|
|
cmat_unavailable(${name} "requires Boost.Serialization")
|
|
return()
|
|
endif()
|
|
add_executable(${name} ${ARG_SOURCES})
|
|
target_compile_features(${name} PRIVATE cxx_std_23)
|
|
target_compile_options(${name} PRIVATE ${CMAT_OPTIONS})
|
|
set_target_properties(${name} PROPERTIES EXCLUDE_FROM_ALL TRUE)
|
|
if (ARG_GUI)
|
|
target_link_libraries(${name} PRIVATE ${CMAT_GUI_LIB})
|
|
endif()
|
|
if (ARG_BOOST)
|
|
target_link_libraries(${name} PRIVATE Boost::serialization)
|
|
endif()
|
|
endfunction()
|
|
|
|
# cmat_unavailable(<name> <reason>)
|
|
#
|
|
# Reports that an exercise cannot be built on this platform. A warning (not a
|
|
# hard error) is used so the configuration completes and all other exercises
|
|
# remain available.
|
|
function(cmat_unavailable name reason)
|
|
message(WARNING "Exercise ${name} is not available on this platform: ${reason}")
|
|
endfunction()
|
|
|
|
# ------------------------------------------------------------------------------
|
|
# Exercises
|
|
# ------------------------------------------------------------------------------
|
|
add_subdirectory(Ex11)
|
|
add_subdirectory(Ex11bug)
|
|
add_subdirectory(Ex21)
|
|
add_subdirectory(Ex22)
|
|
add_subdirectory(Ex31)
|
|
add_subdirectory(Ex32)
|
|
add_subdirectory(Ex33)
|
|
add_subdirectory(Ex41)
|
|
add_subdirectory(Ex42)
|
|
add_subdirectory(Ex51)
|
|
add_subdirectory(Ex61)
|
|
add_subdirectory(Ex62)
|
|
add_subdirectory(Ex71)
|
|
add_subdirectory(Ex71A)
|
|
add_subdirectory(SolutionEx11bug)
|
|
add_subdirectory(SolutionEx21)
|
|
add_subdirectory(SolutionEx22)
|
|
add_subdirectory(SolutionEx22Bonus)
|
|
add_subdirectory(SolutionEx31)
|
|
add_subdirectory(SolutionEx31Bonus)
|
|
add_subdirectory(SolutionEx32)
|
|
add_subdirectory(SolutionEx33)
|
|
add_subdirectory(SolutionEx33Bonus)
|
|
add_subdirectory(SolutionEx41)
|
|
add_subdirectory(SolutionEx41Bonus)
|
|
add_subdirectory(SolutionEx42)
|
|
add_subdirectory(SolutionEx51)
|
|
add_subdirectory(SolutionEx51Bonus2)
|
|
add_subdirectory(SolutionEx61InterimSolution)
|
|
add_subdirectory(SolutionEx61Part1)
|
|
add_subdirectory(SolutionEx61Part2)
|
|
add_subdirectory(SolutionEx61Part2Bonus)
|
|
add_subdirectory(SolutionEx62)
|
|
add_subdirectory(SolutionEx62Bonus)
|
|
add_subdirectory(SolutionEx62Bonus2)
|
|
add_subdirectory(SolutionEx71)
|
|
add_subdirectory(SolutionEx71A)
|
|
add_subdirectory(SolutionEx71ABonus)
|
|
add_subdirectory(SolutionEx71Bonus)
|