ddnet/CMakeLists.txt
bors[bot] 2b5723cdef
Merge #3492 #3559 #3561 #3565
3492: Support F-Client and replace non-extended extension messages r=Learath2 a=heinrich5991

This continues what #3439 started, and also replaces non-extended messages that are DDRace extensions with extended messages. The DDNet server still sends the old message to old clients and the DDNet client still understands the old messages.

Supersedes #3439.

## Checklist

- [x] Tested the change ingame
- [ ] Provided screenshots if it is a visual change
- [ ] Tested in combination with possibly related configuration options
- [ ] Written a unit test if it works standalone, system.c especially
- [x] Considered possible null pointers and out of bounds array indexing
- [x] Changed no physics that affect existing maps
- [ ] Tested the change with [ASan+UBSan or valgrind's memcheck](https://github.com/ddnet/ddnet/#using-addresssanitizer--undefinedbehavioursanitizer-or-valgrinds-memcheck) (optional)


3559: Don't highlight us if we have no name (alternative fix for #3554) r=heinrich5991 a=def-

<!-- What is the motivation for the changes of this pull request -->

## Checklist

- [x] Tested the change ingame
- [ ] Provided screenshots if it is a visual change
- [ ] Tested in combination with possibly related configuration options
- [ ] Written a unit test if it works standalone, system.c especially
- [x] Considered possible null pointers and out of bounds array indexing
- [x] Changed no physics that affect existing maps
- [ ] Tested the change with [ASan+UBSan or valgrind's memcheck](https://github.com/ddnet/ddnet/#using-addresssanitizer--undefinedbehavioursanitizer-or-valgrinds-memcheck) (optional)


3561: Fix input message position in teehistorian files r=heinrich5991 a=Zwelf

Previously the message was recorded when incoming. But the time when the input should apply wasn't recorded. Now inputs are recorded right before they get applied in the game world.

And record exact tick where load/save result is returned.

## Checklist

- [x] Tested the change ingame
- [ ] Provided screenshots if it is a visual change
- [ ] Tested in combination with possibly related configuration options
- [ ] Written a unit test if it works standalone, system.c especially
- [x] Considered possible null pointers and out of bounds array indexing
- [x] Changed no physics that affect existing maps
- [ ] Tested the change with [ASan+UBSan or valgrind's memcheck](https://github.com/ddnet/ddnet/#using-addresssanitizer--undefinedbehavioursanitizer-or-valgrinds-memcheck) (optional)


3565: Add Arabic language translation by .Yukki r=heinrich5991 a=def-

![screenshot-20210131@093216](https://user-images.githubusercontent.com/2335377/106378755-747d7780-63a7-11eb-9553-6a1898907441.png)

## Checklist

- [x] Tested the change ingame
- [x] Provided screenshots if it is a visual change
- [x] Tested in combination with possibly related configuration options
- [ ] Written a unit test if it works standalone, system.c especially
- [x] Considered possible null pointers and out of bounds array indexing
- [x] Changed no physics that affect existing maps
- [ ] Tested the change with [ASan+UBSan or valgrind's memcheck](https://github.com/ddnet/ddnet/#using-addresssanitizer--undefinedbehavioursanitizer-or-valgrinds-memcheck) (optional)


Co-authored-by: fokkonaut <35420825+fokkonaut@users.noreply.github.com>
Co-authored-by: heinrich5991 <heinrich5991@gmail.com>
Co-authored-by: def <dennis@felsin9.de>
Co-authored-by: Zwelf <zwelf@strct.cc>
2021-01-31 14:37:48 +00:00

2704 lines
81 KiB
CMake

cmake_minimum_required(VERSION 2.8.12...3.19.1)
if(CMAKE_VERSION VERSION_LESS 3.12)
cmake_policy(VERSION ${CMAKE_VERSION})
endif()
set(CMAKE_OSX_DEPLOYMENT_TARGET 10.9 CACHE INTERNAL "")
if(CMAKE_OSX_DEPLOYMENT_TARGET VERSION_LESS 10.9)
message(WARNING "Building for macOS <= 10.9 is not supported")
endif()
file(STRINGS src/game/version.h VERSION_LINE
LIMIT_COUNT 1
REGEX "^#define GAME_RELEASE_VERSION "
)
if(VERSION_LINE MATCHES "\"([0-9]+)\\.([0-9]+)\\.([0-9]+)\"")
set(VERSION_MAJOR ${CMAKE_MATCH_1})
set(VERSION_MINOR ${CMAKE_MATCH_2})
set(VERSION_PATCH ${CMAKE_MATCH_3})
elseif(VERSION_LINE MATCHES "\"([0-9]+)\\.([0-9]+)\"")
set(VERSION_MAJOR ${CMAKE_MATCH_1})
set(VERSION_MINOR ${CMAKE_MATCH_2})
set(VERSION_PATCH "0")
else()
message(FATAL_ERROR "Couldn't parse version from src/game/version.h")
endif()
# Extra support for CMake pre-3.0
if(NOT POLICY CMP0048)
set(PROJECT_VERSION_MAJOR ${VERSION_MAJOR})
set(PROJECT_VERSION_MINOR ${VERSION_MINOR})
set(PROJECT_VERSION_PATCH ${VERSION_PATCH})
if(VERSION_PATCH STREQUAL "0")
set(PROJECT_VERSION ${VERSION_MAJOR}.${VERSION_MINOR})
else()
set(PROJECT_VERSION ${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH})
endif()
endif()
if(VERSION_PATCH STREQUAL "0")
project(DDNet VERSION ${VERSION_MAJOR}.${VERSION_MINOR})
else()
project(DDNet VERSION ${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH})
endif()
set(ORIGINAL_CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH})
set(ORIGINAL_CMAKE_REQUIRED_INCLUDES ${CMAKE_REQUIRED_INCLUDES})
set(ORIGINAL_CMAKE_REQUIRED_LIBRARIES ${CMAKE_REQUIRED_LIBRARIES})
set(OWN_CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${PROJECT_SOURCE_DIR}/cmake)
set(CMAKE_MODULE_PATH ${OWN_CMAKE_MODULE_PATH})
if(CMAKE_SIZEOF_VOID_P EQUAL 4)
set(TARGET_BITS "32")
else()
set(TARGET_BITS "64")
endif()
if(CMAKE_SYSTEM_NAME STREQUAL "Windows")
set(TARGET_OS "windows")
elseif(CMAKE_SYSTEM_NAME STREQUAL "Linux")
set(TARGET_OS "linux")
elseif(CMAKE_SYSTEM_NAME STREQUAL "Darwin")
set(TARGET_OS "mac")
endif()
include(CheckCCompilerFlag)
include(CheckCXXCompilerFlag)
include(CheckSymbolExists)
check_symbol_exists(__i386 "" TARGET_ARCH_X86_i386)
if(TARGET_ARCH_X86_i386)
set(TARGET_ARCH x86)
else()
set(TARGET_ARCH)
endif()
set(AUTO_DEPENDENCIES_DEFAULT OFF)
if(TARGET_OS STREQUAL "windows")
set(AUTO_DEPENDENCIES_DEFAULT ON)
elseif(TARGET_OS STREQUAL "linux")
endif()
option(WEBSOCKETS "Enable websockets support" OFF)
option(MYSQL "Enable mysql support" OFF)
option(AUTOUPDATE "Enable the autoupdater" OFF)
option(INFORM_UPDATE "Inform about available updates" ON)
option(VIDEORECORDER "Enable video recording support via FFmpeg" OFF)
option(UPNP "Enable UPnP support" OFF)
option(ANTIBOT "Enable support for a dynamic anticheat library" OFF)
option(CLIENT "Compile client" ON)
option(DOWNLOAD_GTEST "Download and compile GTest" ${AUTO_DEPENDENCIES_DEFAULT})
option(STEAM "Build the Steam release version" OFF)
option(DISCORD "Enable Discord rich presence support" OFF)
option(PREFER_BUNDLED_LIBS "Prefer bundled libraries over system libraries" ${AUTO_DEPENDENCIES_DEFAULT})
option(DEV "Don't generate stuff necessary for packaging" OFF)
# Set version if not explicitly set
if(NOT VERSION)
set(VERSION ${PROJECT_VERSION})
endif()
set(OpenGL_GL_PREFERENCE LEGACY)
# Set the default build type to Release
if(NOT(CMAKE_BUILD_TYPE))
if(NOT(DEV))
set(CMAKE_BUILD_TYPE Release)
else()
set(CMAKE_BUILD_TYPE Debug)
endif()
endif()
if(NOT(CMAKE_BUILD_TYPE MATCHES "^(Release|Debug|RelWithDebInfo|MinSizeRel)$"))
message(WARNING "Unknown CMAKE_BUILD_TYPE, should be one of Release, Debug, RelWithDebInfo or MinSizeRel")
endif()
set(DBG $<OR:$<CONFIG:Debug>,$<CONFIG:RelWithDebInfo>>)
if(CMAKE_VERSION VERSION_LESS 3.0)
configure_file(src/game/version.h vd.h)
else()
set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS
src/game/version.h
)
endif()
set(SERVER_EXECUTABLE DDNet-Server CACHE STRING "Name of the built server executable")
set(CLIENT_EXECUTABLE DDNet CACHE STRING "Name of the build client executable")
########################################################################
# Compiler flags
########################################################################
function(add_c_compiler_flag_if_supported VARIABLE FLAG)
if(ARGC GREATER 2)
set(CHECKED_FLAG "${ARGV2}")
else()
set(CHECKED_FLAG "${FLAG}")
endif()
string(REGEX REPLACE "[^A-Za-z0-9]" "_" CONFIG_VARIABLE "FLAG_SUPPORTED${CHECKED_FLAG}")
check_c_compiler_flag("${CHECKED_FLAG}" ${CONFIG_VARIABLE})
if(${CONFIG_VARIABLE})
if(${VARIABLE})
set("${VARIABLE}" "${${VARIABLE}};${FLAG}" PARENT_SCOPE)
else()
set("${VARIABLE}" "${FLAG}" PARENT_SCOPE)
endif()
endif()
endfunction()
# Force compiler colors on when using ninja. Ninja filters the colors out when
# it's not printing to a terminal on its own.
if(CMAKE_GENERATOR STREQUAL "Ninja")
add_c_compiler_flag_if_supported(OUR_FLAGS -fdiagnostics-color=always)
add_c_compiler_flag_if_supported(OUR_FLAGS -fcolor-diagnostics)
endif()
if(NOT MSVC)
if(CMAKE_VERSION VERSION_LESS 3.1 OR TARGET_OS STREQUAL "mac")
check_cxx_compiler_flag(-std=gnu++11 FLAG_SUPPORTED_std_gnu__11)
if(FLAG_SUPPORTED_std_gnu__11)
if(CMAKE_CXX_FLAGS)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=gnu++11")
else()
set(CMAKE_CXX_FLAGS -std=gnu++11)
endif()
endif()
endif()
# Protect the stack pointer.
# -fstack-protector-all doesn't work on MinGW.
add_c_compiler_flag_if_supported(OUR_FLAGS -fstack-protector-all)
# Inaccurate floating point numbers cause problems on mingw-w64-gcc when
# compiling for x86, might cause problems elsewhere. So don't store floats
# in registers but keep them at higher accuracy.
if(TARGET_ARCH STREQUAL "x86")
add_c_compiler_flag_if_supported(OUR_FLAGS -ffloat-store)
endif()
# Don't insert timestamps into PEs to keep the build reproducible.
if(TARGET_OS STREQUAL "windows")
add_c_compiler_flag_if_supported(OUR_FLAGS_LINK -Wl,--no-insert-timestamp)
endif()
if(TARGET_OS STREQUAL "mac")
add_c_compiler_flag_if_supported(OUR_FLAGS -stdlib=libc++)
endif()
add_c_compiler_flag_if_supported(OUR_FLAGS_OWN -Wall)
if(CMAKE_VERSION VERSION_GREATER 3.3 OR CMAKE_VERSION VERSION_EQUAL 3.3)
add_c_compiler_flag_if_supported(OUR_FLAGS_OWN
$<$<COMPILE_LANGUAGE:C>:-Wdeclaration-after-statement>
-Wdeclaration-after-statement
)
endif()
add_c_compiler_flag_if_supported(OUR_FLAGS_OWN -Wextra)
add_c_compiler_flag_if_supported(OUR_FLAGS_OWN -Wno-unused-parameter)
add_c_compiler_flag_if_supported(OUR_FLAGS_OWN -Wno-missing-field-initializers)
add_c_compiler_flag_if_supported(OUR_FLAGS_OWN -Wformat=2) # Warn about format strings.
add_c_compiler_flag_if_supported(OUR_FLAGS_DEP -Wno-implicit-function-declaration)
add_c_compiler_flag_if_supported(OUR_FLAGS_OWN -Wno-nullability-completeness) # Mac OS build on github
add_c_compiler_flag_if_supported(OUR_FLAGS_OWN -Wduplicated-cond)
add_c_compiler_flag_if_supported(OUR_FLAGS_OWN -Wduplicated-branches)
add_c_compiler_flag_if_supported(OUR_FLAGS_OWN -Wlogical-op)
add_c_compiler_flag_if_supported(OUR_FLAGS_OWN -Wrestrict)
add_c_compiler_flag_if_supported(OUR_FLAGS_OWN -Wthread-safety)
# TODO: Enable for C++ code except gtest
#add_cxx_compiler_flag_if_supported(OUR_FLAGS_OWN "-Wuseless-cast")
endif()
if(NOT MSVC)
check_c_compiler_flag("-O2;-Wp,-Werror;-D_FORTIFY_SOURCE=2" DEFINE_FORTIFY_SOURCE) # Some distributions define _FORTIFY_SOURCE by themselves.
endif()
########################################################################
# COMMON FUNCTIONS
########################################################################
function(set_glob VAR GLOBBING EXTS DIRECTORY) # ...
set(GLOBS)
foreach(ext ${EXTS})
list(APPEND GLOBS "${DIRECTORY}/*.${ext}")
endforeach()
file(${GLOBBING} GLOB_RESULT ${GLOBS})
list(SORT GLOB_RESULT)
set(FILES)
foreach(file ${ARGN})
list(APPEND FILES "${PROJECT_SOURCE_DIR}/${DIRECTORY}/${file}")
endforeach()
if(NOT FILES STREQUAL GLOB_RESULT)
message(AUTHOR_WARNING "${VAR} does not contain every file from directory ${DIRECTORY}")
set(LIST_BUT_NOT_GLOB)
if(POLICY CMP0057)
cmake_policy(SET CMP0057 NEW)
foreach(file ${FILES})
if(NOT file IN_LIST GLOB_RESULT)
list(APPEND LIST_BUT_NOT_GLOB ${file})
endif()
endforeach()
if(LIST_BUT_NOT_GLOB)
message(AUTHOR_WARNING "Entries only present in ${VAR}: ${LIST_BUT_NOT_GLOB}")
endif()
set(GLOB_BUT_NOT_LIST)
foreach(file ${GLOB_RESULT})
if(NOT file IN_LIST FILES)
list(APPEND GLOB_BUT_NOT_LIST ${file})
endif()
endforeach()
if(GLOB_BUT_NOT_LIST)
message(AUTHOR_WARNING "Entries only present in ${DIRECTORY}: ${GLOB_BUT_NOT_LIST}")
endif()
if(NOT LIST_BUT_NOT_GLOB AND NOT GLOB_BUT_NOT_LIST)
message(AUTHOR_WARNING "${VAR} is not alphabetically sorted")
endif()
endif()
endif()
set(${VAR} ${FILES} PARENT_SCOPE)
endfunction()
function(set_src VAR GLOBBING DIRECTORY) # ...
set_glob(${VAR} ${GLOBBING} "c;cpp;h" ${DIRECTORY} ${ARGN})
set(${VAR} ${${VAR}} PARENT_SCOPE)
endfunction()
function(set_own_rpath TARGET)
if(NOT TARGET_OS STREQUAL "windows" AND NOT TARGET_OS STREQUAL "mac")
if(CMAKE_VERSION VERSION_GREATER 3.14 OR CMAKE_VERSION VERSION_EQUAL 3.14)
set_property(TARGET ${TARGET} PROPERTY BUILD_RPATH_USE_ORIGIN TRUE)
elseif(CMAKE_VERSION VERSION_GREATER 3.8 OR CMAKE_VERSION VERSION_EQUAL 3.8)
set_property(TARGET ${TARGET} PROPERTY BUILD_RPATH "$ORIGIN")
endif()
set_property(TARGET ${TARGET} PROPERTY INSTALL_RPATH "$ORIGIN/../lib/ddnet")
endif()
endfunction()
if(NOT TARGET_OS STREQUAL "windows" AND NOT TARGET_OS STREQUAL "mac" AND CMAKE_VERSION VERSION_LESS 3.8)
if((CLIENT AND STEAM) OR ANTIBOT)
message(STATUS "Can't set BUILD_RPATH in CMake before 3.8, pass -Wl,-rpath,'$ORIGIN' manually if you wish to emulate this. Or just install a newer version of CMake...")
endif()
endif()
########################################################################
# INITIALIZE TARGET LISTS
########################################################################
set(TARGETS_OWN)
set(TARGETS_DEP)
set(TARGETS_LINK) # Targets with a linking stage.
########################################################################
# DEPENDENCIES
########################################################################
function(set_extra_dirs_lib VARIABLE NAME)
set("PATHS_${VARIABLE}_LIBDIR" PARENT_SCOPE)
set("HINTS_${VARIABLE}_LIBDIR" PARENT_SCOPE)
if(PREFER_BUNDLED_LIBS)
set(TYPE HINTS)
else()
set(TYPE PATHS)
endif()
if(TARGET_BITS AND TARGET_OS)
set(DIR "ddnet-libs/${NAME}/${TARGET_OS}/lib${TARGET_BITS}")
set("${TYPE}_${VARIABLE}_LIBDIR" "${DIR}" PARENT_SCOPE)
set("EXTRA_${VARIABLE}_LIBDIR" "${DIR}" PARENT_SCOPE)
endif()
endfunction()
function(set_extra_dirs_include VARIABLE NAME LIBRARY)
set("PATHS_${VARIABLE}_INCLUDEDIR" PARENT_SCOPE)
set("HINTS_${VARIABLE}_INCLUDEDIR" PARENT_SCOPE)
is_bundled(IS_BUNDLED "${LIBRARY}")
if(IS_BUNDLED)
set("HINTS_${VARIABLE}_INCLUDEDIR" "ddnet-libs/${NAME}/include" "ddnet-libs/${NAME}/include/${TARGET_OS}" PARENT_SCOPE)
endif()
endfunction()
if(CMAKE_CROSSCOMPILING)
set(CROSSCOMPILING_NO_CMAKE_SYSTEM_PATH NO_CMAKE_SYSTEM_PATH)
else()
set(CROSSCOMPILING_NO_CMAKE_SYSTEM_PATH)
endif()
function(is_bundled VARIABLE PATH)
if(PATH)
string(FIND "${PATH}" "${PROJECT_SOURCE_DIR}" LOCAL_PATH_POS)
if(LOCAL_PATH_POS EQUAL 0 AND TARGET_BITS AND TARGET_OS)
set("${VARIABLE}" ON PARENT_SCOPE)
else()
set("${VARIABLE}" OFF PARENT_SCOPE)
endif()
else()
set("${VARIABLE}" OFF PARENT_SCOPE)
endif()
endfunction()
if(NOT CMAKE_CROSSCOMPILING)
# Check for PkgConfig once so all the other `find_package` calls can do it
# quietly.
find_package(PkgConfig)
endif()
find_package(ZLIB)
find_package(Crypto)
find_package(Curl)
if(VIDEORECORDER)
find_package(FFMPEG)
endif()
find_package(Freetype)
if(DOWNLOAD_GTEST)
find_package(Git)
endif()
find_package(GLEW)
find_package(GTest)
if(UPNP)
find_package(Miniupnpc)
endif()
if(MYSQL)
find_package(MySQL)
else()
set(MYSQL_LIBRARIES)
endif()
find_package(Ogg)
find_package(Opus)
find_package(Opusfile)
find_package(Pnglite)
find_package(PythonInterp 3)
find_package(SDL2)
find_package(SQLite3)
if(DISCORD)
find_package(DiscordSdk)
endif()
if(UNIX)
# Use -pthread instead of -lpthread to draw dependencies other than libpthread
set(THREADS_PREFER_PTHREAD_FLAG TRUE)
endif()
find_package(Threads)
find_package(Wavpack)
if(WEBSOCKETS)
find_package(Websockets)
else()
set(WEBSOCKETS_LIBRARIES)
set(WEBSOCKETS_INCLUDE_DIRS)
endif()
if(TARGET_OS AND TARGET_OS STREQUAL "mac")
find_program(CMAKE_OTOOL otool)
find_program(DMG dmg)
find_program(HFSPLUS hfsplus)
find_program(NEWFS_HFS newfs_hfs)
if(DMG AND HFSPLUS AND NEWFS_HFS)
set(DMGTOOLS_FOUND ON)
else()
set(DMGTOOLS_FOUND OFF)
endif()
find_program(HDIUTIL hdiutil)
if(HDIUTIL)
set(HDIUTIL_FOUND ON)
else()
set(HDIUTIL_FOUND OFF)
endif()
endif()
message(STATUS "******** DDNet ********")
if(NOT TARGET_OS STREQUAL "mac")
message(STATUS "Target OS: ${TARGET_OS} ${TARGET_BITS}bit")
else()
message(STATUS "Target OS: ${TARGET_OS} ${TARGET_BITS}bit (SDK: ${CMAKE_OSX_SYSROOT})")
endif()
message(STATUS "Compiler: ${CMAKE_CXX_COMPILER}")
message(STATUS "Build type: ${CMAKE_BUILD_TYPE}")
message(STATUS "Dependencies:")
function(show_dependency_status OUTPUT_NAME NAME)
if(${NAME}_FOUND)
if(${NAME}_BUNDLED)
message(STATUS " * ${OUTPUT_NAME} not found (using bundled version)")
else()
message(STATUS " * ${OUTPUT_NAME} found")
endif()
else()
message(STATUS " * ${OUTPUT_NAME} not found")
endif()
endfunction()
show_dependency_status("Curl" CURL)
if(TARGET_OS AND TARGET_OS STREQUAL "mac")
show_dependency_status("Dmg tools" DMGTOOLS)
endif()
if(VIDEORECORDER)
show_dependency_status("FFmpeg" FFMPEG)
endif()
show_dependency_status("Freetype" FREETYPE)
if(DOWNLOAD_GTEST)
show_dependency_status("Git" GIT)
endif()
show_dependency_status("Glew" GLEW)
show_dependency_status("GTest" GTEST)
if(TARGET_OS AND TARGET_OS STREQUAL "mac")
show_dependency_status("Hdiutil" HDIUTIL)
endif()
if(UPNP)
show_dependency_status("Miniupnpc" MINIUPNPC)
endif()
if(MYSQL)
show_dependency_status("MySQL" MYSQL)
endif()
show_dependency_status("Ogg" OGG)
show_dependency_status("OpenSSL Crypto" CRYPTO)
show_dependency_status("Opus" OPUS)
show_dependency_status("Opusfile" OPUSFILE)
show_dependency_status("Pnglite" PNGLITE)
show_dependency_status("PythonInterp" PYTHONINTERP)
show_dependency_status("SDL2" SDL2)
show_dependency_status("SQLite3" SQLite3)
show_dependency_status("Wavpack" WAVPACK)
show_dependency_status("Zlib" ZLIB)
if(DISCORD)
show_dependency_status("DiscordSdk" DiscordSdk)
endif()
if(WEBSOCKETS)
show_dependency_status("Websockets" WEBSOCKETS)
endif()
if(CLIENT AND NOT(CURL_FOUND))
message(SEND_ERROR "You must install Curl to compile DDNet")
endif()
if(NOT(PYTHONINTERP_FOUND))
message(SEND_ERROR "You must install Python to compile DDNet")
endif()
if(NOT(SQLite3_FOUND))
message(SEND_ERROR "You must install SQLite3 to compile DDNet")
endif()
if(MYSQL AND NOT(MYSQL_FOUND))
message(SEND_ERROR "You must install MySQL to compile the DDNet server with MySQL support")
endif()
if(WEBSOCKETS AND NOT(WEBSOCKETS_FOUND))
message(SEND_ERROR "You must install libwebsockets to compile the DDNet server with websocket support")
endif()
if(UPNP AND NOT(MINIUPNPC_FOUND))
message(SEND_ERROR "You must install miniupnpc to compile the DDNet server with UPnP support")
endif()
if(DISCORD AND NOT(DISCORDSDK_FOUND))
message(SEND_ERROR "You must install the Discord SDK to compile the DDNet client with Discord support")
endif()
if(CLIENT AND NOT(FREETYPE_FOUND))
message(SEND_ERROR "You must install Freetype to compile the DDNet client")
endif()
if(CLIENT AND NOT(OGG_FOUND))
message(SEND_ERROR "You must install Ogg to compile the DDNet client")
endif()
if(CLIENT AND NOT(OPUS_FOUND))
message(SEND_ERROR "You must install Opus to compile the DDNet client")
endif()
if(CLIENT AND NOT(OPUSFILE_FOUND))
message(SEND_ERROR "You must install Opusfile to compile the DDNet client")
endif()
if(CLIENT AND NOT(SDL2_FOUND))
message(SEND_ERROR "You must install SDL2 to compile the DDNet client")
endif()
if(NOT(GTEST_FOUND))
if(DOWNLOAD_GTEST)
if(GIT_FOUND)
message(STATUS "Automatically downloading GTest to be able to run tests")
else()
set(DOWNLOAD_GTEST OFF)
message(WARNING "To automatically download GTest, you have to install Git")
endif()
else()
message(STATUS "To run the tests, you have to install GTest")
endif()
endif()
if(TARGET_OS STREQUAL "windows")
set(PLATFORM_CLIENT)
set(PLATFORM_CLIENT_LIBS opengl32 winmm)
set(PLATFORM_LIBS ws2_32) # Windows sockets
elseif(TARGET_OS STREQUAL "mac")
find_library(CARBON Carbon)
find_library(COCOA Cocoa)
find_library(OPENGL OpenGL)
find_library(SECURITY Security)
set(PLATFORM_CLIENT
src/osx/notifications.mm
src/osxlaunch/client.m
)
set(PLATFORM_CLIENT_LIBS ${COCOA} ${OPENGL})
set(PLATFORM_LIBS ${CARBON} ${SECURITY})
else()
find_package(Notify)
find_package(OpenGL)
find_package(X11)
set(PLATFORM_CLIENT_LIBS ${OPENGL_gl_LIBRARY} ${X11_X11_LIB} ${NOTIFY_LIBRARIES})
set(PLATFORM_CLIENT_INCLUDE_DIRS ${OPENGL_INCLUDE_DIR} ${X11_X11_INCLUDE_PATH} ${NOTIFY_INCLUDE_DIRS})
set(PLATFORM_CLIENT)
if(TARGET_OS STREQUAL "linux")
set(PLATFORM_LIBS rt) # clock_gettime for glibc < 2.17
else()
set(PLATFORM_LIBS)
endif()
endif()
########################################################################
# DOWNLOAD GTEST
########################################################################
if(NOT(GTEST_FOUND) AND DOWNLOAD_GTEST)
set(DDNET_GTEST_VERSION release-1.10.0) # 703bd9caab50b139428cea1aaff9974ebee5742e
configure_file(cmake/Download_GTest_CMakeLists.txt.in googletest-download/CMakeLists.txt)
execute_process(COMMAND ${CMAKE_COMMAND} -G "${CMAKE_GENERATOR}" .
RESULT_VARIABLE result
WORKING_DIRECTORY ${PROJECT_BINARY_DIR}/googletest-download
)
if(result)
message(WARNING "CMake step for googletest failed: ${result}")
set(DOWNLOAD_GTEST OFF)
else()
execute_process(COMMAND ${CMAKE_COMMAND} --build .
RESULT_VARIABLE result
WORKING_DIRECTORY ${PROJECT_BINARY_DIR}/googletest-download
)
if(result)
message(WARNING "Build step for googletest failed: ${result}")
set(DOWNLOAD_GTEST OFF)
else()
file(GLOB_RECURSE DDNET_GTEST_CMAKELISTS ${CMAKE_BINARY_DIR}/googletest-src/CMakeLists.txt)
foreach(file ${DDNET_GTEST_CMAKELISTS})
file(READ ${file} CONTENTS)
string(REPLACE "cmake_minimum_required(VERSION 2.6.4)" "cmake_minimum_required(VERSION 2.8.12...3.19.1)" CONTENTS "${CONTENTS}")
string(REPLACE "cmake_minimum_required(VERSION 2.6.4)" "cmake_minimum_required(VERSION 2.8.12...3.19.1)" CONTENTS "${CONTENTS}")
string(REPLACE "cmake_minimum_required(VERSION 2.8.8)" "cmake_minimum_required(VERSION 2.8.12...3.19.1)" CONTENTS "${CONTENTS}")
file(WRITE ${file} "${CONTENTS}")
endforeach()
# Prevent overriding the parent project's compiler/linker settings on Windows
set(gtest_force_shared_crt ON CACHE BOOL "" FORCE)
# Add googletest directly to our build. This defines the gtest target.
add_subdirectory(
${PROJECT_BINARY_DIR}/googletest-src
${PROJECT_BINARY_DIR}/googletest-build
EXCLUDE_FROM_ALL
)
if(MSVC)
foreach(target gtest)
# `/w` disables all warnings. This is needed because `gtest` enables
# `/WX` (equivalent of `-Werror`) for some reason, breaking builds
# when MSVS adds new warnings.
target_compile_options(${target} PRIVATE $<$<NOT:${DBG}>:/MT> $<${DBG}:/MTd> /w)
endforeach()
endif()
set(GTEST_LIBRARIES gtest)
set(GTEST_INCLUDE_DIRS)
if(CMAKE_VERSION VERSION_LESS 2.8.11)
set(GTEST_INCLUDE_DIRS "${gtest_SOURCE_DIR}/include")
endif()
endif()
endif()
endif()
########################################################################
# DEPENDENCY COMPILATION
########################################################################
set_src(DEP_JSON_SRC GLOB src/engine/external/json-parser json.c json.h)
add_library(json EXCLUDE_FROM_ALL OBJECT ${DEP_JSON_SRC})
set_src(DEP_MD5_SRC GLOB src/engine/external/md5 md5.c md5.h)
add_library(md5 EXCLUDE_FROM_ALL OBJECT ${DEP_MD5_SRC})
list(APPEND TARGETS_DEP json md5)
set(DEP_JSON $<TARGET_OBJECTS:json>)
set(DEP_MD5)
if(NOT CRYPTO_FOUND)
set(DEP_MD5 $<TARGET_OBJECTS:md5>)
endif()
########################################################################
# DATA
########################################################################
set(EXPECTED_DATA
arrow.png
assets/entities/comfort/ddnet.png
assets/entities/license.txt
assets/game/game_06.png
audio/foley_body_impact-01.wv
audio/foley_body_impact-02.wv
audio/foley_body_impact-03.wv
audio/foley_body_splat-01.wv
audio/foley_body_splat-02.wv
audio/foley_body_splat-03.wv
audio/foley_body_splat-04.wv
audio/foley_dbljump-01.wv
audio/foley_dbljump-02.wv
audio/foley_dbljump-03.wv
audio/foley_foot_left-01.wv
audio/foley_foot_left-02.wv
audio/foley_foot_left-03.wv
audio/foley_foot_left-04.wv
audio/foley_foot_right-01.wv
audio/foley_foot_right-02.wv
audio/foley_foot_right-03.wv
audio/foley_foot_right-04.wv
audio/foley_land-01.wv
audio/foley_land-02.wv
audio/foley_land-03.wv
audio/foley_land-04.wv
audio/hook_attach-01.wv
audio/hook_attach-02.wv
audio/hook_attach-03.wv
audio/hook_loop-01.wv
audio/hook_loop-02.wv
audio/hook_noattach-01.wv
audio/hook_noattach-02.wv
audio/hook_noattach-03.wv
audio/music_menu.wv
audio/sfx_ctf_cap_pl.wv
audio/sfx_ctf_drop.wv
audio/sfx_ctf_grab_en.wv
audio/sfx_ctf_grab_pl.wv
audio/sfx_ctf_rtn.wv
audio/sfx_hit_strong-01.wv
audio/sfx_hit_strong-02.wv
audio/sfx_hit_weak-01.wv
audio/sfx_hit_weak-02.wv
audio/sfx_hit_weak-03.wv
audio/sfx_msg-client.wv
audio/sfx_msg-highlight.wv
audio/sfx_msg-server.wv
audio/sfx_pickup_arm-01.wv
audio/sfx_pickup_arm-02.wv
audio/sfx_pickup_arm-03.wv
audio/sfx_pickup_arm-04.wv
audio/sfx_pickup_gun.wv
audio/sfx_pickup_hrt-01.wv
audio/sfx_pickup_hrt-02.wv
audio/sfx_pickup_launcher.wv
audio/sfx_pickup_ninja.wv
audio/sfx_pickup_sg.wv
audio/sfx_skid-01.wv
audio/sfx_skid-02.wv
audio/sfx_skid-03.wv
audio/sfx_skid-04.wv
audio/sfx_spawn_wpn-01.wv
audio/sfx_spawn_wpn-02.wv
audio/sfx_spawn_wpn-03.wv
audio/vo_teefault_cry-01.wv
audio/vo_teefault_cry-02.wv
audio/vo_teefault_ninja-01.wv
audio/vo_teefault_ninja-02.wv
audio/vo_teefault_ninja-03.wv
audio/vo_teefault_ninja-04.wv
audio/vo_teefault_pain_long-01.wv
audio/vo_teefault_pain_long-02.wv
audio/vo_teefault_pain_short-01.wv
audio/vo_teefault_pain_short-02.wv
audio/vo_teefault_pain_short-03.wv
audio/vo_teefault_pain_short-04.wv
audio/vo_teefault_pain_short-05.wv
audio/vo_teefault_pain_short-06.wv
audio/vo_teefault_pain_short-07.wv
audio/vo_teefault_pain_short-08.wv
audio/vo_teefault_pain_short-09.wv
audio/vo_teefault_pain_short-10.wv
audio/vo_teefault_pain_short-11.wv
audio/vo_teefault_pain_short-12.wv
audio/vo_teefault_sledge-01.wv
audio/vo_teefault_sledge-02.wv
audio/vo_teefault_sledge-03.wv
audio/vo_teefault_spawn-01.wv
audio/vo_teefault_spawn-02.wv
audio/vo_teefault_spawn-03.wv
audio/vo_teefault_spawn-04.wv
audio/vo_teefault_spawn-05.wv
audio/vo_teefault_spawn-06.wv
audio/vo_teefault_spawn-07.wv
audio/wp_flump_explo-01.wv
audio/wp_flump_explo-02.wv
audio/wp_flump_explo-03.wv
audio/wp_flump_launch-01.wv
audio/wp_flump_launch-02.wv
audio/wp_flump_launch-03.wv
audio/wp_gun_fire-01.wv
audio/wp_gun_fire-02.wv
audio/wp_gun_fire-03.wv
audio/wp_hammer_hit-01.wv
audio/wp_hammer_hit-02.wv
audio/wp_hammer_hit-03.wv
audio/wp_hammer_swing-01.wv
audio/wp_hammer_swing-02.wv
audio/wp_hammer_swing-03.wv
audio/wp_laser_bnce-01.wv
audio/wp_laser_bnce-02.wv
audio/wp_laser_bnce-03.wv
audio/wp_laser_fire-01.wv
audio/wp_laser_fire-02.wv
audio/wp_laser_fire-03.wv
audio/wp_ninja_attack-01.wv
audio/wp_ninja_attack-02.wv
audio/wp_ninja_attack-03.wv
audio/wp_ninja_attack-04.wv
audio/wp_ninja_hit-01.wv
audio/wp_ninja_hit-02.wv
audio/wp_ninja_hit-03.wv
audio/wp_ninja_hit-04.wv
audio/wp_noammo-01.wv
audio/wp_noammo-02.wv
audio/wp_noammo-03.wv
audio/wp_noammo-04.wv
audio/wp_noammo-05.wv
audio/wp_shotty_fire-01.wv
audio/wp_shotty_fire-02.wv
audio/wp_shotty_fire-03.wv
audio/wp_switch-01.wv
audio/wp_switch-02.wv
audio/wp_switch-03.wv
blob.png
browse_icons.png
censorlist.txt
console.png
console_bar.png
countryflags/AD.png
countryflags/AE.png
countryflags/AF.png
countryflags/AG.png
countryflags/AI.png
countryflags/AL.png
countryflags/AM.png
countryflags/AO.png
countryflags/AR.png
countryflags/AS.png
countryflags/AT.png
countryflags/AU.png
countryflags/AW.png
countryflags/AX.png
countryflags/AZ.png
countryflags/BA.png
countryflags/BB.png
countryflags/BD.png
countryflags/BE.png
countryflags/BF.png
countryflags/BG.png
countryflags/BH.png
countryflags/BI.png
countryflags/BJ.png
countryflags/BL.png
countryflags/BM.png
countryflags/BN.png
countryflags/BO.png
countryflags/BR.png
countryflags/BS.png
countryflags/BT.png
countryflags/BW.png
countryflags/BY.png
countryflags/BZ.png
countryflags/CA.png
countryflags/CC.png
countryflags/CD.png
countryflags/CF.png
countryflags/CG.png
countryflags/CH.png
countryflags/CI.png
countryflags/CK.png
countryflags/CL.png
countryflags/CM.png
countryflags/CN.png
countryflags/CO.png
countryflags/CR.png
countryflags/CU.png
countryflags/CV.png
countryflags/CW.png
countryflags/CX.png
countryflags/CY.png
countryflags/CZ.png
countryflags/DE.png
countryflags/DJ.png
countryflags/DK.png
countryflags/DM.png
countryflags/DO.png
countryflags/DZ.png
countryflags/EC.png
countryflags/EE.png
countryflags/EG.png
countryflags/EH.png
countryflags/ER.png
countryflags/ES.png
countryflags/ET.png
countryflags/FI.png
countryflags/FJ.png
countryflags/FK.png
countryflags/FM.png
countryflags/FO.png
countryflags/FR.png
countryflags/GA.png
countryflags/GB.png
countryflags/GD.png
countryflags/GE.png
countryflags/GF.png
countryflags/GG.png
countryflags/GH.png
countryflags/GI.png
countryflags/GL.png
countryflags/GM.png
countryflags/GN.png
countryflags/GP.png
countryflags/GQ.png
countryflags/GR.png
countryflags/GS.png
countryflags/GT.png
countryflags/GU.png
countryflags/GW.png
countryflags/GY.png
countryflags/HK.png
countryflags/HN.png
countryflags/HR.png
countryflags/HT.png
countryflags/HU.png
countryflags/ID.png
countryflags/IE.png
countryflags/IL.png
countryflags/IM.png
countryflags/IN.png
countryflags/IO.png
countryflags/IQ.png
countryflags/IR.png
countryflags/IS.png
countryflags/IT.png
countryflags/JE.png
countryflags/JM.png
countryflags/JO.png
countryflags/JP.png
countryflags/KE.png
countryflags/KG.png
countryflags/KH.png
countryflags/KI.png
countryflags/KM.png
countryflags/KN.png
countryflags/KP.png
countryflags/KR.png
countryflags/KW.png
countryflags/KY.png
countryflags/KZ.png
countryflags/LA.png
countryflags/LB.png
countryflags/LC.png
countryflags/LI.png
countryflags/LK.png
countryflags/LR.png
countryflags/LS.png
countryflags/LT.png
countryflags/LU.png
countryflags/LV.png
countryflags/LY.png
countryflags/MA.png
countryflags/MC.png
countryflags/MD.png
countryflags/ME.png
countryflags/MF.png
countryflags/MG.png
countryflags/MH.png
countryflags/MK.png
countryflags/ML.png
countryflags/MM.png
countryflags/MN.png
countryflags/MO.png
countryflags/MP.png
countryflags/MQ.png
countryflags/MR.png
countryflags/MS.png
countryflags/MT.png
countryflags/MU.png
countryflags/MV.png
countryflags/MW.png
countryflags/MX.png
countryflags/MY.png
countryflags/MZ.png
countryflags/NA.png
countryflags/NC.png
countryflags/NE.png
countryflags/NF.png
countryflags/NG.png
countryflags/NI.png
countryflags/NL.png
countryflags/NO.png
countryflags/NP.png
countryflags/NR.png
countryflags/NU.png
countryflags/NZ.png
countryflags/OM.png
countryflags/PA.png
countryflags/PE.png
countryflags/PF.png
countryflags/PG.png
countryflags/PH.png
countryflags/PK.png
countryflags/PL.png
countryflags/PM.png
countryflags/PN.png
countryflags/PR.png
countryflags/PS.png
countryflags/PT.png
countryflags/PW.png
countryflags/PY.png
countryflags/QA.png
countryflags/RE.png
countryflags/RO.png
countryflags/RS.png
countryflags/RU.png
countryflags/RW.png
countryflags/SA.png
countryflags/SB.png
countryflags/SC.png
countryflags/SD.png
countryflags/SE.png
countryflags/SG.png
countryflags/SH.png
countryflags/SI.png
countryflags/SK.png
countryflags/SL.png
countryflags/SM.png
countryflags/SN.png
countryflags/SO.png
countryflags/SR.png
countryflags/SS.png
countryflags/ST.png
countryflags/SV.png
countryflags/SX.png
countryflags/SY.png
countryflags/SZ.png
countryflags/TC.png
countryflags/TD.png
countryflags/TF.png
countryflags/TG.png
countryflags/TH.png
countryflags/TJ.png
countryflags/TK.png
countryflags/TL.png
countryflags/TM.png
countryflags/TN.png
countryflags/TO.png
countryflags/TR.png
countryflags/TT.png
countryflags/TV.png
countryflags/TW.png
countryflags/TZ.png
countryflags/UA.png
countryflags/UG.png
countryflags/US.png
countryflags/UY.png
countryflags/UZ.png
countryflags/VA.png
countryflags/VC.png
countryflags/VE.png
countryflags/VG.png
countryflags/VI.png
countryflags/VN.png
countryflags/VU.png
countryflags/WF.png
countryflags/WS.png
countryflags/XCA.png
countryflags/XEN.png
countryflags/XEU.png
countryflags/XNI.png
countryflags/XSC.png
countryflags/XWA.png
countryflags/YE.png
countryflags/ZA.png
countryflags/ZM.png
countryflags/ZW.png
countryflags/default.png
countryflags/index.txt
debug_font.png
demo_buttons.png
demo_buttons2.png
editor/audio_source.png
editor/background.png
editor/basic_freeze.rules
editor/checker.png
editor/cursor.png
editor/ddmax_freeze.rules
editor/ddnet_tiles.rules
editor/ddnet_walls.rules
editor/desert_main.rules
editor/entities/DDNet.png
editor/entities/FNG.png
editor/entities/Race.png
editor/entities/Vanilla.png
editor/entities/blockworlds.png
editor/entities_clear/blockworlds.png
editor/entities_clear/ddnet.png
editor/entities_clear/ddrace.png
editor/entities_clear/f-ddrace.png
editor/entities_clear/fng.png
editor/entities_clear/race.png
editor/entities_clear/vanilla.png
editor/fadeout.rules
editor/front.png
editor/generic_clear.rules
editor/generic_unhookable.rules
editor/generic_unhookable_0.7.rules
editor/grass_main.rules
editor/grass_main_0.7.rules
editor/jungle_main.rules
editor/jungle_midground.rules
editor/round_tiles.rules
editor/speed_arrow.png
editor/speedup.png
editor/switch.png
editor/tele.png
editor/tune.png
editor/water.rules
editor/winter_main.rules
emoticons.png
file_icons.png
fonts/DejaVuSans.ttf
fonts/Icons.ttf
fonts/SourceHanSansSC-Regular.otf
game.png
gui_buttons.png
gui_cursor.png
gui_icons.png
gui_logo.png
languages/arabic.txt
languages/belarusian.txt
languages/bosnian.txt
languages/brazilian_portuguese.txt
languages/bulgarian.txt
languages/catalan.txt
languages/chuvash.txt
languages/czech.txt
languages/danish.txt
languages/dutch.txt
languages/finnish.txt
languages/french.txt
languages/german.txt
languages/greek.txt
languages/hungarian.txt
languages/index.txt
languages/italian.txt
languages/japanese.txt
languages/korean.txt
languages/kyrgyz.txt
languages/license.txt
languages/norwegian.txt
languages/persian.txt
languages/polish.txt
languages/portuguese.txt
languages/romanian.txt
languages/russian.txt
languages/serbian.txt
languages/serbian_cyrillic.txt
languages/simplified_chinese.txt
languages/slovak.txt
languages/spanish.txt
languages/swedish.txt
languages/traditional_chinese.txt
languages/turkish.txt
languages/ukrainian.txt
mapres/basic_freeze.png
mapres/bg_cloud1.png
mapres/bg_cloud2.png
mapres/bg_cloud3.png
mapres/ddmax_freeze.png
mapres/ddnet_start.png
mapres/ddnet_tiles.png
mapres/ddnet_walls.png
mapres/desert_background.png
mapres/desert_doodads.png
mapres/desert_main.png
mapres/desert_mountains.png
mapres/desert_mountains2.png
mapres/desert_mountains_new_background.png
mapres/desert_mountains_new_foreground.png
mapres/desert_sun.png
mapres/entities.png
mapres/fadeout.png
mapres/font_teeworlds.png
mapres/font_teeworlds_alt.png
mapres/generic_clear.png
mapres/generic_deathtiles.png
mapres/generic_lamps.png
mapres/generic_unhookable.png
mapres/generic_unhookable_0.7.png
mapres/grass_doodads.png
mapres/grass_doodads_0.7.png
mapres/grass_main.png
mapres/grass_main_0.7.png
mapres/jungle_background.png
mapres/jungle_deathtiles.png
mapres/jungle_doodads.png
mapres/jungle_main.png
mapres/jungle_midground.png
mapres/jungle_unhookables.png
mapres/light.png
mapres/mixed_tiles.png
mapres/moon.png
mapres/mountains.png
mapres/round_tiles.png
mapres/snow.png
mapres/snow_mountain.png
mapres/stars.png
mapres/sun.png
mapres/water.png
mapres/winter_doodads.png
mapres/winter_main.png
mapres/winter_mountains.png
mapres/winter_mountains2.png
mapres/winter_mountains3.png
maps/Gold\ Mine.map
maps/LearnToPlay.map
maps/Sunny\ Side\ Up.map
maps/Tsunami.map
maps/ctf1.map
maps/ctf2.map
maps/ctf3.map
maps/ctf4.map
maps/ctf5.map
maps/ctf6.map
maps/ctf7.map
maps/dm1.map
maps/dm2.map
maps/dm6.map
maps/dm7.map
maps/dm8.map
maps/dm9.map
maps/license.txt
maps7/Gold\ Mine.map
maps7/LearnToPlay.map
maps7/Sunny\ Side\ Up.map
maps7/Tsunami.map
maps7/readme.txt
menuimages/demos.png
menuimages/editor.png
menuimages/local_server.png
menuimages/play_game.png
menuimages/settings.png
particles.png
shader/pipeline.frag
shader/pipeline.vert
shader/prim.frag
shader/prim.vert
shader/primex.frag
shader/primex.vert
shader/quad.frag
shader/quad.vert
shader/spritemulti.frag
shader/spritemulti.vert
shader/text.frag
shader/text.vert
shader/tile.frag
shader/tile.vert
skins/Aoe4leg.png
skins/PaladiN.png
skins/antiantey.png
skins/beast.png
skins/blacktee.png
skins/bluekitty.png
skins/bluestripe.png
skins/bomb.png
skins/brownbear.png
skins/cammo.png
skins/cammostripes.png
skins/chinese_by_whis.png
skins/coala.png
skins/coala_bluekitty.png
skins/coala_bluestripe.png
skins/coala_cammo.png
skins/coala_cammostripes.png
skins/coala_default.png
skins/coala_limekitty.png
skins/coala_pinky.png
skins/coala_redbopp.png
skins/coala_redstripe.png
skins/coala_saddo.png
skins/coala_toptri.png
skins/coala_twinbop.png
skins/coala_twintri.png
skins/coala_warpaint.png
skins/coala_x_ninja.png
skins/default.png
skins/demonlimekitty.png
skins/dino.png
skins/dragon.png
skins/evil.png
skins/evilwolfe.png
skins/ghost.png
skins/ghostjtj.png
skins/giraffe.png
skins/greensward.png
skins/greyfox.png
skins/greyfox_2.png
skins/hammie-chew.png
skins/hammie-whis.png
skins/jeet.png
skins/kintaro_2.png
skins/kitty_bluestripe.png
skins/kitty_brownbear.png
skins/kitty_cammo.png
skins/kitty_cammostripes.png
skins/kitty_coala.png
skins/kitty_default.png
skins/kitty_pinky.png
skins/kitty_redbopp.png
skins/kitty_redstripe.png
skins/kitty_saddo.png
skins/kitty_toptri.png
skins/kitty_twinbop.png
skins/kitty_twintri.png
skins/kitty_warpaint.png
skins/kitty_x_ninja.png
skins/license.txt
skins/limekitty.png
skins/mermydon-coala.png
skins/mermydon.png
skins/mouse.png
skins/musmann.png
skins/nanami.png
skins/nanas.png
skins/nersif.png
skins/oldman.png
skins/oldschool.png
skins/penguin.png
skins/pinky.png
skins/random.png
skins/redbopp.png
skins/redstripe.png
skins/saddo.png
skins/santa_bluekitty.png
skins/santa_bluestripe.png
skins/santa_brownbear.png
skins/santa_cammo.png
skins/santa_cammostripes.png
skins/santa_coala.png
skins/santa_default.png
skins/santa_limekitty.png
skins/santa_pinky.png
skins/santa_redbopp.png
skins/santa_redstripe.png
skins/santa_saddo.png
skins/santa_toptri.png
skins/santa_twinbop.png
skins/santa_twintri.png
skins/santa_warpaint.png
skins/teerasta.png
skins/toptri.png
skins/twinbop.png
skins/twintri.png
skins/veteran.png
skins/voodoo_tee.png
skins/warpaint.png
skins/wartee.png
skins/whis.png
skins/x_ninja.png
skins/x_spec.png
themes/auto.png
themes/autumn.png
themes/autumn_day.map
themes/autumn_night.map
themes/heavens.png
themes/heavens_day.map
themes/heavens_night.map
themes/jungle.png
themes/jungle_day.map
themes/jungle_night.map
themes/newyear.map
themes/newyear.png
themes/none.png
themes/rand.png
themes/winter.png
themes/winter_day.map
themes/winter_night.map
wordlist.txt
)
set_glob(DATA GLOB_RECURSE "frag;json;map;otf;png;rules;ttf;txt;vert;wv" data ${EXPECTED_DATA})
########################################################################
# COPY DATA AND DLLS
########################################################################
foreach(datafile ${DATA})
file(RELATIVE_PATH OUT ${PROJECT_SOURCE_DIR}/data ${datafile})
get_filename_component(DESTINATION data/${OUT} PATH)
file(MAKE_DIRECTORY ${DESTINATION})
file(COPY ${datafile} DESTINATION ${DESTINATION})
endforeach()
set(COPY_FILES
${CURL_COPY_FILES}
${FREETYPE_COPY_FILES}
${OPUSFILE_COPY_FILES}
${SDL2_COPY_FILES}
${SQLite3_COPY_FILES}
${FFMPEG_COPY_FILES}
${WEBSOCKETS_COPY_FILES}
${DISCORDSDK_COPY_FILES}
)
file(COPY ${COPY_FILES} DESTINATION .)
########################################################################
# CODE GENERATION
########################################################################
function(generate_source output_file script_parameter)
add_custom_command(OUTPUT ${output_file}
COMMAND ${PYTHON_EXECUTABLE} datasrc/compile.py ${script_parameter}
> "${PROJECT_BINARY_DIR}/${output_file}"
DEPENDS
datasrc/compile.py
datasrc/content.py
datasrc/datatypes.py
datasrc/network.py
WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}
)
endfunction()
function(generate_source7 output_file script_parameter)
add_custom_command(OUTPUT ${output_file}
COMMAND ${PYTHON_EXECUTABLE} -m datasrc.seven.compile ${script_parameter}
> "${PROJECT_BINARY_DIR}/${output_file}"
DEPENDS
datasrc/seven/compile.py
datasrc/seven/content.py
datasrc/seven/datatypes.py
datasrc/seven/network.py
WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}
)
endfunction()
function(generate_maps output_file)
add_custom_command(OUTPUT ${output_file}
COMMAND ${PYTHON_EXECUTABLE} datasrc/crosscompile.py
> "${PROJECT_BINARY_DIR}/${output_file}"
DEPENDS
datasrc/compile.py
datasrc/content.py
datasrc/datatypes.py
datasrc/network.py
datasrc/seven/compile.py
datasrc/seven/content.py
datasrc/seven/datatypes.py
datasrc/seven/network.py
WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}
)
endfunction()
file(MAKE_DIRECTORY "${PROJECT_BINARY_DIR}/src/game/generated/")
execute_process(COMMAND git rev-parse --git-dir
ERROR_QUIET
WORKING_DIRECTORY "${PROJECT_SOURCE_DIR}"
OUTPUT_VARIABLE PROJECT_GIT_DIR
OUTPUT_STRIP_TRAILING_WHITESPACE
RESULT_VARIABLE PROJECT_GIT_DIR_ERROR
)
if(NOT PROJECT_GIT_DIR_ERROR)
set(GIT_REVISION_EXTRA_DEPS
${PROJECT_GIT_DIR}/index
${PROJECT_GIT_DIR}/logs/HEAD
)
endif()
add_custom_command(OUTPUT ${PROJECT_BINARY_DIR}/src/game/generated/git_revision.cpp
COMMAND ${PYTHON_EXECUTABLE}
scripts/git_revision.py
> ${PROJECT_BINARY_DIR}/src/game/generated/git_revision.cpp
WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}
DEPENDS
${GIT_REVISION_EXTRA_DEPS}
scripts/git_revision.py
)
generate_source("src/game/generated/client_data.cpp" "client_content_source")
generate_source("src/game/generated/client_data.h" "client_content_header")
generate_source("src/game/generated/protocol.cpp" "network_source")
generate_source("src/game/generated/protocol.h" "network_header")
generate_source("src/game/generated/server_data.cpp" "server_content_source")
generate_source("src/game/generated/server_data.h" "server_content_header")
generate_source7("src/game/generated/protocol7.cpp" "network_source")
generate_source7("src/game/generated/protocol7.h" "network_header")
generate_source7("src/game/generated/client_data7.cpp" "client_content_source")
generate_source7("src/game/generated/client_data7.h" "client_content_header")
generate_maps("src/game/generated/protocolglue.h")
add_custom_command(OUTPUT "src/game/generated/wordlist.h"
COMMAND ${PYTHON_EXECUTABLE} scripts/wordlist.py > ${PROJECT_BINARY_DIR}/src/game/generated/wordlist.h
WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}
DEPENDS
scripts/wordlist.py
)
########################################################################
# SHARED
########################################################################
# Sources
set_src(BASE GLOB_RECURSE src/base
color.h
detect.h
dynamic.h
hash.c
hash.h
hash_bundled.c
hash_ctxt.h
hash_libtomcrypt.c
hash_openssl.c
math.h
system.c
system.h
tl/algorithm.h
tl/allocator.h
tl/array.h
tl/base.h
tl/range.h
tl/sorted_array.h
tl/string.h
tl/threading.h
unicode/confusables.c
unicode/confusables_data.h
unicode/tolower.c
unicode/tolower_data.h
vmath.h
)
set_src(ENGINE_INTERFACE GLOB src/engine
antibot.h
client.h
config.h
console.h
demo.h
discord.h
editor.h
engine.h
friends.h
ghost.h
graphics.h
input.h
kernel.h
keys.h
map.h
masterserver.h
message.h
server.h
serverbrowser.h
sound.h
steam.h
storage.h
textrender.h
updater.h
uuid.h
warning.h
)
set_src(ENGINE_SHARED GLOB src/engine/shared
compression.cpp
compression.h
config.cpp
config.h
config_variables.h
console.cpp
console.h
csv.cpp
csv.h
datafile.cpp
datafile.h
demo.cpp
demo.h
econ.cpp
econ.h
engine.cpp
fifo.cpp
fifo.h
filecollection.cpp
filecollection.h
global_uuid_manager.cpp
huffman.cpp
huffman.h
image_manipulation.cpp
image_manipulation.h
jobs.cpp
jobs.h
json.cpp
json.h
kernel.cpp
linereader.cpp
linereader.h
map.cpp
map.h
masterserver.cpp
memheap.cpp
memheap.h
message.h
netban.cpp
netban.h
network.cpp
network.h
network_client.cpp
network_conn.cpp
network_console.cpp
network_console_conn.cpp
network_server.cpp
packer.cpp
packer.h
protocol.h
protocol_ex.cpp
protocol_ex.h
protocol_ex_msgs.h
ringbuffer.cpp
ringbuffer.h
serverbrowser.cpp
snapshot.cpp
snapshot.h
storage.cpp
teehistorian_ex.cpp
teehistorian_ex.h
teehistorian_ex_chunks.h
uuid_manager.cpp
uuid_manager.h
video.cpp
video.h
websockets.cpp
websockets.h
)
set_src(GAME_SHARED GLOB src/game
bezier.cpp
bezier.h
collision.cpp
collision.h
ddracechat.h
ddracecommands.h
gamecore.cpp
gamecore.h
layers.cpp
layers.h
localization.cpp
localization.h
mapbugs.cpp
mapbugs.h
mapbugs_list.h
mapitems.cpp
mapitems.h
mapitems_ex.cpp
mapitems_ex.h
mapitems_ex_types.h
prng.cpp
prng.h
teamscore.cpp
teamscore.h
tuning.h
variables.h
version.h
voting.h
)
# A bit hacky, but these are needed to register all the UUIDs, even for stuff
# that doesn't link game.
set(ENGINE_UUID_SHARED
src/game/generated/protocolglue.h
src/game/generated/protocol7.cpp
src/game/generated/protocol7.h
src/game/generated/protocol.cpp
src/game/generated/protocol.h
src/game/mapitems_ex.cpp
src/game/mapitems_ex.h
src/game/mapitems_ex_types.h
)
foreach(s ${GAME_SHARED})
if(s MATCHES "mapitems_(ex.cpp|ex.h|ex_types.h)$")
list(REMOVE_ITEM GAME_SHARED ${s})
endif()
endforeach()
list(REMOVE_ITEM GAME_SHARED ${ENGINE_UUID_SHARED})
set(GAME_GENERATED_SHARED
src/game/generated/git_revision.cpp
src/game/generated/protocol.h
src/game/generated/protocol7.h
src/game/generated/protocolglue.h
)
set(DEPS ${DEP_JSON} ${DEP_MD5} ${ZLIB_DEP})
# Libraries
set(LIBS
${CRYPTO_LIBRARIES}
${WEBSOCKETS_LIBRARIES}
${ZLIB_LIBRARIES}
${PLATFORM_LIBS}
# Add pthreads (on non-Windows) at the end, so that other libraries can depend
# on it.
${CMAKE_THREAD_LIBS_INIT}
)
# Targets
add_library(engine-shared EXCLUDE_FROM_ALL OBJECT ${ENGINE_INTERFACE} ${ENGINE_SHARED} ${ENGINE_UUID_SHARED} ${BASE})
add_library(game-shared EXCLUDE_FROM_ALL OBJECT ${GAME_SHARED} ${GAME_GENERATED_SHARED})
list(APPEND TARGETS_OWN engine-shared game-shared)
if(DISCORD)
add_library(discord-shared SHARED IMPORTED)
set_target_properties(discord-shared PROPERTIES
IMPORTED_LOCATION "${DISCORDSDK_LIBRARIES}"
IMPORTED_IMPLIB "${DISCORDSDK_LIBRARIES}"
INTERFACE_INCLUDE_DIRECTORIES "${DISCORDSDK_INCLUDE_DIRS}"
)
endif()
########################################################################
# CLIENT
########################################################################
if(CLIENT)
# Sources
set_src(STEAMAPI_SRC GLOB_RECURSE src/steam
steam_api_flat.h
steam_api_stub.cpp
)
if(STEAM OR TARGET_OS STREQUAL "windows" OR TARGET_OS STREQUAL "mac")
set(STEAMAPI_KIND SHARED)
else()
set(STEAMAPI_KIND STATIC)
endif()
set(TARGET_STEAMAPI steam_api)
add_library(${TARGET_STEAMAPI} ${STEAMAPI_KIND} ${STEAMAPI_SRC})
list(APPEND TARGETS_OWN ${TARGET_STEAMAPI})
set_src(ENGINE_CLIENT GLOB src/engine/client
backend_sdl.cpp
backend_sdl.h
blocklist_driver.cpp
blocklist_driver.h
client.cpp
client.h
demoedit.cpp
demoedit.h
discord.cpp
friends.cpp
friends.h
ghost.cpp
ghost.h
graphics_threaded.cpp
graphics_threaded.h
http.cpp
http.h
input.cpp
input.h
keynames.h
notifications.cpp
notifications.h
opengl_sl.cpp
opengl_sl.h
opengl_sl_program.cpp
opengl_sl_program.h
serverbrowser.cpp
serverbrowser.h
sound.cpp
sound.h
steam.cpp
text.cpp
updater.cpp
updater.h
video.cpp
video.h
)
set_src(GAME_CLIENT GLOB_RECURSE src/game/client
animstate.cpp
animstate.h
component.h
components/background.cpp
components/background.h
components/binds.cpp
components/binds.h
components/broadcast.cpp
components/broadcast.h
components/camera.cpp
components/camera.h
components/chat.cpp
components/chat.h
components/console.cpp
components/console.h
components/controls.cpp
components/controls.h
components/countryflags.cpp
components/countryflags.h
components/damageind.cpp
components/damageind.h
components/debughud.cpp
components/debughud.h
components/effects.cpp
components/effects.h
components/emoticon.cpp
components/emoticon.h
components/flow.cpp
components/flow.h
components/ghost.cpp
components/ghost.h
components/hud.cpp
components/hud.h
components/items.cpp
components/items.h
components/killmessages.cpp
components/killmessages.h
components/mapimages.cpp
components/mapimages.h
components/maplayers.cpp
components/maplayers.h
components/mapsounds.cpp
components/mapsounds.h
components/menu_background.cpp
components/menu_background.h
components/menus.cpp
components/menus.h
components/menus_browser.cpp
components/menus_demo.cpp
components/menus_ingame.cpp
components/menus_settings.cpp
components/menus_settings_assets.cpp
components/menus_start.cpp
components/motd.cpp
components/motd.h
components/nameplates.cpp
components/nameplates.h
components/particles.cpp
components/particles.h
components/players.cpp
components/players.h
components/race_demo.cpp
components/race_demo.h
components/scoreboard.cpp
components/scoreboard.h
components/skins.cpp
components/skins.h
components/sounds.cpp
components/sounds.h
components/spectator.cpp
components/spectator.h
components/statboard.cpp
components/statboard.h
components/voting.cpp
components/voting.h
gameclient.cpp
gameclient.h
lineinput.cpp
lineinput.h
prediction/entities/character.cpp
prediction/entities/character.h
prediction/entities/laser.cpp
prediction/entities/laser.h
prediction/entities/pickup.cpp
prediction/entities/pickup.h
prediction/entities/projectile.cpp
prediction/entities/projectile.h
prediction/entity.cpp
prediction/entity.h
prediction/gameworld.cpp
prediction/gameworld.h
projectile_data.cpp
projectile_data.h
race.cpp
race.h
render.cpp
render.h
render_map.cpp
skin.h
ui.cpp
ui.h
)
set_src(GAME_EDITOR GLOB src/game/editor
auto_map.cpp
auto_map.h
editor.cpp
editor.h
explanations.cpp
io.cpp
layer_game.cpp
layer_quads.cpp
layer_sounds.cpp
layer_tiles.cpp
popups.cpp
)
set(GAME_GENERATED_CLIENT
src/game/generated/client_data.cpp
src/game/generated/client_data.h
src/game/generated/client_data7.cpp
src/game/generated/client_data7.h
)
set(CLIENT_SRC ${ENGINE_CLIENT} ${PLATFORM_CLIENT} ${GAME_CLIENT} ${GAME_EDITOR} ${GAME_GENERATED_CLIENT})
set(DEPS_CLIENT ${DEPS} ${GLEW_DEP} ${PNGLITE_DEP} ${WAVPACK_DEP})
# Libraries
set(LIBS_CLIENT
${LIBS}
${CURL_LIBRARIES}
${FREETYPE_LIBRARIES}
${GLEW_LIBRARIES}
${PNGLITE_LIBRARIES}
${SDL2_LIBRARIES}
${WAVPACK_LIBRARIES}
${FFMPEG_LIBRARIES}
# Order of these three is important.
${OPUSFILE_LIBRARIES}
${OPUS_LIBRARIES}
${OGG_LIBRARIES}
${TARGET_STEAMAPI}
${PLATFORM_CLIENT_LIBS}
# Add pthreads (on non-Windows) at the end, so that other libraries can depend
# on it.
${CMAKE_THREAD_LIBS_INIT}
)
if(DISCORD)
list(APPEND LIBS_CLIENT discord-shared)
endif()
if(TARGET_OS STREQUAL "windows")
set(CLIENT_ICON "other/icons/DDNet.rc")
if(NOT MINGW)
set(CLIENT_MANIFEST "other/manifest/DDNet.manifest")
else()
set(CLIENT_MANIFEST "other/manifest/DDNet.rc")
set_target_properties(${TARGET_STEAMAPI} PROPERTIES PREFIX "")
endif()
else()
set(CLIENT_ICON)
set(CLIENT_MANIFEST)
endif()
# Target
set(TARGET_CLIENT ${CLIENT_EXECUTABLE})
add_executable(${TARGET_CLIENT}
${CLIENT_SRC}
${CLIENT_ICON}
${CLIENT_MANIFEST}
${DEPS_CLIENT}
$<TARGET_OBJECTS:engine-shared>
$<TARGET_OBJECTS:game-shared>
)
target_link_libraries(${TARGET_CLIENT} ${LIBS_CLIENT})
target_include_directories(${TARGET_CLIENT} PRIVATE
${CURL_INCLUDE_DIRS}
${FREETYPE_INCLUDE_DIRS}
${GLEW_INCLUDE_DIRS}
${OGG_INCLUDE_DIRS}
${OPUSFILE_INCLUDE_DIRS}
${OPUS_INCLUDE_DIRS}
${PNGLITE_INCLUDE_DIRS}
${SDL2_INCLUDE_DIRS}
${WAVPACK_INCLUDE_DIRS}
${FFMPEG_INCLUDE_DIRS}
${DISCORDSDK_INCLUDE_DIRS}
${PLATFORM_CLIENT_INCLUDE_DIRS}
)
if(STEAMAPI_KIND STREQUAL SHARED)
set_own_rpath(${TARGET_CLIENT})
endif()
set(PARAMS "${WAVPACK_INCLUDE_DIRS};${WAVPACK_INCLUDE_DIRS}")
if(NOT(WAVPACK_OPEN_FILE_INPUT_EX_PARAMS STREQUAL PARAMS))
unset(WAVPACK_OPEN_FILE_INPUT_EX CACHE)
endif()
set(WAVPACK_OPEN_FILE_INPUT_EX_PARAMS "${PARAMS}" CACHE INTERNAL "")
set(CMAKE_REQUIRED_INCLUDES ${ORIGINAL_CMAKE_REQUIRED_INCLUDES} ${WAVPACK_INCLUDE_DIRS})
set(CMAKE_REQUIRED_LIBRARIES ${ORIGINAL_CMAKE_REQUIRED_LIBRARIES} ${WAVPACK_LIBRARIES})
check_symbol_exists(WavpackOpenFileInputEx wavpack.h WAVPACK_OPEN_FILE_INPUT_EX)
check_symbol_exists(WavpackCloseFile wavpack.h WAVPACK_CLOSE_FILE)
set(CMAKE_REQUIRED_INCLUDES ${ORIGINAL_CMAKE_REQUIRED_INCLUDES})
set(CMAKE_REQUIRED_LIBRARIES ${ORIGINAL_CMAKE_REQUIRED_LIBRARIES})
if(WAVPACK_OPEN_FILE_INPUT_EX)
target_compile_definitions(${TARGET_CLIENT} PRIVATE CONF_WAVPACK_OPEN_FILE_INPUT_EX)
endif()
if(WAVPACK_CLOSE_FILE)
target_compile_definitions(${TARGET_CLIENT} PRIVATE CONF_WAVPACK_CLOSE_FILE)
endif()
list(APPEND TARGETS_OWN ${TARGET_CLIENT})
list(APPEND TARGETS_LINK ${TARGET_CLIENT})
endif()
########################################################################
# SERVER
########################################################################
# Sources
set_src(ANTIBOT_SRC GLOB src/antibot
antibot_data.h
antibot_interface.h
antibot_null.cpp
)
set_src(ENGINE_SERVER GLOB_RECURSE src/engine/server
antibot.cpp
antibot.h
authmanager.cpp
authmanager.h
databases/connection.cpp
databases/connection.h
databases/connection_pool.cpp
databases/connection_pool.h
databases/mysql.cpp
databases/mysql.h
databases/sqlite.cpp
databases/sqlite.h
name_ban.cpp
name_ban.h
register.cpp
register.h
server.cpp
server.h
sql_string_helpers.cpp
sql_string_helpers.h
upnp.cpp
upnp.h
)
set_src(GAME_SERVER GLOB_RECURSE src/game/server
alloc.h
ddracechat.cpp
ddracecommands.cpp
entities/character.cpp
entities/character.h
entities/door.cpp
entities/door.h
entities/dragger.cpp
entities/dragger.h
entities/flag.cpp
entities/flag.h
entities/gun.cpp
entities/gun.h
entities/laser.cpp
entities/laser.h
entities/light.cpp
entities/light.h
entities/pickup.cpp
entities/pickup.h
entities/plasma.cpp
entities/plasma.h
entities/projectile.cpp
entities/projectile.h
entity.cpp
entity.h
eventhandler.cpp
eventhandler.h
gamecontext.cpp
gamecontext.h
gamecontroller.cpp
gamecontroller.h
gamemodes/DDRace.cpp
gamemodes/DDRace.h
gamemodes/gamemode.h
gameworld.cpp
gameworld.h
player.cpp
player.h
save.cpp
save.h
score.cpp
score.h
teams.cpp
teams.h
teehistorian.cpp
teehistorian.h
teeinfo.cpp
teeinfo.h
)
set(GAME_GENERATED_SERVER
"src/game/generated/server_data.cpp"
"src/game/generated/server_data.h"
"src/game/generated/wordlist.h"
)
set(SERVER_SRC ${ENGINE_SERVER} ${GAME_SERVER} ${GAME_GENERATED_SERVER})
if(TARGET_OS STREQUAL "windows")
set(SERVER_ICON "other/icons/DDNet-Server.rc")
else()
set(SERVER_ICON)
endif()
# Antibot
if(ANTIBOT)
set(TARGET_ANTIBOT antibot)
add_library(${TARGET_ANTIBOT} SHARED ${ANTIBOT_SRC})
list(APPEND TARGETS_OWN ${TARGET_ANTIBOT})
endif()
# Libraries
set(LIBS_SERVER
${LIBS}
${MYSQL_LIBRARIES}
${SQLite3_LIBRARIES}
${TARGET_ANTIBOT}
${MINIUPNPC_LIBRARIES}
# Add pthreads (on non-Windows) at the end, so that other libraries can depend
# on it.
${CMAKE_THREAD_LIBS_INIT}
)
# Target
set(TARGET_SERVER ${SERVER_EXECUTABLE})
add_executable(${TARGET_SERVER}
${DEPS}
${SERVER_SRC}
${SERVER_ICON}
$<TARGET_OBJECTS:engine-shared>
$<TARGET_OBJECTS:game-shared>
)
target_link_libraries(${TARGET_SERVER} ${LIBS_SERVER})
list(APPEND TARGETS_OWN ${TARGET_SERVER})
list(APPEND TARGETS_LINK ${TARGET_SERVER})
if(TARGET_OS AND TARGET_OS STREQUAL "mac")
set(SERVER_LAUNCHER_SRC src/osxlaunch/server.mm)
set(TARGET_SERVER_LAUNCHER ${TARGET_SERVER}-Launcher)
add_executable(${TARGET_SERVER_LAUNCHER} ${SERVER_LAUNCHER_SRC})
target_link_libraries(${TARGET_SERVER_LAUNCHER} ${COCOA})
list(APPEND TARGETS_OWN ${TARGET_SERVER_LAUNCHER})
list(APPEND TARGETS_LINK ${TARGET_SERVER_LAUNCHER})
endif()
########################################################################
# VARIOUS TARGETS
########################################################################
set_src(MASTERSRV_SRC GLOB src/mastersrv mastersrv.cpp mastersrv.h)
set_src(TWPING_SRC GLOB src/twping twping.cpp)
set(TARGET_MASTERSRV mastersrv)
set(TARGET_TWPING twping)
add_executable(${TARGET_MASTERSRV} EXCLUDE_FROM_ALL ${MASTERSRV_SRC} $<TARGET_OBJECTS:engine-shared> ${DEPS})
add_executable(${TARGET_TWPING} EXCLUDE_FROM_ALL ${TWPING_SRC} $<TARGET_OBJECTS:engine-shared> ${DEPS})
target_link_libraries(${TARGET_MASTERSRV} ${LIBS})
target_link_libraries(${TARGET_TWPING} ${LIBS})
list(APPEND TARGETS_OWN ${TARGET_MASTERSRV} ${TARGET_TWPING})
list(APPEND TARGETS_LINK ${TARGET_MASTERSRV} ${TARGET_TWPING})
set(TARGETS_TOOLS)
set_src(TOOLS GLOB src/tools
config_common.h
config_retrieve.cpp
config_store.cpp
crapnet.cpp
dilate.cpp
dummy_map.cpp
fake_server.cpp
map_convert_07.cpp
map_diff.cpp
map_extract.cpp
map_optimize.cpp
map_replace_image.cpp
map_resave.cpp
packetgen.cpp
unicode_confusables.cpp
uuid.cpp
)
foreach(ABS_T ${TOOLS})
file(RELATIVE_PATH T "${PROJECT_SOURCE_DIR}/src/tools/" ${ABS_T})
if(T MATCHES "\\.cpp$")
string(REGEX REPLACE "\\.cpp$" "" TOOL "${T}")
set(TOOL_DEPS ${DEPS})
set(TOOL_LIBS ${LIBS})
if(TOOL MATCHES "^(dilate|map_convert_07|map_optimize|map_extract|map_replace_image)$")
list(APPEND TOOL_DEPS ${PNGLITE_DEP})
list(APPEND TOOL_LIBS ${PNGLITE_LIBRARIES})
list(APPEND TOOL_INCLUDE_DIRS ${PNGLITE_INCLUDE_DIRS})
endif()
if(TOOL MATCHES "^config_")
list(APPEND EXTRA_TOOL_SRC "src/tools/config_common.h")
endif()
set(EXCLUDE_FROM_ALL)
if(DEV)
set(EXCLUDE_FROM_ALL EXCLUDE_FROM_ALL)
endif()
add_executable(${TOOL} ${EXCLUDE_FROM_ALL}
${TOOL_DEPS}
src/tools/${TOOL}.cpp
${EXTRA_TOOL_SRC}
$<TARGET_OBJECTS:engine-shared>
)
target_include_directories(${TOOL} PRIVATE ${TOOL_INCLUDE_DIRS})
target_link_libraries(${TOOL} ${TOOL_LIBS})
list(APPEND TARGETS_TOOLS ${TOOL})
endif()
endforeach()
list(APPEND TARGETS_OWN ${TARGETS_TOOLS})
list(APPEND TARGETS_LINK ${TARGETS_TOOLS})
add_custom_target(tools DEPENDS ${TARGETS_TOOLS})
add_custom_target(everything DEPENDS ${TARGETS_OWN})
########################################################################
# TESTS
########################################################################
if(GTEST_FOUND OR DOWNLOAD_GTEST)
set_src(TESTS GLOB src/test
aio.cpp
bezier.cpp
blocklist_driver.cpp
color.cpp
csv.cpp
datafile.cpp
fs.cpp
git_revision.cpp
hash.cpp
jobs.cpp
json.cpp
mapbugs.cpp
name_ban.cpp
packer.cpp
prng.cpp
str.cpp
strip_path_and_extension.cpp
teehistorian.cpp
test.cpp
test.h
thread.cpp
unix.cpp
uuid.cpp
)
set(TESTS_EXTRA
src/engine/client/blocklist_driver.cpp
src/engine/client/blocklist_driver.h
src/engine/server/name_ban.cpp
src/engine/server/name_ban.h
src/game/server/teehistorian.cpp
src/game/server/teehistorian.h
)
set(TARGET_TESTRUNNER testrunner)
add_executable(${TARGET_TESTRUNNER} EXCLUDE_FROM_ALL
${TESTS}
${TESTS_EXTRA}
$<TARGET_OBJECTS:engine-shared>
$<TARGET_OBJECTS:game-shared>
${DEPS}
)
target_link_libraries(${TARGET_TESTRUNNER} ${LIBS} ${GTEST_LIBRARIES})
target_include_directories(${TARGET_TESTRUNNER} PRIVATE ${GTEST_INCLUDE_DIRS})
list(APPEND TARGETS_OWN ${TARGET_TESTRUNNER})
list(APPEND TARGETS_LINK ${TARGET_TESTRUNNER})
add_custom_target(run_tests
COMMAND $<TARGET_FILE:${TARGET_TESTRUNNER}> ${TESTRUNNER_ARGS}
COMMENT Running tests
DEPENDS ${TARGET_TESTRUNNER}
USES_TERMINAL
)
endif()
########################################################################
# INSTALLATION
########################################################################
function(escape_regex VAR STRING)
string(REGEX REPLACE "([][^$.+*?|()\\\\])" "\\\\\\1" ESCAPED "${STRING}")
set(${VAR} ${ESCAPED} PARENT_SCOPE)
endfunction()
function(escape_backslashes VAR STRING)
string(REGEX REPLACE "\\\\" "\\\\\\\\" ESCAPED "${STRING}")
set(${VAR} ${ESCAPED} PARENT_SCOPE)
endfunction()
function(max_length VAR)
set(MAX_LENGTH 0)
foreach(str ${ARGN})
string(LENGTH ${str} LENGTH)
if(LENGTH GREATER MAX_LENGTH)
set(MAX_LENGTH ${LENGTH})
endif()
endforeach()
set(${VAR} ${MAX_LENGTH} PARENT_SCOPE)
endfunction()
# Tries to generate a list of regex that matches everything except the given
# parameters.
function(regex_inverted VAR)
max_length(MAX_LENGTH ${ARGN})
math(EXPR UPPER_BOUND "${MAX_LENGTH}-1")
set(REMAINING ${ARGN})
set(RESULT)
foreach(i RANGE ${UPPER_BOUND})
set(TEMP ${REMAINING})
set(REMAINING)
foreach(str ${TEMP})
string(LENGTH ${str} LENGTH)
if(i LESS LENGTH)
list(APPEND REMAINING ${str})
endif()
endforeach()
set(ADDITIONAL)
foreach(outer ${REMAINING})
string(SUBSTRING ${outer} 0 ${i} OUTER_PREFIX)
set(CHARS "")
foreach(inner ${REMAINING})
string(SUBSTRING ${inner} 0 ${i} INNER_PREFIX)
if(OUTER_PREFIX STREQUAL INNER_PREFIX)
string(SUBSTRING ${inner} ${i} 1 INNER_NEXT)
set(CHARS "${CHARS}${INNER_NEXT}")
endif()
endforeach()
escape_regex(OUTER_PREFIX_ESCAPED "${OUTER_PREFIX}")
list(APPEND ADDITIONAL "${OUTER_PREFIX_ESCAPED}([^${CHARS}]|$)")
endforeach()
list(REMOVE_DUPLICATES ADDITIONAL)
list(APPEND RESULT ${ADDITIONAL})
endforeach()
set(${VAR} ${RESULT} PARENT_SCOPE)
endfunction()
set(CPACK_PACKAGE_NAME ${PROJECT_NAME})
set(CPACK_GENERATOR TGZ TXZ)
set(CPACK_ARCHIVE_COMPONENT_INSTALL ON)
set(CPACK_STRIP_FILES TRUE)
set(CPACK_COMPONENTS_ALL portable)
set(CPACK_SOURCE_GENERATOR ZIP TGZ TBZ2 TXZ)
set(CPACK_PACKAGE_VERSION_MAJOR ${PROJECT_VERSION_MAJOR})
set(CPACK_PACKAGE_VERSION_MINOR ${PROJECT_VERSION_MINOR})
set(CPACK_PACKAGE_VERSION_PATCH ${PROJECT_VERSION_PATCH})
set(CPACK_PACKAGE_VERSION ${VERSION})
set(CPACK_SYSTEM_NAME ${CMAKE_SYSTEM_NAME})
if(TARGET_OS AND TARGET_BITS)
if(TARGET_OS STREQUAL "windows")
set(CPACK_SYSTEM_NAME "win${TARGET_BITS}")
set(CPACK_GENERATOR ZIP)
elseif(TARGET_OS STREQUAL "linux")
# Let compiler tell its arch
# Both gcc and clang support -dumpmachine
execute_process(
COMMAND ${CMAKE_C_COMPILER} -dumpmachine
OUTPUT_VARIABLE ARCHITECTURE_TUPLE
OUTPUT_STRIP_TRAILING_WHITESPACE
)
if(NOT ARCHITECTURE_TUPLE)
# If you're really using a weird compiler, then assume Intel here.
message(WARNING "Your compiler doesn't support -dumpmachine, this is weird")
if(TARGET_BITS EQUAL 32)
set(ARCHITECTURE "x86")
elseif(TARGET_BITS EQUAL 64)
set(ARCHITECTURE "x86_64")
endif()
else()
string(REGEX MATCH "^[^-]*" ARCHITECTURE "${ARCHITECTURE_TUPLE}")
if(ARCHITECTURE MATCHES "i.86")
set(ARCHITECTURE "x86")
endif()
endif()
set(CPACK_SYSTEM_NAME "linux_${ARCHITECTURE}")
elseif(TARGET_OS STREQUAL "mac")
set(CPACK_SYSTEM_NAME "osx")
set(CPACK_GENERATOR DMG)
endif()
endif()
set(CPACK_PACKAGE_FILE_NAME ${CPACK_PACKAGE_NAME}-${CPACK_PACKAGE_VERSION}-${CPACK_SYSTEM_NAME})
set(CPACK_ARCHIVE_PORTABLE_FILE_NAME ${CPACK_PACKAGE_FILE_NAME})
set(CPACK_SOURCE_PACKAGE_FILE_NAME ${CPACK_PACKAGE_NAME}-${CPACK_PACKAGE_VERSION}-src)
set(CPACK_SOURCE_FILES
CMakeLists.txt
README.md
autoexec_server.cfg
cmake/
data/
datasrc/
ddnet-libs/
license.txt
other/
scripts/
src/
storage.cfg
)
set(CPACK_SOURCE_IGNORE_FILES
"\\\\.pyc$"
"/\\\\.git"
"/__pycache__/"
)
regex_inverted(CPACK_SOURCE_FILES_INVERTED ${CPACK_SOURCE_FILES})
escape_regex(PROJECT_SOURCE_DIR_ESCAPED ${PROJECT_SOURCE_DIR})
foreach(str ${CPACK_SOURCE_FILES_INVERTED})
escape_backslashes(STR_ESCAPED "${PROJECT_SOURCE_DIR_ESCAPED}/${str}")
list(APPEND CPACK_SOURCE_IGNORE_FILES "${STR_ESCAPED}")
endforeach()
set(CMAKE_INSTALL_DEFAULT_COMPONENT_NAME ${PROJECT_NAME})
set(CPACK_TARGETS
${TARGET_CLIENT}
${TARGET_SERVER}
config_retrieve
config_store
dilate
map_convert_07
map_diff
map_extract
)
if(STEAMAPI_KIND STREQUAL SHARED)
list(APPEND CPACK_TARGETS ${TARGET_STEAMAPI})
endif()
set(CPACK_DIRS data)
set(CPACK_FILES
license.txt
storage.cfg
autoexec_server.cfg
${COPY_FILES}
)
if(TARGET_OS STREQUAL "windows")
list(APPEND CPACK_FILES other/config_directory.bat)
endif()
if(NOT DEV)
include(GNUInstallDirs)
install(DIRECTORY data DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/ddnet COMPONENT data)
install(TARGETS ${TARGET_CLIENT} DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT client)
if(STEAMAPI_KIND STREQUAL SHARED)
install(TARGETS ${TARGET_STEAMAPI} DESTINATION ${CMAKE_INSTALL_LIBDIR}/ddnet COMPONENT client)
endif()
install(TARGETS ${TARGET_SERVER} DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT server)
if(ANTIBOT)
install(TARGETS ${TARGET_ANTIBOT} DESTINATION ${CMAKE_INSTALL_LIBDIR}/ddnet COMPONENT server)
endif()
install(TARGETS ${TARGETS_TOOLS} DESTINATION ${CMAKE_INSTALL_LIBDIR}/ddnet COMPONENT tools)
install(FILES other/ddnet.desktop DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/applications COMPONENT client)
install(FILES other/ddnet.appdata.xml DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/metainfo COMPONENT client)
foreach(SIZE 16 32 48 128 256 512)
install(FILES other/icons/DDNet_${SIZE}x${SIZE}x32.png DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/icons/hicolor/${SIZE}x${SIZE}/apps RENAME ddnet.png COMPONENT client)
endforeach()
endif()
if(DEV)
# Don't generate CPack targets.
elseif(CMAKE_VERSION VERSION_LESS 3.6 OR CMAKE_VERSION VERSION_EQUAL 3.6)
message(WARNING "Cannot create CPack targets, CMake version too old. Use CMake 3.6 or newer.")
else()
set(EXTRA_ARGS DESTINATION ${CPACK_PACKAGE_FILE_NAME} COMPONENT portable EXCLUDE_FROM_ALL)
install(TARGETS ${CPACK_TARGETS} ${EXTRA_ARGS})
install(DIRECTORY ${CPACK_DIRS} ${EXTRA_ARGS})
install(FILES ${CPACK_FILES} ${EXTRA_ARGS})
endif()
set(PACKAGE_TARGETS)
if(CLIENT AND (DMGTOOLS_FOUND OR HDIUTIL))
file(MAKE_DIRECTORY bundle/client/)
file(MAKE_DIRECTORY bundle/server/)
configure_file(other/bundle/client/Info.plist.in bundle/client/Info.plist)
configure_file(other/bundle/server/Info.plist.in bundle/server/Info.plist)
if(HDIUTIL)
set(DMG_PARAMS --hdiutil ${HDIUTIL})
elseif(DMGTOOLS_FOUND)
set(DMG_PARAMS --dmgtools ${DMG} ${HFSPLUS} ${NEWFS_HFS})
endif()
set(DMG_TMPDIR pack_${CPACK_PACKAGE_FILE_NAME}_dmg)
set(DMG_MKDIRS
${TARGET_CLIENT}.app
${TARGET_CLIENT}.app/Contents
${TARGET_CLIENT}.app/Contents/Frameworks
${TARGET_CLIENT}.app/Contents/MacOS
${TARGET_CLIENT}.app/Contents/Resources
${TARGET_SERVER}.app
${TARGET_SERVER}.app/Contents
${TARGET_SERVER}.app/Contents/MacOS
${TARGET_SERVER}.app/Contents/Resources
${TARGET_SERVER}.app/Contents/Resources/data
${TARGET_SERVER}.app/Contents/Resources/data/mapres
)
set(DMG_MKDIR_COMMANDS)
foreach(dir ${DMG_MKDIRS})
list(APPEND DMG_MKDIR_COMMANDS COMMAND ${CMAKE_COMMAND} -E make_directory ${DMG_TMPDIR}/${dir})
endforeach()
add_custom_command(OUTPUT ${CPACK_PACKAGE_FILE_NAME}.dmg
COMMAND ${CMAKE_COMMAND} -E remove_directory ${DMG_TMPDIR}
${DMG_MKDIR_COMMANDS}
# CLIENT
COMMAND ${CMAKE_COMMAND} -E copy_directory ${PROJECT_SOURCE_DIR}/data ${DMG_TMPDIR}/${TARGET_CLIENT}.app/Contents/Resources/data
COMMAND ${CMAKE_COMMAND} -E copy ${PROJECT_SOURCE_DIR}/other/icons/${TARGET_CLIENT}.icns ${DMG_TMPDIR}/${TARGET_CLIENT}.app/Contents/Resources/
COMMAND ${CMAKE_COMMAND} -E copy bundle/client/Info.plist ${PROJECT_SOURCE_DIR}/other/bundle/client/PkgInfo ${DMG_TMPDIR}/${TARGET_CLIENT}.app/Contents/
COMMAND ${CMAKE_COMMAND} -E copy $<TARGET_FILE:${TARGET_CLIENT}> ${DMG_TMPDIR}/${TARGET_CLIENT}.app/Contents/MacOS/
COMMAND ${CMAKE_COMMAND} -E copy_directory ${PROJECT_SOURCE_DIR}/ddnet-libs/sdl/mac/lib64/SDL2.framework ${DMG_TMPDIR}/${TARGET_CLIENT}.app/Contents/Frameworks/SDL2.framework
COMMAND ${CMAKE_COMMAND} -E copy ${PROJECT_SOURCE_DIR}/ddnet-libs/freetype/mac/lib64/libfreetype.6.dylib ${DMG_TMPDIR}/${TARGET_CLIENT}.app/Contents/Frameworks/
COMMAND ${CMAKE_COMMAND} -E copy ${PROJECT_SOURCE_DIR}/ddnet-libs/ffmpeg/mac/lib64/libavcodec.58.dylib ${DMG_TMPDIR}/${TARGET_CLIENT}.app/Contents/Frameworks/
COMMAND ${CMAKE_COMMAND} -E copy ${PROJECT_SOURCE_DIR}/ddnet-libs/ffmpeg/mac/lib64/libavformat.58.dylib ${DMG_TMPDIR}/${TARGET_CLIENT}.app/Contents/Frameworks/
COMMAND ${CMAKE_COMMAND} -E copy ${PROJECT_SOURCE_DIR}/ddnet-libs/ffmpeg/mac/lib64/libavutil.56.dylib ${DMG_TMPDIR}/${TARGET_CLIENT}.app/Contents/Frameworks/
COMMAND ${CMAKE_COMMAND} -E copy ${PROJECT_SOURCE_DIR}/ddnet-libs/ffmpeg/mac/lib64/libswresample.3.dylib ${DMG_TMPDIR}/${TARGET_CLIENT}.app/Contents/Frameworks/
COMMAND ${CMAKE_COMMAND} -E copy ${PROJECT_SOURCE_DIR}/ddnet-libs/ffmpeg/mac/lib64/libswscale.5.dylib ${DMG_TMPDIR}/${TARGET_CLIENT}.app/Contents/Frameworks/
COMMAND ${CMAKE_COMMAND} -E copy ${PROJECT_SOURCE_DIR}/ddnet-libs/websockets/mac/lib64/libwebsockets.17.dylib ${DMG_TMPDIR}/${TARGET_CLIENT}.app/Contents/Frameworks/
COMMAND ${CMAKE_COMMAND} -E copy ${PROJECT_BINARY_DIR}/libsteam_api.dylib ${DMG_TMPDIR}/${TARGET_CLIENT}.app/Contents/Frameworks/
COMMAND ${PYTHON_EXECUTABLE} ${PROJECT_SOURCE_DIR}/scripts/darwin_strip_rpath.py ${CMAKE_OTOOL} ${CMAKE_INSTALL_NAME_TOOL} ${DMG_TMPDIR}/${TARGET_CLIENT}.app/Contents/MacOS/${TARGET_CLIENT}
COMMAND ${CMAKE_INSTALL_NAME_TOOL} -add_rpath @loader_path/../Frameworks ${DMG_TMPDIR}/${TARGET_CLIENT}.app/Contents/MacOS/${TARGET_CLIENT}
COMMAND ${CMAKE_INSTALL_NAME_TOOL} -add_rpath @loader_path/../Frameworks ${DMG_TMPDIR}/${TARGET_CLIENT}.app/Contents/Frameworks/libavcodec.58.dylib
COMMAND ${CMAKE_INSTALL_NAME_TOOL} -add_rpath @loader_path/../Frameworks ${DMG_TMPDIR}/${TARGET_CLIENT}.app/Contents/Frameworks/libavformat.58.dylib
COMMAND ${CMAKE_INSTALL_NAME_TOOL} -add_rpath @loader_path/../Frameworks ${DMG_TMPDIR}/${TARGET_CLIENT}.app/Contents/Frameworks/libswscale.5.dylib
COMMAND ${CMAKE_INSTALL_NAME_TOOL} -add_rpath @loader_path/../Frameworks ${DMG_TMPDIR}/${TARGET_CLIENT}.app/Contents/Frameworks/libswresample.3.dylib
COMMAND ${CMAKE_INSTALL_NAME_TOOL} -change /usr/local/lib/libavcodec.58.dylib @rpath/libavcodec.58.dylib ${DMG_TMPDIR}/${TARGET_CLIENT}.app/Contents/MacOS/${TARGET_CLIENT}
COMMAND ${CMAKE_INSTALL_NAME_TOOL} -change /usr/local/lib/libavcodec.58.dylib @rpath/libavcodec.58.dylib ${DMG_TMPDIR}/${TARGET_CLIENT}.app/Contents/Frameworks/libavformat.58.dylib
COMMAND ${CMAKE_INSTALL_NAME_TOOL} -change /usr/local/lib/libavformat.58.dylib @rpath/libavformat.58.dylib ${DMG_TMPDIR}/${TARGET_CLIENT}.app/Contents/MacOS/${TARGET_CLIENT}
COMMAND ${CMAKE_INSTALL_NAME_TOOL} -change /usr/local/lib/libavutil.56.dylib @rpath/libavutil.56.dylib ${DMG_TMPDIR}/${TARGET_CLIENT}.app/Contents/MacOS/${TARGET_CLIENT}
COMMAND ${CMAKE_INSTALL_NAME_TOOL} -change /usr/local/lib/libavutil.56.dylib @rpath/libavutil.56.dylib ${DMG_TMPDIR}/${TARGET_CLIENT}.app/Contents/Frameworks/libavcodec.58.dylib
COMMAND ${CMAKE_INSTALL_NAME_TOOL} -change /usr/local/lib/libavutil.56.dylib @rpath/libavutil.56.dylib ${DMG_TMPDIR}/${TARGET_CLIENT}.app/Contents/Frameworks/libavformat.58.dylib
COMMAND ${CMAKE_INSTALL_NAME_TOOL} -change /usr/local/lib/libavutil.56.dylib @rpath/libavutil.56.dylib ${DMG_TMPDIR}/${TARGET_CLIENT}.app/Contents/Frameworks/libswscale.5.dylib
COMMAND ${CMAKE_INSTALL_NAME_TOOL} -change /usr/local/lib/libavutil.56.dylib @rpath/libavutil.56.dylib ${DMG_TMPDIR}/${TARGET_CLIENT}.app/Contents/Frameworks/libswresample.3.dylib
COMMAND ${CMAKE_INSTALL_NAME_TOOL} -change /usr/local/lib/libswscale.5.dylib @rpath/libswscale.5.dylib ${DMG_TMPDIR}/${TARGET_CLIENT}.app/Contents/MacOS/${TARGET_CLIENT}
COMMAND ${CMAKE_INSTALL_NAME_TOOL} -change /usr/local/lib/libswresample.3.dylib @rpath/libswresample.3.dylib ${DMG_TMPDIR}/${TARGET_CLIENT}.app/Contents/MacOS/${TARGET_CLIENT}
COMMAND ${CMAKE_INSTALL_NAME_TOOL} -change /usr/local/lib/libfreetype.6.dylib @rpath/libfreetype.6.dylib ${DMG_TMPDIR}/${TARGET_CLIENT}.app/Contents/MacOS/${TARGET_CLIENT}
# TODO: Cleaner solution than hardcoding paths
COMMAND ${CMAKE_INSTALL_NAME_TOOL} -change /home/deen/isos/ddnet/debian6/mac64/libwebsockets-4.1.1/lib/libwebsockets.17.dylib @rpath/libwebsockets.17.dylib ${DMG_TMPDIR}/${TARGET_CLIENT}.app/Contents/MacOS/${TARGET_CLIENT}
COMMAND ${CMAKE_INSTALL_NAME_TOOL} -change ${PROJECT_BINARY_DIR}/libsteam_api.dylib @rpath/libsteam_api.dylib ${DMG_TMPDIR}/${TARGET_CLIENT}.app/Contents/MacOS/${TARGET_CLIENT}
COMMAND ${CMAKE_INSTALL_NAME_TOOL} -change ${PROJECT_BINARY_DIR}/libsteam_api.dylib @rpath/libsteam_api.dylib ${DMG_TMPDIR}/${TARGET_CLIENT}.app/Contents/Frameworks/libsteam_api.dylib
# SERVER
COMMAND ${CMAKE_COMMAND} -E copy_directory ${PROJECT_SOURCE_DIR}/data/maps ${DMG_TMPDIR}/${TARGET_SERVER}.app/Contents/Resources/data/maps
COMMAND ${CMAKE_COMMAND} -E copy ${PROJECT_SOURCE_DIR}/other/icons/${TARGET_SERVER}.icns ${DMG_TMPDIR}/${TARGET_SERVER}.app/Contents/Resources/
COMMAND ${CMAKE_COMMAND} -E copy bundle/server/Info.plist ${PROJECT_SOURCE_DIR}/other/bundle/server/PkgInfo ${DMG_TMPDIR}/${TARGET_SERVER}.app/Contents/
COMMAND ${CMAKE_COMMAND} -E copy $<TARGET_FILE:${TARGET_SERVER}> $<TARGET_FILE:${TARGET_SERVER_LAUNCHER}> ${DMG_TMPDIR}/${TARGET_SERVER}.app/Contents/MacOS/
COMMAND ${CMAKE_COMMAND} -E make_directory ${DMG_TMPDIR}/${TARGET_SERVER}.app/Contents/Frameworks/
COMMAND ${CMAKE_COMMAND} -E copy ${PROJECT_SOURCE_DIR}/ddnet-libs/sqlite3/mac/lib64/libsqlite3.0.dylib ${DMG_TMPDIR}/${TARGET_SERVER}.app/Contents/Frameworks/
COMMAND ${CMAKE_COMMAND} -E copy ${PROJECT_SOURCE_DIR}/ddnet-libs/websockets/mac/lib64/libwebsockets.17.dylib ${DMG_TMPDIR}/${TARGET_SERVER}.app/Contents/Frameworks/
COMMAND ${PYTHON_EXECUTABLE} ${PROJECT_SOURCE_DIR}/scripts/darwin_strip_rpath.py ${CMAKE_OTOOL} ${CMAKE_INSTALL_NAME_TOOL} ${DMG_TMPDIR}/${TARGET_SERVER}.app/Contents/MacOS/${TARGET_SERVER}
COMMAND ${CMAKE_INSTALL_NAME_TOOL} -add_rpath @loader_path/../Frameworks ${DMG_TMPDIR}/${TARGET_SERVER}.app/Contents/MacOS/${TARGET_SERVER}
COMMAND ${CMAKE_INSTALL_NAME_TOOL} -change /usr/local/lib/libsqlite3.0.dylib @rpath/libsqlite3.0.dylib ${DMG_TMPDIR}/${TARGET_SERVER}.app/Contents/MacOS/${TARGET_SERVER}
COMMAND ${CMAKE_INSTALL_NAME_TOOL} -change /home/deen/isos/ddnet/debian6/mac64/libwebsockets-4.1.1/lib/libwebsockets.17.dylib @rpath/libwebsockets.17.dylib ${DMG_TMPDIR}/${TARGET_SERVER}.app/Contents/MacOS/${TARGET_SERVER}
# DMG
COMMAND ${PYTHON_EXECUTABLE} ${PROJECT_SOURCE_DIR}/scripts/dmg.py create ${DMG_PARAMS} ${CPACK_PACKAGE_FILE_NAME}.dmg ${CPACK_PACKAGE_FILE_NAME} ${DMG_TMPDIR}
DEPENDS
${TARGET_CLIENT}
${TARGET_STEAMAPI}
${TARGET_SERVER_LAUNCHER}
${TARGET_SERVER}
${PROJECT_BINARY_DIR}/bundle/client/Info.plist
${PROJECT_BINARY_DIR}/bundle/server/Info.plist
data
other/bundle/client/PkgInfo
other/bundle/server/PkgInfo
other/icons/${TARGET_CLIENT}.icns
other/icons/${TARGET_SERVER}.icns
scripts/dmg.py
)
add_custom_target(package_dmg DEPENDS ${CPACK_PACKAGE_FILE_NAME}.dmg)
list(APPEND PACKAGE_TARGETS package_dmg)
endif()
foreach(ext zip tar.gz tar.xz)
set(TAR_MODE c)
set(TAR_EXTRA_ARGS)
string(REPLACE . _ EXT_SLUG ${ext})
set(TMPDIR pack_${CPACK_PACKAGE_FILE_NAME}_${EXT_SLUG}/${CPACK_PACKAGE_FILE_NAME})
set(COPY_FILE_COMMANDS)
set(COPY_DIR_COMMANDS)
set(COPY_TARGET_COMMANDS)
set(STRIP_TARGET_COMMANDS)
foreach(file ${CPACK_FILES})
list(APPEND COPY_FILE_COMMANDS COMMAND ${CMAKE_COMMAND} -E copy ${PROJECT_SOURCE_DIR}/${file} ${TMPDIR}/)
endforeach()
foreach(dir ${CPACK_DIRS})
list(APPEND COPY_DIR_COMMANDS COMMAND ${CMAKE_COMMAND} -E copy_directory ${PROJECT_SOURCE_DIR}/${dir} ${TMPDIR}/${dir})
endforeach()
foreach(target ${CPACK_TARGETS})
list(APPEND COPY_TARGET_COMMANDS COMMAND ${CMAKE_COMMAND} -E copy $<TARGET_FILE:${target}> ${TMPDIR}/)
list(APPEND STRIP_TARGET_COMMANDS COMMAND strip -s ${TMPDIR}/$<TARGET_FILE_NAME:${target}>)
endforeach()
if(ext STREQUAL zip)
set(TAR_EXTRA_ARGS --format=zip)
elseif(ext STREQUAL tar.gz)
set(TAR_MODE cz)
elseif(ext STREQUAL tar.xz)
set(TAR_MODE cJ)
endif()
add_custom_command(OUTPUT ${CPACK_PACKAGE_FILE_NAME}.${ext}
COMMAND ${CMAKE_COMMAND} -E remove_directory ${TMPDIR}
COMMAND ${CMAKE_COMMAND} -E make_directory ${TMPDIR}
${COPY_FILE_COMMANDS}
${COPY_DIR_COMMANDS}
${COPY_TARGET_COMMANDS}
${STRIP_TARGET_COMMANDS}
COMMAND ${CMAKE_COMMAND} -E chdir pack_${CPACK_PACKAGE_FILE_NAME}_${EXT_SLUG} ${CMAKE_COMMAND} -E tar ${TAR_MODE} ../${CPACK_PACKAGE_FILE_NAME}.${ext} ${TAR_EXTRA_ARGS} -- ${CPACK_PACKAGE_FILE_NAME}/
DEPENDS ${CPACK_TARGETS}
)
add_custom_target(package_${EXT_SLUG} DEPENDS ${CPACK_PACKAGE_FILE_NAME}.${ext})
list(APPEND PACKAGE_TARGETS package_${EXT_SLUG})
endforeach()
set(PACKAGE_DEFAULT tar_xz)
if(TARGET_OS STREQUAL "windows")
set(PACKAGE_DEFAULT zip)
elseif(TARGET_OS STREQUAL "mac")
set(PACKAGE_DEFAULT dmg)
endif()
add_custom_target(package_default DEPENDS package_${PACKAGE_DEFAULT})
add_custom_target(package_all DEPENDS ${PACKAGE_TARGETS})
# Unset these variables, they might do something in the future of CPack.
unset(CPACK_SOURCE_FILES)
unset(CPACK_SOURCE_FILES_INVERTED)
unset(CPACK_TARGETS)
unset(CPACK_DIRS)
unset(CPACK_FILES)
include(CPack)
########################################################################
# COMPILER-SPECIFICS
########################################################################
# In the future (CMake 3.8.0+), use source_group(TREE ...)
macro(source_group_tree dir)
file(GLOB ents RELATIVE ${PROJECT_SOURCE_DIR}/${dir} ${PROJECT_SOURCE_DIR}/${dir}/*)
foreach(ent ${ents})
if(IS_DIRECTORY ${PROJECT_SOURCE_DIR}/${dir}/${ent})
source_group_tree(${dir}/${ent})
else()
string(REPLACE "/" "\\" group ${dir})
source_group(${group} FILES ${PROJECT_SOURCE_DIR}/${dir}/${ent})
endif()
endforeach()
endmacro()
source_group_tree(src)
if(ANTIBOT)
# Allow the antibot library to use functions from the server binary.
add_c_compiler_flag_if_supported(OUR_FLAGS_LINK -rdynamic)
set_own_rpath(${TARGET_SERVER})
endif()
set(TARGETS ${TARGETS_OWN} ${TARGETS_DEP})
foreach(target ${TARGETS})
if(MSVC)
target_compile_options(${target} PRIVATE $<$<NOT:${DBG}>:/MT> $<${DBG}:/MTd>) # Use static CRT
target_compile_options(${target} PRIVATE /MP) # Use multiple cores
target_compile_options(${target} PRIVATE /EHsc) # Only catch C++ exceptions with catch.
target_compile_options(${target} PRIVATE /GS) # Protect the stack pointer.
target_compile_options(${target} PRIVATE /wd4996) # Use of non-_s functions.
endif()
if(OUR_FLAGS_LINK)
target_link_libraries(${target} ${OUR_FLAGS_LINK})
endif()
if(OUR_FLAGS)
target_compile_options(${target} PRIVATE ${OUR_FLAGS})
endif()
if(DEFINE_FORTIFY_SOURCE)
if(MINGW)
target_compile_definitions(${target} PRIVATE $<$<NOT:$<CONFIG:Debug>>:_FORTIFY_SOURCE=0>) # Currently broken in MinGW, see https://sourceforge.net/p/mingw-w64/discussion/723798/thread/b9d24f041f/
else()
target_compile_definitions(${target} PRIVATE $<$<NOT:$<CONFIG:Debug>>:_FORTIFY_SOURCE=2>) # Detect some buffer overflows.
endif()
endif()
endforeach()
foreach(target ${TARGETS_LINK})
if(MSVC)
set_property(TARGET ${target} APPEND PROPERTY LINK_FLAGS /SAFESEH:NO) # Disable SafeSEH because the shipped libraries don't support it (would cause error LNK2026 otherwise).
endif()
if(TARGET_OS STREQUAL "mac")
target_link_libraries(${target} -stdlib=libc++)
endif()
if((MINGW OR TARGET_OS STREQUAL "linux") AND PREFER_BUNDLED_LIBS)
# Statically link the standard libraries with on MinGW/Linux so we don't
# have to ship them as DLLs.
target_link_libraries(${target} -static-libgcc)
target_link_libraries(${target} -static-libstdc++)
endif()
endforeach()
foreach(target ${TARGETS_OWN})
if((CMAKE_VERSION VERSION_GREATER 3.1 OR CMAKE_VERSION VERSION_EQUAL 3.1) AND NOT TARGET_OS STREQUAL "mac")
set_property(TARGET ${target} PROPERTY CXX_STANDARD 11)
set_property(TARGET ${target} PROPERTY CXX_STANDARD_REQUIRED ON)
endif()
if(MSVC)
target_compile_options(${target} PRIVATE /wd4244) # Possible loss of data (float -> int, int -> float, etc.).
target_compile_options(${target} PRIVATE /wd4267) # Possible loss of data (size_t - int on win64).
target_compile_options(${target} PRIVATE /wd4800) # Implicit conversion of int to bool.
endif()
if(OUR_FLAGS_OWN)
target_compile_options(${target} PRIVATE ${OUR_FLAGS_OWN})
endif()
target_include_directories(${target} PRIVATE ${PROJECT_BINARY_DIR}/src)
target_include_directories(${target} PRIVATE src)
target_compile_definitions(${target} PRIVATE $<$<CONFIG:Debug>:CONF_DEBUG>)
target_include_directories(${target} PRIVATE ${SQLite3_INCLUDE_DIRS} ${ZLIB_INCLUDE_DIRS})
target_compile_definitions(${target} PRIVATE GLEW_STATIC)
if(CRYPTO_FOUND)
target_compile_definitions(${target} PRIVATE CONF_OPENSSL)
target_include_directories(${target} PRIVATE ${CRYPTO_INCLUDE_DIRS})
endif()
if(WEBSOCKETS)
target_compile_definitions(${target} PRIVATE CONF_WEBSOCKETS)
target_include_directories(${target} PRIVATE ${WEBSOCKETS_INCLUDE_DIRS})
endif()
if(UPNP)
target_compile_definitions(${target} PRIVATE CONF_UPNP)
target_include_directories(${target} PRIVATE ${MINIUPNPC_INCLUDE_DIRS})
endif()
if(VIDEORECORDER)
target_compile_definitions(${target} PRIVATE CONF_VIDEORECORDER)
endif()
if(ANTIBOT)
target_compile_definitions(${target} PRIVATE CONF_ANTIBOT)
endif()
if(MYSQL)
target_compile_definitions(${target} PRIVATE CONF_SQL)
target_include_directories(${target} PRIVATE ${MYSQL_INCLUDE_DIRS})
endif()
if(AUTOUPDATE AND NOT STEAM)
target_compile_definitions(${target} PRIVATE CONF_AUTOUPDATE)
endif()
if(INFORM_UPDATE AND NOT STEAM)
target_compile_definitions(${target} PRIVATE CONF_INFORM_UPDATE)
endif()
if(STEAM)
target_compile_definitions(${target} PRIVATE PLATFORM_SUFFIX="-steam")
endif()
if(DISCORD)
target_compile_definitions(${target} PRIVATE CONF_DISCORD)
endif()
if(VERSION)
target_compile_definitions(${target} PRIVATE GAME_RELEASE_VERSION="${VERSION}")
endif()
endforeach()
foreach(target ${TARGETS_DEP})
if(MSVC)
target_compile_options(${target} PRIVATE /W0)
endif()
if(OUR_FLAGS_DEP)
target_compile_options(${target} PRIVATE ${OUR_FLAGS_DEP})
endif()
endforeach()