summaryrefslogtreecommitdiff
path: root/cmake
diff options
context:
space:
mode:
authorPatric Stout <truebrain@openttd.org>2019-04-07 11:57:55 +0200
committerglx22 <glx22@users.noreply.github.com>2020-06-05 19:36:05 +0200
commit56d54cf60eb5814f77dfcce91cf12879f01e1d1b (patch)
treee35fc5b7becc8f993d8c44179bc16e2586c3c64d /cmake
parent85315e2e3132dd7aff9ee96c1ba8d282350d9d5e (diff)
downloadopenttd-56d54cf60eb5814f77dfcce91cf12879f01e1d1b.tar.xz
Add: introduce CMake for project management
CMake works on all our supported platforms, like MSVC, Mingw, GCC, Clang, and many more. It allows for a single way of doing things, so no longer we need shell scripts and vbs scripts to work on all our supported platforms. Additionally, CMake allows to generate project files for like MSVC, KDevelop, etc. This heavily reduces the lines of code we need to support multiple platforms from a project perspective. Addtiionally, this heavily improves our detection of libraries, etc.
Diffstat (limited to 'cmake')
-rw-r--r--cmake/AddCustomXXXTimestamp.cmake145
-rw-r--r--cmake/CompileFlags.cmake120
-rw-r--r--cmake/CreateGrfCommand.cmake50
-rw-r--r--cmake/CreateRegression.cmake86
-rw-r--r--cmake/Endian.cmake14
-rw-r--r--cmake/FindAllegro.cmake65
-rw-r--r--cmake/FindEditbin.cmake13
-rw-r--r--cmake/FindFluidsynth.cmake65
-rw-r--r--cmake/FindFontconfig.cmake101
-rw-r--r--cmake/FindGrfcodec.cmake13
-rw-r--r--cmake/FindICU.cmake64
-rw-r--r--cmake/FindIconv.cmake133
-rw-r--r--cmake/FindLZO.cmake89
-rw-r--r--cmake/FindSSE.cmake17
-rw-r--r--cmake/FindXDG_basedir.cmake65
-rw-r--r--cmake/FindXaudio2.cmake18
-rw-r--r--cmake/LinkPackage.cmake18
-rw-r--r--cmake/Options.cmake84
-rw-r--r--cmake/SourceList.cmake63
-rw-r--r--cmake/Static.cmake14
-rw-r--r--cmake/scripts/FindVersion.cmake134
21 files changed, 1371 insertions, 0 deletions
diff --git a/cmake/AddCustomXXXTimestamp.cmake b/cmake/AddCustomXXXTimestamp.cmake
new file mode 100644
index 000000000..ca9398873
--- /dev/null
+++ b/cmake/AddCustomXXXTimestamp.cmake
@@ -0,0 +1,145 @@
+macro(_parse_arguments_with_multi_hack ORIGINAL_COMMAND_LINE)
+ # cmake_parse_arguments() put all the MULTIS in a single variable; you
+ # lose the ability to see for example multiple COMMANDs. To be able to
+ # passthrough multiple MULTIS, we add a marker after every MULTI. This
+ # allows us to reassemble the correct amount again before giving it to
+ # the wrapped command with _reassemble_command_line().
+
+ set(COMMAND_LINE "${ORIGINAL_COMMAND_LINE}")
+
+ foreach(MULTI IN LISTS MULTIS)
+ string(REPLACE "${MULTI}" "${MULTI};:::" COMMAND_LINE "${COMMAND_LINE}")
+ endforeach(MULTI)
+
+ cmake_parse_arguments(PARAM "${OPTIONS}" "${SINGLES}" "${MULTIS}" ${COMMAND_LINE})
+endmacro()
+
+macro(_reassemble_command_line)
+ # Reassemble the command line as we original got it.
+ set(NEW_COMMAND_LINE ${PARAM_UNPARSED_ARGUMENTS})
+
+ foreach(OPTION IN LISTS OPTIONS)
+ if (PARAM_${OPTION})
+ list(APPEND NEW_COMMAND_LINE "${OPTION}")
+ endif (PARAM_${OPTION})
+ endforeach(OPTION)
+
+ foreach(SINGLE IN LISTS SINGLES)
+ if (PARAM_${SINGLE})
+ list(APPEND NEW_COMMAND_LINE "${SINGLE}" "${PARAM_${SINGLE}}")
+ endif (PARAM_${SINGLE})
+ endforeach(SINGLE)
+
+ foreach(MULTI IN LISTS MULTIS)
+ if (PARAM_${MULTI})
+ # Replace our special marker with the name of the MULTI again. This
+ # restores for example multiple COMMANDs again.
+ string(REPLACE ":::" "${MULTI}" PARAM_${MULTI} "${PARAM_${MULTI}}")
+ list(APPEND NEW_COMMAND_LINE "${PARAM_${MULTI}}")
+ endif (PARAM_${MULTI})
+ endforeach(MULTI)
+endmacro()
+
+# Generated files can be older than their dependencies, causing useless
+# regenerations. This function replaces each file in OUTPUT with a .timestamp
+# file, adds a command to touch it and move the original file in BYPRODUCTS,
+# before calling add_custom_command().
+#
+# Note: Any add_custom_target() depending on files in original OUTPUT must use
+# add_custom_target_timestamp() instead to have the correct dependencies.
+#
+# add_custom_command_timestamp(OUTPUT output1 [output2 ...]
+# COMMAND command1 [ARGS] [args1...]
+# [COMMAND command2 [ARGS] [args2...] ...]
+# [MAIN_DEPENDENCY depend]
+# [DEPENDS [depends...]]
+# [BYPRODUCTS [files...]]
+# [IMPLICIT_DEPENDS <lang1> depend1
+# [<lang2> depend2] ...]
+# [WORKING_DIRECTORY dir]
+# [COMMENT comment]
+# [VERBATIM] [APPEND] [USES_TERMINAL])
+function(add_custom_command_timestamp)
+ set(OPTIONS VERBATIM APPEND USES_TERMINAL)
+ set(SINGLES MAIN_DEPENDENCY WORKING_DIRECTORY COMMENT)
+ set(MULTIS OUTPUT COMMAND DEPENDS BYPRODUCTS IMPLICIT_DEPENDS)
+
+ _parse_arguments_with_multi_hack("${ARGN}")
+
+ # Create a list of all the OUTPUTs (by removing our magic marker)
+ string(REPLACE ":::;" "" OUTPUTS "${PARAM_OUTPUT}")
+
+ # Reset the OUTPUT and BYPRODUCTS as an empty list (if needed).
+ # Because they are MULTIS, we need to add our special marker here.
+ set(PARAM_OUTPUT ":::")
+ if (NOT PARAM_BYPRODUCTS)
+ set(PARAM_BYPRODUCTS ":::")
+ endif ()
+
+ foreach(OUTPUT IN LISTS OUTPUTS)
+ # For every output, we add a 'cmake -E touch' entry to update the
+ # timestamp on each run.
+ get_filename_component(OUTPUT_FILENAME ${OUTPUT} NAME)
+ string(APPEND PARAM_COMMAND ";:::;${CMAKE_COMMAND};-E;touch;${CMAKE_CURRENT_BINARY_DIR}/${OUTPUT_FILENAME}.timestamp")
+
+ # We change the OUTPUT to a '.timestamp' variant, and make the real
+ # output a byproduct.
+ list(APPEND PARAM_OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${OUTPUT_FILENAME}.timestamp)
+ list(APPEND PARAM_BYPRODUCTS ${OUTPUT})
+
+ # Mark this file as being a byproduct; we use this again with
+ # add_custom_target_timestamp() to know if we should point to the
+ # '.timestamp' variant or not.
+ set_source_files_properties(${OUTPUT} PROPERTIES BYPRODUCT ${CMAKE_CURRENT_BINARY_DIR}/${OUTPUT_FILENAME}.timestamp)
+ endforeach(OUTPUT)
+
+ # Reassemble and call the wrapped command
+ _reassemble_command_line()
+ add_custom_command(${NEW_COMMAND_LINE})
+endfunction(add_custom_command_timestamp)
+
+# Generated files can be older than their dependencies, causing useless
+# regenerations. This function adds a .timestamp file for each file in DEPENDS
+# replaced by add_custom_command_timestamp(), before calling add_custom_target().
+#
+# add_custom_target_timestamp(Name [ALL] [command1 [args1...]]
+# [COMMAND command2 [args2...] ...]
+# [DEPENDS depend depend depend ... ]
+# [BYPRODUCTS [files...]]
+# [WORKING_DIRECTORY dir]
+# [COMMENT comment]
+# [VERBATIM] [USES_TERMINAL]
+# [SOURCES src1 [src2...]])
+function(add_custom_target_timestamp)
+ set(OPTIONS VERBATIM USES_TERMINAL)
+ set(SINGLES WORKING_DIRECTORY COMMENT)
+ set(MULTIS COMMAND DEPENDS BYPRODUCTS SOURCES)
+ # ALL is missing, as the order is important here. It will be picked up
+ # by ${PARAM_UNPARSED_ARGUMENTS} when reassembling the command line.
+
+ _parse_arguments_with_multi_hack("${ARGN}")
+
+ # Create a list of all the DEPENDs (by removing our magic marker)
+ string(REPLACE ":::;" "" DEPENDS "${PARAM_DEPENDS}")
+
+ # Reset the DEPEND as an empty list.
+ # Because it is a MULTI, we need to add our special marker here.
+ set(PARAM_DEPENDS ":::")
+
+ foreach(DEPEND IN LISTS DEPENDS)
+ # Check if the output is produced by add_custom_command_timestamp()
+ get_source_file_property(BYPRODUCT ${DEPEND} BYPRODUCT)
+
+ if (BYPRODUCT STREQUAL "NOTFOUND")
+ # If it is not, just keep it as DEPEND
+ list(APPEND PARAM_DEPENDS "${DEPEND}")
+ else (BYPRODUCT STREQUAL "NOTFOUND")
+ # If it is, the BYPRODUCT property points to the timestamp we want to depend on
+ list(APPEND PARAM_DEPENDS "${BYPRODUCT}")
+ endif (BYPRODUCT STREQUAL "NOTFOUND")
+ endforeach(DEPEND)
+
+ # Reassemble and call the wrapped command
+ _reassemble_command_line()
+ add_custom_target(${NEW_COMMAND_LINE})
+endfunction(add_custom_target_timestamp)
diff --git a/cmake/CompileFlags.cmake b/cmake/CompileFlags.cmake
new file mode 100644
index 000000000..05c19abab
--- /dev/null
+++ b/cmake/CompileFlags.cmake
@@ -0,0 +1,120 @@
+# Macro which contains all bits to setup the compile flags correctly.
+#
+# compile_flags()
+#
+macro(compile_flags)
+ if (MSVC)
+ # Switch to MT (static) instead of MD (dynamic) binary
+
+ # For MSVC two generators are available
+ # - a command line generator (Ninja) using CMAKE_BUILD_TYPE to specify the
+ # configuration of the build tree
+ # - an IDE generator (Visual Studio) using CMAKE_CONFIGURATION_TYPES to
+ # specify all configurations that will be available in the generated solution
+ list(APPEND MSVC_CONFIGS "${CMAKE_BUILD_TYPE}" "${CMAKE_CONFIGURATION_TYPES}")
+
+ # Set usage of static runtime for all configurations
+ foreach(MSVC_CONFIG ${MSVC_CONFIGS})
+ string(TOUPPER "CMAKE_CXX_FLAGS_${MSVC_CONFIG}" MSVC_FLAGS)
+ string(REPLACE "/MD" "/MT" ${MSVC_FLAGS} "${${MSVC_FLAGS}}")
+ endforeach()
+
+ # "If /Zc:rvalueCast is specified, the compiler follows section 5.4 of the
+ # C++11 standard". We need C++11 for the way we use threads.
+ add_compile_options(/Zc:rvalueCast)
+
+ # Add DPI manifest to project; other WIN32 targets get this via ottdres.rc
+ list(APPEND GENERATED_SOURCE_FILES "${CMAKE_SOURCE_DIR}/os/windows/openttd.manifest")
+ endif (MSVC)
+
+ # Add some -D flags for Debug builds. We cannot use add_definitions(), because
+ # it does not appear to support the $<> tags.
+ add_compile_options(
+ "$<$<CONFIG:Debug>:-D_DEBUG>"
+ "$<$<CONFIG:Debug>:-D_FORTIFY_SOURCE=2>"
+ )
+
+ # Prepare a generator that checks if we are not a debug, and don't have asserts
+ # on. We need this later on to set some compile options for stable releases.
+ set(IS_STABLE_RELEASE "$<AND:$<NOT:$<CONFIG:Debug>>,$<NOT:$<BOOL:${OPTION_USE_ASSERTS}>>>")
+
+ if (MSVC)
+ add_compile_options(/W3)
+ elseif (CMAKE_CXX_COMPILER_ID STREQUAL "GNU" OR CMAKE_CXX_COMPILER_ID STREQUAL "Clang" OR CMAKE_CXX_COMPILER_ID STREQUAL "AppleClang")
+ add_compile_options(
+ -W
+ -Wall
+ -Wcast-qual
+ -Wextra
+ -Wsign-compare
+ -Wundef
+ -Wpointer-arith
+ -Wwrite-strings
+ -Wredundant-decls
+ -Wformat-security
+ -Wformat=2
+ -Winit-self
+ -Wnon-virtual-dtor
+
+ # Often parameters are unused, which is fine.
+ -Wno-unused-parameter
+ # We use 'ABCD' multichar for SaveLoad chunks identifiers
+ -Wno-multichar
+
+ # Compilers complains about that we break strict-aliasing.
+ # On most places we don't see how to fix it, and it doesn't
+ # break anything. So disable strict-aliasing to make the
+ # compiler all happy.
+ -fno-strict-aliasing
+ )
+
+ add_compile_options(
+ # When we are a stable release (Release build + USE_ASSERTS not set),
+ # assertations are off, which trigger a lot of warnings. We disable
+ # these warnings for these releases.
+ "$<${IS_STABLE_RELEASE}:-Wno-unused-variable>"
+ "$<${IS_STABLE_RELEASE}:-Wno-unused-but-set-parameter>"
+ "$<${IS_STABLE_RELEASE}:-Wno-unused-but-set-variable>"
+ )
+
+ if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
+ include(CheckCXXCompilerFlag)
+ check_cxx_compiler_flag("-flifetime-dse=1" LIFETIME_DSE_FOUND)
+
+ add_compile_options(
+ # GCC 4.2+ automatically assumes that signed overflows do
+ # not occur in signed arithmetics, whereas we are not
+ # sure that they will not happen. It furthermore complains
+ # about its own optimized code in some places.
+ "-fno-strict-overflow"
+
+ # Prevent optimisation supposing enums are in a range specified by the standard
+ # For details, see http://gcc.gnu.org/PR43680
+ "-fno-tree-vrp"
+
+ # -flifetime-dse=2 (default since GCC 6) doesn't play
+ # well with our custom pool item allocator
+ "$<$<BOOL:${LIFETIME_DSE_FOUND}>:-flifetime-dse=1>"
+ )
+ endif (CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
+ elseif (CMAKE_CXX_COMPILER_ID STREQUAL "Intel")
+ add_compile_options(
+ -Wall
+ # warning #873: function ... ::operator new ... has no corresponding operator delete ...
+ -wd873
+ # warning #1292: unknown attribute "fallthrough"
+ -wd1292
+ # warning #1899: multicharacter character literal (potential portability problem)
+ -wd1899
+ # warning #2160: anonymous union qualifier is ignored
+ -wd2160
+ )
+ else ()
+ message(FATAL_ERROR "No warning flags are set for this compiler yet; please consider creating a Pull Request to add support for this compiler.")
+ endif ()
+
+ if (NOT WIN32)
+ # rdynamic is used to get useful stack traces from crash reports.
+ set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -rdynamic")
+ endif (NOT WIN32)
+endmacro()
diff --git a/cmake/CreateGrfCommand.cmake b/cmake/CreateGrfCommand.cmake
new file mode 100644
index 000000000..25e599f56
--- /dev/null
+++ b/cmake/CreateGrfCommand.cmake
@@ -0,0 +1,50 @@
+# Macro which contains all bits and pieces to create a single grf file based
+# on NFO and PNG files.
+#
+# create_grf_command()
+#
+function(create_grf_command)
+ set(EXTRA_PNG_SOURCE_FILES ${ARGV})
+
+ get_filename_component(GRF_SOURCE_FOLDER_NAME "${CMAKE_CURRENT_SOURCE_DIR}" NAME)
+ get_filename_component(GRF_BINARY_FILE ${CMAKE_CURRENT_SOURCE_DIR}/../${GRF_SOURCE_FOLDER_NAME}.grf ABSOLUTE)
+ file(GLOB_RECURSE GRF_PNG_SOURCE_FILES ${CMAKE_CURRENT_SOURCE_DIR}/*.png)
+ file(GLOB_RECURSE GRF_NFO_SOURCE_FILES ${CMAKE_CURRENT_SOURCE_DIR}/*.nfo)
+ set(GRF_PNG_SOURCE_FILES ${GRF_PNG_SOURCE_FILES} ${EXTRA_PNG_SOURCE_FILES})
+
+ # Copy over all the PNG files to the correct folder
+ foreach(GRF_PNG_SOURCE_FILE IN LISTS GRF_PNG_SOURCE_FILES)
+ get_filename_component(GRF_PNG_SOURCE_FILE_NAME "${GRF_PNG_SOURCE_FILE}" NAME)
+ set(GRF_PNG_BINARY_FILE "${CMAKE_CURRENT_BINARY_DIR}/sprites/${GRF_PNG_SOURCE_FILE_NAME}")
+
+ add_custom_command(OUTPUT ${GRF_PNG_BINARY_FILE}
+ COMMAND ${CMAKE_COMMAND} -E copy
+ ${GRF_PNG_SOURCE_FILE}
+ ${GRF_PNG_BINARY_FILE}
+ MAIN_DEPENDENCY ${GRF_PNG_SOURCE_FILE}
+ COMMENT "Copying ${GRF_PNG_SOURCE_FILE_NAME} sprite file"
+ )
+
+ list(APPEND GRF_PNG_BINARY_FILES ${GRF_PNG_BINARY_FILE})
+ endforeach(GRF_PNG_SOURCE_FILE)
+
+ add_custom_command(OUTPUT ${GRF_BINARY_FILE}
+ COMMAND ${CMAKE_COMMAND}
+ -DGRF_SOURCE_FOLDER=${CMAKE_CURRENT_SOURCE_DIR}
+ -DGRF_BINARY_FILE=${GRF_BINARY_FILE}
+ -DNFORENUM_EXECUTABLE=${NFORENUM_EXECUTABLE}
+ -DGRFCODEC_EXECUTABLE=${GRFCODEC_EXECUTABLE}
+ -P ${CMAKE_SOURCE_DIR}/cmake/scripts/CreateGRF.cmake
+ MAIN_DEPENDENCY ${GRF_NFO_SOURCE_FILES}
+ DEPENDS ${GRF_PNG_BINARY_FILES}
+ ${CMAKE_SOURCE_DIR}/cmake/scripts/CreateGRF.cmake
+ WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
+ COMMENT "Generating ${GRF_SOURCE_FOLDER_NAME}.grf"
+ )
+
+ # For conviance, if you want to only test building the GRF
+ add_custom_target(${GRF_SOURCE_FOLDER_NAME}.grf
+ DEPENDS
+ ${GRF_BINARY_FILE}
+ )
+endfunction()
diff --git a/cmake/CreateRegression.cmake b/cmake/CreateRegression.cmake
new file mode 100644
index 000000000..443332368
--- /dev/null
+++ b/cmake/CreateRegression.cmake
@@ -0,0 +1,86 @@
+# Macro which contains all bits and pieces to create the regression tests.
+# This creates both a standalone target 'regression', and it integrates with
+# 'ctest'. The first is prefered, as it is more verbose, and takes care of
+# dependencies correctly.
+#
+# create_regression()
+#
+macro(create_regression)
+ # Find all the files in the regression folder; they need to be copied to the
+ # build folder before we can run the regression
+ file(GLOB_RECURSE REGRESSION_SOURCE_FILES ${CMAKE_SOURCE_DIR}/regression/*)
+ foreach(REGRESSION_SOURCE_FILE IN LISTS REGRESSION_SOURCE_FILES)
+ string(REGEX REPLACE "^${CMAKE_SOURCE_DIR}/regression/" "${CMAKE_BINARY_DIR}/ai/" REGRESSION_BINARY_FILE "${REGRESSION_SOURCE_FILE}")
+ string(REGEX REPLACE "^${CMAKE_SOURCE_DIR}/regression/" "" REGRESSION_SOURCE_FILE_NAME "${REGRESSION_SOURCE_FILE}")
+
+ if ("${REGRESSION_SOURCE_FILE_NAME}" STREQUAL "regression.cfg")
+ continue()
+ endif ("${REGRESSION_SOURCE_FILE_NAME}" STREQUAL "regression.cfg")
+
+ add_custom_command(OUTPUT ${REGRESSION_BINARY_FILE}
+ COMMAND ${CMAKE_COMMAND} -E copy
+ ${REGRESSION_SOURCE_FILE}
+ ${REGRESSION_BINARY_FILE}
+ MAIN_DEPENDENCY ${REGRESSION_SOURCE_FILE}
+ COMMENT "Copying ${REGRESSION_SOURCE_FILE_NAME} regression file"
+ )
+
+ list(APPEND REGRESSION_BINARY_FILES ${REGRESSION_BINARY_FILE})
+ endforeach(REGRESSION_SOURCE_FILE)
+
+ # Copy the regression configuration in a special folder, so all autogenerated
+ # folders end up in the same place after running regression.
+ add_custom_command(OUTPUT ${CMAKE_BINARY_DIR}/regression/regression.cfg
+ COMMAND ${CMAKE_COMMAND} -E copy
+ ${CMAKE_SOURCE_DIR}/regression/regression.cfg
+ ${CMAKE_BINARY_DIR}/regression/regression.cfg
+ MAIN_DEPENDENCY ${CMAKE_SOURCE_DIR}/regression/regression.cfg
+ COMMENT "Copying ${REGRESSION_SOURCE_FILE_NAME} regression file"
+ )
+ list(APPEND REGRESSION_BINARY_FILES ${CMAKE_BINARY_DIR}/regression/regression.cfg)
+
+ # Create a new target which copies all regression files
+ add_custom_target(regression_files
+ ALL # this is needed because 'make test' doesn't resolve dependencies, and otherwise this is never executed
+ DEPENDS
+ ${REGRESSION_BINARY_FILES}
+ )
+
+ enable_testing()
+
+ # Find all the tests we have, and create a target for them
+ file(GLOB REGRESSION_TESTS ${CMAKE_SOURCE_DIR}/regression/*)
+ foreach(REGRESSION_TEST IN LISTS REGRESSION_TESTS)
+ get_filename_component(REGRESSION_TEST_NAME "${REGRESSION_TEST}" NAME)
+
+ if ("${REGRESSION_TEST_NAME}" STREQUAL "regression.cfg")
+ continue()
+ endif ("${REGRESSION_TEST_NAME}" STREQUAL "regression.cfg")
+
+ add_custom_target(regression_${REGRESSION_TEST_NAME}
+ COMMAND ${CMAKE_COMMAND}
+ -DOPENTTD_EXECUTABLE=$<TARGET_FILE:openttd>
+ -DEDITBIN_EXECUTABLE=${EDITBIN_EXECUTABLE}
+ -DREGRESSION_TEST=${REGRESSION_TEST_NAME}
+ -P "${CMAKE_SOURCE_DIR}/cmake/scripts/Regression.cmake"
+ DEPENDS openttd regression_files
+ WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
+ COMMENT "Running regression test ${REGRESSION_TEST_NAME}"
+ )
+
+ # Also make sure that 'make test' runs the regression
+ add_test(NAME regression_${REGRESSION_TEST_NAME}
+ COMMAND ${CMAKE_COMMAND}
+ -DOPENTTD_EXECUTABLE=$<TARGET_FILE:openttd>
+ -DEDITBIN_EXECUTABLE=${EDITBIN_EXECUTABLE}
+ -DREGRESSION_TEST=${REGRESSION_TEST_NAME}
+ -P "${CMAKE_SOURCE_DIR}/cmake/scripts/Regression.cmake"
+ WORKING_DIRECTORY ${CMAKE_BINARY_DIR})
+
+ list(APPEND REGRESSION_TARGETS regression_${REGRESSION_TEST_NAME})
+ endforeach(REGRESSION_TEST)
+
+ # Create a new target which runs the regression
+ add_custom_target(regression
+ DEPENDS ${REGRESSION_TARGETS})
+endmacro()
diff --git a/cmake/Endian.cmake b/cmake/Endian.cmake
new file mode 100644
index 000000000..00cb97544
--- /dev/null
+++ b/cmake/Endian.cmake
@@ -0,0 +1,14 @@
+# Add the definitions to indicate which endian we are building for.
+#
+# add_endian_definition()
+#
+function(add_endian_definition)
+ include(TestBigEndian)
+ TEST_BIG_ENDIAN(IS_BIG_ENDIAN)
+
+ if (IS_BIG_ENDIAN)
+ add_definitions(-DTTD_ENDIAN=TTD_BIG_ENDIAN)
+ else (IS_BIG_ENDIAN)
+ add_definitions(-DTTD_ENDIAN=TTD_LITTLE_ENDIAN)
+ endif (IS_BIG_ENDIAN)
+endfunction()
diff --git a/cmake/FindAllegro.cmake b/cmake/FindAllegro.cmake
new file mode 100644
index 000000000..85b2ffd39
--- /dev/null
+++ b/cmake/FindAllegro.cmake
@@ -0,0 +1,65 @@
+#[=======================================================================[.rst:
+FindAllegro
+-------
+
+Finds the allegro library.
+
+Result Variables
+^^^^^^^^^^^^^^^^
+
+This will define the following variables:
+
+``Allegro_FOUND``
+ True if the system has the allegro library.
+``Allegro_INCLUDE_DIRS``
+ Include directories needed to use allegro.
+``Allegro_LIBRARIES``
+ Libraries needed to link to allegro.
+``Allegro_VERSION``
+ The version of the allegro library which was found.
+
+Cache Variables
+^^^^^^^^^^^^^^^
+
+The following cache variables may also be set:
+
+``Allegro_INCLUDE_DIR``
+ The directory containing ``allegro.h``.
+``Allegro_LIBRARY``
+ The path to the allegro library.
+
+#]=======================================================================]
+
+find_package(PkgConfig QUIET)
+pkg_check_modules(PC_Allegro QUIET allegro)
+
+find_path(Allegro_INCLUDE_DIR
+ NAMES allegro.h
+ PATHS ${PC_Allegro_INCLUDE_DIRS}
+)
+
+find_library(Allegro_LIBRARY
+ NAMES alleg
+ PATHS ${PC_Allegro_LIBRARY_DIRS}
+)
+
+set(Allegro_VERSION ${PC_Allegro_VERSION})
+
+include(FindPackageHandleStandardArgs)
+find_package_handle_standard_args(Allegro
+ FOUND_VAR Allegro_FOUND
+ REQUIRED_VARS
+ Allegro_LIBRARY
+ Allegro_INCLUDE_DIR
+ VERSION_VAR Allegro_VERSION
+)
+
+if (Allegro_FOUND)
+ set(Allegro_LIBRARIES ${Allegro_LIBRARY})
+ set(Allegro_INCLUDE_DIRS ${Allegro_INCLUDE_DIR})
+endif ()
+
+mark_as_advanced(
+ Allegro_INCLUDE_DIR
+ Allegro_LIBRARY
+)
diff --git a/cmake/FindEditbin.cmake b/cmake/FindEditbin.cmake
new file mode 100644
index 000000000..363bc0053
--- /dev/null
+++ b/cmake/FindEditbin.cmake
@@ -0,0 +1,13 @@
+# Autodetect editbin. Only useful for MSVC.
+
+get_filename_component(MSVC_COMPILE_DIRECTORY ${CMAKE_CXX_COMPILER} DIRECTORY)
+find_program(
+ EDITBIN_EXECUTABLE editbin.exe
+ HINTS ${MSVC_COMPILE_DIRECTORY}
+)
+
+include(FindPackageHandleStandardArgs)
+find_package_handle_standard_args(Editbin
+ FOUND_VAR EDITBIN_FOUND
+ REQUIRED_VARS EDITBIN_EXECUTABLE
+)
diff --git a/cmake/FindFluidsynth.cmake b/cmake/FindFluidsynth.cmake
new file mode 100644
index 000000000..063726dbe
--- /dev/null
+++ b/cmake/FindFluidsynth.cmake
@@ -0,0 +1,65 @@
+#[=======================================================================[.rst:
+FindFluidsynth
+-------
+
+Finds the fluidsynth library.
+
+Result Variables
+^^^^^^^^^^^^^^^^
+
+This will define the following variables:
+
+``Fluidsynth_FOUND``
+ True if the system has the fluidsynth library.
+``Fluidsynth_INCLUDE_DIRS``
+ Include directories needed to use fluidsynth.
+``Fluidsynth_LIBRARIES``
+ Libraries needed to link to fluidsynth.
+``Fluidsynth_VERSION``
+ The version of the fluidsynth library which was found.
+
+Cache Variables
+^^^^^^^^^^^^^^^
+
+The following cache variables may also be set:
+
+``Fluidsynth_INCLUDE_DIR``
+ The directory containing ``fluidsynth.h``.
+``Fluidsynth_LIBRARY``
+ The path to the fluidsynth library.
+
+#]=======================================================================]
+
+find_package(PkgConfig QUIET)
+pkg_check_modules(PC_Fluidsynth QUIET fluidsynth)
+
+find_path(Fluidsynth_INCLUDE_DIR
+ NAMES fluidsynth.h
+ PATHS ${PC_Fluidsynth_INCLUDE_DIRS}
+)
+
+find_library(Fluidsynth_LIBRARY
+ NAMES fluidsynth
+ PATHS ${PC_Fluidsynth_LIBRARY_DIRS}
+)
+
+set(Fluidsynth_VERSION ${PC_Fluidsynth_VERSION})
+
+include(FindPackageHandleStandardArgs)
+find_package_handle_standard_args(Fluidsynth
+ FOUND_VAR Fluidsynth_FOUND
+ REQUIRED_VARS
+ Fluidsynth_LIBRARY
+ Fluidsynth_INCLUDE_DIR
+ VERSION_VAR Fluidsynth_VERSION
+)
+
+if (Fluidsynth_FOUND)
+ set(Fluidsynth_LIBRARIES ${Fluidsynth_LIBRARY})
+ set(Fluidsynth_INCLUDE_DIRS ${Fluidsynth_INCLUDE_DIR})
+endif ()
+
+mark_as_advanced(
+ Fluidsynth_INCLUDE_DIR
+ Fluidsynth_LIBRARY
+)
diff --git a/cmake/FindFontconfig.cmake b/cmake/FindFontconfig.cmake
new file mode 100644
index 000000000..a6f0180b3
--- /dev/null
+++ b/cmake/FindFontconfig.cmake
@@ -0,0 +1,101 @@
+# Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+# file Copyright.txt or https://cmake.org/licensing for details.
+
+#[=======================================================================[.rst:
+FindFontconfig
+--------------
+
+Find Fontconfig headers and library.
+
+Imported Targets
+^^^^^^^^^^^^^^^^
+
+``Fontconfig::Fontconfig``
+ The Fontconfig library, if found.
+
+Result Variables
+^^^^^^^^^^^^^^^^
+
+This will define the following variables in your project:
+
+``Fontconfig_FOUND``
+ true if (the requested version of) Fontconfig is available.
+``Fontconfig_VERSION``
+ the version of Fontconfig.
+``Fontconfig_LIBRARIES``
+ the libraries to link against to use Fontconfig.
+``Fontconfig_INCLUDE_DIRS``
+ where to find the Fontconfig headers.
+``Fontconfig_COMPILE_OPTIONS``
+ this should be passed to target_compile_options(), if the
+ target is not used for linking
+
+#]=======================================================================]
+
+
+# use pkg-config to get the directories and then use these values
+# in the FIND_PATH() and FIND_LIBRARY() calls
+find_package(PkgConfig QUIET)
+pkg_check_modules(PKG_FONTCONFIG QUIET fontconfig)
+set(Fontconfig_COMPILE_OPTIONS ${PKG_FONTCONFIG_CFLAGS_OTHER})
+set(Fontconfig_VERSION ${PKG_FONTCONFIG_VERSION})
+
+find_path( Fontconfig_INCLUDE_DIR
+ NAMES
+ fontconfig/fontconfig.h
+ HINTS
+ ${PKG_FONTCONFIG_INCLUDE_DIRS}
+ /usr/X11/include
+)
+
+find_library( Fontconfig_LIBRARY
+ NAMES
+ fontconfig
+ PATHS
+ ${PKG_FONTCONFIG_LIBRARY_DIRS}
+)
+
+if (Fontconfig_INCLUDE_DIR AND NOT Fontconfig_VERSION)
+ file(STRINGS ${Fontconfig_INCLUDE_DIR}/fontconfig/fontconfig.h _contents REGEX "^#define[ \t]+FC_[A-Z]+[ \t]+[0-9]+$")
+ unset(Fontconfig_VERSION)
+ foreach(VPART MAJOR MINOR REVISION)
+ foreach(VLINE ${_contents})
+ if(VLINE MATCHES "^#define[\t ]+FC_${VPART}[\t ]+([0-9]+)$")
+ set(Fontconfig_VERSION_PART "${CMAKE_MATCH_1}")
+ if(Fontconfig_VERSION)
+ string(APPEND Fontconfig_VERSION ".${Fontconfig_VERSION_PART}")
+ else()
+ set(Fontconfig_VERSION "${Fontconfig_VERSION_PART}")
+ endif()
+ endif()
+ endforeach()
+ endforeach()
+endif ()
+
+include(FindPackageHandleStandardArgs)
+find_package_handle_standard_args(Fontconfig
+ FOUND_VAR
+ Fontconfig_FOUND
+ REQUIRED_VARS
+ Fontconfig_LIBRARY
+ Fontconfig_INCLUDE_DIR
+ VERSION_VAR
+ Fontconfig_VERSION
+)
+
+
+if(Fontconfig_FOUND AND NOT TARGET Fontconfig::Fontconfig)
+ add_library(Fontconfig::Fontconfig UNKNOWN IMPORTED)
+ set_target_properties(Fontconfig::Fontconfig PROPERTIES
+ IMPORTED_LOCATION "${Fontconfig_LIBRARY}"
+ INTERFACE_COMPILE_OPTIONS "${Fontconfig_COMPILE_OPTIONS}"
+ INTERFACE_INCLUDE_DIRECTORIES "${Fontconfig_INCLUDE_DIR}"
+ )
+endif()
+
+mark_as_advanced(Fontconfig_LIBRARY Fontconfig_INCLUDE_DIR)
+
+if(Fontconfig_FOUND)
+ set(Fontconfig_LIBRARIES ${Fontconfig_LIBRARY})
+ set(Fontconfig_INCLUDE_DIRS ${Fontconfig_INCLUDE_DIR})
+endif()
diff --git a/cmake/FindGrfcodec.cmake b/cmake/FindGrfcodec.cmake
new file mode 100644
index 000000000..089f95670
--- /dev/null
+++ b/cmake/FindGrfcodec.cmake
@@ -0,0 +1,13 @@
+# Autodetect grfcodec and nforenum.
+#
+
+find_program(GRFCODEC_EXECUTABLE grfcodec)
+find_program(NFORENUM_EXECUTABLE nforenum)
+
+include(FindPackageHandleStandardArgs)
+find_package_handle_standard_args(Grfcodec
+ FOUND_VAR GRFCODEC_FOUND
+ REQUIRED_VARS
+ GRFCODEC_EXECUTABLE
+ NFORENUM_EXECUTABLE
+)
diff --git a/cmake/FindICU.cmake b/cmake/FindICU.cmake
new file mode 100644
index 000000000..471e43c1d
--- /dev/null
+++ b/cmake/FindICU.cmake
@@ -0,0 +1,64 @@
+#[=======================================================================[.rst:
+FindICU
+-------
+
+Finds components of the ICU library.
+
+Accepted components are: uc, i18n, le, lx, io
+
+Result Variables
+^^^^^^^^^^^^^^^^
+
+This will define the following variables:
+
+``ICU_FOUND``
+ True if components of ICU library are found.
+``ICU_VERSION``
+ The version of the ICU library which was found.
+``ICU_<c>_FOUND``
+ True if the system has the <c> component of ICU library.
+``ICU_<c>_INCLUDE_DIRS``
+ Include directories needed to use the <c> component of ICU library.
+``ICU_<c>_LIBRARIES``
+ Libraries needed to link to the <c> component of ICU library.
+
+#]=======================================================================]
+
+find_package(PkgConfig QUIET)
+
+set(ICU_KNOWN_COMPONENTS "uc" "i18n" "le" "lx" "io")
+
+foreach(MOD_NAME IN LISTS ICU_FIND_COMPONENTS)
+ if (NOT MOD_NAME IN_LIST ICU_KNOWN_COMPONENTS)
+ message(FATAL_ERROR "Unknown ICU component: ${MOD_NAME}")
+ endif()
+ pkg_check_modules(PC_ICU_${MOD_NAME} QUIET icu-${MOD_NAME})
+
+ # Check the libraries returned by pkg-config really exist.
+ unset(PC_LIBRARIES)
+ foreach(LIBRARY IN LISTS PC_ICU_${MOD_NAME}_LIBRARIES)
+ unset(PC_LIBRARY CACHE)
+ find_library(PC_LIBRARY NAMES ${LIBRARY})
+ if (NOT PC_LIBRARY)
+ unset(PC_ICU_${MOD_NAME}_FOUND)
+ endif()
+ list(APPEND PC_LIBRARIES ${PC_LIBRARY})
+ endforeach()
+ unset(PC_LIBRARY CACHE)
+
+ if (${PC_ICU_${MOD_NAME}_FOUND})
+ set(ICU_COMPONENT_FOUND TRUE)
+ set(ICU_${MOD_NAME}_FOUND TRUE)
+ set(ICU_${MOD_NAME}_LIBRARIES ${PC_LIBRARIES})
+ set(ICU_${MOD_NAME}_INCLUDE_DIRS ${PC_ICU_${MOD_NAME}_INCLUDE_DIRS})
+ set(ICU_VERSION ${PC_ICU_${MOD_NAME}_VERSION})
+ endif()
+endforeach()
+
+include(FindPackageHandleStandardArgs)
+find_package_handle_standard_args(ICU
+ FOUND_VAR ICU_FOUND
+ REQUIRED_VARS ICU_COMPONENT_FOUND
+ VERSION_VAR ICU_VERSION
+ HANDLE_COMPONENTS
+)
diff --git a/cmake/FindIconv.cmake b/cmake/FindIconv.cmake
new file mode 100644
index 000000000..5185601ab
--- /dev/null
+++ b/cmake/FindIconv.cmake
@@ -0,0 +1,133 @@
+# Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+# file Copyright.txt or https://cmake.org/licensing for details.
+
+#[=======================================================================[.rst:
+FindIconv
+---------
+
+This module finds the ``iconv()`` POSIX.1 functions on the system.
+These functions might be provided in the regular C library or externally
+in the form of an additional library.
+
+The following variables are provided to indicate iconv support:
+
+.. variable:: Iconv_FOUND
+
+ Variable indicating if the iconv support was found.
+
+.. variable:: Iconv_INCLUDE_DIRS
+
+ The directories containing the iconv headers.
+
+.. variable:: Iconv_LIBRARIES
+
+ The iconv libraries to be linked.
+
+.. variable:: Iconv_IS_BUILT_IN
+
+ A variable indicating whether iconv support is stemming from the
+ C library or not. Even if the C library provides `iconv()`, the presence of
+ an external `libiconv` implementation might lead to this being false.
+
+Additionally, the following :prop_tgt:`IMPORTED` target is being provided:
+
+.. variable:: Iconv::Iconv
+
+ Imported target for using iconv.
+
+The following cache variables may also be set:
+
+.. variable:: Iconv_INCLUDE_DIR
+
+ The directory containing the iconv headers.
+
+.. variable:: Iconv_LIBRARY
+
+ The iconv library (if not implicitly given in the C library).
+
+.. note::
+ On POSIX platforms, iconv might be part of the C library and the cache
+ variables ``Iconv_INCLUDE_DIR`` and ``Iconv_LIBRARY`` might be empty.
+
+#]=======================================================================]
+
+include(CMakePushCheckState)
+if(CMAKE_C_COMPILER_LOADED)
+ include(CheckCSourceCompiles)
+elseif(CMAKE_CXX_COMPILER_LOADED)
+ include(CheckCXXSourceCompiles)
+else()
+ # If neither C nor CXX are loaded, implicit iconv makes no sense.
+ set(Iconv_IS_BUILT_IN FALSE)
+endif()
+
+# iconv can only be provided in libc on a POSIX system.
+# If any cache variable is already set, we'll skip this test.
+if(NOT DEFINED Iconv_IS_BUILT_IN)
+ if(UNIX AND NOT DEFINED Iconv_INCLUDE_DIR AND NOT DEFINED Iconv_LIBRARY)
+ cmake_push_check_state(RESET)
+ # We always suppress the message here: Otherwise on supported systems
+ # not having iconv in their C library (e.g. those using libiconv)
+ # would always display a confusing "Looking for iconv - not found" message
+ set(CMAKE_FIND_QUIETLY TRUE)
+ # The following code will not work, but it's sufficient to see if it compiles.
+ # Note: libiconv will define the iconv functions as macros, so CheckSymbolExists
+ # will not yield correct results.
+ set(Iconv_IMPLICIT_TEST_CODE
+ "
+ #include <stddef.h>
+ #include <iconv.h>
+ int main() {
+ char *a, *b;
+ size_t i, j;
+ iconv_t ic;
+ ic = iconv_open(\"to\", \"from\");
+ iconv(ic, &a, &i, &b, &j);
+ iconv_close(ic);
+ }
+ "
+ )
+ if(CMAKE_C_COMPILER_LOADED)
+ check_c_source_compiles("${Iconv_IMPLICIT_TEST_CODE}" Iconv_IS_BUILT_IN)
+ else()
+ check_cxx_source_compiles("${Iconv_IMPLICIT_TEST_CODE}" Iconv_IS_BUILT_IN)
+ endif()
+ cmake_pop_check_state()
+ else()
+ set(Iconv_IS_BUILT_IN FALSE)
+ endif()
+endif()
+
+if(NOT Iconv_IS_BUILT_IN)
+ find_path(Iconv_INCLUDE_DIR
+ NAMES "iconv.h"
+ DOC "iconv include directory")
+ set(Iconv_LIBRARY_NAMES "iconv" "libiconv")
+else()
+ set(Iconv_INCLUDE_DIR "" CACHE FILEPATH "iconv include directory")
+ set(Iconv_LIBRARY_NAMES "c")
+endif()
+
+find_library(Iconv_LIBRARY
+ NAMES ${Iconv_LIBRARY_NAMES}
+ DOC "iconv library (potentially the C library)")
+
+mark_as_advanced(Iconv_INCLUDE_DIR)
+mark_as_advanced(Iconv_LIBRARY)
+
+include(FindPackageHandleStandardArgs)
+if(NOT Iconv_IS_BUILT_IN)
+ find_package_handle_standard_args(Iconv REQUIRED_VARS Iconv_LIBRARY Iconv_INCLUDE_DIR)
+else()
+ find_package_handle_standard_args(Iconv REQUIRED_VARS Iconv_LIBRARY)
+endif()
+
+if(Iconv_FOUND)
+ set(Iconv_INCLUDE_DIRS "${Iconv_INCLUDE_DIR}")
+ set(Iconv_LIBRARIES "${Iconv_LIBRARY}")
+ if(NOT TARGET Iconv::Iconv)
+ add_library(Iconv::Iconv INTERFACE IMPORTED)
+ endif()
+ set_property(TARGET Iconv::Iconv PROPERTY INTERFACE_INCLUDE_DIRECTORIES "${Iconv_INCLUDE_DIRS}")
+ set_property(TARGET Iconv::Iconv PROPERTY INTERFACE_LINK_LIBRARIES "${Iconv_LIBRARIES}")
+endif()
diff --git a/cmake/FindLZO.cmake b/cmake/FindLZO.cmake
new file mode 100644
index 000000000..9a409002d
--- /dev/null
+++ b/cmake/FindLZO.cmake
@@ -0,0 +1,89 @@
+#[=======================================================================[.rst:
+FindLZO
+-------
+
+Finds the LZO library.
+
+Result Variables
+^^^^^^^^^^^^^^^^
+
+This will define the following variables:
+
+``LZO_FOUND``
+ True if the system has the LZO library.
+``LZO_INCLUDE_DIRS``
+ Include directories needed to use LZO.
+``LZO_LIBRARIES``
+ Libraries needed to link to LZO.
+``LZO_VERSION``
+ The version of the LZO library which was found.
+
+Cache Variables
+^^^^^^^^^^^^^^^
+
+The following cache variables may also be set:
+
+``LZO_INCLUDE_DIR``
+ The directory containing ``lzo/lzo1x.h``.
+``LZO_LIBRARY``
+ The path to the LZO library.
+
+#]=======================================================================]
+
+find_package(PkgConfig QUIET)
+pkg_check_modules(PC_LZO QUIET lzo2)
+
+find_path(LZO_INCLUDE_DIR
+ NAMES lzo/lzo1x.h
+ PATHS ${PC_LZO_INCLUDE_DIRS}
+)
+
+find_library(LZO_LIBRARY
+ NAMES lzo2
+ PATHS ${PC_LZO_LIBRARY_DIRS}
+)
+
+# With vcpkg, the library path should contain both 'debug' and 'optimized'
+# entries (see target_link_libraries() documentation for more information)
+#
+# NOTE: we only patch up when using vcpkg; the same issue might happen
+# when not using vcpkg, but this is non-trivial to fix, as we have no idea
+# what the paths are. With vcpkg we do. And we only official support vcpkg
+# with Windows.
+#
+# NOTE: this is based on the assumption that the debug file has the same
+# name as the optimized file. This is not always the case, but so far
+# experiences has shown that in those case vcpkg CMake files do the right
+# thing.
+if (VCPKG_TOOLCHAIN AND LZO_LIBRARY)
+ if (LZO_LIBRARY MATCHES "/debug/")
+ set(LZO_LIBRARY_DEBUG ${LZO_LIBRARY})
+ string(REPLACE "/debug/lib/" "/lib/" LZO_LIBRARY_RELEASE ${LZO_LIBRARY})
+ else()
+ set(LZO_LIBRARY_RELEASE ${LZO_LIBRARY})
+ string(REPLACE "/lib/" "/debug/lib/" LZO_LIBRARY_DEBUG ${LZO_LIBRARY})
+ endif()
+ include(SelectLibraryConfigurations)
+ select_library_configurations(LZO)
+endif()
+
+set(LZO_VERSION ${PC_LZO_VERSION})
+
+include(FindPackageHandleStandardArgs)
+find_package_handle_standard_args(LZO
+ FOUND_VAR LZO_FOUND
+ REQUIRED_VARS
+ LZO_LIBRARY
+ LZO_INCLUDE_DIR
+ VERSION_VAR LZO_VERSION
+)
+
+if (LZO_FOUND)
+ set(LZO_LIBRARIES ${LZO_LIBRARY})
+ set(LZO_INCLUDE_DIRS ${LZO_INCLUDE_DIR})
+endif ()
+
+mark_as_advanced(
+ LZO_INCLUDE_DIR
+ LZO_LIBRARY
+)
diff --git a/cmake/FindSSE.cmake b/cmake/FindSSE.cmake
new file mode 100644
index 000000000..d0a57ccbb
--- /dev/null
+++ b/cmake/FindSSE.cmake
@@ -0,0 +1,17 @@
+# Autodetect if SSE4.1 can be used. If so, the assumption is, so can the other
+# SSE version (SSE 2.0, SSSE 3.0).
+
+include(CheckCXXSourceCompiles)
+set(CMAKE_REQUIRED_FLAGS "")
+
+if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU" OR CMAKE_CXX_COMPILER_ID STREQUAL "Clang" OR CMAKE_CXX_COMPILER_ID STREQUAL "AppleClang")
+ set(CMAKE_REQUIRED_FLAGS "-msse4.1")
+endif (CMAKE_CXX_COMPILER_ID STREQUAL "GNU" OR CMAKE_CXX_COMPILER_ID STREQUAL "Clang" OR CMAKE_CXX_COMPILER_ID STREQUAL "AppleClang")
+
+check_cxx_source_compiles("
+ #include <xmmintrin.h>
+ #include <smmintrin.h>
+ #include <tmmintrin.h>
+ int main() { return 0; }"
+ SSE_FOUND
+)
diff --git a/cmake/FindXDG_basedir.cmake b/cmake/FindXDG_basedir.cmake
new file mode 100644
index 000000000..913b425e2
--- /dev/null
+++ b/cmake/FindXDG_basedir.cmake
@@ -0,0 +1,65 @@
+#[=======================================================================[.rst:
+FindXDG_basedir
+-------
+
+Finds the xdg-basedir library.
+
+Result Variables
+^^^^^^^^^^^^^^^^
+
+This will define the following variables:
+
+``XDG_basedir_FOUND``
+ True if the system has the xdg-basedir library.
+``XDG_basedir_INCLUDE_DIRS``
+ Include directories needed to use xdg-basedir.
+``XDG_basedir_LIBRARIES``
+ Libraries needed to link to xdg-basedir.
+``XDG_basedir_VERSION``
+ The version of the xdg-basedir library which was found.
+
+Cache Variables
+^^^^^^^^^^^^^^^
+
+The following cache variables may also be set:
+
+``XDG_basedir_INCLUDE_DIR``
+ The directory containing ``xdg-basedir.h``.
+``XDG_basedir_LIBRARY``
+ The path to the xdg-basedir library.
+
+#]=======================================================================]
+
+find_package(PkgConfig QUIET)
+pkg_check_modules(PC_XDG_basedir QUIET libxdg-basedir)
+
+find_path(XDG_basedir_INCLUDE_DIR
+ NAMES basedir.h
+ PATHS ${PC_XDG_basedir_INCLUDE_DIRS}
+)
+
+find_library(XDG_basedir_LIBRARY
+ NAMES xdg-basedir
+ PATHS ${PC_XDG_basedir_LIBRARY_DIRS}
+)
+
+set(XDG_basedir_VERSION ${PC_XDG_basedir_VERSION})
+
+include(FindPackageHandleStandardArgs)
+find_package_handle_standard_args(XDG_basedir
+ FOUND_VAR XDG_basedir_FOUND
+ REQUIRED_VARS
+ XDG_basedir_LIBRARY
+ XDG_basedir_INCLUDE_DIR
+ VERSION_VAR XDG_basedir_VERSION
+)
+
+if (XDG_basedir_FOUND)
+ set(XDG_basedir_LIBRARIES ${XDG_basedir_LIBRARY})
+ set(XDG_basedir_INCLUDE_DIRS ${XDG_basedir_INCLUDE_DIR})
+endif ()
+
+mark_as_advanced(
+ XDG_basedir_INCLUDE_DIR
+ XDG_basedir_LIBRARY
+)
diff --git a/cmake/FindXaudio2.cmake b/cmake/FindXaudio2.cmake
new file mode 100644
index 000000000..065e2d358
--- /dev/null
+++ b/cmake/FindXaudio2.cmake
@@ -0,0 +1,18 @@
+# Autodetect if xaudio2 can be used.
+
+include(CheckCXXSourceCompiles)
+set(CMAKE_REQUIRED_FLAGS "")
+
+check_cxx_source_compiles("
+ #include <windows.h>
+
+ #undef NTDDI_VERSION
+ #undef _WIN32_WINNT
+
+ #define NTDDI_VERSION NTDDI_WIN8
+ #define _WIN32_WINNT _WIN32_WINNT_WIN8
+
+ #include <xaudio2.h>
+ int main() { return 0; }"
+ XAUDIO2_FOUND
+)
diff --git a/cmake/LinkPackage.cmake b/cmake/LinkPackage.cmake
new file mode 100644
index 000000000..f64ccfd51
--- /dev/null
+++ b/cmake/LinkPackage.cmake
@@ -0,0 +1,18 @@
+function(link_package NAME)
+ cmake_parse_arguments(LP "ENCOURAGED" "TARGET" "" ${ARGN})
+
+ if (${NAME}_FOUND)
+ string(TOUPPER "${NAME}" UCNAME)
+ add_definitions(-DWITH_${UCNAME})
+ if (LP_TARGET AND TARGET ${LP_TARGET})
+ target_link_libraries(openttd ${LP_TARGET})
+ message(STATUS "${NAME} found -- -DWITH_${UCNAME} -- ${LP_TARGET}")
+ else()
+ include_directories(${${NAME}_INCLUDE_DIRS} ${${NAME}_INCLUDE_DIR})
+ target_link_libraries(openttd ${${NAME}_LIBRARIES} ${${NAME}_LIBRARY})
+ message(STATUS "${NAME} found -- -DWITH_${UCNAME} -- ${${NAME}_INCLUDE_DIRS} ${${NAME}_INCLUDE_DIR} -- ${${NAME}_LIBRARIES} ${${NAME}_LIBRARY}")
+ endif()
+ elseif (LP_ENCOURAGED)
+ message(WARNING "${NAME} not found; compiling OpenTTD without ${NAME} is strongly disencouraged")
+ endif()
+endfunction()
diff --git a/cmake/Options.cmake b/cmake/Options.cmake
new file mode 100644
index 000000000..b292567f0
--- /dev/null
+++ b/cmake/Options.cmake
@@ -0,0 +1,84 @@
+# Set the options for the directories (personal, shared, global).
+#
+# set_directory_options()
+#
+function(set_directory_options)
+ if (APPLE)
+ set(DEFAULT_PERSONAL_DIR "Documents/OpenTTD")
+ set(DEFAULT_SHARED_DIR "/Library/Application Support/OpenTTD")
+ set(DEFAULT_GLOBAL_DIR "(not set)")
+ elseif (WIN32)
+ set(DEFAULT_PERSONAL_DIR "OpenTTD")
+ set(DEFAULT_SHARED_DIR "(not set)")
+ set(DEFAULT_GLOBAL_DIR "(not set)")
+ elseif (UNIX)
+ set(DEFAULT_PERSONAL_DIR ".openttd")
+ set(DEFAULT_SHARED_DIR "(not set)")
+ set(DEFAULT_GLOBAL_DIR "${CMAKE_INSTALL_PREFIX}/share/games/openttd")
+ else ()
+ message(FATAL_ERROR "Unknown OS found; please consider creating a Pull Request to add support for this OS.")
+ endif ()
+
+ if (NOT PERSONAL_DIR)
+ set(PERSONAL_DIR "${DEFAULT_PERSONAL_DIR}" CACHE STRING "Personal directory")
+ message(STATUS "Detecting Personal Data directory - ${PERSONAL_DIR}")
+ endif (NOT PERSONAL_DIR)
+
+ if (NOT SHARED_DIR)
+ set(SHARED_DIR "${DEFAULT_SHARED_DIR}" CACHE STRING "Shared directory")
+ message(STATUS "Detecting Shared Data directory - ${SHARED_DIR}")
+ endif (NOT SHARED_DIR)
+
+ if (NOT GLOBAL_DIR)
+ set(GLOBAL_DIR "${DEFAULT_GLOBAL_DIR}" CACHE STRING "Global directory")
+ message(STATUS "Detecting Global Data directory - ${GLOBAL_DIR}")
+ endif (NOT GLOBAL_DIR)
+endfunction()
+
+# Set some generic options that influence what is being build.
+#
+# set_options()
+#
+function(set_options)
+ if (UNIX AND NOT APPLE)
+ set(DEFAULT_OPTION_INSTALL_FHS YES)
+ else (UNIX AND NOT APPLE)
+ set(DEFAULT_OPTION_INSTALL_FHS NO)
+ endif (UNIX AND NOT APPLE)
+
+ option(OPTION_DEDICATED "Build dedicated server only (no GUI)" NO)
+ option(OPTION_INSTALL_FHS "Install with Filesstem Hierarchy Standard folders" ${DEFAULT_OPTION_INSTALL_FHS})
+ option(OPTION_USE_ASSERTS "Use assertions; leave enabled for nightlies, betas, and RCs" YES)
+ option(OPTION_USE_THREADS "Use threads" YES)
+endfunction()
+
+# Show the values of the generic options.
+#
+# show_options()
+#
+function(show_options)
+ message(STATUS "Option Dedicated - ${OPTION_DEDICATED}")
+ message(STATUS "Option Install FHS - ${OPTION_INSTALL_FHS}")
+ message(STATUS "Option Use assert - ${OPTION_USE_ASSERTS}")
+ message(STATUS "Option Use threads - ${OPTION_USE_THREADS}")
+endfunction()
+
+# Add the definitions for the options that are selected.
+#
+# add_definitions_based_on_options()
+#
+function(add_definitions_based_on_options)
+ if (OPTION_DEDICATED)
+ add_definitions(-DDEDICATED)
+ endif (OPTION_DEDICATED)
+
+ if (NOT OPTION_USE_THREADS)
+ add_definitions(-DNO_THREADS)
+ endif (NOT OPTION_USE_THREADS)
+
+ if (OPTION_USE_ASSERTS)
+ add_definitions(-DWITH_ASSERT)
+ else (OPTION_USE_ASSERTS)
+ add_definitions(-DNDEBUG)
+ endif (OPTION_USE_ASSERTS)
+endfunction()
diff --git a/cmake/SourceList.cmake b/cmake/SourceList.cmake
new file mode 100644
index 000000000..6300a19a4
--- /dev/null
+++ b/cmake/SourceList.cmake
@@ -0,0 +1,63 @@
+# Add a file to be compiled.
+#
+# add_files([file1 ...] CONDITION condition [condition ...])
+#
+# CONDITION is a complete statement that can be evaluated with if().
+# If it evaluates true, the source files will be added; otherwise not.
+# For example: ADD_IF SDL_FOUND AND Allegro_FOUND
+#
+function(add_files)
+ cmake_parse_arguments(PARAM "" "" "CONDITION" ${ARGN})
+ set(PARAM_FILES "${PARAM_UNPARSED_ARGUMENTS}")
+
+ if (PARAM_CONDITION)
+ if (NOT (${PARAM_CONDITION}))
+ return()
+ endif (NOT (${PARAM_CONDITION}))
+ endif (PARAM_CONDITION)
+
+ foreach(FILE IN LISTS PARAM_FILES)
+ target_sources(openttd PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/${FILE})
+ endforeach()
+endfunction(add_files)
+
+# This function works around an 'issue' with CMake, where
+# set_source_files_properties() only works in the scope of the file. We want
+# to set properties for the source file on a more global level. To solve this,
+# this function records the flags you want, and a macro adds them in the root
+# CMakeLists.txt.
+# See this URL for more information on the issue:
+# http://cmake.3232098.n2.nabble.com/scope-of-set-source-files-properties-td4766111.html
+#
+# set_compile_flags([file1 ...] COMPILE_FLAGS cflag [cflag ...])
+#
+function(set_compile_flags)
+ cmake_parse_arguments(PARAM "" "" "COMPILE_FLAGS" ${ARGN})
+ set(PARAM_FILES "${PARAM_UNPARSED_ARGUMENTS}")
+
+ get_property(SOURCE_PROPERTIES GLOBAL PROPERTY source_properties)
+
+ foreach(FILE IN LISTS PARAM_FILES)
+ list(APPEND SOURCE_PROPERTIES "${CMAKE_CURRENT_SOURCE_DIR}/${FILE}::${PARAM_COMPILE_FLAGS}")
+ endforeach()
+
+ set_property(GLOBAL PROPERTY source_properties "${SOURCE_PROPERTIES}")
+endfunction(set_compile_flags)
+
+# Call this macro in the same CMakeLists.txt and after add_executable().
+# This makes sure all the COMPILE_FLAGS of set_compile_flags() are set
+# correctly.
+#
+# process_compile_flags()
+#
+function(process_compile_flags)
+ get_property(SOURCE_PROPERTIES GLOBAL PROPERTY source_properties)
+
+ foreach(ENTRY ${SOURCE_PROPERTIES})
+ string(REPLACE "::" ";" ENTRY "${ENTRY}")
+ list(GET ENTRY 0 FILE)
+ list(GET ENTRY 1 PROPERTIES)
+
+ set_source_files_properties(${FILE} PROPERTIES COMPILE_FLAGS ${PROPERTIES})
+ endforeach()
+endfunction(process_compile_flags)
diff --git a/cmake/Static.cmake b/cmake/Static.cmake
new file mode 100644
index 000000000..7648d05e7
--- /dev/null
+++ b/cmake/Static.cmake
@@ -0,0 +1,14 @@
+# Set static linking if the platform requires it.
+#
+# set_static()
+#
+function(set_static_if_needed)
+ if (MINGW)
+ # Let exectutables run outside MinGW environment
+ # Force searching static libs
+ set(CMAKE_FIND_LIBRARY_SUFFIXES ".a" PARENT_SCOPE)
+
+ # Force static linking
+ link_libraries(-static -static-libgcc -static-libstdc++)
+ endif()
+endfunction()
diff --git a/cmake/scripts/FindVersion.cmake b/cmake/scripts/FindVersion.cmake
new file mode 100644
index 000000000..5edabeb19
--- /dev/null
+++ b/cmake/scripts/FindVersion.cmake
@@ -0,0 +1,134 @@
+cmake_minimum_required(VERSION 3.5)
+
+#
+# Finds the current version of the current folder.
+#
+
+find_package(Git QUIET)
+# ${CMAKE_SOURCE_DIR}/.git may be a directory or a regular file
+if (GIT_FOUND AND EXISTS "${CMAKE_SOURCE_DIR}/.git")
+ # Make sure LC_ALL is set to something desirable
+ set(SAVED_LC_ALL "$ENV{LC_ALL}")
+ set(ENV{LC_ALL} C)
+
+ # Assume the dir is not modified
+ set(REV_MODIFIED 0)
+
+ # Refresh the index to make sure file stat info is in sync, then look for modifications
+ execute_process(COMMAND ${GIT_EXECUTABLE} update-index --refresh
+ WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
+ OUTPUT_QUIET
+ )
+
+ # See if git tree is modified
+ execute_process(COMMAND ${GIT_EXECUTABLE} diff-index HEAD
+ OUTPUT_VARIABLE IS_MODIFIED
+ OUTPUT_STRIP_TRAILING_WHITESPACE
+ WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
+ )
+ if (NOT IS_MODIFIED STREQUAL "")
+ set(REV_MODIFIED 2)
+ endif()
+
+ # Get last commit hash
+ execute_process(COMMAND ${GIT_EXECUTABLE} rev-parse --verify HEAD
+ OUTPUT_VARIABLE FULLHASH
+ OUTPUT_STRIP_TRAILING_WHITESPACE
+ WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
+ ERROR_QUIET
+ )
+ set(REV_HASH "${FULLHASH}")
+
+ string(SUBSTRING "${FULLHASH}" 0 10 SHORTHASH)
+
+ # Get the last commit date
+ execute_process(COMMAND ${GIT_EXECUTABLE} show -s --pretty=format:%ci HEAD
+ OUTPUT_VARIABLE COMMITDATE
+ OUTPUT_STRIP_TRAILING_WHITESPACE
+ WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
+ )
+ string(REGEX REPLACE "([0-9]+)-([0-9]+)-([0-9]+).*" "\\1\\2\\3" COMMITDATE "${COMMITDATE}")
+ set(REV_ISODATE "${COMMITDATE}")
+ string(SUBSTRING REV_ISODATE 1 4 REV_YEAR)
+
+ # Get the branch
+ execute_process(COMMAND ${GIT_EXECUTABLE} symbolic-ref -q HEAD
+ OUTPUT_VARIABLE BRANCH
+ OUTPUT_STRIP_TRAILING_WHITESPACE
+ WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
+ ERROR_QUIET
+ )
+ string(REGEX REPLACE ".*/" "" BRANCH "${BRANCH}")
+
+ # Get the tag
+ execute_process(COMMAND ${GIT_EXECUTABLE} name-rev --name-only --tags --no-undefined HEAD
+ OUTPUT_VARIABLE TAG
+ OUTPUT_STRIP_TRAILING_WHITESPACE
+ WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
+ ERROR_QUIET
+ )
+ string(REGEX REPLACE "\^0$" "" TAG "${TAG}")
+
+ if (REV_MODIFIED EQUAL 0)
+ set(HASHPREFIX "-g")
+ elseif (REV_MODIFIED EQUAL 2)
+ set(HASHPREFIX "-m")
+ else ()
+ set(HASHPREFIX "-u")
+ endif()
+
+ # Set the version string
+ if (NOT TAG STREQUAL "")
+ set(REV_VERSION "${TAG}")
+ set(REV_ISTAG 1)
+
+ string(REGEX REPLACE "^[0-9.]*$" "" STABLETAG "${TAG}")
+ if (NOT STABLETAG STREQUAL "")
+ set(REV_ISSTABLETAG 1)
+ else ()
+ set(REV_ISSTABLETAG 0)
+ endif ()
+ else ()
+ set(REV_VERSION "${REV_ISODATE}-${BRANCH}${HASHPREFIX}${SHORTHASH}")
+ set(REV_ISTAG 0)
+ set(REV_ISSTABLETAG 0)
+ endif ()
+
+ # Restore LC_ALL
+ set(ENV{LC_ALL} "${SAVED_LC_ALL}")
+elseif (EXISTS "${CMAKE_SOURCE_DIR}/.ottdrev")
+ file(READ "${CMAKE_SOURCE_DIR}/.ottdrev" OTTDREV)
+ string(REPLACE "\t" ";" OTTDREV "${OTTDREV}")
+ list(GET OTTDREV 0 REV_VERSION)
+ list(GET OTTDREV 1 REV_ISODATE)
+ list(GET OTTDREV 2 REV_MODIFIED)
+ list(GET OTTDREV 3 REV_HASH)
+ list(GET OTTDREV 4 REV_ISTAG)
+ list(GET OTTDREV 5 REV_ISSTABLETAG)
+ list(GET OTTDREV 6 REV_YEAR)
+else ()
+ message(WARNING "No version detected; this build will NOT be network compatible")
+ set(REV_VERSION "norev0000")
+ set(REV_ISODATE "19700101")
+ set(REV_MODIFIED 1)
+ set(REV_HASH "unknown")
+ set(REV_ISTAG 0)
+ set(REV_ISSTABLETAG 0)
+ set(REV_YEAR "1970")
+endif ()
+
+message(STATUS "Version string: ${REV_VERSION}")
+
+message(STATUS "Generating rev.cpp")
+configure_file("${CMAKE_SOURCE_DIR}/src/rev.cpp.in"
+ "${FIND_VERSION_BINARY_DIR}/rev.cpp")
+
+if (WIN32)
+ message(STATUS "Generating ottdres.rc")
+ configure_file("${CMAKE_SOURCE_DIR}/src/os/windows/ottdres.rc.in"
+ "${FIND_VERSION_BINARY_DIR}/ottdres.rc")
+endif (WIN32)
+
+message(STATUS "Generating CPackProperties.cmake")
+configure_file("${CMAKE_SOURCE_DIR}/CPackProperties.cmake.in"
+ "${CPACK_BINARY_DIR}/CPackProperties.cmake" @ONLY)