From 4b21821aa4b3cf89aad4e59b0df9a04eefe89b99 Mon Sep 17 00:00:00 2001 From: bicarus-dev <202771338+bicarus-dev@users.noreply.github.com> Date: Thu, 16 Oct 2025 16:19:10 -0700 Subject: [PATCH] Introduce builds for Linux, split archive into release and extras (#405) ## Link to GitHub Issue, if one exists n/a ## Description of change Add a "Linux" variant of spicecfg/spice/spice64.exe - currently these are the same as Windows binaries but built without dependency on WinSCard, which makes it easier to run on WINE. Split dist archive into two, move api and extras into the new extras zip. ## Testing I only checked to see that Linux variants run fine on Windows, and checked with dumpbin to confirm that the dependency on winscard DLL is removed. No official support will be provided for Linux builds. --- src/spice2x/CMakeLists.txt | 84 +++++++++++++++++++------- src/spice2x/build_all.sh | 34 ++++++++--- src/spice2x/external/scard/scard.cpp | 3 + src/spice2x/launcher/launcher.cpp | 25 +++++--- src/spice2x/launcher/options.cpp | 4 +- src/spice2x/overlay/windows/config.cpp | 7 +++ 6 files changed, 117 insertions(+), 40 deletions(-) diff --git a/src/spice2x/CMakeLists.txt b/src/spice2x/CMakeLists.txt index a7b6285..5b0c0ad 100644 --- a/src/spice2x/CMakeLists.txt +++ b/src/spice2x/CMakeLists.txt @@ -3,11 +3,6 @@ cmake_policy(SET CMP0069 NEW) project(spicetools) include(CheckIPOSupported) -option(WITH_SCARD "Build spice2x with SCard support" ON) -if(WITH_SCARD) - add_definitions(-DWITH_SCARD) -endif() - # set language level set(CMAKE_CXX_STANDARD 20) set(CMAKE_CXX_STANDARD_REQUIRED TRUE) @@ -367,6 +362,7 @@ set(SOURCE_FILES ${SOURCE_FILES} external/http-parser/http_parser.c external/usbhidusage/usb-hid-usage.c external/toojpeg/toojpeg.cpp + external/scard/scard.cpp # games games/game.cpp @@ -617,9 +613,6 @@ set(SOURCE_FILES ${SOURCE_FILES} util/dependencies.cpp util/deferlog.cpp ) -if(WITH_SCARD) - list(APPEND SOURCE_FILES external/scard/scard.cpp) -endif() source_group(TREE ${CMAKE_CURRENT_SOURCE_DIR} PREFIX "Source Files" FILES ${SOURCE_FILES}) @@ -631,9 +624,7 @@ add_executable(spicetools_spice ${SOURCE_FILES} ${RESOURCE_FILES}) target_link_libraries(spicetools_spice PUBLIC d3d9 ws2_32 version comctl32 shlwapi iphlpapi hid secur32 setupapi psapi winmm winhttp PRIVATE fmt-header-only discord-rpc imgui hash-library minhook imm32 dwmapi CpuFeatures::cpu_features) -if(WITH_SCARD) - target_link_libraries(spicetools_spice PUBLIC winscard) -endif() +target_link_libraries(spicetools_spice PUBLIC winscard) set_target_properties(spicetools_spice PROPERTIES PREFIX "") set_target_properties(spicetools_spice PROPERTIES OUTPUT_NAME "spice") @@ -649,9 +640,7 @@ add_executable(spicetools_spice_laa ${SOURCE_FILES} ${RESOURCE_FILES}) target_link_libraries(spicetools_spice_laa PUBLIC d3d9 ws2_32 version comctl32 shlwapi iphlpapi hid secur32 setupapi psapi winmm winhttp PRIVATE fmt-header-only discord-rpc imgui hash-library minhook imm32 dwmapi CpuFeatures::cpu_features) -if(WITH_SCARD) - target_link_libraries(spicetools_spice_laa PUBLIC winscard) -endif() +target_link_libraries(spicetools_spice_laa PUBLIC winscard) set_target_properties(spicetools_spice_laa PROPERTIES PREFIX "") set_target_properties(spicetools_spice_laa PROPERTIES OUTPUT_NAME "spice_laa") target_compile_definitions(spicetools_spice_laa PRIVATE SPICE32_LARGE_ADDRESS_AWARE=1) @@ -660,6 +649,22 @@ IF(NOT MSVC) set_target_properties(spicetools_spice_laa PROPERTIES COMPILE_FLAGS "-m32" LINK_FLAGS "-m32 -Wl,--large-address-aware") endif() +# spice_linux.exe +########### + +set(RESOURCE_FILES build/manifest.manifest build/manifest.rc build/icon.rc cfg/Win32D.rc) +add_executable(spicetools_spice_linux ${SOURCE_FILES} ${RESOURCE_FILES}) +target_link_libraries(spicetools_spice_linux + PUBLIC d3d9 ws2_32 version comctl32 shlwapi iphlpapi hid secur32 setupapi psapi winmm winhttp + PRIVATE fmt-header-only discord-rpc imgui hash-library minhook imm32 dwmapi CpuFeatures::cpu_features) +set_target_properties(spicetools_spice_linux PROPERTIES PREFIX "") +set_target_properties(spicetools_spice_linux PROPERTIES OUTPUT_NAME "spice_linux") +target_compile_definitions(spicetools_spice_linux PRIVATE NO_SCARD=1 PRIVATE SPICE_LINUX=1) + +IF(NOT MSVC) + set_target_properties(spicetools_spice_linux PROPERTIES COMPILE_FLAGS "-m32" LINK_FLAGS "-m32") +endif() + # spice64.exe ############# @@ -670,9 +675,7 @@ add_executable(spicetools_spice64 ${SOURCE_FILES} ${RESOURCE_FILES}) target_link_libraries(spicetools_spice64 PUBLIC d3d9 ws2_32 version comctl32 shlwapi iphlpapi hid secur32 setupapi psapi winmm winhttp mfuuid strmiids dxva2 PRIVATE fmt-header-only discord-rpc imgui hash-library minhook imm32 dwmapi CpuFeatures::cpu_features) -if(WITH_SCARD) - target_link_libraries(spicetools_spice64 PUBLIC winscard) -endif() +target_link_libraries(spicetools_spice64 PUBLIC winscard) set_target_properties(spicetools_spice64 PROPERTIES PREFIX "") set_target_properties(spicetools_spice64 PROPERTIES OUTPUT_NAME "spice64") target_compile_definitions(spicetools_spice64 PRIVATE SPICE64=1) @@ -681,6 +684,25 @@ IF(NOT MSVC) set_target_properties(spicetools_spice64 PROPERTIES COMPILE_FLAGS "-m64" LINK_FLAGS "-m64") endif() +# spice64_linux.exe +############# + +set(RESOURCE_FILES build/manifest.manifest build/manifest64.rc build/icon.rc cfg/Win32D.rc) +add_executable(spicetools_spice64_linux ${SOURCE_FILES} ${RESOURCE_FILES}) + +# do NOT link against: mf, mfplat, mfreadwrite; otherwise unity games will break +target_link_libraries(spicetools_spice64_linux + PUBLIC d3d9 ws2_32 version comctl32 shlwapi iphlpapi hid secur32 setupapi psapi winmm winhttp mfuuid strmiids dxva2 + PRIVATE fmt-header-only discord-rpc imgui hash-library minhook imm32 dwmapi CpuFeatures::cpu_features) +set_target_properties(spicetools_spice64_linux PROPERTIES PREFIX "") +set_target_properties(spicetools_spice64_linux PROPERTIES OUTPUT_NAME "spice64_linux") +target_compile_definitions(spicetools_spice64_linux PRIVATE SPICE64=1) +target_compile_definitions(spicetools_spice64_linux PRIVATE NO_SCARD=1 PRIVATE SPICE_LINUX=1) + +IF(NOT MSVC) + set_target_properties(spicetools_spice64_linux PROPERTIES COMPILE_FLAGS "-m64" LINK_FLAGS "-m64") +endif() + # spicecfg.exe ############## @@ -690,9 +712,7 @@ add_executable(spicetools_cfg WIN32 ${SOURCE_FILES} ${RESOURCE_FILES}) target_link_libraries(spicetools_cfg PUBLIC ws2_32 version comctl32 shlwapi iphlpapi hid secur32 setupapi psapi winmm winhttp strmiids PRIVATE fmt-header-only discord-rpc imgui hash-library minhook imm32 dwmapi CpuFeatures::cpu_features) -if(WITH_SCARD) - target_link_libraries(spicetools_cfg PUBLIC winscard) -endif() +target_link_libraries(spicetools_cfg PUBLIC winscard) set_target_properties(spicetools_cfg PROPERTIES PREFIX "") set_target_properties(spicetools_cfg PROPERTIES OUTPUT_NAME "spicecfg") target_compile_definitions(spicetools_cfg PRIVATE SPICETOOLS_SPICECFG_STANDALONE=1) @@ -701,6 +721,24 @@ if(NOT MSVC) set_target_properties(spicetools_cfg PROPERTIES COMPILE_FLAGS "-m32" LINK_FLAGS "-m32") endif() +# spicecfg_linux.exe +############## + +set(SOURCE_FILES ${SOURCE_FILES} launcher/options.h launcher/options.cpp) +set(RESOURCE_FILES cfg/manifest.manifest cfg/manifest.rc cfg/icon.rc cfg/Win32D.rc) +add_executable(spicetools_cfg_linux WIN32 ${SOURCE_FILES} ${RESOURCE_FILES}) +target_link_libraries(spicetools_cfg_linux + PUBLIC ws2_32 version comctl32 shlwapi iphlpapi hid secur32 setupapi psapi winmm winhttp strmiids + PRIVATE fmt-header-only discord-rpc imgui hash-library minhook imm32 dwmapi CpuFeatures::cpu_features) +set_target_properties(spicetools_cfg_linux PROPERTIES PREFIX "") +set_target_properties(spicetools_cfg_linux PROPERTIES OUTPUT_NAME "spicecfg_linux") +target_compile_definitions(spicetools_cfg_linux PRIVATE SPICETOOLS_SPICECFG_STANDALONE=1) +target_compile_definitions(spicetools_cfg_linux PRIVATE NO_SCARD=1 PRIVATE SPICE_LINUX=1) + +if(NOT MSVC) + set_target_properties(spicetools_cfg_linux PROPERTIES COMPILE_FLAGS "-m32" LINK_FLAGS "-m32") +endif() + # stubs ####### @@ -794,19 +832,19 @@ endif() #################### # output config -set_target_properties(spicetools_cfg +set_target_properties(spicetools_cfg spicetools_cfg_linux PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/spicetools") # output 32bit -set_target_properties(spicetools_spice spicetools_spice_laa spicetools_stubs_kbt spicetools_stubs_kld spicetools_stubs_cpusbxpkm +set_target_properties(spicetools_spice spicetools_spice_laa spicetools_spice_linux spicetools_stubs_kbt spicetools_stubs_kld spicetools_stubs_cpusbxpkm PROPERTIES ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/archive32" LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/spicetools/32" RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/spicetools/32") # output 64bit -set_target_properties(spicetools_spice64 spicetools_stubs_kbt64 spicetools_stubs_kld64 spicetools_stubs_nvcuda spicetools_stubs_nvcuvid spicetools_stubs_nvEncodeAPI64 +set_target_properties(spicetools_spice64 spicetools_spice64_linux spicetools_stubs_kbt64 spicetools_stubs_kld64 spicetools_stubs_nvcuda spicetools_stubs_nvcuvid spicetools_stubs_nvEncodeAPI64 PROPERTIES ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/archive64" LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/spicetools/64" diff --git a/src/spice2x/build_all.sh b/src/spice2x/build_all.sh index 4283280..21f16c9 100755 --- a/src/spice2x/build_all.sh +++ b/src/spice2x/build_all.sh @@ -49,6 +49,7 @@ BUILDDIR_64_RELEASE="./cmake-build-release-64" BUILDDIR_64_DEBUG="./cmake-build-debug-64" DEBUG=0 OUTDIR="./bin/spice2x" +OUTDIR_EXTRAS="./bin/spice2x_extras" # disabled UPX since it tends to falsely trigger malware detection UPX_ENABLE=0 @@ -60,8 +61,9 @@ DIST_ENABLE=1 DIST_FOLDER="./dist" DIST_NAME="spice2x-$(date +%y)-$(date +%m)-$(date +%d).zip" DIST_COMMENT=${DIST_NAME}$'\n'"$GIT_BRANCH - $GIT_HEAD"$'\nThank you for playing.' -TARGETS_32="spicetools_stubs_kbt spicetools_stubs_kld spicetools_cfg spicetools_spice spicetools_spice_laa spicetools_stubs_cpusbxpkm" -TARGETS_64="spicetools_stubs_kbt64 spicetools_stubs_kld64 spicetools_stubs_nvEncodeAPI64 spicetools_stubs_nvcuvid spicetools_stubs_nvcuda spicetools_spice64" +DIST_NAME_EXTRAS="spice2x-$(date +%y)-$(date +%m)-$(date +%d)-extras.zip" +TARGETS_32="spicetools_stubs_kbt spicetools_stubs_kld spicetools_cfg spicetools_cfg_linux spicetools_spice spicetools_spice_laa spicetools_spice_linux spicetools_stubs_cpusbxpkm" +TARGETS_64="spicetools_stubs_kbt64 spicetools_stubs_kld64 spicetools_stubs_nvEncodeAPI64 spicetools_stubs_nvcuvid spicetools_stubs_nvcuda spicetools_spice64 spicetools_spice64_linux" # determine build type BUILD_TYPE="Release" @@ -179,11 +181,17 @@ fi # copy to output directory echo "Copy files to output directory..." + rm -rf ${OUTDIR} mkdir -p ${OUTDIR} mkdir -p ${OUTDIR}/stubs/32 mkdir -p ${OUTDIR}/stubs/64 -mkdir -p ${OUTDIR}/extras/largeaddressaware + +rm -rf ${OUTDIR_EXTRAS} +mkdir -p ${OUTDIR_EXTRAS} +mkdir -p ${OUTDIR_EXTRAS}/largeaddressaware +mkdir -p ${OUTDIR_EXTRAS}/linux + if false # ((DEBUG > 0)) then # debug files @@ -204,11 +212,14 @@ then else # release files cp ${BUILDDIR_32}/spicetools/spicecfg.exe ${OUTDIR} 2>/dev/null + cp ${BUILDDIR_32}/spicetools/spicecfg_linux.exe ${OUTDIR_EXTRAS}/linux/spicecfg.exe 2>/dev/null cp ${BUILDDIR_32}/spicetools/32/spice.exe ${OUTDIR} 2>/dev/null - cp ${BUILDDIR_32}/spicetools/32/spice_laa.exe ${OUTDIR}/extras/largeaddressaware/spice.exe 2>/dev/null + cp ${BUILDDIR_32}/spicetools/32/spice_laa.exe ${OUTDIR_EXTRAS}/largeaddressaware/spice.exe 2>/dev/null + cp ${BUILDDIR_32}/spicetools/32/spice_linux.exe ${OUTDIR_EXTRAS}/linux/spice.exe 2>/dev/null #cp ${BUILDDIR_32}/spicetools/32/kbt.dll ${OUTDIR}/stubs/32 2>/dev/null #cp ${BUILDDIR_32}/spicetools/32/kld.dll ${OUTDIR}/stubs/32 2>/dev/null cp ${BUILDDIR_64}/spicetools/64/spice64.exe ${OUTDIR} 2>/dev/null + cp ${BUILDDIR_64}/spicetools/64/spice64_linux.exe ${OUTDIR_EXTRAS}/linux/spice64.exe 2>/dev/null #cp ${BUILDDIR_64}/spicetools/64/kbt.dll ${OUTDIR}/stubs/64 2>/dev/null #cp ${BUILDDIR_64}/spicetools/64/kld.dll ${OUTDIR}/stubs/64 2>/dev/null cp ${BUILDDIR_64}/spicetools/64/nvEncodeAPI64.dll ${OUTDIR}/stubs/64 2>/dev/null @@ -220,18 +231,21 @@ fi # pack source files to output directory rm -rf ${OUTDIR}/src mkdir -p ${OUTDIR}/src +rm -rf ${OUTDIR_EXTRAS}/src +mkdir -p ${OUTDIR_EXTRAS}/src if ((INCLUDE_SRC > 0)) then echo "Generating source file archive..." git archive --format tar.gz --prefix=spice2x/ HEAD ./ > ${OUTDIR}/src/spice2x-${GIT_BRANCH}.tar.gz 2>/dev/null || \ echo "WARNING: Couldn't get git to create the archive. Is this a git repository?" + cp -r ${OUTDIR}/src/* ${OUTDIR_EXTRAS}/src fi # copy resources -rm -rf ${OUTDIR}/api -mkdir ${OUTDIR}/api +rm -rf ${OUTDIR_EXTRAS}/api +mkdir ${OUTDIR_EXTRAS}/api find ./api/resources/python -name "__pycache__" -exec rm -rf {} + -cp -r ./api/resources/* ${OUTDIR}/api +cp -r ./api/resources/* ${OUTDIR_EXTRAS}/api # build distribution archive if ((DIST_ENABLE > 0)) @@ -240,7 +254,11 @@ then mkdir -p ${DIST_FOLDER} rm -rf ${DIST_FOLDER}/${DIST_NAME} pushd ${OUTDIR}/.. > /dev/null - zip -qrXT9 $OLDPWD/${DIST_FOLDER}/${DIST_NAME} . -z <<< "$DIST_COMMENT" + zip -qrXT9 $OLDPWD/${DIST_FOLDER}/${DIST_NAME} spice2x -z <<< "$DIST_COMMENT" + popd > /dev/null + echo "Building extras..." + pushd ${OUTDIR_EXTRAS}/.. > /dev/null + zip -qrXT9 $OLDPWD/${DIST_FOLDER}/${DIST_NAME_EXTRAS} spice2x_extras -z <<< "$DIST_COMMENT" popd > /dev/null fi diff --git a/src/spice2x/external/scard/scard.cpp b/src/spice2x/external/scard/scard.cpp index d3d6b52..5f66190 100644 --- a/src/spice2x/external/scard/scard.cpp +++ b/src/spice2x/external/scard/scard.cpp @@ -23,6 +23,7 @@ * Modified version. */ +#ifndef NO_SCARD #include "scard.h" #include @@ -409,3 +410,5 @@ void scard_threadstart() { void scard_fini() { should_exit = true; } + +#endif diff --git a/src/spice2x/launcher/launcher.cpp b/src/spice2x/launcher/launcher.cpp index 8908be2..952d1f6 100644 --- a/src/spice2x/launcher/launcher.cpp +++ b/src/spice2x/launcher/launcher.cpp @@ -20,7 +20,7 @@ #include "cfg/screen_resize.h" #include "easrv/easrv.h" #include "external/cardio/cardio_runner.h" -#ifdef WITH_SCARD +#ifndef NO_SCARD #include "external/scard/scard.h" #endif #include "games/game.h" @@ -822,7 +822,7 @@ int main_implementation(int argc, char *argv[]) { for (auto &sextet : options[launcher::Options::SextetStreamPort].values_text()) { sextet_devices.emplace_back(sextet); } -#ifdef WITH_SCARD +#ifndef NO_SCARD if (options[launcher::Options::HIDSmartCard].value_bool()) { WINSCARD_CONFIG.cardinfo_callback = eamuse_scard_callback; scard_threadstart(); @@ -1208,13 +1208,22 @@ int main_implementation(int argc, char *argv[]) { } // log -#ifdef SPICE64 - log_info("launcher", "SpiceTools Bootstrap (x64) (spice2x)"); -#elif SPICE32_LARGE_ADDRESS_AWARE - log_info("launcher", "SpiceTools Bootstrap (x32) (Large Address Aware) (spice2x)"); +#ifndef SPICE_LINUX + #ifdef SPICE64 + log_info("launcher", "SpiceTools Bootstrap (x64) (spice2x)"); + #elif SPICE32_LARGE_ADDRESS_AWARE + log_info("launcher", "SpiceTools Bootstrap (x32 - Large Address Aware) (spice2x)"); + #else + log_info("launcher", "SpiceTools Bootstrap (x32) (spice2x)"); + #endif #else - log_info("launcher", "SpiceTools Bootstrap (x32) (spice2x)"); + #ifdef SPICE64 + log_info("launcher", "SpiceTools Bootstrap (x64) (spice2x) for Linux"); + #else + log_info("launcher", "SpiceTools Bootstrap (x32) (spice2x) for Linux"); + #endif #endif + log_info("launcher", "{}", VERSION_STRING); // log command line arguments @@ -2322,7 +2331,7 @@ int main_implementation(int argc, char *argv[]) { // debug hook debughook::detach(); -#ifdef WITH_SCARD +#ifndef NO_SCARD // scard scard_fini(); #endif diff --git a/src/spice2x/launcher/options.cpp b/src/spice2x/launcher/options.cpp index 8fb72dd..84231f6 100644 --- a/src/spice2x/launcher/options.cpp +++ b/src/spice2x/launcher/options.cpp @@ -6,8 +6,10 @@ #include -#ifndef WITH_SCARD +#ifdef NO_SCARD #define WITH_SCARD 0 +#else +#define WITH_SCARD 1 #endif static const std::vector CATEGORY_ORDER_API = { diff --git a/src/spice2x/overlay/windows/config.cpp b/src/spice2x/overlay/windows/config.cpp index 91bb240..9b874f5 100644 --- a/src/spice2x/overlay/windows/config.cpp +++ b/src/spice2x/overlay/windows/config.cpp @@ -2904,10 +2904,17 @@ namespace overlay::windows { } void Config::build_about() { +#ifndef SPICE_LINUX ImGui::TextUnformatted(std::string( "spice2x (a fork of SpiceTools)\r\n" "=========================\r\n" + to_string(VERSION_STRING)).c_str()); +#else + ImGui::TextUnformatted(std::string( + "spice2x (a fork of SpiceTools) for Linux\r\n" + "=========================\r\n" + + to_string(VERSION_STRING)).c_str()); +#endif ImGui::TextUnformatted(""); if (ImGui::Button(PROJECT_URL)) {