mirror of
https://github.com/1dot13/source.git
synced 2026-07-29 13:52:17 +02:00
binkw32.lib as shipped is a long-format ordinal import library built in 2002, and link.exe is the only linker left that binds it. lld-link takes it without complaint and writes an import descriptor with an empty thunk table, so every Bink call reaches whatever the stale IAT slot holds. The first one is BinkSoundUseDirectSound, reached from BinkInitialize during EnterIntroScreen, which is unconditional -- Intro.cpp constructs its VideoPlayer with VT_SMK|VT_BINK in every application, so a Smacker-only gamedir still runs the Bink init path. The process dies before the splash with an access violation executing an unmapped address. clang-cl.cmake and mingw.cmake already rebuilt the library from binkw32.def for exactly this reason, but they are toolchain files, so the rebuild only happened when someone cross-compiled. Which linker is in use is not a cross-compilation question: a preset that points CMAKE_CXX_COMPILER at clang-cl -- how you use it from Visual Studio -- loads no toolchain file and linked the broken library instead. The test was a proxy for "is this lld-link", correct until it wasn't. So the rebuild moves to the top-level CMakeLists and runs unconditionally, and clang-cl.cmake loses its copy: it already sets CMAKE_AR to llvm-lib, which is the same binary the new code invokes with the same arguments. mingw.cmake keeps its own, because GNU ar cannot build an import library at all and dlltool takes different flags. Only the name shape differs between archivers. lib.exe prepends the x86 leading underscore to every name in the .def; llvm-lib and llvm-dlltool take the name as written. The checked-in file keeps the underscore for the llvm tools and the MSVC path strips it back off. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
43 lines
1.6 KiB
CMake
43 lines
1.6 KiB
CMake
# TODO: make this work
|
|
# Usage:
|
|
# cmake --toolchain cmake/toolchains/mingw.cmake ...
|
|
#
|
|
# Unlike clang-cl.cmake this needs no MSVC_SDK: mingw-w64 ships its own Windows
|
|
# headers and import libraries in its sysroot, so the compiler finds everything
|
|
# itself. Install the i686 cross toolchain (mingw-w64-gcc) and it is on PATH as
|
|
# i686-w64-mingw32-*.
|
|
|
|
set(CMAKE_SYSTEM_NAME Windows)
|
|
set(CMAKE_SYSTEM_PROCESSOR i686)
|
|
|
|
set(triple ${CMAKE_SYSTEM_PROCESSOR}-w64-mingw32)
|
|
|
|
# Find every tool here rather than trusting a bare name, so the toolchain file
|
|
# alone decides which cross compiler, rc and dlltool are used.
|
|
foreach(tool gcc g++ windres dlltool ar)
|
|
string(TOUPPER "${tool}" _variable)
|
|
string(REPLACE "+" "X" _variable "${_variable}")
|
|
find_program(MINGW_${_variable} NAMES ${triple}-${tool} REQUIRED)
|
|
endforeach()
|
|
|
|
set(CMAKE_C_COMPILER "${MINGW_GCC}")
|
|
set(CMAKE_CXX_COMPILER "${MINGW_GXX}")
|
|
set(CMAKE_RC_COMPILER "${MINGW_WINDRES}")
|
|
set(CMAKE_AR "${MINGW_AR}")
|
|
|
|
set(CMAKE_C_COMPILER_TARGET ${triple})
|
|
set(CMAKE_CXX_COMPILER_TARGET ${triple})
|
|
|
|
# GNU ld cannot bind the Bink import library the game ships either, so rebuild a
|
|
# bindable one from binkw32.def (which explains why) and hand it to the top-level
|
|
# CMakeLists through binkw32_lib.
|
|
execute_process(
|
|
COMMAND "${MINGW_DLLTOOL}" -m i386
|
|
-d "${CMAKE_CURRENT_LIST_DIR}/../../binkw32.def"
|
|
-l "${CMAKE_BINARY_DIR}/binkw32.lib"
|
|
RESULT_VARIABLE _binkw32DlltoolResult)
|
|
if(NOT _binkw32DlltoolResult EQUAL 0)
|
|
message(FATAL_ERROR "dlltool failed to build the binkw32 import library")
|
|
endif()
|
|
set(binkw32_lib "${CMAKE_BINARY_DIR}/binkw32.lib")
|