2020-01-01 21:29:24 +01:00
# CMake File for VVVVVV
# Written by Ethan "flibitijibibo" Lee
2021-04-17 01:30:51 +02:00
cmake_minimum_required(VERSION 2.8.12)
2020-01-01 21:29:24 +01:00
2020-01-11 01:58:33 +01:00
# CMake Options
2021-04-17 01:30:51 +02:00
option(ENABLE_WARNINGS "Enable compilation warnings" ON)
option(ENABLE_WERROR "Treat compilation warnings as errors" OFF)
2020-01-11 01:58:33 +01:00
2021-04-17 01:35:31 +02:00
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)
Add option to not use bundled TinyXML-2, PhysFS, and UTF8-CPP
If you configure the build with -DBUNDLE_DEPENDENCIES=OFF, then VVVVVV
will dynamically link with TinyXML-2 and PhysicsFS instead of using the
bundled source code in third_party/ and statically linking with them.
Unfortunately, it doesn't seem like distros package LodePNG, and LodePNG
isn't intended to be packaged, so we can't dynamically link with it, nor
can we use some system LodePNG header files somewhere else because those
don't exist.
UTF8-CPP is a special case, because no matter what, it's going to be
statically linked with the binary (it doesn't come as a shared object
file in any way). So with -DBUNDLE_DEPENDENCIES=OFF, we will use the
system UTF8-CPP header files instead of the bundled ones, but it will
still be statically linked in with the binary.
The main motivation for doing this is so if VVVVVV ever gets packaged in
distros, distro maintainers would be more likely to accept it if there
was an option to compile the game without bundled dependencies. Also, it
discourages modifying the third-party dependencies we have, because it's
always possible for someone to compile those dependencies without our
changes, with this CMake option.
2020-12-21 22:30:01 +01:00
2021-04-17 01:30:51 +02:00
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)
2020-02-10 03:21:19 +01:00
2021-04-17 01:35:31 +02:00
option(STEAM "Use the Steam API" OFF)
option(GOG "Use the GOG API" OFF)
2020-06-01 18:23:07 +02:00
2021-04-17 01:35:31 +02:00
option(OFFICIAL_BUILD "Compile an official build of the game" OFF)
2020-11-21 03:15:25 +01:00
2021-04-17 01:35:31 +02:00
option(MAKEANDPLAY "Compile a version of the game without the main campaign (provided for convenience; consider modifying MakeAndPlay.h instead" OFF)
Add official, M&P, no custom levels, and no editor builds to CI
CI builds were added to this repository on the first day it was
released, and haven't really been touched since then. And since then,
2.3 has added NO_CUSTOM_LEVELS, NO_EDITOR, and OFFICIAL_BUILD builds to
the CMake file.
On top of the MAKEANDPLAY define already existing, this means CI
coverage is a bit sparse - covering compile failures for changes made to
most of the codebase, except for Steam and GOG, and not covering compile
failures if certain parts of the code get stripped out. And people do
forget to check for those configurations as well.
These mess of configurations is kind of a wake-up call to refactor and
generalize the code a bit, because we would probably be able to get rid
of at least two of these (Make & Play, and no-custom-levels) by making
it so custom levels behave indistinguishably from the main game. But,
that's something to do in 2.4. At the very least, we should cover these
in CI right now.
On a small note, I had to add a MAKEANDPLAY configure option to the
CMake file to be able to easily configure a Make & Play build from the
CI runner. This option shouldn't really be used otherwise, so I added a
note to it telling people to consider modifying MakeAndPlay.h instead.
2020-12-27 08:40:28 +01:00
2021-04-17 01:30:51 +02:00
if(OFFICIAL_BUILD AND NOT MAKEANDPLAY)
set(STEAM ON)
set(GOG ON)
endif()
2020-06-01 18:23:07 +02:00
2021-04-17 01:38:31 +02:00
if(${CMAKE_VERSION} VERSION_LESS "3.1.3")
2021-04-17 01:40:08 +02:00
message(WARNING "Your CMake version is too old; set -std=c90 -std=c++98 yourself!")
2021-04-17 01:38:31 +02:00
else()
2021-04-17 01:40:08 +02:00
set(CMAKE_C_STANDARD 90)
set(CMAKE_C_EXTENSIONS OFF)
2021-04-17 01:38:31 +02:00
set(CMAKE_CXX_STANDARD 98)
set(CMAKE_CXX_EXTENSIONS OFF)
endif()
2020-06-07 21:57:18 +02:00
2020-01-01 21:29:24 +01:00
# Architecture Flags
2021-04-17 01:30:51 +02:00
if(APPLE)
2020-01-01 21:29:24 +01:00
# Wow, Apple is a huge jerk these days huh?
2021-04-17 01:30:51 +02:00
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()
2020-01-11 13:40:07 +01:00
2020-01-11 17:23:49 +01:00
# RPATH
2021-04-17 01:30:51 +02:00
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()
2020-01-01 21:29:24 +01:00
# Source Lists
2021-04-17 01:30:51 +02:00
set(VVV_SRC
2020-01-01 21:29:24 +01:00
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
2020-04-04 07:53:31 +02:00
src/Render.cpp
2020-11-08 00:47:49 +01:00
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
2020-09-25 18:08:20 +02:00
src/XMLUtils.cpp
2020-01-01 21:29:24 +01:00
src/main.cpp
2020-12-24 08:24:31 +01:00
src/DeferCallbacks.c
Split glitchrunner mode into multiple versions
Previously, turning glitchrunner mode on essentially locked you to
emulating 2.0, and turning it off just meant normal 2.3 behavior. But
what if you wanted 2.2 behavior instead? Well, that's what I had to ask
when a TAS of mine would desync in 2.3 because of the two-frame delay
fix (glitchrunner off), but would also desync because of 2.0 warp lines
(glitchrunner on).
What I've done is made it so there are three states to glitchrunner mode
now: 2.0 (previously just the "on" state), 2.2 (previously a state you
couldn't use), and "off". Furthermore, I made it an enum, so in case
future versions of the game patch out more glitches, we can add them to
the enum (and the only other thing we have to update is a lookup table
in GlitchrunnerMode.c). Also, 2.2 glitches exist in 2.0, so you'll want
to use GlitchrunnerMode_less_than_or_equal() to check glitchrunner
version.
2021-08-05 02:09:49 +02:00
src/GlitchrunnerMode.c
2020-01-13 17:15:17 +01:00
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
2021-02-23 09:54:45 +01:00
src/Vlogging.c
2021-08-22 04:51:19 +02:00
src/Xoshiro.c
2021-09-01 08:09:13 +02:00
../third_party/physfs/extras/physfsrwops.c
2020-01-01 21:29:24 +01:00
)
2021-04-17 01:30:51 +02:00
if(NOT CUSTOM_LEVEL_SUPPORT STREQUAL "DISABLED")
2021-02-20 05:51:25 +01:00
list(APPEND VVV_SRC src/CustomLevels.cpp)
if(NOT CUSTOM_LEVEL_SUPPORT STREQUAL "NO_EDITOR")
LIST(APPEND VVV_SRC src/Editor.cpp)
endif()
2021-04-17 01:30:51 +02:00
endif()
if(STEAM)
list(APPEND VVV_SRC src/SteamNetwork.c)
endif()
if(GOG)
list(APPEND VVV_SRC src/GOGNetwork.c)
2021-04-17 04:09:59 +02:00
endif()
# Executable information
if(WIN32)
2021-08-28 17:21:49 +02:00
add_executable(VVVVVV WIN32 ${VVV_SRC} icon.rc)
2021-04-17 04:09:59 +02:00
else()
add_executable(VVVVVV ${VVV_SRC})
endif()
# Include Directories
if(BUNDLE_DEPENDENCIES)
target_include_directories(
VVVVVV PRIVATE
src
../third_party/tinyxml2
../third_party/physfs
2021-09-01 08:09:13 +02:00
../third_party/physfs/extras
2021-04-17 04:09:59 +02:00
../third_party/lodepng
../third_party/utfcpp/source
)
else()
target_include_directories(
VVVVVV PRIVATE
src
../third_party/lodepng
2021-09-01 08:09:13 +02:00
../third_party/physfs/extras
2021-04-17 04:09:59 +02:00
)
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)
2021-04-17 01:30:51 +02:00
endif()
set(XML2_SRC
2020-06-03 18:42:42 +02:00
../third_party/tinyxml2/tinyxml2.cpp
)
2021-04-17 01:30:51 +02:00
set(PFS_SRC
2020-01-12 18:54:34 +01:00
../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
)
2021-04-17 01:30:51 +02:00
if(APPLE)
2020-01-01 21:29:24 +01:00
# Are you noticing a pattern with this Apple crap yet?
2021-04-17 01:30:51 +02:00
set(PFS_SRC ${PFS_SRC} ../third_party/physfs/physfs_platform_apple.m)
endif()
set(PNG_SRC ../third_party/lodepng/lodepng.c)
2020-01-01 21:29:24 +01:00
2021-04-17 01:30:51 +02:00
if(NOT OFFICIAL_BUILD)
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
# Add interim commit hash and its date to the build
2021-04-17 01:30:51 +02:00
# find_package sets GIT_FOUND and GIT_EXECUTABLE
find_package(Git)
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
2021-04-17 01:30:51 +02:00
if(GIT_FOUND)
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
# These filenames have to be qualified, because when we run
# the CMake script, its work dir gets set to the build folder
2021-04-17 01:30:51 +02:00
set(VERSION_INPUT_FILE ${CMAKE_CURRENT_SOURCE_DIR}/src/Version.h.in)
set(VERSION_OUTPUT_FILE ${CMAKE_CURRENT_SOURCE_DIR}/src/Version.h.out)
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
2021-04-17 01:30:51 +02:00
add_custom_target(
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
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
)
2021-04-17 01:30:51 +02:00
add_dependencies(VVVVVV GenerateVersion)
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
# This lets Version.h know that Version.h.out exists
2021-04-17 01:30:51 +02:00
add_definitions(-DVERSION_H_OUT_EXISTS)
endif()
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
2020-01-11 01:58:33 +01:00
# Build options
2021-04-17 01:30:51 +02:00
if(ENABLE_WARNINGS)
2020-01-11 01:58:33 +01:00
# The weird syntax is due to CMake generator expressions.
# Saves quite a few lines and boilerplate at the price of readability.
2021-04-17 01:30:51 +02:00
target_compile_options(VVVVVV PRIVATE
2020-01-11 01:58:33 +01:00
$<$<OR:$<CXX_COMPILER_ID:GNU>,$<CXX_COMPILER_ID:Clang>,$<CXX_COMPILER_ID:AppleClang>>:
2021-04-15 06:59:01 +02:00
-Wall -Wpedantic $<$<BOOL:${ENABLE_WERROR}>:-Werror>>
2020-01-11 01:58:33 +01:00
$<$<CXX_COMPILER_ID:MSVC>:
2020-01-12 01:28:39 +01:00
/W4 $<$<BOOL:${ENABLE_WERROR}>:/WX>>)
2021-04-17 01:30:51 +02:00
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")
2021-04-17 04:30:27 +02:00
set(SUPPORTS_IMPLICIT_FALLTHROUGH TRUE)
2021-04-17 01:30:51 +02:00
elseif(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
if(CMAKE_CXX_COMPILER_VERSION VERSION_GREATER 7.0)
2021-04-17 04:30:27 +02:00
set(SUPPORTS_IMPLICIT_FALLTHROUGH TRUE)
2021-04-17 01:30:51 +02:00
else()
2021-04-17 04:30:27 +02:00
set(SUPPORTS_IMPLICIT_FALLTHROUGH FALSE)
2021-04-17 01:30:51 +02:00
endif()
else()
2021-04-17 04:30:27 +02:00
set(SUPPORTS_IMPLICIT_FALLTHROUGH FALSE)
2021-04-17 01:30:51 +02:00
endif()
if(SUPPORTS_IMPLICIT_FALLTHROUGH)
target_compile_options(VVVVVV PRIVATE -Werror=implicit-fallthrough)
endif()
if(MSVC)
2021-01-14 04:18:29 +01:00
# Disable MSVC warnings about implicit conversion
2021-04-17 01:30:51 +02:00
target_compile_options(VVVVVV PRIVATE /wd4244)
endif()
2021-01-14 04:18:29 +01:00
2021-04-17 04:42:26 +02:00
if(MSVC)
# Disable exceptions
2021-04-20 20:19:59 +02:00
string(REGEX REPLACE "/EH[a-z]+" "" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
2021-04-17 04:42:26 +02:00
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /EHsc")
# Disable RTTI
2021-04-20 20:19:59 +02:00
string(REGEX REPLACE "/GR" "" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
2021-04-17 04:42:26 +02:00
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /GR-")
else()
# Disable exceptions
2021-04-20 20:19:59 +02:00
string(REGEX REPLACE "-fexceptions" "" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
2021-04-17 04:42:26 +02:00
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-exceptions")
# Disable RTTI
2021-04-20 20:19:59 +02:00
string(REGEX REPLACE "-frtti" "" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
2021-04-17 04:42:26 +02:00
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-rtti")
endif()
Add option to not use bundled TinyXML-2, PhysFS, and UTF8-CPP
If you configure the build with -DBUNDLE_DEPENDENCIES=OFF, then VVVVVV
will dynamically link with TinyXML-2 and PhysicsFS instead of using the
bundled source code in third_party/ and statically linking with them.
Unfortunately, it doesn't seem like distros package LodePNG, and LodePNG
isn't intended to be packaged, so we can't dynamically link with it, nor
can we use some system LodePNG header files somewhere else because those
don't exist.
UTF8-CPP is a special case, because no matter what, it's going to be
statically linked with the binary (it doesn't come as a shared object
file in any way). So with -DBUNDLE_DEPENDENCIES=OFF, we will use the
system UTF8-CPP header files instead of the bundled ones, but it will
still be statically linked in with the binary.
The main motivation for doing this is so if VVVVVV ever gets packaged in
distros, distro maintainers would be more likely to accept it if there
was an option to compile the game without bundled dependencies. Also, it
discourages modifying the third-party dependencies we have, because it's
always possible for someone to compile those dependencies without our
changes, with this CMake option.
2020-12-21 22:30:01 +01:00
# Unfortunately, it doesn't seem like distros package LodePNG
2021-04-17 01:30:51 +02:00
add_library(lodepng-static STATIC ${PNG_SRC})
2020-01-01 21:29:24 +01:00
2021-04-17 01:30:51 +02:00
target_compile_definitions(lodepng-static PRIVATE
2021-01-14 04:12:58 +01:00
-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
2021-04-17 01:30:51 +02:00
if(BUNDLE_DEPENDENCIES)
add_library(tinyxml2-static STATIC ${XML2_SRC})
2021-04-17 04:15:50 +02:00
add_library(physfs-static STATIC ${PFS_SRC})
2021-04-17 04:09:59 +02:00
target_compile_definitions(physfs-static PRIVATE
-DPHYSFS_SUPPORTS_DEFAULT=0 -DPHYSFS_SUPPORTS_ZIP=1
)
Add option to not use bundled TinyXML-2, PhysFS, and UTF8-CPP
If you configure the build with -DBUNDLE_DEPENDENCIES=OFF, then VVVVVV
will dynamically link with TinyXML-2 and PhysicsFS instead of using the
bundled source code in third_party/ and statically linking with them.
Unfortunately, it doesn't seem like distros package LodePNG, and LodePNG
isn't intended to be packaged, so we can't dynamically link with it, nor
can we use some system LodePNG header files somewhere else because those
don't exist.
UTF8-CPP is a special case, because no matter what, it's going to be
statically linked with the binary (it doesn't come as a shared object
file in any way). So with -DBUNDLE_DEPENDENCIES=OFF, we will use the
system UTF8-CPP header files instead of the bundled ones, but it will
still be statically linked in with the binary.
The main motivation for doing this is so if VVVVVV ever gets packaged in
distros, distro maintainers would be more likely to accept it if there
was an option to compile the game without bundled dependencies. Also, it
discourages modifying the third-party dependencies we have, because it's
always possible for someone to compile those dependencies without our
changes, with this CMake option.
2020-12-21 22:30:01 +01:00
2021-04-17 01:40:08 +02:00
# PhysFS needs some extensions...
if(${CMAKE_VERSION} VERSION_GREATER "3.1.3"
OR ${CMAKE_VERSION} VERSION_EQUAL "3.1.3")
set_property(TARGET physfs-static PROPERTY C_EXTENSIONS ON)
endif()
2021-04-17 01:30:51 +02:00
target_link_libraries(VVVVVV physfs-static tinyxml2-static lodepng-static)
else()
find_package(utf8cpp CONFIG)
Add option to not use bundled TinyXML-2, PhysFS, and UTF8-CPP
If you configure the build with -DBUNDLE_DEPENDENCIES=OFF, then VVVVVV
will dynamically link with TinyXML-2 and PhysicsFS instead of using the
bundled source code in third_party/ and statically linking with them.
Unfortunately, it doesn't seem like distros package LodePNG, and LodePNG
isn't intended to be packaged, so we can't dynamically link with it, nor
can we use some system LodePNG header files somewhere else because those
don't exist.
UTF8-CPP is a special case, because no matter what, it's going to be
statically linked with the binary (it doesn't come as a shared object
file in any way). So with -DBUNDLE_DEPENDENCIES=OFF, we will use the
system UTF8-CPP header files instead of the bundled ones, but it will
still be statically linked in with the binary.
The main motivation for doing this is so if VVVVVV ever gets packaged in
distros, distro maintainers would be more likely to accept it if there
was an option to compile the game without bundled dependencies. Also, it
discourages modifying the third-party dependencies we have, because it's
always possible for someone to compile those dependencies without our
changes, with this CMake option.
2020-12-21 22:30:01 +01:00
2021-04-17 01:30:51 +02:00
target_link_libraries(VVVVVV physfs tinyxml2 utf8cpp lodepng-static)
endif()
2020-01-01 21:29:24 +01:00
# SDL2 Dependency (Detection pulled from FAudio)
2021-04-17 01:30:51 +02:00
if(DEFINED SDL2_INCLUDE_DIRS AND DEFINED SDL2_LIBRARIES)
2020-01-01 21:29:24 +01:00
message(STATUS "Using pre-defined SDL2 variables SDL2_INCLUDE_DIRS and SDL2_LIBRARIES")
2021-04-17 02:27:54 +02:00
target_include_directories(VVVVVV SYSTEM PRIVATE "$<BUILD_INTERFACE:${SDL2_INCLUDE_DIRS}>")
2020-01-11 17:23:49 +01:00
target_link_libraries(VVVVVV ${SDL2_LIBRARIES})
2021-03-31 19:48:45 +02:00
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)
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)
2021-04-17 01:30:51 +02:00
if(TARGET SDL2::SDL2)
2020-01-01 21:29:24 +01:00
message(STATUS "Using TARGET SDL2::SDL2")
2020-01-11 17:23:49 +01:00
target_link_libraries(VVVVVV SDL2::SDL2 SDL2_mixer)
2021-04-17 01:30:51 +02:00
elseif(TARGET SDL2)
2020-01-01 21:29:24 +01:00
message(STATUS "Using TARGET SDL2")
2020-01-11 17:23:49 +01:00
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")
2020-06-07 22:11:12 +02:00
find_path(SDL2_MIXER_INCLUDE_DIRS NAMES SDL_mixer.h PATH_SUFFIXES SDL2)
2021-04-17 02:27:54 +02:00
target_include_directories(VVVVVV SYSTEM PRIVATE "$<BUILD_INTERFACE:${SDL2_INCLUDE_DIRS}>" ${SDL2_MIXER_INCLUDE_DIRS})
2020-01-11 17:23:49 +01:00
target_link_libraries(VVVVVV ${SDL2_LIBRARIES} SDL2_mixer)
2020-01-01 21:29:24 +01:00
endif()
endif()
# Yes, more Apple Crap
2021-04-17 01:30:51 +02:00
if(APPLE)
find_library(FOUNDATION NAMES Foundation)
find_library(IOKIT NAMES IOKit)
target_link_libraries(VVVVVV objc ${IOKIT} ${FOUNDATION})
endif()
2020-01-14 05:31:14 +01:00
# But hey, also some Haiku crap
2021-04-17 01:30:51 +02:00
if(HAIKU)
find_library(BE_LIBRARY be)
find_library(ROOT_LIBRARY root)
target_link_libraries(VVVVVV ${BE_LIBRARY} ${ROOT_LIBRARY})
endif()
2021-03-31 20:27:23 +02:00
if(EMSCRIPTEN)
target_compile_options(VVVVVV PUBLIC -sFORCE_FILESYSTEM=1)
# 256MB is enough for everybody
target_link_libraries(VVVVVV -sFORCE_FILESYSTEM=1 -sTOTAL_MEMORY=256MB)
endif()