diff --git a/CMakeLists.txt b/CMakeLists.txt index 5d8ba774b..95fc333df 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2,21 +2,27 @@ cmake_minimum_required(VERSION 3.24.0) project(Flarial) set(CMAKE_CXX_STANDARD 23) +set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded") -set(CLIENT_VERSION "2.00") # Update this for every new release - -set(CLIENT_BUILD_TYPE "Release") -if (CMAKE_BUILD_TYPE STREQUAL "Debug") - set(CLIENT_BUILD_TYPE "Debug") - add_compile_definitions(__DEBUG__) -elseif (CMAKE_BUILD_TYPE STREQUAL "Test") - set(CLIENT_BUILD_TYPE "Test") - add_compile_definitions(__TEST__) +get_property(IS_MULTI_CONFIG GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG) +if (IS_MULTI_CONFIG) + set(CMAKE_CONFIGURATION_TYPES "Debug;Release;Test" CACHE STRING "Supported build configurations" FORCE) else() - set(CLIENT_BUILD_TYPE "Release") - add_compile_definitions(__RELEASE__) + set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS Debug Release Test) + if (NOT CMAKE_BUILD_TYPE) + set(CMAKE_BUILD_TYPE "Release" CACHE STRING "Build type" FORCE) + endif() endif() +set(CLIENT_VERSION "2.00") # Update this for every new release + +set(FLARIAL_BUILD_TYPE_EXPR "$,Debug,$,Test,Release>>") +add_compile_definitions( + $<$:__DEBUG__> + $<$:__TEST__> + $<$,$>>:__RELEASE__> +) + execute_process( COMMAND git rev-parse --short HEAD OUTPUT_VARIABLE COMMIT_HASH @@ -51,21 +57,18 @@ add_compile_options($<$:/Ob2>) add_compile_options(/bigobj) add_compile_options(/utf-8) -if (CMAKE_BUILD_TYPE STREQUAL "Release" OR CMAKE_BUILD_TYPE STREQUAL "Test") - # Optimize for performance with debug info for symbolication - add_compile_options(/O2 /Oi /Gy /Gw /GF /fp:fast /Gd /MT /Ob2 /Zi) - # Generate PDB with optimizations preserved - add_link_options(/DEBUG /OPT:REF /OPT:ICF) - set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded") - # Ignore debug runtime library to avoid conflicts - add_link_options(/NODEFAULTLIB:MSVCRTD) -elseif (CMAKE_BUILD_TYPE STREQUAL "Debug") - # Optimize for build time - add_compile_options(/Od /Zi /MT) - set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded") - # Ignore debug runtime library to avoid conflicts - add_link_options(/NODEFAULTLIB:MSVCRTD) -endif() +add_compile_options(/FS) +add_compile_options($<$:/EHsc>) + +# Preserve the intended runtime / debug-info behavior for both single-config and multi-config generators. +add_compile_options($<$,$>:/fp:fast>) +add_compile_options($<$,$>:/Zi>) +add_compile_options($<$:/Od>) +add_compile_options($<$:/Zi>) +add_link_options($<$,$>:/DEBUG>) +add_link_options($<$,$>:/OPT:REF>) +add_link_options($<$,$>:/OPT:ICF>) +add_link_options(/NODEFAULTLIB:MSVCRTD) # Generate version and build date string(TIMESTAMP BUILD_DATE "%Y-%m-%d %H:%M:%S" UTC) @@ -73,12 +76,12 @@ set(FLARIAL_BUILD_DATE "${BUILD_DATE}") add_compile_definitions( FLARIAL_VERSION=\"${CLIENT_VERSION}\" - FLARIAL_BUILD_TYPE=\"${CLIENT_BUILD_TYPE}\" + FLARIAL_BUILD_TYPE=\"${FLARIAL_BUILD_TYPE_EXPR}\" FLARIAL_BUILD_DATE=\"${FLARIAL_BUILD_DATE}\" ) -file(GLOB_RECURSE SOURCE_FILES "src/*.cpp" "src/*.hpp") -file(GLOB_RECURSE LIB_FILES "lib/*.cpp" "lib/*.h") +file(GLOB_RECURSE SOURCE_FILES CONFIGURE_DEPENDS "src/*.cpp" "src/*.hpp") +file(GLOB_RECURSE LIB_FILES CONFIGURE_DEPENDS "lib/*.cpp" "lib/*.h") add_library(Flarial SHARED main.cpp ${SOURCE_FILES} ${LIB_FILES} src/Assets/Assets.rc src/SDK/Client/Network/Packet/AnimatePacket.hpp src/Client/Module/Modules/Subtitles/Subtitles.cpp @@ -86,6 +89,73 @@ add_library(Flarial SHARED main.cpp ${SOURCE_FILES} ${LIB_FILES} src/Assets/Asse src/Client/Events/Game/SoundEnginePlayEvent.hpp src/SDK/Client/Network/Packet/TakeItemActorPacket.hpp) +function(flarial_assign_unique_object_names target) + if (NOT MSVC) + return() + endif() + + get_target_property(target_sources ${target} SOURCES) + if (NOT target_sources) + return() + endif() + + set(compiled_sources) + foreach(source IN LISTS target_sources) + if (IS_ABSOLUTE "${source}") + set(source_path "${source}") + else() + set(source_path "${CMAKE_CURRENT_SOURCE_DIR}/${source}") + endif() + + get_filename_component(source_ext "${source_path}" EXT) + string(TOLOWER "${source_ext}" source_ext_lower) + if (NOT source_ext_lower STREQUAL ".c" AND + NOT source_ext_lower STREQUAL ".cc" AND + NOT source_ext_lower STREQUAL ".cxx" AND + NOT source_ext_lower STREQUAL ".cpp") + continue() + endif() + + get_filename_component(source_name "${source_path}" NAME_WE) + string(TOLOWER "${source_name}" source_name_lower) + set(source_count_var "FLARIAL_SOURCE_BASENAME_COUNT_${source_name_lower}") + if (DEFINED ${source_count_var}) + math(EXPR ${source_count_var} "${${source_count_var}} + 1") + else() + set(${source_count_var} 1) + endif() + + list(APPEND compiled_sources "${source}") + endforeach() + + foreach(source IN LISTS compiled_sources) + if (IS_ABSOLUTE "${source}") + set(source_path "${source}") + else() + set(source_path "${CMAKE_CURRENT_SOURCE_DIR}/${source}") + endif() + + get_filename_component(source_name "${source_path}" NAME_WE) + string(TOLOWER "${source_name}" source_name_lower) + set(source_count_var "FLARIAL_SOURCE_BASENAME_COUNT_${source_name_lower}") + if (NOT ${${source_count_var}} GREATER 1) + continue() + endif() + + file(RELATIVE_PATH rel_source_path "${CMAKE_CURRENT_SOURCE_DIR}" "${source_path}") + get_filename_component(rel_source_dir "${rel_source_path}" DIRECTORY) + set(unique_object_name "${rel_source_dir}_${source_name}") + string(REGEX REPLACE "[^A-Za-z0-9_]" "_" unique_object_name "${unique_object_name}") + + # Visual Studio uses a flat object-output directory by default; duplicate + # basenames like Manager.cpp would otherwise collide under the same .obj path. + set_property(SOURCE "${source}" APPEND PROPERTY COMPILE_OPTIONS + "/Fo$(IntDir)${unique_object_name}.obj") + endforeach() +endfunction() + +flarial_assign_unique_object_names(Flarial) + target_include_directories(Flarial PRIVATE "." "src" @@ -114,11 +184,12 @@ set_target_properties(MinHook PROPERTIES IMPORTED_IMPLIB "${CMAKE_CURRENT_SOURCE add_library(FreeType SHARED IMPORTED GLOBAL) set_target_properties(FreeType PROPERTIES IMPORTED_IMPLIB "${CMAKE_CURRENT_SOURCE_DIR}/lib/freetype/libs/freetype.lib") -add_library(libcurl SHARED IMPORTED GLOBAL) +add_library(libcurl STATIC IMPORTED GLOBAL) set_target_properties(libcurl PROPERTIES MSVC_RUNTIME_LIBRARY "MultiThreaded" + INTERFACE_COMPILE_DEFINITIONS "CURL_STATICLIB" + IMPORTED_LOCATION "${CMAKE_CURRENT_SOURCE_DIR}/lib/curl/libcurl.lib" ) -set_target_properties(libcurl PROPERTIES IMPORTED_IMPLIB "${CMAKE_CURRENT_SOURCE_DIR}/lib/curl/libcurl.lib") add_library(zlib SHARED IMPORTED GLOBAL) set_target_properties(zlib PROPERTIES @@ -127,6 +198,7 @@ set_target_properties(zlib PROPERTIES set_target_properties(zlib PROPERTIES IMPORTED_IMPLIB "${CMAKE_CURRENT_SOURCE_DIR}/lib/curl/zlib.lib") include(FetchContent) +set(FETCHCONTENT_UPDATES_DISCONNECTED ON CACHE BOOL "" FORCE) FetchContent_Declare( entt @@ -143,13 +215,13 @@ FetchContent_Declare( FetchContent_Declare( libhat GIT_REPOSITORY https://github.com/BasedInc/libhat.git - GIT_TAG d6297514b05fd238f5b46d003325f108c22741e3 + GIT_TAG v0.9.0 ) FetchContent_Declare( fmt GIT_REPOSITORY https://github.com/fmtlib/fmt.git - GIT_TAG master + GIT_TAG 12.1.0 ) FetchContent_Declare( @@ -191,7 +263,11 @@ FetchContent_Declare( set(FMT_MODULE OFF CACHE BOOL "" FORCE) FetchContent_MakeAvailable(libhat entt nes fmt magic_enum LuaBridge safetyhook jsoncpp discord-rpc rift) -target_link_libraries(Flarial PRIVATE jsoncpp safetyhook libcurl ws2_32.lib crypt32.lib normaliz.lib wldap32.lib LuaBridge lua_static libhat fmt::fmt EnTT::EnTT NES windowscodecs.lib urlmon.lib dwrite.lib d3d12.lib dxgi.lib d3d11.lib d2d1.lib wininet.lib setupapi.lib version FreeType magic_enum runtimeobject discord-rpc rift) +target_link_libraries(Flarial PRIVATE jsoncpp safetyhook libcurl ws2_32.lib crypt32.lib normaliz.lib wldap32.lib bcrypt.lib secur32.lib iphlpapi.lib advapi32.lib LuaBridge lua_static libhat fmt::fmt EnTT::EnTT NES windowscodecs.lib urlmon.lib dwrite.lib d3d12.lib dxgi.lib d3d11.lib d2d1.lib wininet.lib setupapi.lib version FreeType magic_enum runtimeobject discord-rpc rift) + +# curl 8.17 protocol-handler table is referenced only internally; without WHOLEARCHIVE, +# LTCG strips Curl_handler_http/https/ws/wss and curl_easy_perform returns CURLE_UNSUPPORTED_PROTOCOL. +target_link_options(Flarial PRIVATE "/WHOLEARCHIVE:libcurl.lib") target_link_libraries(Flarial PUBLIC MinHook)