mirror of
https://github.com/TerryCavanagh/VVVVVV.git
synced 2024-06-28 15:38:30 +02:00
c61c4fab6f
So, it turns out we weren't quite done fighting CMake yet...
To accommodate #869 (and actually also #272), the C standard was raised
from C90 to C99. This turned out to require a bit of a fight with the
CentOS CI's CMake version to get it to set the flags we wanted (and to
not overwrite them later). Eventually the fix was to move the block
that sets the standards to later in the file, which was done in
24353a54bb
.
As it apparently turns out, if your CMake is at least 3.1.3 and
`CMAKE_<LANG>_STANDARD` is used instead of the workaround, the standard
setting now has an effect on the third party libraries, but not on
VVVVVV itself. The cause is (probably) the phrase "if it is set when a
target is created" in the CMake documentation - the
`CMAKE_<LANG>_STANDARD` values have to come before the VVVVVV target is
defined. In other words, the compiler's default C/C++ standard will be
used, probably something like C17 and C++17. As I can confirm with
`__cplusplus` and `__STDC_VERSION__` with my recent-enough CMake. If I
force the pre-3.1.3 workaround to be used, everything is compiled with
C99/C++98 as expected; and the `-fno-exceptions` `-fno-rtti` flags
appear everywhere regardless of version.
So my fix is to make the CMakeLists a little less complex by
simplifying away the `CMAKE_<LANG>_STANDARD` and
`CMAKE_<LANG>_EXTENSIONS`, and always using the workaround regardless
of CMake version. There's nothing wrong with the workaround, the same
thing is also done for `-fno-exceptions` `-fno-rtti`, and it's good to
have a less complicated CMakeLists that doesn't do different and
unexpected things for different versions.
342 lines
11 KiB
CMake
342 lines
11 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/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/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
|
|
)
|
|
else()
|
|
target_include_directories(
|
|
VVVVVV PRIVATE
|
|
src
|
|
../third_party/lodepng
|
|
../third_party/physfs/extras
|
|
)
|
|
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(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
|
|
)
|
|
|
|
target_link_libraries(VVVVVV physfs-static tinyxml2-static lodepng-static)
|
|
else()
|
|
find_package(utf8cpp CONFIG)
|
|
|
|
target_link_libraries(VVVVVV physfs tinyxml2 utf8cpp lodepng-static)
|
|
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})
|
|
elseif (EMSCRIPTEN)
|
|
message(STATUS "Using Emscripten SDL2")
|
|
target_compile_options(VVVVVV PUBLIC -sUSE_SDL=2 -sUSE_SDL_MIXER=2)
|
|
target_link_libraries(VVVVVV -sUSE_SDL=2 -sUSE_SDL_MIXER=2)
|
|
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 SDL2_mixer)
|
|
elseif(TARGET SDL2)
|
|
message(STATUS "Using TARGET SDL2")
|
|
target_link_libraries(VVVVVV SDL2 SDL2_mixer)
|
|
else()
|
|
message(STATUS "No TARGET SDL2::SDL2, or SDL2, using variables")
|
|
find_path(SDL2_MIXER_INCLUDE_DIRS NAMES SDL_mixer.h PATH_SUFFIXES SDL2)
|
|
target_include_directories(VVVVVV SYSTEM PRIVATE "$<BUILD_INTERFACE:${SDL2_INCLUDE_DIRS}>" ${SDL2_MIXER_INCLUDE_DIRS})
|
|
target_link_libraries(VVVVVV ${SDL2_LIBRARIES} SDL2_mixer)
|
|
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()
|