1 cmake_minimum_required(VERSION 3.9)
4 set(BINARY_NAME openttd)
11 if(CMAKE_SOURCE_DIR STREQUAL CMAKE_BINARY_DIR)
12 message(FATAL_ERROR "In-source builds not allowed. Please run \"cmake ..\" from the build directory. You may need to delete \"${CMAKE_SOURCE_DIR}/CMakeCache.txt\" first.")
15 # Debug mode by default.
16 if(NOT CMAKE_BUILD_TYPE)
17 set(CMAKE_BUILD_TYPE Debug)
21 set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/os/emscripten/cmake")
24 set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake")
25 set(CMAKE_OSX_DEPLOYMENT_TARGET 10.9)
27 # Use GNUInstallDirs to allow customisation
28 # but set our own default data and bin dir
29 if(NOT CMAKE_INSTALL_DATADIR)
30 set(CMAKE_INSTALL_DATADIR "share/games")
32 if(NOT CMAKE_INSTALL_BINDIR)
33 set(CMAKE_INSTALL_BINDIR "games")
35 include(GNUInstallDirs)
39 set_directory_options()
42 set_static_if_needed()
44 set(CMAKE_CXX_STANDARD 17)
45 set(CMAKE_CXX_STANDARD_REQUIRED YES)
46 set(CMAKE_CXX_EXTENSIONS NO)
48 set(CMAKE_EXPORT_COMPILE_COMMANDS YES)
50 # An empty target for the tools
51 add_custom_target(tools)
54 add_endian_definition()
60 add_definitions(-DUNIX)
67 list(APPEND GENERATED_SOURCE_FILES "${CMAKE_BINARY_DIR}/generated/rev.cpp")
69 list(APPEND GENERATED_SOURCE_FILES "${CMAKE_BINARY_DIR}/generated/ottdres.rc")
72 # Generate a target to determine version, which is execute every 'make' run
73 add_custom_target(find_version
75 -DFIND_VERSION_BINARY_DIR=${CMAKE_BINARY_DIR}/generated
76 -DCPACK_BINARY_DIR=${CMAKE_BINARY_DIR}
77 -DREV_MAJOR=${CMAKE_PROJECT_VERSION_MAJOR}
78 -DREV_MINOR=${CMAKE_PROJECT_VERSION_MINOR}
79 -DREV_BUILD=${CMAKE_PROJECT_VERSION_PATCH}
80 -P "${CMAKE_SOURCE_DIR}/cmake/scripts/FindVersion.cmake"
81 WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
82 BYPRODUCTS ${GENERATED_SOURCE_FILES}
86 if(DOXYGEN_EXECUTABLE)
87 add_custom_target(docs)
88 add_custom_target(docs_source
89 ${CMAKE_COMMAND} -E make_directory ${CMAKE_BINARY_DIR}/docs
90 COMMAND ${DOXYGEN_EXECUTABLE} ${CMAKE_BINARY_DIR}/Doxyfile
91 WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
92 COMMENT "Generating documentation for source"
94 add_dependencies(docs_source
102 include(AddCustomXXXTimestamp)
104 if(OPTION_TOOLS_ONLY)
106 unset(HOST_BINARY_DIR CACHE)
108 add_subdirectory(${CMAKE_SOURCE_DIR}/src)
113 # Avoid searching for headers in Frameworks, and libraries in LIBDIR.
114 set(CMAKE_FIND_FRAMEWORK LAST)
117 # Prefer -pthread over -lpthread, which is often the better option of the two.
118 set(CMAKE_THREAD_PREFER_PTHREAD YES)
119 # Make sure we have Threads available.
120 find_package(Threads REQUIRED)
123 find_package(LibLZMA)
127 if(NOT OPTION_DEDICATED)
129 find_package(Allegro)
131 find_package(Freetype)
136 find_package(Fluidsynth)
137 find_package(Fontconfig)
138 find_package(ICU OPTIONAL_COMPONENTS i18n lx)
145 find_library(AUDIOTOOLBOX_LIBRARY AudioToolbox)
146 find_library(AUDIOUNIT_LIBRARY AudioUnit)
147 find_library(COCOA_LIBRARY Cocoa)
148 find_library(QUARTZCORE_LIBRARY QuartzCore)
151 if(NOT EMSCRIPTEN AND NOT OPTION_DEDICATED)
152 find_package(OpenGL COMPONENTS OpenGL)
156 find_package(Editbin REQUIRED)
160 find_package(Xaudio2)
162 find_package(Grfcodec)
164 include(CheckIPOSupported)
165 check_ipo_supported(RESULT IPO_FOUND)
169 if(UNIX AND NOT APPLE AND NOT OPTION_DEDICATED)
170 if(NOT SDL_FOUND AND NOT SDL2_FOUND AND NOT ALLEGRO_FOUND)
171 message(FATAL_ERROR "SDL, SDL2 or Allegro is required for this platform")
175 if(NOT AUDIOTOOLBOX_LIBRARY)
176 message(FATAL_ERROR "AudioToolbox is required for this platform")
178 if(NOT AUDIOUNIT_LIBRARY)
179 message(FATAL_ERROR "AudioUnit is required for this platform")
181 if(NOT COCOA_LIBRARY)
182 message(FATAL_ERROR "Cocoa is required for this platform")
184 if(NOT QUARTZCORE_LIBRARY)
185 message(FATAL_ERROR "QuartzCore is required for this platform")
189 if(OPTION_PACKAGE_DEPENDENCIES)
191 message(FATAL_ERROR "Can only package dependencies on Linux")
193 if(OPTION_INSTALL_FHS)
194 message(FATAL_ERROR "Cannot install in FHS folders when we are packaging dependencies")
196 if(${CMAKE_VERSION} VERSION_LESS "3.16.0")
197 message(FATAL_ERROR "OPTION_PACKAGE_DEPENDENCIES can only work with CMake 3.16+; you are using ${CMAKE_VERSION}")
200 # If we are packaging dependencies, we do two things:
201 # 1) set the RPATH to include $ORIGIN/lib; $ORIGIN (that literal string)
202 # is a Linux indicator for "path where application is". In CMake, we
203 # have to do this before add_executable() is executed.
204 # 2) copy the libraries that we compile against to the "lib" folder.
205 # This is done in InstallAndPackage.cmake.
206 set(CMAKE_INSTALL_RPATH "\$ORIGIN/lib")
207 set(CMAKE_BUILD_WITH_INSTALL_RPATH ON)
213 include_directories(${CMAKE_SOURCE_DIR}/src)
214 # Needed by everything that uses Squirrel
215 include_directories(${CMAKE_SOURCE_DIR}/src/3rdparty/squirrel/include)
219 add_executable(openttd WIN32 ${GENERATED_SOURCE_FILES})
220 set_target_properties(openttd PROPERTIES OUTPUT_NAME "${BINARY_NAME}")
221 # All other files are added via target_sources()
224 # Add DPI manifest to project; other WIN32 targets get this via ottdres.rc
225 target_sources(openttd PRIVATE "${CMAKE_SOURCE_DIR}/os/windows/openttd.manifest")
228 add_subdirectory(${CMAKE_SOURCE_DIR}/bin)
229 add_subdirectory(${CMAKE_SOURCE_DIR}/src)
230 add_subdirectory(${CMAKE_SOURCE_DIR}/media)
232 add_dependencies(openttd
235 target_link_libraries(openttd
245 set_target_properties(openttd PROPERTIES INTERPROCEDURAL_OPTIMIZATION_RELEASE True)
246 set_target_properties(openttd PROPERTIES INTERPROCEDURAL_OPTIMIZATION_MINSIZEREL True)
247 set_target_properties(openttd PROPERTIES INTERPROCEDURAL_OPTIMIZATION_RELWITHDEBINFO True)
249 set_target_properties(openttd PROPERTIES VS_DEBUGGER_WORKING_DIRECTORY "${CMAKE_BINARY_DIR}")
250 process_compile_flags()
253 link_package(PNG TARGET PNG::PNG ENCOURAGED)
254 link_package(ZLIB TARGET ZLIB::ZLIB ENCOURAGED)
255 link_package(LIBLZMA TARGET LibLZMA::LibLZMA ENCOURAGED)
258 if(NOT OPTION_DEDICATED)
259 link_package(Fluidsynth)
261 link_package(SDL2 TARGET SDL2::SDL2)
262 link_package(Allegro)
263 link_package(FREETYPE TARGET Freetype::Freetype)
264 link_package(Fontconfig TARGET Fontconfig::Fontconfig)
266 link_package(ICU_i18n)
268 if(SDL2_FOUND AND OPENGL_FOUND AND UNIX)
269 # SDL2 dynamically loads OpenGL if needed, so do not link to OpenGL when
270 # on Linux. For Windows, we need to link to OpenGL as we also have a win32
272 add_definitions(-DWITH_OPENGL)
273 message(STATUS "OpenGL found -- -DWITH_OPENGL -- (via SDL2)")
275 link_package(OpenGL TARGET OpenGL::GL)
280 link_package(Iconv TARGET Iconv::Iconv)
282 target_link_libraries(openttd
283 ${AUDIOTOOLBOX_LIBRARY}
286 ${QUARTZCORE_LIBRARY}
295 add_library(WASM::WASM INTERFACE IMPORTED)
297 # Allow heap-growth, and start with a bigger memory size.
298 target_link_libraries(WASM::WASM INTERFACE "-s ALLOW_MEMORY_GROWTH=1")
299 target_link_libraries(WASM::WASM INTERFACE "-s INITIAL_MEMORY=33554432")
300 target_link_libraries(WASM::WASM INTERFACE "-s DISABLE_EXCEPTION_CATCHING=0")
301 add_definitions(-s DISABLE_EXCEPTION_CATCHING=0)
303 # Export functions to Javascript.
304 target_link_libraries(WASM::WASM INTERFACE "-s EXPORTED_FUNCTIONS='[\"_main\", \"_em_openttd_add_server\"]' -s EXTRA_EXPORTED_RUNTIME_METHODS='[\"cwrap\"]'")
306 # Preload all the files we generate during build.
307 # As we do not compile with FreeType / FontConfig, we also have no way to
308 # render several languages (like Chinese, ..), so where do you draw the
309 # line what languages to include and which not? In the end, especially as
310 # the more languages you add the slower downloading becomes, we decided to
311 # only ship the English language.
312 target_link_libraries(WASM::WASM INTERFACE "--preload-file ${CMAKE_BINARY_DIR}/baseset@/baseset")
313 target_link_libraries(WASM::WASM INTERFACE "--preload-file ${CMAKE_BINARY_DIR}/lang/english.lng@/lang/english.lng")
314 target_link_libraries(WASM::WASM INTERFACE "--preload-file ${CMAKE_SOURCE_DIR}/bin/ai@/ai")
315 target_link_libraries(WASM::WASM INTERFACE "--preload-file ${CMAKE_SOURCE_DIR}/bin/game@/game")
317 # We use IDBFS for persistent storage.
318 target_link_libraries(WASM::WASM INTERFACE "-lidbfs.js")
320 # Use custom pre-js and shell.html.
321 target_link_libraries(WASM::WASM INTERFACE "--pre-js ${CMAKE_SOURCE_DIR}/os/emscripten/pre.js")
322 target_link_libraries(WASM::WASM INTERFACE "--shell-file ${CMAKE_SOURCE_DIR}/os/emscripten/shell.html")
324 # Build the .html (which builds the .js, .wasm, and .data too).
325 set_target_properties(openttd PROPERTIES SUFFIX ".html")
326 target_link_libraries(openttd WASM::WASM)
329 if(NOT PERSONAL_DIR STREQUAL "(not set)")
332 -DPERSONAL_DIR="${PERSONAL_DIR}"
336 if(NOT SHARED_DIR STREQUAL "(not set)")
339 -DSHARED_DIR="${SHARED_DIR}"
343 if(NOT GLOBAL_DIR STREQUAL "(not set)")
345 -DGLOBAL_DATA_DIR="${GLOBAL_DIR}"
351 add_definitions_based_on_options()
360 target_link_libraries(openttd
367 if(CMAKE_SIZEOF_VOID_P EQUAL 8)
368 add_definitions(-D_SQ64)
371 include(CreateRegression)
378 include(InstallAndPackage)