Add `/MT` flag for MSVC

This flag makes it so the MSVC runtime libraries are statically linked.
This avoids needing Windows users to have these libraries installed.

Apparently /MT stands for "MultiThreaded", and there's a bit of a
history there where originally by default you could only have a
single-threaded library, and then the multi-threaded flags were added in
later.

First I tried doing target_compile_options on VVVVVV, but then got a
linker error. Then I tried doing add_compile_options because I figured
/MT had to be applied everywhere, and it seemed to work, but it still
linked to the runtime libraries. Apparently it was being overridden.
Then I tried target_compile_options again but this time did it to
everything, and that linked correctly and also removed the runtime
dependency. I would've tried using the MSVC_RUNTIME_LIBRARY property
- along with the CMP0091 policy - but those were only introduced in
CMake 3.15.

You can verify that a binary is built without dependencies by installing
LLVM and running llvm-readobj --needed-libs path/to/binary. This is the
output for a binary with runtime dependencies:

    infoteddy@fedorarune  ~/d  llvm-readobj --needed-libs VVVVVV.exe

    File: VVVVVV.exe
    Format: COFF-i386
    Arch: i386
    AddressSize: 32bit
    NeededLibraries [
      ADVAPI32.dll
      KERNEL32.dll
      MSVCP140.dll
      SDL2.dll
      SHELL32.dll
      USER32.dll
      VCRUNTIME140.dll
      api-ms-win-crt-heap-l1-1-0.dll
      api-ms-win-crt-locale-l1-1-0.dll
      api-ms-win-crt-math-l1-1-0.dll
      api-ms-win-crt-runtime-l1-1-0.dll
      api-ms-win-crt-stdio-l1-1-0.dll
      api-ms-win-crt-string-l1-1-0.dll
      api-ms-win-crt-time-l1-1-0.dll
      api-ms-win-crt-utility-l1-1-0.dll
    ]

And this is the output for a binary with those dependencies having been
statically-linked in:

     infoteddy@fedorarune  ~/d  llvm-readobj --needed-libs VVVVVV.exe

    File: VVVVVV.exe
    Format: COFF-i386
    Arch: i386
    AddressSize: 32bit
    NeededLibraries [
      ADVAPI32.dll
      KERNEL32.dll
      SDL2.dll
      SHELL32.dll
      USER32.dll
    ]
This commit is contained in:
Misa 2022-06-28 17:49:03 -07:00
parent 10acd67377
commit 5e25161a10
1 changed files with 14 additions and 0 deletions

View File

@ -314,6 +314,20 @@ else()
target_link_libraries(VVVVVV physfs tinyxml2 utf8cpp lodepng-static FAudio)
endif()
if(MSVC)
# Statically link Microsoft's runtime library so end users don't have to install it
target_compile_options(VVVVVV PRIVATE /MT)
# /MT must also be applied to every statically-linked library, else you get a linker error
if(BUNDLE_DEPENDENCIES)
target_compile_options(tinyxml2-static PRIVATE /MT)
target_compile_options(physfs-static PRIVATE /MT)
target_compile_options(faudio-static PRIVATE /MT)
endif()
target_compile_options(lodepng-static PRIVATE /MT)
endif()
# SDL2 Dependency (Detection pulled from FAudio)
if(DEFINED SDL2_INCLUDE_DIRS AND DEFINED SDL2_LIBRARIES)
message(STATUS "Using pre-defined SDL2 variables SDL2_INCLUDE_DIRS and SDL2_LIBRARIES")