# ============================================================================== # 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( [GUI] [BOOST] ...) # # 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( ) # # 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)