Files
VVVVVV/desktop_version/CMakeLists.txt
Misa 02a45f9cbc Don't recompile all files when the commit hash is changed
The previous implementation of showing the commit hash on the title
screen used a preprocessor definition added at CMake time to pass the
hash and date. This was passed for every file compiled, so if the date
or hash changed, then every file would be recompiled. This is especially
annoying if you're working on the game and switching branches all the
time - the game has at least 50 source files to recompile!

To fix this, we'll switch to using a generated file, named
Version.h.out, that only gets included by the necessary files (which
there is only one of - Render.cpp). It will be autogenerated by CMake
(by using CONFIGURE_FILE(), which takes a templated file and does a
find-and-replace on it, not unlike C macros), and since there's only one
file that includes it, only one file will need to be recompiled when it
changes.

And also to prevent Version.h.out being a required file, it will only be
included if necessary (i.e. OFFICIAL_BUILD is off). Since the C
preprocessor can't ignore non-existing include files and will always
error on them, I wrapped the #include in an #ifdef VERSION_H_EXISTS, and
CMake will add the VERSION_H_OUT_EXISTS define when generating
Version.h.out. The wrapper is named Version.h, so any file
that #includes the commit hash and date should #include Version.h
instead of Version.h.out.

As an added bonus, I've also made it so CMake will print "This is
interim commit [HASH] (committed [DATE])" at configure time if the game
is going to be compiled with an interim commit hash.

Now, there is also the issue that the commit hash change will only be
noticed in the first place if CMake needs to be re-ran for anything, but
that's a less severe issue than requiring recompilation of 50(!) or so
files.
2020-12-25 20:17:01 -05:00

259 lines
7.3 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)
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")
IF(OFFICIAL_BUILD)
SET(STEAM ON)
SET(GOG ON)
ELSE()
# Get interim commit and date of commit
FIND_PACKAGE(Git)
IF(GIT_FOUND)
EXECUTE_PROCESS(
COMMAND "${GIT_EXECUTABLE}" log -1 --format=%h
OUTPUT_VARIABLE INTERIM_COMMIT
ERROR_QUIET OUTPUT_STRIP_TRAILING_WHITESPACE
)
EXECUTE_PROCESS(
COMMAND "${GIT_EXECUTABLE}" log -1 --format=%cs
OUTPUT_VARIABLE COMMIT_DATE
ERROR_QUIET OUTPUT_STRIP_TRAILING_WHITESPACE
)
MESSAGE(STATUS "This is interim commit ${INTERIM_COMMIT} (committed ${COMMIT_DATE})")
# Take template file and replace the macros with what we have
# Unfortunately the output is taken relative to binary path so we have to qualify it
CONFIGURE_FILE(src/Version.h.in ${CMAKE_CURRENT_SOURCE_DIR}/src/Version.h.out)
# This lets Version.h know that Version.h.out exists
ADD_DEFINITIONS(-DVERSION_H_OUT_EXISTS)
ENDIF()
ENDIF()
# Set standard to C++98/C++03
SET(CMAKE_CXX_STANDARD 98)
SET(CMAKE_CXX_EXTENSIONS OFF) # prevent mixing stdlib implementations (dangerous!)
# 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()
# 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)
ENDIF()
# Include Directories
INCLUDE_DIRECTORIES(
src
../third_party/tinyxml2
../third_party/physfs
../third_party/lodepng
../third_party/utfcpp/source
)
# 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/SoundSystem.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/Network.c
)
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
)
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
../third_party/physfs/physfs_platform_haiku.cpp
)
IF(APPLE)
# Are you noticing a pattern with this Apple crap yet?
SET(PFS_SRC ${PFS_SRC} ../third_party/physfs/physfs_platform_apple.m)
ENDIF()
SET(PNG_SRC ../third_party/lodepng/lodepng.c)
# Executable information
IF(WIN32)
ADD_EXECUTABLE(VVVVVV WIN32 ${VVV_SRC})
ELSE()
ADD_EXECUTABLE(VVVVVV ${VVV_SRC})
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 $<$<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 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()
SET_PROPERTY(TARGET VVVVVV PROPERTY CXX_STANDARD 98)
SET_PROPERTY(TARGET VVVVVV PROPERTY CXX_EXTENSIONS FALSE)
# Library information
ADD_LIBRARY(tinyxml2-static STATIC ${XML2_SRC})
ADD_LIBRARY(physfs-static STATIC ${PFS_SRC} ${PFSP_SRC})
ADD_LIBRARY(lodepng-static STATIC ${PNG_SRC})
# Static Dependencies
TARGET_LINK_LIBRARIES(VVVVVV physfs-static tinyxml2-static lodepng-static)
# 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 PUBLIC "$<BUILD_INTERFACE:${SDL2_INCLUDE_DIRS}>")
target_link_libraries(VVVVVV ${SDL2_LIBRARIES})
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 PUBLIC "$<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()