From b1134b340f9ef61a7571d5387992df9e9524d3c7 Mon Sep 17 00:00:00 2001 From: David Markowitz <39972741+EmosewaMC@users.noreply.github.com> Date: Tue, 2 Jan 2024 16:25:57 -0800 Subject: [PATCH] Add config update function (#1379) Update CMakeLists.txt FINALLY dont ignore cmake module directory move to separate file very cool feature tested that this still works Co-authored-by: Aaron Kimbrell --- .gitignore | 1 + CMakeLists.txt | 63 ++++++++++++++++++++++++++++++----------------- cmake/Utils.cmake | 47 +++++++++++++++++++++++++++++++++++ 3 files changed, 89 insertions(+), 22 deletions(-) create mode 100644 cmake/Utils.cmake diff --git a/.gitignore b/.gitignore index e093ba4b..12a3b284 100644 --- a/.gitignore +++ b/.gitignore @@ -122,3 +122,4 @@ docker/__pycache__ docker-compose.override.yml !*Test.bin +!cmake/* diff --git a/CMakeLists.txt b/CMakeLists.txt index 5d47c595..06fb3992 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -3,6 +3,7 @@ project(Darkflame) include(CTest) set(CMAKE_CXX_STANDARD 20) +set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake") # Read variables from file FILE(READ "${CMAKE_SOURCE_DIR}/CMakeVariables.txt" variables) @@ -14,14 +15,13 @@ string(REPLACE "\n" ";" variables ${variables}) foreach(variable ${variables}) # If the string contains a #, skip it if(NOT "${variable}" MATCHES "#") - # Split the variable into name and value string(REPLACE "=" ";" variable ${variable}) # Check that the length of the variable is 2 (name and value) list(LENGTH variable length) - if(${length} EQUAL 2) + if(${length} EQUAL 2) list(GET variable 0 variable_name) list(GET variable 1 variable_value) @@ -53,15 +53,16 @@ set(RECASTNAVIGATION_EXAMPLES OFF CACHE BOOL "" FORCE) if(UNIX) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=gnu++17 -O2 -Wuninitialized -fPIC") add_compile_definitions(_GLIBCXX_USE_CXX11_ABI=0 _GLIBCXX_USE_CXX17_ABI=0) + if(NOT APPLE) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -static-libgcc -lstdc++fs") endif() - if (${DYNAMIC} AND CMAKE_CXX_COMPILER_ID STREQUAL "GNU") + if(${DYNAMIC} AND CMAKE_CXX_COMPILER_ID STREQUAL "GNU") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -rdynamic") endif() - if (${GGDB}) + if(${GGDB}) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -ggdb") endif() @@ -97,47 +98,61 @@ make_directory(${CMAKE_BINARY_DIR}/logs) # Copy resource files on first build set(RESOURCE_FILES "sharedconfig.ini" "authconfig.ini" "chatconfig.ini" "worldconfig.ini" "masterconfig.ini" "blacklist.dcf") message(STATUS "Checking resource file integrity") -foreach (resource_file ${RESOURCE_FILES}) + +include(Utils) + +foreach(resource_file ${RESOURCE_FILES}) set(file_size 0) - if (EXISTS ${PROJECT_BINARY_DIR}/${resource_file}) + + if(EXISTS ${PROJECT_BINARY_DIR}/${resource_file}) file(SIZE ${PROJECT_BINARY_DIR}/${resource_file} file_size) endif() - if (${file_size} EQUAL 0) + + if(${file_size} EQUAL 0) configure_file( ${CMAKE_SOURCE_DIR}/resources/${resource_file} ${PROJECT_BINARY_DIR}/${resource_file} COPYONLY ) message(STATUS "Moved " ${resource_file} " to project binary directory") - elseif (resource_file MATCHES ".ini") + elseif(resource_file MATCHES ".ini") message(STATUS "Checking " ${resource_file} " for missing config options") file(READ ${PROJECT_BINARY_DIR}/${resource_file} current_file_contents) string(REPLACE "\\\n" "" current_file_contents ${current_file_contents}) string(REPLACE "\n" ";" current_file_contents ${current_file_contents}) set(parsed_current_file_contents "") + # Remove comment lines so they do not interfere with the variable parsing - foreach (line ${current_file_contents}) + foreach(line ${current_file_contents}) string(FIND ${line} "#" is_comment) - if (NOT ${is_comment} EQUAL 0) + + if(NOT ${is_comment} EQUAL 0) string(APPEND parsed_current_file_contents ${line}) endif() endforeach() + file(READ ${CMAKE_SOURCE_DIR}/resources/${resource_file} depot_file_contents) string(REPLACE "\\\n" "" depot_file_contents ${depot_file_contents}) string(REPLACE "\n" ";" depot_file_contents ${depot_file_contents}) set(line_to_add "") - foreach (line ${depot_file_contents}) + + foreach(line ${depot_file_contents}) string(FIND ${line} "#" is_comment) - if (NOT ${is_comment} EQUAL 0) + + if(NOT ${is_comment} EQUAL 0) string(REPLACE "=" ";" line_split ${line}) list(GET line_split 0 variable_name) - if (NOT ${parsed_current_file_contents} MATCHES ${variable_name}) + + if(NOT ${parsed_current_file_contents} MATCHES ${variable_name}) message(STATUS "Adding missing config option " ${variable_name} " to " ${resource_file}) set(line_to_add ${line_to_add} ${line}) - foreach (line_to_append ${line_to_add}) + + foreach(line_to_append ${line_to_add}) file(APPEND ${PROJECT_BINARY_DIR}/${resource_file} "\n" ${line_to_append}) endforeach() + file(APPEND ${PROJECT_BINARY_DIR}/${resource_file} "\n") endif() + set(line_to_add "") else() set(line_to_add ${line_to_add} ${line}) @@ -145,10 +160,11 @@ foreach (resource_file ${RESOURCE_FILES}) endforeach() endif() endforeach() + message(STATUS "Resource file integrity check complete") # if navmeshes directory does not exist, create it -if (NOT EXISTS ${PROJECT_BINARY_DIR}/navmeshes) +if(NOT EXISTS ${PROJECT_BINARY_DIR}/navmeshes) file(MAKE_DIRECTORY ${PROJECT_BINARY_DIR}/navmeshes) endif() @@ -160,6 +176,7 @@ file(REMOVE ${PROJECT_BINARY_DIR}/navmeshes.zip) # Copy vanity files on first build set(VANITY_FILES "CREDITS.md" "INFO.md" "TESTAMENT.md" "NPC.xml") + foreach(file ${VANITY_FILES}) configure_file("${CMAKE_SOURCE_DIR}/vanity/${file}" "${CMAKE_BINARY_DIR}/vanity/${file}" COPYONLY) endforeach() @@ -167,6 +184,7 @@ endforeach() # Move our migrations for MasterServer to run file(MAKE_DIRECTORY ${PROJECT_BINARY_DIR}/migrations/dlu/) file(GLOB SQL_FILES ${CMAKE_SOURCE_DIR}/migrations/dlu/*.sql) + foreach(file ${SQL_FILES}) get_filename_component(file ${file} NAME) configure_file(${CMAKE_SOURCE_DIR}/migrations/dlu/${file} ${PROJECT_BINARY_DIR}/migrations/dlu/${file}) @@ -174,6 +192,7 @@ endforeach() file(MAKE_DIRECTORY ${PROJECT_BINARY_DIR}/migrations/cdserver/) file(GLOB SQL_FILES ${CMAKE_SOURCE_DIR}/migrations/cdserver/*.sql) + foreach(file ${SQL_FILES}) get_filename_component(file ${file} NAME) configure_file(${CMAKE_SOURCE_DIR}/migrations/cdserver/${file} ${PROJECT_BINARY_DIR}/migrations/cdserver/${file}) @@ -301,20 +320,20 @@ set(INCLUDED_DIRECTORIES ) # Add system specfic includes for Apple, Windows and Other Unix OS' (including Linux) -if (APPLE) +if(APPLE) include_directories("/usr/local/include/") endif() # Actually include the directories from our list -foreach (dir ${INCLUDED_DIRECTORIES}) +foreach(dir ${INCLUDED_DIRECTORIES}) include_directories(${PROJECT_SOURCE_DIR}/${dir}) endforeach() -if (NOT WIN32) +if(NOT WIN32) include_directories("${PROJECT_SOURCE_DIR}/thirdparty/libbcrypt/include/bcrypt") endif() -include_directories("${PROJECT_SOURCE_DIR}/thirdparty/libbcrypt/include") +include_directories("${PROJECT_SOURCE_DIR}/thirdparty/libbcrypt/include") # Add linking directories: link_directories(${PROJECT_BINARY_DIR}) @@ -368,10 +387,10 @@ add_subdirectory(dPhysics) set(COMMON_LIBRARIES "dCommon" "dDatabase" "dNet" "raknet" "mariadbConnCpp" "magic_enum") # Add platform specific common libraries -if (UNIX) +if(UNIX) set(COMMON_LIBRARIES ${COMMON_LIBRARIES} "dl" "pthread") - if (NOT APPLE AND ${INCLUDE_BACKTRACE}) + if(NOT APPLE AND ${INCLUDE_BACKTRACE}) set(COMMON_LIBRARIES ${COMMON_LIBRARIES} "backtrace") endif() endif() @@ -409,6 +428,6 @@ target_precompile_headers( "$<$:${PROJECT_SOURCE_DIR}/thirdparty/tinyxml2/tinyxml2.h>" ) -if (${ENABLE_TESTING}) +if(${ENABLE_TESTING}) add_subdirectory(tests) endif() diff --git a/cmake/Utils.cmake b/cmake/Utils.cmake new file mode 100644 index 00000000..c0c67ef0 --- /dev/null +++ b/cmake/Utils.cmake @@ -0,0 +1,47 @@ +# Parses a config file for a specific option and appends the new option if it does not exist +# If the new option does exist, this function will do nothing. +# file_name: The name of the file to parse +# old_option_name: The name of the option to find +# new_option_name: The name of the option to add +function(UpdateConfigOption file_name old_option_name new_option_name) + string(APPEND old_option_name "=") + string(APPEND new_option_name "=") + message(STATUS "Checking " ${file_name} " for " ${old_option_name} " and adding " ${new_option_name} " if it does not exist") + file(READ ${file_name} current_file_contents) + string(REPLACE "\\\n" "" current_file_contents ${current_file_contents}) + string(REPLACE "\n" ";" current_file_contents ${current_file_contents}) + set(parsed_current_file_contents "") + + # Remove comment lines so they do not interfere with the variable parsing + foreach(line ${current_file_contents}) + string(FIND ${line} "#" is_comment) + + if(NOT ${is_comment} EQUAL 0) + string(APPEND parsed_current_file_contents ${line}) + endif() + endforeach() + + set(found_new_option -1) + set(found_old_option -1) + set(current_value -1) + + foreach(line ${current_file_contents}) + string(FIND ${line} ${old_option_name} old_option_in_file) + + if(${old_option_in_file} EQUAL 0) + set(found_old_option 1) + set(current_value ${line}) + endif() + + string(FIND ${line} ${new_option_name} found_new_option_in_file) + + if(${found_new_option_in_file} EQUAL 0) + set(found_new_option 1) + endif() + endforeach(line ${current_file_contents}) + + if(${found_old_option} EQUAL 1 AND NOT ${found_new_option} EQUAL 1) + string(REPLACE ${old_option_name} ${new_option_name} current_value ${current_value}) + file(APPEND ${file_name} "\n" ${current_value}) + endif() +endfunction()