]> git.lizzy.rs Git - dragonfireclient.git/blob - src/CMakeLists.txt
Fix BSD iconv declaration
[dragonfireclient.git] / src / CMakeLists.txt
1 project(minetest)
2
3 INCLUDE(CheckIncludeFiles)
4 INCLUDE(CheckLibraryExists)
5
6 # Add custom SemiDebug build mode
7 set(CMAKE_CXX_FLAGS_SEMIDEBUG "-O1 -g -Wall" CACHE STRING
8         "Flags used by the C++ compiler during semidebug builds."
9         FORCE
10 )
11 set(CMAKE_C_FLAGS_SEMIDEBUG "-O1 -g -Wall -pedantic" CACHE STRING
12         "Flags used by the C compiler during semidebug builds."
13         FORCE
14 )
15 mark_as_advanced(
16         CMAKE_CXX_FLAGS_SEMIDEBUG
17         CMAKE_C_FLAGS_SEMIDEBUG
18 )
19 set(CMAKE_BUILD_TYPE "${CMAKE_BUILD_TYPE}" CACHE STRING
20         "Choose the type of build. Options are: None Debug SemiDebug RelWithDebInfo MinSizeRel."
21         FORCE
22 )
23
24
25 # Set some random things default to not being visible in the GUI
26 mark_as_advanced(EXECUTABLE_OUTPUT_PATH LIBRARY_OUTPUT_PATH)
27
28
29 if(NOT (BUILD_CLIENT OR BUILD_SERVER))
30         message(WARNING "Neither BUILD_CLIENT nor BUILD_SERVER is set! Setting BUILD_SERVER=true")
31         set(BUILD_SERVER TRUE)
32 endif()
33
34
35 option(ENABLE_CURL "Enable cURL support for fetching media" TRUE)
36 set(USE_CURL FALSE)
37
38 if(ENABLE_CURL)
39         find_package(CURL)
40         if (CURL_FOUND)
41                 message(STATUS "cURL support enabled.")
42                 set(USE_CURL TRUE)
43         endif()
44 else()
45         mark_as_advanced(CLEAR CURL_LIBRARY CURL_INCLUDE_DIR)
46 endif()
47
48 if(NOT USE_CURL)
49         if(BUILD_CLIENT)
50                 message(WARNING "cURL is required to load the server list")
51         endif()
52         if(BUILD_SERVER)
53                 message(WARNING "cURL is required to announce to the server list")
54         endif()
55 endif()
56
57
58 option(ENABLE_GETTEXT "Use GetText for internationalization" ${BUILD_CLIENT})
59 set(USE_GETTEXT FALSE)
60
61 if(ENABLE_GETTEXT)
62         find_package(GettextLib)
63         if(GETTEXTLIB_FOUND)
64                 if(WIN32)
65                         message(STATUS "GetText library: ${GETTEXT_LIBRARY}")
66                         message(STATUS "GetText DLL(s): ${GETTEXT_DLL}")
67                 endif()
68                 set(USE_GETTEXT TRUE)
69                 message(STATUS "GetText enabled; locales found: ${GETTEXT_AVAILABLE_LOCALES}")
70         endif(GETTEXTLIB_FOUND)
71 else()
72         mark_as_advanced(GETTEXT_INCLUDE_DIR GETTEXT_LIBRARY GETTEXT_MSGFMT)
73         message(STATUS "GetText disabled.")
74 endif()
75
76
77 option(ENABLE_SOUND "Enable sound" TRUE)
78 set(USE_SOUND FALSE)
79
80 if(BUILD_CLIENT AND ENABLE_SOUND)
81         # Sound libraries
82         find_package(OpenAL)
83         find_package(Vorbis)
84         if(NOT OPENAL_FOUND)
85                 message(STATUS "Sound enabled, but OpenAL not found!")
86                 mark_as_advanced(CLEAR OPENAL_LIBRARY OPENAL_INCLUDE_DIR)
87         endif()
88         if(NOT VORBIS_FOUND)
89                 message(STATUS "Sound enabled, but Vorbis libraries not found!")
90                 mark_as_advanced(CLEAR OGG_INCLUDE_DIR VORBIS_INCLUDE_DIR OGG_LIBRARY VORBIS_LIBRARY VORBISFILE_LIBRARY)
91         endif()
92         if(OPENAL_FOUND AND VORBIS_FOUND)
93                 set(USE_SOUND TRUE)
94                 message(STATUS "Sound enabled.")
95         else()
96                 message(FATAL_ERROR "Sound enabled, but cannot be used.\n"
97                         "To continue, either fill in the required paths or disable sound. (-DENABLE_SOUND=0)")
98         endif()
99 endif()
100
101 # TODO: this should be removed one day, we can enable it unconditionally
102 option(ENABLE_GLES "Enable extra support code for OpenGL ES" FALSE)
103 mark_as_advanced(ENABLE_GLES)
104
105 option(ENABLE_TOUCH "Enable Touchscreen support" FALSE)
106 if(ENABLE_TOUCH)
107         add_definitions(-DHAVE_TOUCHSCREENGUI)
108 endif()
109
110 if(BUILD_CLIENT)
111         find_package(Freetype REQUIRED)
112 endif()
113
114 option(ENABLE_CURSES "Enable ncurses console" TRUE)
115 set(USE_CURSES FALSE)
116
117 if(ENABLE_CURSES)
118         find_package(Ncursesw)
119         if(CURSES_FOUND)
120                 set(USE_CURSES TRUE)
121                 message(STATUS "ncurses console enabled.")
122                 include_directories(${CURSES_INCLUDE_DIRS})
123         else()
124                 message(STATUS "ncurses not found!")
125         endif()
126 endif(ENABLE_CURSES)
127
128 option(ENABLE_POSTGRESQL "Enable PostgreSQL backend" TRUE)
129 set(USE_POSTGRESQL FALSE)
130
131 if(ENABLE_POSTGRESQL)
132         if(CMAKE_VERSION VERSION_LESS "3.20")
133                 find_package(PostgreSQL QUIET)
134                 # Before CMake 3.20 FindPostgreSQL.cmake always looked for server includes
135                 # but we don't need them, so continue anyway if only those are missing.
136                 if(PostgreSQL_INCLUDE_DIR AND PostgreSQL_LIBRARY)
137                         set(PostgreSQL_FOUND TRUE)
138                         set(PostgreSQL_INCLUDE_DIRS ${PostgreSQL_INCLUDE_DIR})
139                         set(PostgreSQL_LIBRARIES ${PostgreSQL_LIBRARY})
140                 endif()
141         else()
142                 find_package(PostgreSQL)
143         endif()
144
145         if(PostgreSQL_FOUND)
146                 set(USE_POSTGRESQL TRUE)
147                 message(STATUS "PostgreSQL backend enabled")
148                 # This variable is case sensitive, don't try to change it to POSTGRESQL_INCLUDE_DIR
149                 message(STATUS "PostgreSQL includes: ${PostgreSQL_INCLUDE_DIRS}")
150                 include_directories(${PostgreSQL_INCLUDE_DIRS})
151         else()
152                 message(STATUS "PostgreSQL not found!")
153         endif()
154 endif(ENABLE_POSTGRESQL)
155
156 option(ENABLE_LEVELDB "Enable LevelDB backend" TRUE)
157 set(USE_LEVELDB FALSE)
158
159 if(ENABLE_LEVELDB)
160         find_library(LEVELDB_LIBRARY NAMES leveldb libleveldb)
161         find_path(LEVELDB_INCLUDE_DIR db.h PATH_SUFFIXES leveldb)
162         if(LEVELDB_LIBRARY AND LEVELDB_INCLUDE_DIR)
163                 set(USE_LEVELDB TRUE)
164                 message(STATUS "LevelDB backend enabled.")
165                 include_directories(${LEVELDB_INCLUDE_DIR})
166         else()
167                 message(STATUS "LevelDB not found!")
168         endif()
169 endif(ENABLE_LEVELDB)
170
171
172 OPTION(ENABLE_REDIS "Enable Redis backend" TRUE)
173 set(USE_REDIS FALSE)
174
175 if(ENABLE_REDIS)
176         find_library(REDIS_LIBRARY hiredis)
177         find_path(REDIS_INCLUDE_DIR hiredis.h PATH_SUFFIXES hiredis)
178         if(REDIS_LIBRARY AND REDIS_INCLUDE_DIR)
179                 set(USE_REDIS TRUE)
180                 message(STATUS "Redis backend enabled.")
181                 include_directories(${REDIS_INCLUDE_DIR})
182         else(REDIS_LIBRARY AND REDIS_INCLUDE_DIR)
183                 message(STATUS "Redis not found!")
184         endif(REDIS_LIBRARY AND REDIS_INCLUDE_DIR)
185 endif(ENABLE_REDIS)
186
187
188 find_package(SQLite3 REQUIRED)
189
190
191 OPTION(ENABLE_PROMETHEUS "Enable prometheus client support" FALSE)
192 set(USE_PROMETHEUS FALSE)
193
194 if(ENABLE_PROMETHEUS)
195         find_path(PROMETHEUS_CPP_INCLUDE_DIR NAMES prometheus/counter.h)
196         find_library(PROMETHEUS_PULL_LIBRARY NAMES prometheus-cpp-pull)
197         find_library(PROMETHEUS_CORE_LIBRARY NAMES prometheus-cpp-core)
198         if(PROMETHEUS_CPP_INCLUDE_DIR AND PROMETHEUS_PULL_LIBRARY AND PROMETHEUS_CORE_LIBRARY)
199                 set(PROMETHEUS_LIBRARIES ${PROMETHEUS_PULL_LIBRARY} ${PROMETHEUS_CORE_LIBRARY})
200                 set(USE_PROMETHEUS TRUE)
201                 include_directories(${PROMETHEUS_CPP_INCLUDE_DIR})
202         endif(PROMETHEUS_CPP_INCLUDE_DIR AND PROMETHEUS_PULL_LIBRARY AND PROMETHEUS_CORE_LIBRARY)
203 endif(ENABLE_PROMETHEUS)
204
205 if(USE_PROMETHEUS)
206         message(STATUS "Prometheus client enabled.")
207 else(USE_PROMETHEUS)
208         message(STATUS "Prometheus client disabled.")
209 endif(USE_PROMETHEUS)
210
211 OPTION(ENABLE_SPATIAL "Enable SpatialIndex AreaStore backend" TRUE)
212 set(USE_SPATIAL FALSE)
213
214 if(ENABLE_SPATIAL)
215         find_library(SPATIAL_LIBRARY spatialindex)
216         find_path(SPATIAL_INCLUDE_DIR spatialindex/SpatialIndex.h)
217         if(SPATIAL_LIBRARY AND SPATIAL_INCLUDE_DIR)
218                 set(USE_SPATIAL TRUE)
219                 message(STATUS "SpatialIndex AreaStore backend enabled.")
220                 include_directories(${SPATIAL_INCLUDE_DIR})
221         else(SPATIAL_LIBRARY AND SPATIAL_INCLUDE_DIR)
222                 message(STATUS "SpatialIndex not found!")
223         endif(SPATIAL_LIBRARY AND SPATIAL_INCLUDE_DIR)
224 endif(ENABLE_SPATIAL)
225
226
227 find_package(ZLIB REQUIRED)
228 find_package(Zstd REQUIRED)
229
230
231 if(NOT MSVC)
232         set(USE_GPROF FALSE CACHE BOOL "Use -pg flag for g++")
233 endif()
234
235 # Haiku endian support
236 if(HAIKU)
237         set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -D_BSD_SOURCE")
238         set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -D_BSD_SOURCE")
239 endif()
240
241 # Use cmake_config.h
242 add_definitions(-DUSE_CMAKE_CONFIG_H)
243
244 if(WIN32)
245         # Windows
246         if(MSVC) # MSVC Specifics
247                 set(PLATFORM_LIBS dbghelp.lib ${PLATFORM_LIBS})
248                 # Surpress some useless warnings
249                 add_definitions ( /D "_CRT_SECURE_NO_DEPRECATE" /W1 )
250                 # Get M_PI to work
251                 add_definitions(/D "_USE_MATH_DEFINES")
252                 # Dont define min/max macros in minwindef.h
253                 add_definitions(/D "NOMINMAX")
254         else() # Probably MinGW = GCC
255                 set(PLATFORM_LIBS "")
256         endif()
257         set(PLATFORM_LIBS ws2_32.lib version.lib shlwapi.lib winmm.lib ${PLATFORM_LIBS})
258
259         set(EXTRA_DLL "" CACHE FILEPATH "Optional paths to additional DLLs that should be packaged")
260
261         # DLLs are automatically copied to the output directory by vcpkg when VCPKG_APPLOCAL_DEPS=ON
262         if(NOT VCPKG_APPLOCAL_DEPS)
263                 set(ZLIB_DLL "" CACHE FILEPATH "Path to Zlib DLL for installation (optional)")
264                 set(ZSTD_DLL "" CACHE FILEPATH "Path to Zstd DLL for installation (optional)")
265                 if(ENABLE_SOUND)
266                         set(OPENAL_DLL "" CACHE FILEPATH "Path to OpenAL32.dll for installation (optional)")
267                         set(OGG_DLL "" CACHE FILEPATH "Path to libogg.dll for installation (optional)")
268                         set(VORBIS_DLL "" CACHE FILEPATH "Path to Vorbis DLLs for installation (optional)")
269                 endif()
270                 if(USE_GETTEXT)
271                         set(GETTEXT_DLL "" CACHE FILEPATH "Path to Intl/Iconv DLLs for installation (optional)")
272                 endif()
273                 if(USE_LUAJIT)
274                         set(LUA_DLL "" CACHE FILEPATH "Path to luajit-5.1.dll for installation (optional)")
275                 endif()
276         endif()
277 else()
278         # Unix probably
279         if(BUILD_CLIENT)
280                 if(NOT HAIKU AND NOT APPLE)
281                         find_package(X11 REQUIRED)
282                 endif(NOT HAIKU AND NOT APPLE)
283         endif()
284
285         set(PLATFORM_LIBS -lpthread ${CMAKE_DL_LIBS})
286         if(APPLE)
287                 set(PLATFORM_LIBS "-framework CoreFoundation" ${PLATFORM_LIBS})
288         else()
289                 check_library_exists(rt clock_gettime "" HAVE_LIBRT)
290                 if (HAVE_LIBRT)
291                         set(PLATFORM_LIBS -lrt ${PLATFORM_LIBS})
292                 endif(HAVE_LIBRT)
293         endif(APPLE)
294
295         # Prefer local iconv if installed
296         find_library(ICONV_LIBRARY iconv)
297         mark_as_advanced(ICONV_LIBRARY)
298         if (ICONV_LIBRARY)
299                 set(PLATFORM_LIBS ${PLATFORM_LIBS} ${ICONV_LIBRARY})
300         endif()
301         if (HAIKU)
302                 set(PLATFORM_LIBS ${PLATFORM_LIBS} intl network)
303         endif()
304
305 endif()
306
307 check_include_files(endian.h HAVE_ENDIAN_H)
308
309 configure_file(
310         "${PROJECT_SOURCE_DIR}/cmake_config.h.in"
311         "${PROJECT_BINARY_DIR}/cmake_config.h"
312 )
313
314
315 # Add a target that always rebuilds cmake_config_githash.h
316 add_custom_target(GenerateVersion
317         COMMAND ${CMAKE_COMMAND}
318         -D "GENERATE_VERSION_SOURCE_DIR=${CMAKE_CURRENT_SOURCE_DIR}"
319         -D "GENERATE_VERSION_BINARY_DIR=${CMAKE_CURRENT_BINARY_DIR}"
320         -D "VERSION_STRING=${VERSION_STRING}"
321         -D "DEVELOPMENT_BUILD=${DEVELOPMENT_BUILD}"
322         -P "${CMAKE_SOURCE_DIR}/cmake/Modules/GenerateVersion.cmake"
323         WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}")
324
325
326 add_subdirectory(threading)
327 add_subdirectory(content)
328 add_subdirectory(database)
329 add_subdirectory(gui)
330 add_subdirectory(mapgen)
331 add_subdirectory(network)
332 add_subdirectory(script)
333 add_subdirectory(unittest)
334 add_subdirectory(benchmark)
335 add_subdirectory(util)
336 add_subdirectory(irrlicht_changes)
337 add_subdirectory(server)
338
339 set(common_SRCS
340         ${database_SRCS}
341         ${mapgen_SRCS}
342         ${server_SRCS}
343         ${content_SRCS}
344         ban.cpp
345         chat.cpp
346         clientiface.cpp
347         collision.cpp
348         content_mapnode.cpp
349         content_nodemeta.cpp
350         convert_json.cpp
351         craftdef.cpp
352         debug.cpp
353         defaultsettings.cpp
354         emerge.cpp
355         environment.cpp
356         face_position_cache.cpp
357         filesys.cpp
358         gettext.cpp
359         httpfetch.cpp
360         hud.cpp
361         inventory.cpp
362         inventorymanager.cpp
363         itemdef.cpp
364         itemstackmetadata.cpp
365         light.cpp
366         log.cpp
367         main.cpp
368         map.cpp
369         map_settings_manager.cpp
370         mapblock.cpp
371         mapnode.cpp
372         mapsector.cpp
373         metadata.cpp
374         modchannels.cpp
375         nameidmapping.cpp
376         nodedef.cpp
377         nodemetadata.cpp
378         nodetimer.cpp
379         noise.cpp
380         objdef.cpp
381         object_properties.cpp
382         particles.cpp
383         pathfinder.cpp
384         player.cpp
385         porting.cpp
386         profiler.cpp
387         raycast.cpp
388         reflowscan.cpp
389         remoteplayer.cpp
390         rollback.cpp
391         rollback_interface.cpp
392         serialization.cpp
393         server.cpp
394         serverenvironment.cpp
395         serverlist.cpp
396         settings.cpp
397         staticobject.cpp
398         terminal_chat_console.cpp
399         texture_override.cpp
400         tileanimation.cpp
401         tool.cpp
402         translation.cpp
403         version.cpp
404         voxel.cpp
405         voxelalgorithms.cpp
406         hud.cpp
407         ${common_network_SRCS}
408         ${JTHREAD_SRCS}
409         ${common_SCRIPT_SRCS}
410         ${UTIL_SRCS}
411 )
412
413 if(BUILD_UNITTESTS)
414         set(common_SRCS ${common_SRCS} ${UNITTEST_SRCS})
415 endif()
416
417 if(BUILD_BENCHMARKS)
418         set(common_SRCS ${common_SRCS} ${BENCHMARK_SRCS})
419 endif()
420
421 # This gives us the icon and file version information
422 if(WIN32)
423         set(WINRESOURCE_FILE "${CMAKE_CURRENT_SOURCE_DIR}/../misc/winresource.rc")
424         set(MINETEST_EXE_MANIFEST_FILE "${CMAKE_CURRENT_SOURCE_DIR}/../misc/minetest.exe.manifest")
425         if(MINGW)
426                 if(NOT CMAKE_RC_COMPILER)
427                         set(CMAKE_RC_COMPILER "windres.exe")
428                 endif()
429                 ADD_CUSTOM_COMMAND(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/winresource_rc.o
430                         COMMAND ${CMAKE_RC_COMPILER} -I${CMAKE_CURRENT_SOURCE_DIR} -I${CMAKE_CURRENT_BINARY_DIR}
431                         -i${WINRESOURCE_FILE}
432                         -o ${CMAKE_CURRENT_BINARY_DIR}/winresource_rc.o
433                         WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
434                         DEPENDS ${WINRESOURCE_FILE} ${MINETEST_EXE_MANIFEST_FILE})
435                 SET(extra_windows_SRCS ${CMAKE_CURRENT_BINARY_DIR}/winresource_rc.o)
436         else(MINGW) # Probably MSVC
437                 set(extra_windows_SRCS ${WINRESOURCE_FILE} ${MINETEST_EXE_MANIFEST_FILE})
438         endif(MINGW)
439 endif()
440
441
442 # Client sources
443 if (BUILD_CLIENT)
444         add_subdirectory(client)
445 endif(BUILD_CLIENT)
446
447 set(client_SRCS
448         ${client_SRCS}
449         ${common_SRCS}
450         ${gui_SRCS}
451         ${client_network_SRCS}
452         ${client_irrlicht_changes_SRCS}
453         ${client_SCRIPT_SRCS}
454 )
455
456 if(BUILD_UNITTESTS)
457         set(client_SRCS ${client_SRCS} ${UNITTEST_CLIENT_SRCS})
458 endif()
459
460 if(BUILD_BENCHMARKS)
461         set(client_SRCS ${client_SRCS} ${BENCHMARK_CLIENT_SRCS})
462 endif()
463
464 list(SORT client_SRCS)
465
466 # Server sources
467 set(server_SRCS
468         ${common_SRCS}
469 )
470 list(SORT server_SRCS)
471
472 # Avoid source_group on broken CMake version.
473 # see issue #7074 #7075
474 if (CMAKE_VERSION VERSION_GREATER 3.8.1)
475         source_group(TREE ${PROJECT_SOURCE_DIR} PREFIX "Source Files" FILES ${client_SRCS})
476         source_group(TREE ${PROJECT_SOURCE_DIR} PREFIX "Source Files" FILES ${server_SRCS})
477 endif()
478
479 include_directories(
480         ${PROJECT_BINARY_DIR}
481         ${PROJECT_SOURCE_DIR}
482         ${PROJECT_SOURCE_DIR}/script
483 )
484 include_directories(SYSTEM
485         ${ZLIB_INCLUDE_DIR}
486         ${ZSTD_INCLUDE_DIR}
487         ${SQLITE3_INCLUDE_DIR}
488         ${LUA_INCLUDE_DIR}
489         ${GMP_INCLUDE_DIR}
490         ${JSON_INCLUDE_DIR}
491         ${LUA_BIT_INCLUDE_DIR}
492 )
493
494 if(USE_GETTEXT)
495         include_directories(${GETTEXT_INCLUDE_DIR})
496 endif()
497
498 if(BUILD_CLIENT)
499         include_directories(SYSTEM
500                 ${FREETYPE_INCLUDE_DIRS}
501                 ${SOUND_INCLUDE_DIRS}
502                 ${X11_INCLUDE_DIR}
503         )
504 endif()
505
506 if(USE_CURL)
507         include_directories(${CURL_INCLUDE_DIR})
508 endif()
509
510
511 # When cross-compiling assume the user doesn't want to run the executable anyway,
512 # otherwise place it in <source dir>/bin/ since Minetest can only run from there.
513 if(NOT CMAKE_CROSSCOMPILING)
514         set(EXECUTABLE_OUTPUT_PATH "${CMAKE_SOURCE_DIR}/bin")
515 endif()
516
517 if(BUILD_CLIENT)
518         add_executable(${PROJECT_NAME} ${client_SRCS} ${extra_windows_SRCS})
519         add_dependencies(${PROJECT_NAME} GenerateVersion)
520         target_link_libraries(
521                 ${PROJECT_NAME}
522                 ${ZLIB_LIBRARIES}
523                 IrrlichtMt::IrrlichtMt
524                 ${ZSTD_LIBRARY}
525                 ${X11_LIBRARIES}
526                 ${SOUND_LIBRARIES}
527                 ${SQLITE3_LIBRARY}
528                 ${LUA_LIBRARY}
529                 ${GMP_LIBRARY}
530                 ${JSON_LIBRARY}
531                 ${LUA_BIT_LIBRARY}
532                 ${FREETYPE_LIBRARY}
533                 ${PLATFORM_LIBS}
534         )
535         if(NOT USE_LUAJIT)
536                 set_target_properties(${PROJECT_NAME} PROPERTIES
537                         # This is necessary for dynamic Lua modules
538                         # to work when Lua is statically linked (issue #10806)
539                         ENABLE_EXPORTS 1
540                 )
541         endif()
542
543         if(USE_GETTEXT)
544                 target_link_libraries(
545                         ${PROJECT_NAME}
546                         ${GETTEXT_LIBRARY}
547                 )
548         endif()
549         if(USE_CURL)
550                 target_link_libraries(
551                         ${PROJECT_NAME}
552                         ${CURL_LIBRARY}
553                 )
554         endif()
555         if(FREETYPE_PKGCONFIG_FOUND)
556                 set_target_properties(${PROJECT_NAME}
557                         PROPERTIES
558                         COMPILE_FLAGS "${FREETYPE_CFLAGS_STR}"
559         )
560         endif()
561         if (USE_CURSES)
562                 target_link_libraries(${PROJECT_NAME} ${CURSES_LIBRARIES})
563         endif()
564         if (USE_POSTGRESQL)
565                 target_link_libraries(${PROJECT_NAME} ${PostgreSQL_LIBRARIES})
566         endif()
567         if (USE_LEVELDB)
568                 target_link_libraries(${PROJECT_NAME} ${LEVELDB_LIBRARY})
569         endif()
570         if (USE_REDIS)
571                 target_link_libraries(${PROJECT_NAME} ${REDIS_LIBRARY})
572         endif()
573         if (USE_PROMETHEUS)
574                 target_link_libraries(${PROJECT_NAME} ${PROMETHEUS_LIBRARIES})
575         endif()
576         if (USE_SPATIAL)
577                 target_link_libraries(${PROJECT_NAME} ${SPATIAL_LIBRARY})
578         endif()
579         if(BUILD_BENCHMARKS)
580                 target_link_libraries(${PROJECT_NAME} catch2)
581         endif()
582 endif(BUILD_CLIENT)
583
584
585 if(BUILD_SERVER)
586         add_executable(${PROJECT_NAME}server ${server_SRCS} ${extra_windows_SRCS})
587         add_dependencies(${PROJECT_NAME}server GenerateVersion)
588
589         get_target_property(
590                 IRRLICHT_INCLUDES IrrlichtMt::IrrlichtMt INTERFACE_INCLUDE_DIRECTORIES)
591         # Doesn't work without PRIVATE/PUBLIC/INTERFACE mode specified.
592         target_include_directories(${PROJECT_NAME}server PRIVATE ${IRRLICHT_INCLUDES})
593         target_link_libraries(
594                 ${PROJECT_NAME}server
595                 ${ZLIB_LIBRARIES}
596                 ${ZSTD_LIBRARY}
597                 ${SQLITE3_LIBRARY}
598                 ${JSON_LIBRARY}
599                 ${LUA_LIBRARY}
600                 ${LUA_BIT_LIBRARY}
601                 ${GMP_LIBRARY}
602                 ${PLATFORM_LIBS}
603         )
604         set_target_properties(${PROJECT_NAME}server PROPERTIES
605                 COMPILE_DEFINITIONS "SERVER")
606         if(NOT USE_LUAJIT)
607                 set_target_properties(${PROJECT_NAME}server PROPERTIES
608                         # This is necessary for dynamic Lua modules
609                         # to work when Lua is statically linked (issue #10806)
610                         ENABLE_EXPORTS 1
611                 )
612         endif()
613
614         if (USE_GETTEXT)
615                 target_link_libraries(${PROJECT_NAME}server ${GETTEXT_LIBRARY})
616         endif()
617         if (USE_CURSES)
618                 target_link_libraries(${PROJECT_NAME}server ${CURSES_LIBRARIES})
619         endif()
620         if (USE_POSTGRESQL)
621                 target_link_libraries(${PROJECT_NAME}server ${PostgreSQL_LIBRARIES})
622         endif()
623         if (USE_LEVELDB)
624                 target_link_libraries(${PROJECT_NAME}server ${LEVELDB_LIBRARY})
625         endif()
626         if (USE_REDIS)
627                 target_link_libraries(${PROJECT_NAME}server ${REDIS_LIBRARY})
628         endif()
629         if (USE_PROMETHEUS)
630                 target_link_libraries(${PROJECT_NAME}server ${PROMETHEUS_LIBRARIES})
631         endif()
632         if (USE_SPATIAL)
633                 target_link_libraries(${PROJECT_NAME}server ${SPATIAL_LIBRARY})
634         endif()
635         if(USE_CURL)
636                 target_link_libraries(
637                         ${PROJECT_NAME}server
638                         ${CURL_LIBRARY}
639                 )
640         endif()
641         if(BUILD_BENCHMARKS)
642                 target_link_libraries(${PROJECT_NAME}server catch2)
643         endif()
644 endif(BUILD_SERVER)
645
646 # Blacklisted locales that don't work.
647 # see issue #4638
648 set(GETTEXT_BLACKLISTED_LOCALES
649         ar
650         dv
651         he
652         hi
653         kn
654         ms_Arab
655         th
656 )
657
658 option(APPLY_LOCALE_BLACKLIST "Use a blacklist to avoid known broken locales" TRUE)
659
660 if (GETTEXTLIB_FOUND AND APPLY_LOCALE_BLACKLIST)
661         set(GETTEXT_USED_LOCALES "")
662         foreach(LOCALE ${GETTEXT_AVAILABLE_LOCALES})
663                 if (NOT "${LOCALE}" IN_LIST GETTEXT_BLACKLISTED_LOCALES)
664                         list(APPEND GETTEXT_USED_LOCALES ${LOCALE})
665                 endif()
666         endforeach()
667         message(STATUS "Locale blacklist applied; Locales used: ${GETTEXT_USED_LOCALES}")
668 elseif (GETTEXTLIB_FOUND)
669         set(GETTEXT_USED_LOCALES ${GETTEXT_AVAILABLE_LOCALES})
670 endif()
671
672 # Set some optimizations and tweaks
673
674 include(CheckCSourceCompiles)
675
676 if(MSVC)
677         # Visual Studio
678         set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /D WIN32_LEAN_AND_MEAN")
679         # EHa enables SEH exceptions (used for catching segfaults)
680         set(CMAKE_CXX_FLAGS_RELEASE "/EHa /Ox /MD /GS- /Zi /fp:fast /D NDEBUG /D _HAS_ITERATOR_DEBUGGING=0")
681         if(CMAKE_SIZEOF_VOID_P EQUAL 4)
682                 set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /arch:SSE")
683         endif()
684
685         set(CMAKE_EXE_LINKER_FLAGS_RELEASE "/INCREMENTAL:NO /DEBUG /OPT:REF /OPT:ICF /SUBSYSTEM:WINDOWS /ENTRY:mainCRTStartup")
686
687         set(CMAKE_CXX_FLAGS_SEMIDEBUG "/MDd /Zi /Ob0 /O1 /RTC1")
688
689         # Debug build doesn't catch exceptions by itself
690         # Add some optimizations because otherwise it's VERY slow
691         set(CMAKE_CXX_FLAGS_DEBUG "/MDd /Zi /Ob0 /Od /RTC1")
692
693         # Flags for C files (sqlite)
694         # /MD = dynamically link to MSVCRxxx.dll
695         set(CMAKE_C_FLAGS_RELEASE "/O2 /Ob2 /MD")
696
697         # Flags that cannot be shared between cl and clang-cl
698         # https://clang.llvm.org/docs/UsersManual.html#clang-cl
699         if(CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
700                 set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fuse-ld=lld")
701
702                 # Disable pragma-pack warning
703                 set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -Wno-pragma-pack")
704         else()
705                 set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /MP")
706                 set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /TP /FD /GL")
707                 set(CMAKE_EXE_LINKER_FLAGS_RELEASE "${CMAKE_EXE_LINKER_FLAGS_RELEASE} /LTCG")
708         endif()
709 else()
710         # GCC or compatible compilers such as Clang
711         set(WARNING_FLAGS "-Wall -Wextra")
712         set(WARNING_FLAGS "${WARNING_FLAGS} -Wno-unused-parameter -Wno-implicit-fallthrough")
713         if(WARN_ALL)
714                 set(RELEASE_WARNING_FLAGS "${WARNING_FLAGS}")
715         else()
716                 set(RELEASE_WARNING_FLAGS "")
717         endif()
718
719         if(APPLE AND USE_LUAJIT)
720                 # required per http://luajit.org/install.html
721                 SET(CMAKE_EXE_LINKER_FLAGS  "${CMAKE_EXE_LINKER_FLAGS} -pagezero_size 10000 -image_base 100000000")
722         elseif(UNIX AND USE_LUAJIT)
723                 check_c_source_compiles("#ifndef __aarch64__\n#error\n#endif\nint main(){}" IS_AARCH64)
724                 if(IS_AARCH64)
725                         # Move text segment below LuaJIT's 47-bit limit (see issue #9367)
726                         if(CMAKE_SYSTEM_NAME MATCHES "FreeBSD")
727                                 # FreeBSD uses lld, and lld does not support -Ttext-segment, suggesting
728                                 # --image-base instead. Not sure if it's equivalent change for the purpose
729                                 # but at least if fixes build on FreeBSD/aarch64
730                                 # XXX: the condition should also be changed to check for lld regardless of
731                                 # os, bit CMake doesn't have anything like CMAKE_LINKER_IS_LLD yet
732                                 SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,--image-base=0x200000000")
733                         else()
734                                 SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,-Ttext-segment=0x200000000")
735                         endif()
736                 endif()
737         endif()
738
739         if(MINGW)
740                 set(OTHER_FLAGS "${OTHER_FLAGS} -mthreads -fexceptions")
741                 set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DWIN32_LEAN_AND_MEAN")
742         endif()
743
744         # Use a safe subset of flags to speed up math calculations:
745         # - we don't need errno or math exceptions
746         # - we don't deal with Inf/NaN or signed zero
747         set(MATH_FLAGS "-fno-math-errno -fno-trapping-math -ffinite-math-only -fno-signed-zeros")
748
749         # Enable SSE for floating point math on 32-bit x86 by default
750         # reasoning see minetest issue #11810 and https://gcc.gnu.org/wiki/FloatingPointMath
751         if(CMAKE_SIZEOF_VOID_P EQUAL 4)
752                 check_c_source_compiles("#ifndef __i686__\n#error\n#endif\nint main(){}" IS_I686)
753                 if(IS_I686)
754                         message(STATUS "Detected Intel x86: using SSE instead of x87 FPU")
755                         set(OTHER_FLAGS "${OTHER_FLAGS} -mfpmath=sse -msse")
756                 endif()
757         endif()
758
759         set(CMAKE_CXX_FLAGS_RELEASE "-DNDEBUG ${RELEASE_WARNING_FLAGS} ${OTHER_FLAGS} -pipe -funroll-loops")
760         if(CMAKE_SYSTEM_NAME MATCHES "(Darwin|BSD|DragonFly)")
761                 set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -Os")
762         else()
763                 set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -O3 -fomit-frame-pointer")
764                 if(CMAKE_SYSTEM_NAME STREQUAL "Linux"
765                                 AND CMAKE_CXX_COMPILER_ID STREQUAL "Clang"
766                                 AND CMAKE_CXX_COMPILER_VERSION MATCHES "^9\\.")
767                         # Clang 9 has broken -ffast-math on glibc
768                 else()
769                         set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} ${MATH_FLAGS}")
770                 endif()
771         endif()
772         set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELEASE} -g")
773         set(CMAKE_CXX_FLAGS_SEMIDEBUG "-g -O1 ${WARNING_FLAGS} ${OTHER_FLAGS}")
774         set(CMAKE_CXX_FLAGS_DEBUG "-g -O0 ${WARNING_FLAGS} ${OTHER_FLAGS}")
775
776         if(USE_GPROF)
777                 set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -pg")
778         endif()
779
780         if(MINGW)
781                 set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -mwindows")
782         endif()
783 endif()
784
785
786 # Installation
787
788 if(WIN32)
789         if(EXTRA_DLL)
790                 install(FILES ${EXTRA_DLL} DESTINATION ${BINDIR})
791         endif()
792         if(VCPKG_APPLOCAL_DEPS)
793                 # Collect the dll's from the output path
794                 install(DIRECTORY ${EXECUTABLE_OUTPUT_PATH}/Release/
795                                 DESTINATION ${BINDIR}
796                                 CONFIGURATIONS Release
797                                 FILES_MATCHING PATTERN "*.dll")
798                 install(DIRECTORY ${EXECUTABLE_OUTPUT_PATH}/Debug/
799                                 DESTINATION ${BINDIR}
800                                 CONFIGURATIONS Debug
801                                 FILES_MATCHING PATTERN "*.dll")
802                 install(DIRECTORY ${EXECUTABLE_OUTPUT_PATH}/RelWithDebInfo/
803                                 DESTINATION ${BINDIR}
804                                 CONFIGURATIONS RelWithDebInfo
805                                 FILES_MATCHING PATTERN "*.dll")
806                 install(DIRECTORY ${EXECUTABLE_OUTPUT_PATH}/MinSizeRel/
807                                 DESTINATION ${BINDIR}
808                                 CONFIGURATIONS MinSizeRel
809                                 FILES_MATCHING PATTERN "*.dll")
810         else()
811                 # Use the old-style way to install dll's
812                 if(BUILD_CLIENT AND USE_SOUND)
813                         if(OPENAL_DLL)
814                                 install(FILES ${OPENAL_DLL} DESTINATION ${BINDIR})
815                         endif()
816                         if(OGG_DLL)
817                                 install(FILES ${OGG_DLL} DESTINATION ${BINDIR})
818                         endif()
819                         if(VORBIS_DLL)
820                                 install(FILES ${VORBIS_DLL} DESTINATION ${BINDIR})
821                         endif()
822                 endif()
823                 if(CURL_DLL)
824                         install(FILES ${CURL_DLL} DESTINATION ${BINDIR})
825                 endif()
826                 if(ZLIB_DLL)
827                         install(FILES ${ZLIB_DLL} DESTINATION ${BINDIR})
828                 endif()
829                 if(ZSTD_DLL)
830                         install(FILES ${ZSTD_DLL} DESTINATION ${BINDIR})
831                 endif()
832                 if(BUILD_CLIENT AND FREETYPE_DLL)
833                         install(FILES ${FREETYPE_DLL} DESTINATION ${BINDIR})
834                 endif()
835                 if(SQLITE3_DLL)
836                         install(FILES ${SQLITE3_DLL} DESTINATION ${BINDIR})
837                 endif()
838                 if(LEVELDB_DLL)
839                         install(FILES ${LEVELDB_DLL} DESTINATION ${BINDIR})
840                 endif()
841                 if(LUA_DLL)
842                         install(FILES ${LUA_DLL} DESTINATION ${BINDIR})
843                 endif()
844                 if(BUILD_CLIENT AND USE_GETTEXT AND GETTEXT_DLL)
845                         install(FILES ${GETTEXT_DLL} DESTINATION ${BINDIR})
846                 endif()
847         endif()
848
849         if(BUILD_CLIENT AND IRRLICHT_DLL)
850                 install(FILES ${IRRLICHT_DLL} DESTINATION ${BINDIR})
851         endif()
852 endif()
853
854 if(BUILD_CLIENT)
855         install(TARGETS ${PROJECT_NAME}
856                 RUNTIME DESTINATION ${BINDIR}
857                 LIBRARY DESTINATION ${BINDIR}
858                 ARCHIVE DESTINATION ${BINDIR}
859                 BUNDLE DESTINATION .
860         )
861
862         if(APPLE)
863                 install(CODE "
864                         set(BU_CHMOD_BUNDLE_ITEMS ON)
865                         include(BundleUtilities)
866                         fixup_bundle(\"\${CMAKE_INSTALL_PREFIX}/${BUNDLE_PATH}\" \"\" \"\${CMAKE_INSTALL_PREFIX}/${BINDIR}\")
867                 " COMPONENT Runtime)
868         endif()
869
870         if(USE_GETTEXT)
871                 foreach(LOCALE ${GETTEXT_USED_LOCALES})
872                         set_mo_paths(MO_BUILD_PATH MO_DEST_PATH ${LOCALE})
873                         set(MO_BUILD_PATH "${MO_BUILD_PATH}/${PROJECT_NAME}.mo")
874                         install(FILES ${MO_BUILD_PATH} DESTINATION ${MO_DEST_PATH})
875                 endforeach()
876         endif()
877
878         install(DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/../fonts" DESTINATION "${SHAREDIR}"
879                         FILES_MATCHING PATTERN "*.ttf" PATTERN "*.txt")
880 endif(BUILD_CLIENT)
881
882 if(BUILD_SERVER)
883         install(TARGETS ${PROJECT_NAME}server DESTINATION ${BINDIR})
884 endif()
885
886 if (USE_GETTEXT)
887         set(MO_FILES)
888
889         foreach(LOCALE ${GETTEXT_USED_LOCALES})
890                 set(PO_FILE_PATH "${GETTEXT_PO_PATH}/${LOCALE}/${PROJECT_NAME}.po")
891                 set_mo_paths(MO_BUILD_PATH MO_DEST_PATH ${LOCALE})
892                 set(MO_FILE_PATH "${MO_BUILD_PATH}/${PROJECT_NAME}.mo")
893
894                 add_custom_command(OUTPUT ${MO_BUILD_PATH}
895                         COMMAND ${CMAKE_COMMAND} -E make_directory ${MO_BUILD_PATH}
896                         COMMENT "mo-update [${LOCALE}]: Creating locale directory.")
897
898                 add_custom_command(
899                         OUTPUT ${MO_FILE_PATH}
900                         COMMAND ${GETTEXT_MSGFMT} -o ${MO_FILE_PATH} ${PO_FILE_PATH}
901                         DEPENDS ${MO_BUILD_PATH} ${PO_FILE_PATH}
902                         WORKING_DIRECTORY "${GETTEXT_PO_PATH}/${LOCALE}"
903                         COMMENT "mo-update [${LOCALE}]: Creating mo file."
904                         )
905
906                 set(MO_FILES ${MO_FILES} ${MO_FILE_PATH})
907         endforeach()
908
909         add_custom_target(translations ALL COMMENT "mo update" DEPENDS ${MO_FILES})
910 endif()