1
0
Fork 0
mirror of https://github.com/TerryCavanagh/VVVVVV.git synced 2024-11-04 18:29:41 +01:00
VVVVVV/desktop_version/CMakeLists.txt

300 lines
8.6 KiB
Text
Raw Normal View History

2020-01-01 21:29:24 +01:00
# 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)
SET(BUNDLE_DEPENDENCIES ON CACHE BOOL "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)")
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)
SET(STEAM OFF CACHE BOOL "Use the Steam API")
SET(GOG OFF CACHE BOOL "Use the GOG API")
SET(OFFICIAL_BUILD OFF CACHE BOOL "Compile an official build of the game")
SET(MAKEANDPLAY OFF CACHE BOOL "Compile a version of the game without the main campaign (provided for convenience; consider modifying MakeAndPlay.h instead")
IF(OFFICIAL_BUILD AND NOT MAKEANDPLAY)
SET(STEAM ON)
SET(GOG ON)
ENDIF()
IF(MAKEANDPLAY)
ADD_DEFINITIONS(-DMAKEANDPLAY)
ENDIF()
# Set standard to C++98/C++03
SET(CMAKE_CXX_STANDARD 98)
SET(CMAKE_CXX_EXTENSIONS OFF) # prevent mixing stdlib implementations (dangerous!)
2020-01-01 21:29:24 +01:00
# 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()
2020-01-01 21:29:24 +01:00
SET(CMAKE_OSX_DEPLOYMENT_TARGET 10.9)
LINK_DIRECTORIES(/usr/local/lib)
ADD_COMPILE_OPTIONS(-Werror=partial-availability)
2020-01-01 21:29:24 +01:00
ENDIF()
PROJECT(VVVVVV)
IF(APPLE)
MESSAGE(STATUS "Using macOS SDK at ${CMAKE_OSX_SYSROOT}")
ENDIF()
2020-01-01 21:29:24 +01:00
# Compiler Flags
ADD_DEFINITIONS(-DPHYSFS_SUPPORTS_DEFAULT=0 -DPHYSFS_SUPPORTS_ZIP=1)
# 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)
2020-01-01 21:29:24 +01:00
ENDIF()
# Include Directories
IF(BUNDLE_DEPENDENCIES)
INCLUDE_DIRECTORIES(
src
../third_party/tinyxml2
../third_party/physfs
../third_party/lodepng
../third_party/utfcpp/source
)
ELSE()
INCLUDE_DIRECTORIES(
src
../third_party/lodepng
)
ENDIF()
2020-01-01 21:29:24 +01:00
# 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
2020-01-01 21:29:24 +01:00
src/Screen.cpp
src/Script.cpp
src/Scripts.cpp
src/SoundSystem.cpp
src/Spacestation2.cpp
src/TerminalScripts.cpp
src/Textbox.cpp
src/Tower.cpp
src/UtilityClass.cpp
src/WarpClass.cpp
src/XMLUtils.cpp
2020-01-01 21:29:24 +01:00
src/main.cpp
src/DeferCallbacks.c
src/Network.c
Reduce dependency on libc functions During 2.3 development, there's been a gradual shift to using SDL stdlib functions instead of libc functions, but there are still some libc functions (or the same libc function but from the STL) in the code. Well, this patch replaces all the rest of them in one fell swoop. SDL's stdlib can replace most of these, but its SDL_min() and SDL_max() are inadequate - they aren't really functions, they're more like macros with a nasty penchant for double-evaluation. So I just made my own VVV_min() and VVV_max() functions and placed them in Maths.h instead, then replaced all the previous usages of min(), max(), std::min(), std::max(), SDL_min(), and SDL_max() with VVV_min() and VVV_max(). Additionally, there's no SDL_isxdigit(), so I just implemented my own VVV_isxdigit(). SDL has SDL_malloc() and SDL_free(), but they have some refcounting built in to them, so in order to use them with LodePNG, I have to replace the malloc() and free() that LodePNG uses. Which isn't too hard, I did it in a new file called ThirdPartyDeps.c, and LodePNG is now compiled with the LODEPNG_NO_COMPILE_ALLOCATORS definition. Lastly, I also refactored the awful strcpy() and strcat() usages in PLATFORM_migrateSaveData() to use SDL_snprintf() instead. I know save migration is getting axed in 2.4, but it still bothers me to have something like that in the codebase otherwise. Without further ado, here is the full list of functions that the codebase now uses: - SDL_strlcpy() instead of strcpy() - SDL_strlcat() instead of strcat() - SDL_snprintf() instead of sprintf(), strcpy(), or strcat() (see above) - VVV_min() instead of min(), std::min(), or SDL_min() - VVV_max() instead of max(), std::max(), or SDL_max() - VVV_isxdigit() instead of isxdigit() - SDL_strcmp() instead of strcmp() - SDL_strcasecmp() instead of strcasecmp() or Win32 strcmpi() - SDL_strstr() instead of strstr() - SDL_strlen() instead of strlen() - SDL_sscanf() instead of sscanf() - SDL_getenv() instead of getenv() - SDL_malloc() instead of malloc() (replacing in LodePNG as well) - SDL_free() instead of free() (replacing in LodePNG as well)
2021-01-12 01:17:45 +01:00
src/ThirdPartyDeps.c
2020-01-01 21:29:24 +01:00
)
IF(NOT CUSTOM_LEVEL_SUPPORT STREQUAL "DISABLED")
LIST(APPEND VVV_SRC src/editor.cpp)
ENDIF()
IF(STEAM)
LIST(APPEND VVV_SRC src/SteamNetwork.c)
ADD_DEFINITIONS(-DSTEAM_NETWORK)
ENDIF()
IF(GOG)
LIST(APPEND VVV_SRC src/GOGNetwork.c)
ADD_DEFINITIONS(-DGOG_NETWORK)
ENDIF()
SET(XML2_SRC
../third_party/tinyxml2/tinyxml2.cpp
)
2020-01-01 21:29:24 +01:00
SET(PFS_SRC
../third_party/physfs/physfs.c
../third_party/physfs/physfs_archiver_dir.c
../third_party/physfs/physfs_archiver_unpacked.c
../third_party/physfs/physfs_archiver_zip.c
../third_party/physfs/physfs_byteorder.c
../third_party/physfs/physfs_unicode.c
../third_party/physfs/physfs_platform_posix.c
../third_party/physfs/physfs_platform_unix.c
../third_party/physfs/physfs_platform_windows.c
2020-01-14 05:31:14 +01:00
../third_party/physfs/physfs_platform_haiku.cpp
2020-01-01 21:29:24 +01:00
)
IF(APPLE)
# Are you noticing a pattern with this Apple crap yet?
SET(PFS_SRC ${PFS_SRC} ../third_party/physfs/physfs_platform_apple.m)
2020-01-01 21:29:24 +01:00
ENDIF()
SET(PNG_SRC ../third_party/lodepng/lodepng.c)
2020-01-01 21:29:24 +01:00
# Executable information
IF(WIN32)
ADD_EXECUTABLE(VVVVVV WIN32 ${VVV_SRC})
2020-01-01 21:29:24 +01:00
ELSE()
ADD_EXECUTABLE(VVVVVV ${VVV_SRC})
2020-01-01 21:29:24 +01:00
ENDIF()
Update commit hash every time it changes, not just when CMake is re-ran The commit hash is now properly updated every time it gets changed, and not just when CMake gets re-ran. For this to work, we need to use a few CMake tricks. We add a custom target with ADD_CUSTOM_TARGET(), which is apparently always considered out-of-date (but I had to add a BYPRODUCTS line to get it to actually work), and we use the target to run a .cmake file every time we build. Also, VVVVVV needs to depend on this custom target, to ensure that the game gets built AFTER the version gets generated - otherwise there'll be an error. So we do an ADD_DEPENDENCIES() after the ADD_EXECUTABLE() for VVVVVV. This file, version.cmake, is just the Version.h.out generation that I added previously, but the important thing about all of this is that if the contents of Version.h.out doesn't change, and thus if the commit hash hasn't changed, then CMake will never recompile and relink anything at all. (At least with the Ninja generator.) On a small note, since the Version.h.out generation is now a separate script that is guaranteed to get ran on every single build, while the Git FIND_PACKAGE() gets ran only at configure time, it is possible for the cached path of the Git executable to get out of date. Fixing this requires a simple re-configure (ideally), but in case it wasn't fixed, the INTERIM_COMMIT and COMMIT_DATE variables would get set to empty strings instead of containing a value. To prevent this from happening, I've removed ERROR_QUIET from the EXECUTE_PROCESS() calls in version.cmake, because it's better to explicitly error if the Git executable wasn't found than implicitly carry on like nothing happened.
2020-12-26 05:24:14 +01:00
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>>:
2020-01-12 01:28:39 +01:00
-Wall $<$<BOOL:${ENABLE_WERROR}>:-Werror>>
$<$<CXX_COMPILER_ID:MSVC>:
2020-01-12 01:28:39 +01:00
/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 1)
ELSEIF(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
IF(CMAKE_CXX_COMPILER_VERSION VERSION_GREATER 7.0)
SET(SUPPORTS_IMPLICIT_FALLTHROUGH 1)
ELSE()
SET(SUPPORTS_IMPLICIT_FALLTHROUGH 0)
ENDIF()
ELSE()
SET(SUPPORTS_IMPLICIT_FALLTHROUGH 0)
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()
2020-06-07 21:48:07 +02:00
SET_PROPERTY(TARGET VVVVVV PROPERTY CXX_STANDARD 98)
SET_PROPERTY(TARGET VVVVVV PROPERTY CXX_EXTENSIONS FALSE)
# Unfortunately, it doesn't seem like distros package LodePNG
2020-01-01 21:29:24 +01:00
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
)
Reduce dependency on libc functions During 2.3 development, there's been a gradual shift to using SDL stdlib functions instead of libc functions, but there are still some libc functions (or the same libc function but from the STL) in the code. Well, this patch replaces all the rest of them in one fell swoop. SDL's stdlib can replace most of these, but its SDL_min() and SDL_max() are inadequate - they aren't really functions, they're more like macros with a nasty penchant for double-evaluation. So I just made my own VVV_min() and VVV_max() functions and placed them in Maths.h instead, then replaced all the previous usages of min(), max(), std::min(), std::max(), SDL_min(), and SDL_max() with VVV_min() and VVV_max(). Additionally, there's no SDL_isxdigit(), so I just implemented my own VVV_isxdigit(). SDL has SDL_malloc() and SDL_free(), but they have some refcounting built in to them, so in order to use them with LodePNG, I have to replace the malloc() and free() that LodePNG uses. Which isn't too hard, I did it in a new file called ThirdPartyDeps.c, and LodePNG is now compiled with the LODEPNG_NO_COMPILE_ALLOCATORS definition. Lastly, I also refactored the awful strcpy() and strcat() usages in PLATFORM_migrateSaveData() to use SDL_snprintf() instead. I know save migration is getting axed in 2.4, but it still bothers me to have something like that in the codebase otherwise. Without further ado, here is the full list of functions that the codebase now uses: - SDL_strlcpy() instead of strcpy() - SDL_strlcat() instead of strcat() - SDL_snprintf() instead of sprintf(), strcpy(), or strcat() (see above) - VVV_min() instead of min(), std::min(), or SDL_min() - VVV_max() instead of max(), std::max(), or SDL_max() - VVV_isxdigit() instead of isxdigit() - SDL_strcmp() instead of strcmp() - SDL_strcasecmp() instead of strcasecmp() or Win32 strcmpi() - SDL_strstr() instead of strstr() - SDL_strlen() instead of strlen() - SDL_sscanf() instead of sscanf() - SDL_getenv() instead of getenv() - SDL_malloc() instead of malloc() (replacing in LodePNG as well) - SDL_free() instead of free() (replacing in LodePNG as well)
2021-01-12 01:17:45 +01:00
IF(BUNDLE_DEPENDENCIES)
ADD_LIBRARY(tinyxml2-static STATIC ${XML2_SRC})
ADD_LIBRARY(physfs-static STATIC ${PFS_SRC} ${PFSP_SRC})
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()
2020-01-01 21:29:24 +01:00
# 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")
2020-11-17 17:31:40 +01:00
target_include_directories(VVVVVV SYSTEM PUBLIC "$<BUILD_INTERFACE:${SDL2_INCLUDE_DIRS}>")
target_link_libraries(VVVVVV ${SDL2_LIBRARIES})
2020-01-01 21:29:24 +01:00
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)
2020-01-01 21:29:24 +01:00
elseif (TARGET SDL2)
message(STATUS "Using TARGET SDL2")
target_link_libraries(VVVVVV SDL2 SDL2_mixer)
2020-01-01 21:29:24 +01:00
else()
message(STATUS "No TARGET SDL2::SDL2, or SDL2, using variables")
find_path(SDL2_MIXER_INCLUDE_DIRS NAMES SDL_mixer.h PATH_SUFFIXES SDL2)
2020-11-17 17:31:40 +01:00
target_include_directories(VVVVVV SYSTEM PUBLIC "$<BUILD_INTERFACE:${SDL2_INCLUDE_DIRS}>" ${SDL2_MIXER_INCLUDE_DIRS})
target_link_libraries(VVVVVV ${SDL2_LIBRARIES} SDL2_mixer)
2020-01-01 21:29:24 +01:00
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})
2020-01-01 21:29:24 +01:00
ENDIF()
2020-01-14 05:31:14 +01:00
# 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()