summaryrefslogtreecommitdiff
path: root/cmake
diff options
context:
space:
mode:
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)