diff --git a/.gitignore b/.gitignore index 6466f05c..5ef609a7 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,5 @@ +dummy.cpp + # CLion /.idea/ /cmake-build-*/ diff --git a/CMakeLists.txt b/CMakeLists.txt index 71e351a8..9f642790 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -66,33 +66,44 @@ target_link_libraries(bfVFS PRIVATE 7z) # ja2export utility add_subdirectory("ext/export/src") -# static libraries whose source files, header files or header files included -# by header files do not rely on Applications or Languages preprocessor definitions, -# and therefore only need to be compiled once. Good. +# static libraries whose translation units don't rely on Application preprocessor definitions. add_subdirectory(Lua) add_subdirectory(Multiplayer) -# static libraries whose source files, header files or header files included -# by header files rely on Application and Language preprocessor definitions, and -# therefore need to be compiled multiple times. Very Bad. +set(Ja2_Libraries +"${CMAKE_SOURCE_DIR}/binkw32.lib" +"${CMAKE_SOURCE_DIR}/libexpatMT.lib" +"${CMAKE_SOURCE_DIR}/lua51.lib" +"${CMAKE_SOURCE_DIR}/lua51.vc9.lib" +"${CMAKE_SOURCE_DIR}/SMACKW32.LIB" +"Dbghelp.lib" +"Winmm.lib" +"ws2_32.lib" +bfVFS +Lua +Multiplayer +) + +# static libraries whose translation units rely on Application preprocessor definitions. set(Ja2_Libs - TileEngine - TacticalAI - Utils - Strategic - sgp - Laptop - Editor Console - Tactical + Editor + Ja2 + Laptop ModularizedTacticalAI - i18n + sgp + Strategic + Tactical + TacticalAI + TileEngine + Utils ) foreach(lib IN LISTS Ja2_Libs) add_subdirectory(${lib}) endforeach() -add_subdirectory(Ja2) +# language library relies on Application _and_ Language preprocessor definition. very bad. +add_subdirectory(i18n) # simple function to validate Languages and Application choices include(cmake/ValidateOptions.cmake) @@ -107,47 +118,47 @@ ValidateOptions("${ValidApplications}" "Applications" "${Applications}" "Applica # preprocessor definitions for Debug build, per the legacy MSBuild set(debugFlags $,JA2BETAVERSION;JA2TESTVERSION;DEBUG_ATTACKBUSY,>) -# Due to widespread preprocessor definition abuse in the codebase, practically -# every library-language-executable combination is its own compilation target -# TODO: refactor preprocessor usage onto, ideally, a single translation unit -foreach(lang IN LISTS LangTargets) - foreach(exe IN LISTS ApplicationTargets) - set(Executable ${exe}_${lang}) +foreach(app IN LISTS ApplicationTargets) + set(isEditor $) + set(isUb $) + set(isUbEditor $) + set(compilationFlags + $ + $ + $ + ) - # executable for an application/language combination, e.g. JA2_ENGLISH.exe - add_executable(${Executable} WIN32) - target_sources(${Executable} PRIVATE ${Ja2Src}) - - # Good libraries have already been built, can be simply linked here - target_link_libraries(${Executable} PRIVATE ${Ja2_Libraries} $) - target_link_options(${Executable} PRIVATE $) - - # for each app/lang combination, the Very Bad libraries need to be built, - # with the appropriate preprocessor definitions - foreach(lib IN LISTS Ja2_Libs) - # syntactic sugar to hopefully make this more readable - set(VeryBadLib ${Executable}_${lib}) - set(isEditor $) - set(isUb $) - set(isUbEditor $) - - # static library for an app/lang combination, e.g. JA2_ENGLISH_sgp.lib - add_library(${VeryBadLib}) - target_sources(${VeryBadLib} PRIVATE ${${lib}Src}) - - target_compile_definitions(${VeryBadLib} PUBLIC - $ - $ - $ - ${debugFlags} - ${lang} - ) - target_link_libraries(${Executable} PUBLIC ${VeryBadLib}) - endforeach() - - # for sgp only - target_link_libraries(${Executable}_sgp PRIVATE "ddraw.lib" "${PROJECT_SOURCE_DIR}/fmodvc.lib") - target_link_libraries(${Executable}_sgp PUBLIC libpng) - target_compile_definitions(${Executable}_sgp PRIVATE NO_ZLIB_COMPRESSION) + foreach(lib IN LISTS Ja2_Libs) + # library for an application, e.g. JA2UB_sgp + set(game_library ${app}_${lib}) + add_library(${game_library}) + target_sources(${game_library} PRIVATE ${${lib}Src}) + target_compile_definitions(${game_library} PRIVATE ${compilationFlags} ${debugFlags}) endforeach() + + foreach(lang IN LISTS LangTargets) + # executable for an application/language combination, e.g. JA2_ENGLISH.exe + set(exe ${app}_${lang}) + file(WRITE dummy.cpp "") + add_executable(${exe} WIN32 dummy.cpp) + target_link_libraries(${exe} PRIVATE ${Ja2_Libraries} $) + target_link_options(${exe} PRIVATE $) + + # language library for an application, e.g. JA2MAPEDITOR_ENGLISH_i18n + set(language_library ${exe}_i18n) + add_library(${language_library}) + target_sources(${language_library} PRIVATE ${i18nSrc}) + target_compile_definitions(${language_library} PRIVATE ${compilationFlags} ${debugFlags} ${lang}) + target_link_libraries(${exe} PRIVATE ${language_library}) + + # go through all game libraries again and link them to the app/language executable + foreach(lib IN LISTS Ja2_Libs) + target_link_libraries(${exe} PRIVATE ${app}_${lib}) + endforeach() + endforeach() + + # for SGP only + target_link_libraries(${app}_sgp PRIVATE "ddraw.lib" "${PROJECT_SOURCE_DIR}/fmodvc.lib") + target_link_libraries(${app}_sgp PRIVATE libpng) + target_compile_definitions(${app}_sgp PRIVATE NO_ZLIB_COMPRESSION) endforeach() diff --git a/Ja2/CMakeLists.txt b/Ja2/CMakeLists.txt index 7f8806f9..c990339d 100644 --- a/Ja2/CMakeLists.txt +++ b/Ja2/CMakeLists.txt @@ -36,17 +36,3 @@ set(Ja2Src "${CMAKE_CURRENT_SOURCE_DIR}/XML_Layout_MainMenu.cpp" ${CMAKE_CURRENT_SOURCE_DIR}/Res/ja2.rc PARENT_SCOPE) - -set(Ja2_Libraries -"${CMAKE_SOURCE_DIR}/libexpatMT.lib" -"Dbghelp.lib" -Lua -"${CMAKE_SOURCE_DIR}/lua51.lib" -"${CMAKE_SOURCE_DIR}/lua51.vc9.lib" -"Winmm.lib" -"${CMAKE_SOURCE_DIR}/SMACKW32.LIB" -"${CMAKE_SOURCE_DIR}/binkw32.lib" -bfVFS -"ws2_32.lib" -Multiplayer -PARENT_SCOPE) diff --git a/TODO b/TODO index e4bb3a3c..e2e87827 100644 --- a/TODO +++ b/TODO @@ -2,3 +2,4 @@ # priority (LOW,HIGH) and description LOW readd the C4838 (https://learn.microsoft.com/en-us/cpp/error-messages/compiler-warnings/compiler-warning-level-1-c4838) warning to CMakeLists.txt once they're all fixed in the code +HIGH get rid of ENGLISH, GERMAN, etc preprocessor definitions completely. that way i18n can be built just once and language can be changed in the options screen pending game restart (hotloading will likely require more work)