diff --git a/.clangd b/.clangd new file mode 100644 index 0000000..48d3cb0 --- /dev/null +++ b/.clangd @@ -0,0 +1,67 @@ +# Use `zig cc` as the compiler for C files +If: + PathMatch: [ + .*\.c, + .*\.h, + ] +CompileFlags: + Compiler: zig cc +--- +# Use `clang` as the compiler for C files +If: + PathMatch: [ + .*\.c, + .*\.h, + ] +CompileFlags: + Compiler: clang +--- +# Use `zig c++` as the compiler for C++ files +If: + PathMatch: [ + .*\.cpp, + .*\.c\+\+, + .*\.cc, + .*\.cp, + .*\.cppm, + .*\.cxx, + .*\.h\+\+, + .*\.hh, + .*\.hpp, + .*\.hxx, + .*\.inc, + .*\.inl, + .*\.ino, + .*\.ipp, + .*\.ixx, + .*\.re, + .*\.tcc, + .*\.tpp, + ] +CompileFlags: + Compiler: zig c++ +--- +# Use `clang++` as the compiler for C++ files +If: + PathMatch: [ + .*\.cpp, + .*\.c\+\+, + .*\.cc, + .*\.cp, + .*\.cppm, + .*\.cxx, + .*\.h\+\+, + .*\.hh, + .*\.hpp, + .*\.hxx, + .*\.inc, + .*\.inl, + .*\.ino, + .*\.ipp, + .*\.ixx, + .*\.re, + .*\.tcc, + .*\.tpp, + ] +CompileFlags: + Compiler: clang++ \ No newline at end of file diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 8c05570..dc92e44 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -3,9 +3,9 @@ name: CI on: [ push, pull_request ] jobs: - ci: + native-compilation: runs-on: [ self-hosted, Windows ] - name: CI + name: Native Compilation steps: - uses: actions/checkout@v4 @@ -37,7 +37,52 @@ jobs: - name: Upload Artifact uses: actions/upload-artifact@v4 with: - name: RelWithDebInfo-Clang + name: RelWithDebInfo-Native-Clang path: | build/YimMenuV2-dev-*.dll build/YimMenuV2-dev-*.pdb + + cross-compilation: + runs-on: ubuntu-latest + name: Cross-compilation + strategy: + matrix: + compiler: ["Zig", "Clang"] + steps: + - uses: actions/checkout@v4 + + - name: Setup Zig + if: matrix.compiler == 'Zig' + uses: mlugg/setup-zig@v2 + + - name: Setup MinGW + if: matrix.compiler == 'Clang' + run: | + sudo apt-get update + sudo apt-get install -y clang lld binutils-mingw-w64-x86-64 mingw-w64-x86-64-dev gcc-mingw-w64-x86-64 g++-mingw-w64-x86-64 + + - name: Check CMake version + run: cmake --version + + - name: Generate CMake project + run: cmake -DUSE_CROSSCOMPILER=${{ matrix.compiler }} -DCMAKE_BUILD_TYPE=RelWithDebInfo -S . -B build -G Ninja + + - name: Build 64bit RelWithDebInfo DLL + run: cmake --build ./build --config RelWithDebInfo --target YimMenuV2 -- + + - name: Check if DLL got built + run: if [ ! -f build/libYimMenuV2.dll ]; then exit 1; fi + + - name: Rename DLL to libYimMenuV2-dev-{GITHUB_SHA}.dll + run: | + mv libYimMenuV2.dll libYimMenuV2-dev-${{github.sha}}.dll + mv libYimMenuV2.pdb libYimMenuV2-dev-${{github.sha}}.pdb || true + working-directory: build/ + + - name: Upload Artifact + uses: actions/upload-artifact@v4 + with: + name: RelWithDebInfo-Cross-${{ matrix.compiler }} + path: | + build/libYimMenuV2-dev-*.dll + build/libYimMenuV2-dev-*.pdb diff --git a/.vscode/settings.json b/.vscode/settings.json index ee84d27..68101ac 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,6 +1,9 @@ { + "cmake.configureSettings": { + "CMAKE_GENERATOR": "Ninja" + }, "files.associations": { - "*.c": "c", + ".clangd": "yaml", "string_view": "cpp", "algorithm": "cpp", "atomic": "cpp", diff --git a/CMakeLists.txt b/CMakeLists.txt index 8ebed46..7ac9344 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -38,4 +38,22 @@ target_include_directories(${PROJECT_NAME} PRIVATE ) message(STATUS "Setting up linked libraries") -target_link_libraries(${PROJECT_NAME} PRIVATE AsyncLogger imgui minhook nlohmann_json::nlohmann_json dbghelp d3dcompiler dwmapi) \ No newline at end of file +target_link_libraries(${PROJECT_NAME} PRIVATE + # Project dependencies + AsyncLogger + imgui + minhook + nlohmann_json::nlohmann_json + dbghelp + + # ImGui dependencies + $,d3dcompiler_47,d3dcompiler> + dwmapi + gdi32 +) + +target_compile_options(${PROJECT_NAME} PRIVATE + # Do not warn about non-reproducible code + $<$:-Wno-date-time> + $<$:-Wno-date-time> +) diff --git a/cmake/cross-compile.cmake b/cmake/cross-compile.cmake index 1cee051..c255833 100644 --- a/cmake/cross-compile.cmake +++ b/cmake/cross-compile.cmake @@ -1,46 +1,172 @@ -# credits to @tupoy-ya for this -option(USE_GCC "Use MinGW toolchain with gcc compiler and uasm assembler.") -option(USE_CLANG "Use MinGW toolchain with clang compiler and uasm assembler. Clang support is experimental.") +if(WIN32 OR CYGWIN) + set(CROSSCOMPILE_DEFAULT OFF) +else() + set(CROSSCOMPILE_DEFAULT ON) +endif() -if(USE_GCC OR USE_CLANG) - message(STATUS "Cross-compile is enabled. Using MinGW and uasm.") +option(CROSSCOMPILE "Enable cross-compilation by using Zig/Clang(with MinGW) toolchain." ${CROSSCOMPILE_DEFAULT}) - set(TOOLCHAIN_PREFIX "x86_64-w64-mingw32" CACHE STRING "Set toolchain. Default: x86_64-w64-mingw32") - message(STATUS "Using ${TOOLCHAIN_PREFIX} toolchain") - set(CMAKE_FIND_ROOT_PATH /usr/x86_64-w64-mingw32) - set(CMAKE_ASM_MASM_COMPILER "uasm") +if(CROSSCOMPILE) + message(STATUS "Cross-compile is enabled.") - set(CMAKE_Fortran_COMPILER ${TOOLCHAIN_PREFIX}-gfortran) - set(CMAKE_RC_COMPILER ${TOOLCHAIN_PREFIX}-windres) + # Set the CMake system name to Windows for cross-compilation + set(CMAKE_SYSTEM_NAME Windows) - # modify default behavior of FIND_XXX() commands + # adjust the default behavior of the FIND_XXX() commands: + # search programs in the host environment set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) + + # search headers and libraries in the target environment set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) - add_compile_options("$<$:-win64${ASM_MASM_FLAGS}>") + # Link statically to avoid runtime dependencies add_link_options(-static) - add_compile_definitions(CROSSCOMPILING) - if(USE_GCC) - # Disable RTTI to work around libstdc++ issue https://stackoverflow.com/a/77025827 - add_compile_options("$<$:-fpermissive;-fno-rtti${CXX_FLAGS}>") - set(CMAKE_C_COMPILER ${TOOLCHAIN_PREFIX}-gcc) - set(CMAKE_CXX_COMPILER ${TOOLCHAIN_PREFIX}-g++) - set(CMAKE_C_COMPILER_TARGET x86_64-windows-gnu) - set(CMAKE_CXX_COMPILER_TARGET x86_64-windows-gnu) + # Detect available compilers + message(STATUS "Searching for compiler...") + + # Force specific compiler by using CMake cache variables + set(USE_CROSSCOMPILER "Auto" CACHE STRING "Cross-compiler to use (default: Auto)") + set_property(CACHE USE_CROSSCOMPILER PROPERTY STRINGS "Auto" "Zig" "Clang") + + # Seach for Zig + find_program(ZIG_EXECUTABLE zig) + if(ZIG_EXECUTABLE AND (USE_CROSSCOMPILER STREQUAL "Auto" OR USE_CROSSCOMPILER STREQUAL "Zig")) + set(USE_CROSSCOMPILER "Zig") + elseif(NOT ZIG_EXECUTABLE) + message(STATUS "Zig compiler not found.") endif() - if(USE_CLANG) - message(STATUS "Using clang compiler.") - set(CMAKE_C_COMPILER clang) - set(CMAKE_CXX_COMPILER clang++) - set(CMAKE_C_COMPILER_TARGET x86_64-windows-msvc) - set(CMAKE_CXX_COMPILER_TARGET x86_64-windows-msvc) + # Search for Clang + find_program(CLANG_EXECUTABLE clang) + if(CLANG_EXECUTABLE AND (USE_CROSSCOMPILER STREQUAL "Auto" OR USE_CROSSCOMPILER STREQUAL "Clang")) + set(USE_CROSSCOMPILER "Clang") + elseif(NOT CLANG_EXECUTABLE) + message(STATUS "Clang compiler not found.") + endif() + + # Configure the toolchain based on the selected compiler + if(USE_CROSSCOMPILER STREQUAL "Zig") + + message(STATUS "Using Zig for cross-compilation.") + + # Set Zig target triple + set(ZIG_ARCH "x86_64") + set(ZIG_SYS "windows") + set(ZIG_ENV "gnu") # "msvc" will not work, as it lacks libc support + set(ZIG_TARGET "${ZIG_ARCH}-${ZIG_SYS}-${ZIG_ENV}") + + # Define Zig toolchain commands + # Some of them intentionally are not in double quotes + set(ZIG_AR "${ZIG_EXECUTABLE} ar") + set(ZIG_CC ${ZIG_EXECUTABLE} cc) + set(ZIG_CXX ${ZIG_EXECUTABLE} c++) + #set(ZIG_DLLTOOL "${ZIG_EXECUTABLE} dlltool") + set(ZIG_LD "${ZIG_EXECUTABLE} ld.lld") + #set(ZIG_LIB "${ZIG_EXECUTABLE} lib") + set(ZIG_RANLIB "${ZIG_EXECUTABLE} ranlib") + #set(ZIG_OBJCOPY "${ZIG_EXECUTABLE} objcopy") + set(ZIG_RC "${ZIG_EXECUTABLE} rc") + + # Setup archive commands + # We're not using `CMAKE_AR` and `CMAKE_RANLIB` because they expect path without arguments + # and `ar` and `ranlib` are arguments of `zig` command + set(CMAKE_C_ARCHIVE_CREATE "${ZIG_AR} qc ") + set(CMAKE_CXX_ARCHIVE_CREATE "${ZIG_AR} qc ") + set(CMAKE_C_ARCHIVE_APPEND "${ZIG_AR} q ") + set(CMAKE_CXX_ARCHIVE_APPEND "${ZIG_AR} q ") + set(CMAKE_C_ARCHIVE_FINISH "${ZIG_RANLIB} ") + set(CMAKE_CXX_ARCHIVE_FINISH "${ZIG_RANLIB} ") + + # Setup compiler + set(CMAKE_C_COMPILER ${ZIG_CC} -target ${ZIG_TARGET}) + set(CMAKE_CXX_COMPILER ${ZIG_CXX} -target ${ZIG_TARGET}) + set(CMAKE_C_COMPILER_TARGET ${ZIG_TARGET}) + set(CMAKE_CXX_COMPILER_TARGET ${ZIG_TARGET}) + + # Setup linker + set(CMAKE_LINKER_TYPE LLD) + if (CMAKE_VERSION VERSION_LESS "4.0.0") + set(CMAKE_C_USING_LINKER_MODE TOOL) + set(CMAKE_CXX_USING_LINKER_MODE TOOL) + else() + set(CMAKE_C_LINK_MODE LINKER) + set(CMAKE_CXX_LINK_MODE LINKER) + endif() + set(CMAKE_C_USING_LINKER_LLD ${ZIG_LD}) + set(CMAKE_CXX_USING_LINKER_LLD ${ZIG_LD}) + + # Setup resource compiler + set(CMAKE_RC_COMPILER ${ZIG_RC}) + + # Enable Microsoft Extensions for Zig (__try/__except/__finally, etc.) + add_compile_options("$<$:-fms-extensions${C_FLAGS}>") + add_compile_options("$<$:-fms-extensions${CXX_FLAGS}>") + + elseif(USE_CROSSCOMPILER STREQUAL "Clang") + + message(STATUS "Using Clang(MinGW) compiler.") + + set(TOOLCHAIN_PREFIX "auto" CACHE STRING "Set toolchain. Default: auto") + + if(TOOLCHAIN_PREFIX STREQUAL "auto") + # Define list of possible toolchain prefixes to try + set(POSSIBLE_TOOLCHAIN_PREFIXES + "x86_64-w64-mingw32ucrt" + "x86_64-w64-mingw32" + ) + + # Probe each prefix to find the first existing one + foreach(PREFIX ${POSSIBLE_TOOLCHAIN_PREFIXES}) + if(EXISTS "/usr/${PREFIX}") + set(TOOLCHAIN_PREFIX ${PREFIX}) + set(CMAKE_FIND_ROOT_PATH /usr/${TOOLCHAIN_PREFIX}) + message(STATUS "Found toolchain: ${TOOLCHAIN_PREFIX}") + break() + endif() + endforeach() + + # Check if we found a valid toolchain + if(TOOLCHAIN_PREFIX STREQUAL "auto") + message(FATAL_ERROR "No MinGW toolchain found in /usr/. Tried: ${POSSIBLE_TOOLCHAIN_PREFIXES}") + endif() + message(STATUS "Using auto-detected toolchain.") + else() + # Use the specified by user toolchain prefix + set(CMAKE_FIND_ROOT_PATH /usr/${TOOLCHAIN_PREFIX}) + message(STATUS "Using specified toolchain prefix: ${TOOLCHAIN_PREFIX}") + endif() + + set(CMAKE_C_COMPILER ${CLANG_EXECUTABLE}) + set(CMAKE_CXX_COMPILER ${CLANG_EXECUTABLE}++) + set(CMAKE_C_COMPILER_TARGET ${TOOLCHAIN_PREFIX}) + set(CMAKE_CXX_COMPILER_TARGET ${TOOLCHAIN_PREFIX}) + + # Enable Microsoft Extensions for Clang (__try/__except/__finally, etc.) + add_compile_options("$<$:-fms-extensions${C_FLAGS}>") + add_compile_options("$<$:-fms-extensions${CXX_FLAGS}>") + + # Emulate TLS for Clang + # This is needed for compatibility with MinGW's libstdc++. + # See https://github.com/msys2/MINGW-packages/issues/5786 + add_compile_options("$<$:-femulated-tls${CXX_FLAGS}>") # Disable RTTI to work around libstdc++ issue https://stackoverflow.com/a/77025827 add_compile_options("$<$:-fuse-ld=lld;-fno-rtti${CXX_FLAGS}>") add_link_options(-fuse-ld=lld -fno-rtti) + + else() + + message(FATAL_ERROR + "No suitable cross-compilation toolchain found." + "\nInstall either:" + "\n - Zig:" + "\n - Just install Zig and make sure it is in PATH." + "\n - Clang:" + "\n - Install Clang and MinGW toolchain (recommended: x86_64-w64-mingw32ucrt)." + ) + endif() endif() \ No newline at end of file diff --git a/cmake/imgui.cmake b/cmake/imgui.cmake index 6677894..48d4898 100644 --- a/cmake/imgui.cmake +++ b/cmake/imgui.cmake @@ -6,28 +6,23 @@ message(STATUS "Setting up ${LIB_NAME}") FetchContent_Declare( ${LIB_NAME} GIT_REPOSITORY https://github.com/ocornut/imgui - GIT_TAG v1.91.9 + GIT_TAG 725d185a31f860b74014aba167aa69003d12c01a GIT_PROGRESS TRUE ) +FetchContent_MakeAvailable(${LIB_NAME}) -FetchContent_GetProperties(${LIB_NAME}) +file(GLOB SRC_IMGUI + "${imgui_SOURCE_DIR}/*.cpp" + "${imgui_SOURCE_DIR}/*.h" + "${imgui_SOURCE_DIR}/backends/imgui_impl_win32.*" + "${imgui_SOURCE_DIR}/backends/imgui_impl_dx12.*" + "${imgui_SOURCE_DIR}/misc/cpp/imgui_stdlib.*" +) -if(NOT imgui_POPULATED) - FetchContent_Populate(${LIB_NAME}) - - file(GLOB SRC_IMGUI - "${imgui_SOURCE_DIR}/*.cpp" - "${imgui_SOURCE_DIR}/*.h" - "${imgui_SOURCE_DIR}/backends/imgui_impl_win32.*" - "${imgui_SOURCE_DIR}/backends/imgui_impl_dx12.*" - "${imgui_SOURCE_DIR}/misc/cpp/imgui_stdlib.*" - ) - - add_library(imgui STATIC ${SRC_IMGUI}) - source_group(TREE ${imgui_SOURCE_DIR} PREFIX "imgui" FILES ${SRC_IMGUI}) - target_include_directories(imgui PRIVATE - "${imgui_SOURCE_DIR}" - "${imgui_SOURCE_DIR}/backends" - "${imgui_SOURCE_DIR}/misc/cpp" - ) -endif() \ No newline at end of file +add_library(imgui STATIC ${SRC_IMGUI}) +source_group(TREE ${imgui_SOURCE_DIR} PREFIX "imgui" FILES ${SRC_IMGUI}) +target_include_directories(imgui PRIVATE + "${imgui_SOURCE_DIR}" + "${imgui_SOURCE_DIR}/backends" + "${imgui_SOURCE_DIR}/misc/cpp" +) \ No newline at end of file diff --git a/src/game/frontend/submenus/Self/Weapons.cpp b/src/game/frontend/submenus/Self/Weapons.cpp index 0638a72..f42ec71 100644 --- a/src/game/frontend/submenus/Self/Weapons.cpp +++ b/src/game/frontend/submenus/Self/Weapons.cpp @@ -153,7 +153,7 @@ namespace YimMenu::Submenus }); } - if (*Pointers.IsSessionStarted && selectedWeaponHash != NULL) + if (*Pointers.IsSessionStarted && selectedWeaponHash != 0) { ImGui::Text("Kills With: %d", kills); ImGui::Text("Deaths By: %d", deaths);