mirror of
https://github.com/TerryCavanagh/VVVVVV.git
synced 2024-12-23 01:59:43 +01:00
5e25161a10
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 ]
389 lines
12 KiB
CMake
389 lines
12 KiB
CMake
# CMake File for VVVVVV
|
|
# Written by Ethan "flibitijibibo" Lee
|
|
|
|
cmake_minimum_required(VERSION 2.8.12)
|
|
|
|
# CMake Options
|
|
option(ENABLE_WARNINGS "Enable compilation warnings" ON)
|
|
option(ENABLE_WERROR "Treat compilation warnings as errors" OFF)
|
|
|
|
option(BUNDLE_DEPENDENCIES "Use bundled TinyXML-2, PhysicsFS, and UTF8-CPP (if disabled, TinyXML-2 and PhysicsFS will be dynamically linked, LodePNG and UTF8-CPP will still be statically linked)" ON)
|
|
|
|
set(CUSTOM_LEVEL_SUPPORT ENABLED CACHE STRING "Optionally disable playing and/or editing of custom levels")
|
|
set_property(CACHE CUSTOM_LEVEL_SUPPORT PROPERTY STRINGS ENABLED NO_EDITOR DISABLED)
|
|
|
|
option(STEAM "Use the Steam API" OFF)
|
|
option(GOG "Use the GOG API" OFF)
|
|
|
|
option(OFFICIAL_BUILD "Compile an official build of the game" OFF)
|
|
|
|
option(MAKEANDPLAY "Compile a version of the game without the main campaign (provided for convenience; consider modifying MakeAndPlay.h instead" OFF)
|
|
|
|
if(OFFICIAL_BUILD AND NOT MAKEANDPLAY)
|
|
set(STEAM ON)
|
|
set(GOG ON)
|
|
endif()
|
|
|
|
# Architecture Flags
|
|
if(APPLE)
|
|
# Wow, Apple is a huge jerk these days huh?
|
|
set(OSX_10_9_SDK_PATH /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.9.sdk)
|
|
if(NOT CMAKE_OSX_SYSROOT)
|
|
if(IS_DIRECTORY ${OSX_10_9_SDK_PATH})
|
|
set(CMAKE_OSX_SYSROOT ${OSX_10_9_SDK_PATH})
|
|
else()
|
|
message(WARNING "CMAKE_OSX_SYSROOT not set and macOS 10.9 SDK not found! Using default one.")
|
|
endif()
|
|
endif()
|
|
set(CMAKE_OSX_DEPLOYMENT_TARGET 10.9)
|
|
link_directories(/usr/local/lib)
|
|
add_compile_options(-Werror=partial-availability)
|
|
endif()
|
|
|
|
project(VVVVVV)
|
|
|
|
if(APPLE)
|
|
message(STATUS "Using macOS SDK at ${CMAKE_OSX_SYSROOT}")
|
|
endif()
|
|
|
|
# RPATH
|
|
if(NOT WIN32)
|
|
if(APPLE)
|
|
set(BIN_LIBROOT "osx")
|
|
set(BIN_RPATH "@executable_path/osx")
|
|
elseif(CMAKE_SIZEOF_VOID_P MATCHES "8")
|
|
set(BIN_LIBROOT "lib64")
|
|
set(BIN_RPATH "\$ORIGIN/lib64")
|
|
else()
|
|
set(BIN_LIBROOT "lib")
|
|
set(BIN_RPATH "\$ORIGIN/lib")
|
|
endif()
|
|
set(CMAKE_SKIP_BUILD_RPATH TRUE)
|
|
set(CMAKE_BUILD_WITH_INSTALL_RPATH TRUE)
|
|
set(CMAKE_INSTALL_RPATH ${BIN_RPATH})
|
|
set(CMAKE_INSTALL_RPATH_USE_LINK_PATH FALSE)
|
|
endif()
|
|
|
|
# Source Lists
|
|
set(VVV_SRC
|
|
src/BinaryBlob.cpp
|
|
src/BlockV.cpp
|
|
src/CWrappers.cpp
|
|
src/Ent.cpp
|
|
src/Entity.cpp
|
|
src/FileSystemUtils.cpp
|
|
src/Finalclass.cpp
|
|
src/Game.cpp
|
|
src/Graphics.cpp
|
|
src/GraphicsResources.cpp
|
|
src/GraphicsUtil.cpp
|
|
src/Input.cpp
|
|
src/KeyPoll.cpp
|
|
src/Labclass.cpp
|
|
src/Logic.cpp
|
|
src/Map.cpp
|
|
src/Music.cpp
|
|
src/Otherlevel.cpp
|
|
src/preloader.cpp
|
|
src/Render.cpp
|
|
src/RenderFixed.cpp
|
|
src/Screen.cpp
|
|
src/Script.cpp
|
|
src/Scripts.cpp
|
|
src/Spacestation2.cpp
|
|
src/TerminalScripts.cpp
|
|
src/Textbox.cpp
|
|
src/Tower.cpp
|
|
src/UtilityClass.cpp
|
|
src/WarpClass.cpp
|
|
src/XMLUtils.cpp
|
|
src/main.cpp
|
|
src/DeferCallbacks.c
|
|
src/GlitchrunnerMode.c
|
|
src/Network.c
|
|
src/ThirdPartyDeps.c
|
|
src/VFormat.c
|
|
src/Vlogging.c
|
|
src/Xoshiro.c
|
|
../third_party/physfs/extras/physfsrwops.c
|
|
)
|
|
if(NOT CUSTOM_LEVEL_SUPPORT STREQUAL "DISABLED")
|
|
list(APPEND VVV_SRC src/CustomLevels.cpp)
|
|
if(NOT CUSTOM_LEVEL_SUPPORT STREQUAL "NO_EDITOR")
|
|
LIST(APPEND VVV_SRC src/Editor.cpp)
|
|
endif()
|
|
endif()
|
|
if(STEAM)
|
|
list(APPEND VVV_SRC src/SteamNetwork.c)
|
|
endif()
|
|
if(GOG)
|
|
list(APPEND VVV_SRC src/GOGNetwork.c)
|
|
endif()
|
|
|
|
# Executable information
|
|
if(WIN32)
|
|
add_executable(VVVVVV WIN32 ${VVV_SRC} icon.rc)
|
|
else()
|
|
add_executable(VVVVVV ${VVV_SRC})
|
|
endif()
|
|
|
|
# Include Directories
|
|
if(BUNDLE_DEPENDENCIES)
|
|
target_include_directories(
|
|
VVVVVV PRIVATE
|
|
src
|
|
../third_party/tinyxml2
|
|
../third_party/physfs/src
|
|
../third_party/physfs/extras
|
|
../third_party/lodepng
|
|
../third_party/utfcpp/source
|
|
../third_party/FAudio/include
|
|
../third_party/FAudio/src
|
|
)
|
|
else()
|
|
target_include_directories(
|
|
VVVVVV PRIVATE
|
|
src
|
|
../third_party/lodepng
|
|
../third_party/physfs/extras
|
|
../third_party/FAudio/src
|
|
)
|
|
endif()
|
|
|
|
if(MAKEANDPLAY)
|
|
target_compile_definitions(VVVVVV PRIVATE -DMAKEANDPLAY)
|
|
endif()
|
|
|
|
if(STEAM)
|
|
target_compile_definitions(VVVVVV PRIVATE -DSTEAM_NETWORK)
|
|
endif()
|
|
if(GOG)
|
|
target_compile_definitions(VVVVVV PRIVATE -DGOG_NETWORK)
|
|
endif()
|
|
|
|
set(XML2_SRC
|
|
../third_party/tinyxml2/tinyxml2.cpp
|
|
)
|
|
set(FAUDIO_SRC
|
|
../third_party/FAudio/src/FAudio.c
|
|
../third_party/FAudio/src/FAudio_internal.c
|
|
../third_party/FAudio/src/FAudio_internal_simd.c
|
|
../third_party/FAudio/src/FAudio_operationset.c
|
|
../third_party/FAudio/src/FAudio_platform_sdl2.c
|
|
)
|
|
set(PFS_SRC
|
|
../third_party/physfs/src/physfs.c
|
|
../third_party/physfs/src/physfs_archiver_dir.c
|
|
../third_party/physfs/src/physfs_archiver_unpacked.c
|
|
../third_party/physfs/src/physfs_archiver_zip.c
|
|
../third_party/physfs/src/physfs_byteorder.c
|
|
../third_party/physfs/src/physfs_unicode.c
|
|
../third_party/physfs/src/physfs_platform_posix.c
|
|
../third_party/physfs/src/physfs_platform_unix.c
|
|
../third_party/physfs/src/physfs_platform_windows.c
|
|
../third_party/physfs/src/physfs_platform_haiku.cpp
|
|
)
|
|
if(APPLE)
|
|
# Are you noticing a pattern with this Apple crap yet?
|
|
set(PFS_SRC ${PFS_SRC} ../third_party/physfs/src/physfs_platform_apple.m)
|
|
endif()
|
|
set(PNG_SRC src/lodepng_wrapper.c)
|
|
|
|
if(NOT OFFICIAL_BUILD)
|
|
# Add interim commit hash and its date to the build
|
|
|
|
# find_package sets GIT_FOUND and GIT_EXECUTABLE
|
|
find_package(Git)
|
|
|
|
if(GIT_FOUND)
|
|
# These filenames have to be qualified, because when we run
|
|
# the CMake script, its work dir gets set to the build folder
|
|
set(VERSION_INPUT_FILE ${CMAKE_CURRENT_SOURCE_DIR}/src/Version.h.in)
|
|
set(VERSION_OUTPUT_FILE ${CMAKE_CURRENT_SOURCE_DIR}/src/Version.h.out)
|
|
|
|
add_custom_target(
|
|
GenerateVersion ALL
|
|
# This BYPRODUCTS line is required for this to be ran every time
|
|
BYPRODUCTS ${VERSION_OUTPUT_FILE}
|
|
COMMAND ${CMAKE_COMMAND}
|
|
# These args have to be passed through, otherwise the script can't see them
|
|
# Also, these args have to come BEFORE `-P`! (Otherwise it fails with an unclear error)
|
|
-DGIT_EXECUTABLE=${GIT_EXECUTABLE}
|
|
-DINPUT_FILE=${VERSION_INPUT_FILE}
|
|
-DOUTPUT_FILE=${VERSION_OUTPUT_FILE}
|
|
-P ${CMAKE_CURRENT_SOURCE_DIR}/version.cmake
|
|
)
|
|
|
|
add_dependencies(VVVVVV GenerateVersion)
|
|
|
|
# This lets Version.h know that Version.h.out exists
|
|
add_definitions(-DVERSION_H_OUT_EXISTS)
|
|
endif()
|
|
endif()
|
|
|
|
# Build options
|
|
if(ENABLE_WARNINGS)
|
|
# The weird syntax is due to CMake generator expressions.
|
|
# Saves quite a few lines and boilerplate at the price of readability.
|
|
target_compile_options(VVVVVV PRIVATE
|
|
$<$<OR:$<CXX_COMPILER_ID:GNU>,$<CXX_COMPILER_ID:Clang>,$<CXX_COMPILER_ID:AppleClang>>:
|
|
-Wall -Wpedantic $<$<BOOL:${ENABLE_WERROR}>:-Werror>>
|
|
$<$<CXX_COMPILER_ID:MSVC>:
|
|
/W4 $<$<BOOL:${ENABLE_WERROR}>:/WX>>)
|
|
endif()
|
|
|
|
if(CUSTOM_LEVEL_SUPPORT STREQUAL "NO_EDITOR")
|
|
add_definitions(-DNO_EDITOR)
|
|
elseif(CUSTOM_LEVEL_SUPPORT STREQUAL "DISABLED")
|
|
add_definitions(-DNO_CUSTOM_LEVELS -DNO_EDITOR)
|
|
endif()
|
|
|
|
if(CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
|
|
set(SUPPORTS_IMPLICIT_FALLTHROUGH TRUE)
|
|
elseif(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
|
|
if(CMAKE_CXX_COMPILER_VERSION VERSION_GREATER 7.0)
|
|
set(SUPPORTS_IMPLICIT_FALLTHROUGH TRUE)
|
|
else()
|
|
set(SUPPORTS_IMPLICIT_FALLTHROUGH FALSE)
|
|
endif()
|
|
else()
|
|
set(SUPPORTS_IMPLICIT_FALLTHROUGH FALSE)
|
|
endif()
|
|
|
|
|
|
if(SUPPORTS_IMPLICIT_FALLTHROUGH)
|
|
target_compile_options(VVVVVV PRIVATE -Werror=implicit-fallthrough)
|
|
endif()
|
|
|
|
if(MSVC)
|
|
# Disable MSVC warnings about implicit conversion
|
|
target_compile_options(VVVVVV PRIVATE /wd4244)
|
|
endif()
|
|
|
|
if(MSVC)
|
|
# MSVC doesn't have /std:c99 or /std:c++98 switches!
|
|
|
|
# Disable exceptions
|
|
string(REGEX REPLACE "/EH[a-z]+" "" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
|
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /EHsc")
|
|
|
|
# Disable RTTI
|
|
string(REPLACE "/GR" "" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
|
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /GR-")
|
|
else()
|
|
string(REGEX REPLACE "-std=[a-z0-9]+" "" CMAKE_C_FLAGS "${CMAKE_C_FLAGS}")
|
|
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=c99")
|
|
|
|
string(REGEX REPLACE "-std=[a-z0-9+]+" "" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
|
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++98")
|
|
|
|
# Disable exceptions
|
|
string(REPLACE "-fexceptions" "" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
|
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-exceptions")
|
|
|
|
# Disable RTTI
|
|
string(REPLACE "-frtti" "" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
|
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-rtti")
|
|
endif()
|
|
|
|
# Unfortunately, it doesn't seem like distros package LodePNG
|
|
add_library(lodepng-static STATIC ${PNG_SRC})
|
|
|
|
target_compile_definitions(lodepng-static PRIVATE
|
|
-DLODEPNG_NO_COMPILE_ALLOCATORS
|
|
-DLODEPNG_NO_COMPILE_DISK
|
|
-DLODEPNG_NO_COMPILE_ENCODER
|
|
)
|
|
|
|
if(BUNDLE_DEPENDENCIES)
|
|
add_library(tinyxml2-static STATIC ${XML2_SRC})
|
|
add_library(physfs-static STATIC ${PFS_SRC})
|
|
target_compile_definitions(physfs-static PRIVATE
|
|
-DPHYSFS_SUPPORTS_DEFAULT=0 -DPHYSFS_SUPPORTS_ZIP=1
|
|
)
|
|
add_library(faudio-static STATIC ${FAUDIO_SRC})
|
|
target_include_directories(
|
|
faudio-static PRIVATE
|
|
../third_party/FAudio/include
|
|
)
|
|
|
|
target_link_libraries(VVVVVV physfs-static tinyxml2-static lodepng-static faudio-static)
|
|
else()
|
|
find_package(utf8cpp CONFIG)
|
|
|
|
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")
|
|
target_include_directories(VVVVVV SYSTEM PRIVATE "$<BUILD_INTERFACE:${SDL2_INCLUDE_DIRS}>")
|
|
target_link_libraries(VVVVVV ${SDL2_LIBRARIES})
|
|
if(BUNDLE_DEPENDENCIES)
|
|
target_include_directories(faudio-static SYSTEM PRIVATE "$<BUILD_INTERFACE:${SDL2_INCLUDE_DIRS}>")
|
|
target_link_libraries(faudio-static ${SDL2_LIBRARIES})
|
|
endif()
|
|
elseif (EMSCRIPTEN)
|
|
message(STATUS "Using Emscripten SDL2")
|
|
target_compile_options(VVVVVV PUBLIC -sUSE_SDL=2)
|
|
target_link_libraries(VVVVVV -sUSE_SDL=2)
|
|
if(BUNDLE_DEPENDENCIES)
|
|
target_compile_options(faudio-static PUBLIC -sUSE_SDL=2)
|
|
target_link_libraries(faudio-static -sUSE_SDL=2)
|
|
endif()
|
|
else()
|
|
# Only try to autodetect if both SDL2 variables aren't explicitly set
|
|
find_package(SDL2 CONFIG)
|
|
if(TARGET SDL2::SDL2)
|
|
message(STATUS "Using TARGET SDL2::SDL2")
|
|
target_link_libraries(VVVVVV SDL2::SDL2)
|
|
if(BUNDLE_DEPENDENCIES)
|
|
target_link_libraries(faudio-static SDL2::SDL2)
|
|
endif()
|
|
elseif(TARGET SDL2)
|
|
message(STATUS "Using TARGET SDL2")
|
|
target_link_libraries(VVVVVV SDL2)
|
|
if(BUNDLE_DEPENDENCIES)
|
|
target_link_libraries(faudio-static SDL2)
|
|
endif()
|
|
else()
|
|
message(STATUS "No TARGET SDL2::SDL2, or SDL2, using variables")
|
|
target_include_directories(VVVVVV SYSTEM PRIVATE "$<BUILD_INTERFACE:${SDL2_INCLUDE_DIRS}>")
|
|
target_link_libraries(VVVVVV ${SDL2_LIBRARIES})
|
|
if(BUNDLE_DEPENDENCIES)
|
|
target_include_directories(faudio-static SYSTEM PRIVATE "$<BUILD_INTERFACE:${SDL2_INCLUDE_DIRS}>")
|
|
target_link_libraries(faudio-static ${SDL2_LIBRARIES})
|
|
endif()
|
|
endif()
|
|
endif()
|
|
|
|
# Yes, more Apple Crap
|
|
if(APPLE)
|
|
find_library(FOUNDATION NAMES Foundation)
|
|
find_library(IOKIT NAMES IOKit)
|
|
target_link_libraries(VVVVVV objc ${IOKIT} ${FOUNDATION})
|
|
endif()
|
|
# But hey, also some Haiku crap
|
|
if(HAIKU)
|
|
find_library(BE_LIBRARY be)
|
|
find_library(ROOT_LIBRARY root)
|
|
target_link_libraries(VVVVVV ${BE_LIBRARY} ${ROOT_LIBRARY})
|
|
endif()
|
|
if(EMSCRIPTEN)
|
|
# 256MB is enough for everybody
|
|
target_link_libraries(VVVVVV -sFORCE_FILESYSTEM=1 -sTOTAL_MEMORY=256MB)
|
|
endif()
|