mirror of
https://github.com/spice2x/spice2x.github.io.git
synced 2026-08-02 14:50:41 -07:00
cf86fbd238
## Link to GitHub Issue or related Pull Request, if one exists Fixes #779 Regressed by #720 ## Description of change #720 introduced a static dependency on DX9 which caused `d3d9.dll` to be loaded at boot from `system32`. Some third party hooks (like ifs_layeredfs and dxvk) rely on supplying a custom `d3d9.dll` in the DLL search path (usually in modules) but this change caused Windows to skip that check. Remove the hard dependency on d3d9 and add a CMake check to ensure that compiled binaries do not accidentally introduce new static imports in the future. ## Testing Confirmed that dxvk runs again.
73 lines
3.1 KiB
CMake
73 lines
3.1 KiB
CMake
# fails the build if a PE binary statically imports a forbidden DLL.
|
|
#
|
|
# some DLLs must never end up in spice's static import table, for two reasons:
|
|
#
|
|
# 1. user-overridable DLLs (e.g. DXVK's d3d9.dll): users drop their own copy
|
|
# into the modules directory to replace the system one. a static import
|
|
# forces the loader to load the SYSTEM copy at process startup - before the
|
|
# modules directory is added to the DLL search path and before the game DLL
|
|
# loads - so the user-supplied override never takes effect (see issue #779).
|
|
#
|
|
# 2. DLLs that break games when present (e.g. Media Foundation: mf/mfplat/
|
|
# mfreadwrite): a static import loads them eagerly and breaks Unity games.
|
|
#
|
|
# in both cases the DLL must instead be loaded dynamically (libutils::try_library
|
|
# / GetProcAddress / delay load) so it is only pulled in when actually needed.
|
|
#
|
|
# invoked via `cmake -P` from a POST_BUILD step. required -D variables:
|
|
# OBJDUMP - path to objdump (CMAKE_OBJDUMP)
|
|
# TARGET_FILE - path to the PE binary to inspect
|
|
# FORBIDDEN - semicolon-separated list of lowercase DLL names to reject
|
|
|
|
if(NOT OBJDUMP OR NOT EXISTS "${OBJDUMP}")
|
|
message(WARNING
|
|
"check_no_static_dll_imports: objdump not found, skipping import check for ${TARGET_FILE}")
|
|
return()
|
|
endif()
|
|
|
|
execute_process(
|
|
COMMAND "${OBJDUMP}" -p "${TARGET_FILE}"
|
|
OUTPUT_VARIABLE dump_output
|
|
RESULT_VARIABLE dump_result
|
|
ERROR_VARIABLE dump_error)
|
|
|
|
if(NOT dump_result EQUAL 0)
|
|
message(WARNING
|
|
"check_no_static_dll_imports: objdump failed for ${TARGET_FILE}: ${dump_error}")
|
|
return()
|
|
endif()
|
|
|
|
# both GNU objdump and llvm-objdump print one "DLL Name: <name>" line per
|
|
# statically imported DLL in their PE private-header dump.
|
|
string(REGEX MATCHALL "DLL Name:[ \t]*[^\n\r]+" dll_lines "${dump_output}")
|
|
|
|
set(violations "")
|
|
foreach(line IN LISTS dll_lines)
|
|
string(REGEX REPLACE "DLL Name:[ \t]*" "" dll_name "${line}")
|
|
string(STRIP "${dll_name}" dll_name)
|
|
string(TOLOWER "${dll_name}" dll_name_lower)
|
|
if(dll_name_lower IN_LIST FORBIDDEN)
|
|
list(APPEND violations "${dll_name}")
|
|
endif()
|
|
endforeach()
|
|
|
|
if(violations)
|
|
list(REMOVE_DUPLICATES violations)
|
|
string(REPLACE ";" ", " violations_str "${violations}")
|
|
message(FATAL_ERROR
|
|
"static DLL import check FAILED for ${TARGET_FILE}\n"
|
|
" forbidden static imports found: ${violations_str}\n"
|
|
"\n"
|
|
" these DLLs must never be statically imported by spice:\n"
|
|
" * user-overridable DLLs (e.g. DXVK d3d9.dll) - a static import loads the\n"
|
|
" system copy at startup and preempts the modules override (issue #779).\n"
|
|
" * Media Foundation DLLs (mf/mfplat/mfreadwrite) - a static import breaks\n"
|
|
" Unity games.\n"
|
|
"\n"
|
|
" fix: load the DLL dynamically instead - replace the direct API call with a\n"
|
|
" libutils::try_library() + libutils::try_proc() lookup (or a delay load), then\n"
|
|
" call through the resolved function pointer.")
|
|
endif()
|
|
|
|
message(STATUS "static DLL import check passed for ${TARGET_FILE}")
|