Update: Translations from eints
[openttd-github.git] / cmake / InstallAndPackage.cmake
blobde0159713240b5b3b39d3f1a8dba37c55d70d6f1
1 include(GNUInstallDirs)
3 # If requested, use FHS layout; otherwise fall back to a flat layout.
4 if(OPTION_INSTALL_FHS)
5     set(BINARY_DESTINATION_DIR "${CMAKE_INSTALL_BINDIR}")
6     set(DATA_DESTINATION_DIR "${CMAKE_INSTALL_DATADIR}/${BINARY_NAME}")
7     set(DOCS_DESTINATION_DIR "${CMAKE_INSTALL_DOCDIR}")
8     set(MAN_DESTINATION_DIR "${CMAKE_INSTALL_MANDIR}")
9 else()
10     if(APPLE)
11         set(BINARY_DESTINATION_DIR "../MacOS")
12     else()
13         set(BINARY_DESTINATION_DIR ".")
14     endif()
15     set(DATA_DESTINATION_DIR ".")
16     set(DOCS_DESTINATION_DIR ".")
17     set(MAN_DESTINATION_DIR ".")
18 endif()
20 install(TARGETS openttd
21         RUNTIME
22             DESTINATION ${BINARY_DESTINATION_DIR}
23             COMPONENT Runtime
24         )
26 if (NOT EMSCRIPTEN)
27     # Emscripten embeds these files in openttd.data.
28     # See CMakeLists.txt in the root.
29     install(DIRECTORY
30                     ${CMAKE_BINARY_DIR}/lang
31                     ${CMAKE_BINARY_DIR}/baseset
32                     ${CMAKE_BINARY_DIR}/ai
33                     ${CMAKE_BINARY_DIR}/game
34                     ${CMAKE_SOURCE_DIR}/bin/scripts
35             DESTINATION ${DATA_DESTINATION_DIR}
36             COMPONENT language_files
37             REGEX "ai/[^\.]+$" EXCLUDE # Ignore subdirs in ai dir
38     )
39 else()
40     install(FILES
41                 ${CMAKE_BINARY_DIR}/openttd.js
42                 ${CMAKE_BINARY_DIR}/openttd.wasm
43                 ${CMAKE_BINARY_DIR}/openttd.data
44             DESTINATION ${BINARY_DESTINATION_DIR}
45             COMPONENT Runtime
46     )
47 endif()
49 install(FILES
50                 ${CMAKE_SOURCE_DIR}/COPYING.md
51                 ${CMAKE_SOURCE_DIR}/README.md
52                 ${CMAKE_SOURCE_DIR}/CREDITS.md
53                 ${CMAKE_SOURCE_DIR}/CONTRIBUTING.md
54                 ${CMAKE_SOURCE_DIR}/changelog.md
55                 ${CMAKE_SOURCE_DIR}/known-bugs.md
56         DESTINATION ${DOCS_DESTINATION_DIR}
57         COMPONENT docs)
59 install(FILES
60                 ${CMAKE_SOURCE_DIR}/docs/admin_network.md
61                 ${CMAKE_SOURCE_DIR}/docs/debugging_desyncs.md
62                 ${CMAKE_SOURCE_DIR}/docs/desync.md
63                 ${CMAKE_SOURCE_DIR}/docs/directory_structure.md
64                 ${CMAKE_SOURCE_DIR}/docs/eints.md
65                 ${CMAKE_SOURCE_DIR}/docs/game_coordinator.md
66                 ${CMAKE_SOURCE_DIR}/docs/linkgraph.md
67                 ${CMAKE_SOURCE_DIR}/docs/logging_and_performance_metrics.md
68                 ${CMAKE_SOURCE_DIR}/docs/multiplayer.md
69                 ${CMAKE_SOURCE_DIR}/docs/savegame_format.md
70                 ${CMAKE_SOURCE_DIR}/docs/symbol_server.md
71                 ${CMAKE_SOURCE_DIR}/docs/obg_format.txt
72                 ${CMAKE_SOURCE_DIR}/docs/obm_format.txt
73                 ${CMAKE_SOURCE_DIR}/docs/obs_format.txt
74         DESTINATION ${DOCS_DESTINATION_DIR}/docs
75         COMPONENT docs)
77 # A Linux manual only makes sense when using FHS. Otherwise it is a very odd
78 # file with little context to what it is.
79 if(OPTION_INSTALL_FHS)
80     set(MAN_SOURCE_FILE ${CMAKE_SOURCE_DIR}/docs/openttd.6)
81     set(MAN_BINARY_FILE ${CMAKE_BINARY_DIR}/docs/${BINARY_NAME}.6)
82     install(CODE
83             "
84                 execute_process(COMMAND ${CMAKE_COMMAND} -E copy ${MAN_SOURCE_FILE} ${MAN_BINARY_FILE})
85                 execute_process(COMMAND gzip -9 -n -f ${MAN_BINARY_FILE})
86             "
87             COMPONENT manual)
88     install(FILES
89                     ${MAN_BINARY_FILE}.gz
90             DESTINATION ${MAN_DESTINATION_DIR}/man6
91             COMPONENT manual)
92 endif()
94 if(UNIX AND NOT APPLE AND NOT EMSCRIPTEN)
95     install(DIRECTORY
96                     ${CMAKE_BINARY_DIR}/media/icons
97                     ${CMAKE_BINARY_DIR}/media/pixmaps
98             DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}
99             COMPONENT media)
101     install(FILES
102                     ${CMAKE_BINARY_DIR}/media/${BINARY_NAME}.desktop
103             DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/applications
104             COMPONENT menu)
105 endif()
107 if(CMAKE_SYSTEM_PROCESSOR STREQUAL "x86_64")
108     set(ARCHITECTURE "amd64")
109 else()
110     string(TOLOWER "${CMAKE_SYSTEM_PROCESSOR}" ARCHITECTURE)
111 endif()
113 # Windows is a bit more annoying to detect; using the size of void pointer
114 # seems to be the most robust.
115 if(WIN32)
116     # Check if the MSVC platform has been defined
117     if ("$ENV{Platform}" STREQUAL "arm64")
118         set(ARCHITECTURE "arm64")
119     else()
120         if(CMAKE_SIZEOF_VOID_P EQUAL 8)
121             set(ARCHITECTURE "win64")
122         else()
123             set(ARCHITECTURE "win32")
124         endif()
125     endif()
126 endif()
127 if(APPLE AND CMAKE_OSX_ARCHITECTURES)
128     string(TOLOWER "${CMAKE_OSX_ARCHITECTURES}" ARCHITECTURE)
129 endif()
131 set(CPACK_SYSTEM_NAME "${ARCHITECTURE}")
133 set(CPACK_PACKAGE_NAME "openttd")
134 set(CPACK_PACKAGE_VENDOR "OpenTTD")
135 set(CPACK_PACKAGE_DESCRIPTION "OpenTTD")
136 set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "OpenTTD")
137 set(CPACK_PACKAGE_HOMEPAGE_URL "https://www.openttd.org/")
138 set(CPACK_PACKAGE_CONTACT "OpenTTD <info@openttd.org>")
139 set(CPACK_PACKAGE_INSTALL_DIRECTORY "OpenTTD")
140 set(CPACK_PACKAGE_CHECKSUM "SHA256")
142 if((APPLE OR WIN32) AND EXISTS ${PANDOC_EXECUTABLE})
143     execute_process(COMMAND ${PANDOC_EXECUTABLE} "${CMAKE_SOURCE_DIR}/COPYING.md" -s -o "${CMAKE_BINARY_DIR}/COPYING.rtf")
144     set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_BINARY_DIR}/COPYING.rtf")
145 else()
146     set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_SOURCE_DIR}/COPYING.md")
147 endif()
149 set(CPACK_RESOURCE_FILE_README "${CMAKE_SOURCE_DIR}/README.md")
150 set(CPACK_MONOLITHIC_INSTALL YES)
151 set(CPACK_PACKAGE_EXECUTABLES "openttd;OpenTTD")
152 set(CPACK_STRIP_FILES YES)
153 set(CPACK_OUTPUT_FILE_PREFIX "bundles")
155 if(APPLE)
156     # Stripping would produce unreadable stacktraces.
157     set(CPACK_STRIP_FILES NO)
158     set(CPACK_GENERATOR "Bundle")
159     include(PackageBundle)
161     if (APPLE_UNIVERSAL_PACKAGE)
162         set(CPACK_PACKAGE_FILE_NAME "openttd-#CPACK_PACKAGE_VERSION#-macos-universal")
163     else()
164         set(CPACK_PACKAGE_FILE_NAME "openttd-#CPACK_PACKAGE_VERSION#-macos-${CPACK_SYSTEM_NAME}")
165     endif()
166 elseif(WIN32)
167     set(CPACK_GENERATOR "ZIP")
168     if(OPTION_USE_NSIS)
169         list(APPEND CPACK_GENERATOR "NSIS")
170         include(PackageNSIS)
171     endif()
173     set(CPACK_PACKAGE_FILE_NAME "openttd-#CPACK_PACKAGE_VERSION#-windows-${CPACK_SYSTEM_NAME}")
175     if(DEFINED ENV{AZURE_CODESIGN_PROFILE_NAME})
176       add_custom_command(TARGET openttd
177         POST_BUILD
178         COMMAND "${CMAKE_SOURCE_DIR}/os/windows/sign.bat" "${BINARY_DESTINATION_DIR}"
179       )
180     endif()
181 elseif(UNIX)
182     # With FHS, we can create deb/rpm/... Without it, they would be horribly broken
183     # and not work. The other way around is also true; with FHS they are not
184     # usable, and only flat formats work.
185     if(OPTION_PACKAGE_DEPENDENCIES)
186         set(CPACK_GENERATOR "TXZ")
187         set(PLATFORM "generic")
188     elseif(NOT OPTION_INSTALL_FHS)
189         set(CPACK_GENERATOR "TXZ")
190         set(PLATFORM "unknown")
191     else()
192         find_program(LSB_RELEASE_EXEC lsb_release)
193         execute_process(COMMAND ${LSB_RELEASE_EXEC} -is
194             OUTPUT_VARIABLE LSB_RELEASE_ID
195             OUTPUT_STRIP_TRAILING_WHITESPACE
196         )
197         if(LSB_RELEASE_ID)
198             if(LSB_RELEASE_ID STREQUAL "Ubuntu" OR LSB_RELEASE_ID STREQUAL "Debian" OR LSB_RELEASE_ID STREQUAL "Linuxmint")
199                 execute_process(COMMAND ${LSB_RELEASE_EXEC} -cs
200                     OUTPUT_VARIABLE LSB_RELEASE_CODENAME
201                     OUTPUT_STRIP_TRAILING_WHITESPACE
202                 )
203                 string(TOLOWER "${LSB_RELEASE_ID}-${LSB_RELEASE_CODENAME}" PLATFORM)
205                 set(CPACK_GENERATOR "DEB")
206                 include(PackageDeb)
207             elseif(LSB_RELEASE_ID STREQUAL "Fedora")
208                 set(PLATFORM "fedora")
209                 set(CPACK_GENERATOR "RPM")
210                 include(PackageRPM)
211             else()
212                 set(UNSUPPORTED_PLATFORM_NAME "LSB-based Linux distribution '${LSB_RELEASE_ID}'")
213             endif()
214         elseif(EXISTS "/etc/os-release")
215             file(STRINGS "/etc/os-release" OS_RELEASE_CONTENTS REGEX "^ID=")
216             string(REGEX MATCH "ID=(.*)" _ ${OS_RELEASE_CONTENTS})
217             set(DISTRO_ID ${CMAKE_MATCH_1})
218             if(DISTRO_ID STREQUAL "arch")
219                 set(PLATFORM "arch")
220                 set(CPACK_GENERATOR "TXZ")
221             elseif(DISTRO_ID STREQUAL "fedora" OR DISTRO_ID STREQUAL "rhel")
222                 set(PLATFORM "fedora")
223                 set(CPACK_GENERATOR "RPM")
224                 include(PackageRPM)
225             else()
226                 set(UNSUPPORTED_PLATFORM_NAME "Linux distribution '${DISTRO_ID}' from /etc/os-release")
227             endif()
228         else()
229             set(UNSUPPORTED_PLATFORM_NAME "Linux distribution")
230         endif()
232         if(NOT PLATFORM)
233             set(PLATFORM "generic")
234             set(CPACK_GENERATOR "TXZ")
235             message(WARNING "Unknown ${UNSUPPORTED_PLATFORM_NAME} found for packaging; can only pack to a txz. Please consider creating a Pull Request to add support for this distribution.")
236         endif()
237     endif()
239     set(CPACK_PACKAGE_FILE_NAME "openttd-#CPACK_PACKAGE_VERSION#-linux-${PLATFORM}-${CPACK_SYSTEM_NAME}")
241 else()
242     message(FATAL_ERROR "Unknown OS found for packaging; please consider creating a Pull Request to add support for this OS.")
243 endif()
245 include(CPack)
247 if(OPTION_PACKAGE_DEPENDENCIES)
248     # Install all dependencies we can resolve, with the exception of ones that
249     # every Linux machine should have. This should make this build as generic
250     # as possible, where it runs on any machine with the same or newer libc
251     # than the one this is compiled with.
252     # We copy these libraries into lib/ folder, so they can be found on game
253     # startup. See comment in root CMakeLists.txt for how this works exactly.
254     install(CODE [[
255         file(GET_RUNTIME_DEPENDENCIES
256                 RESOLVED_DEPENDENCIES_VAR DEPENDENCIES
257                 UNRESOLVED_DEPENDENCIES_VAR UNRESOLVED_DEPENDENCIES
258                 EXECUTABLES openttd
259                 POST_EXCLUDE_REGEXES "ld-linux|libc.so|libdl.so|libm.so|libgcc_s.so|libpthread.so|librt.so|libstdc...so")
260         file(INSTALL
261                 DESTINATION "${CMAKE_INSTALL_PREFIX}/lib"
262                 FILES ${DEPENDENCIES}
263                 FOLLOW_SYMLINK_CHAIN)
265         # This should not be possible, but error out when a dependency cannot
266         # be resolved.
267         list(LENGTH UNRESOLVED_DEPENDENCIES UNRESOLVED_LENGTH)
268         if(${UNRESOLVED_LENGTH} GREATER 0)
269             message(FATAL_ERROR "Unresolved dependencies: ${UNRESOLVED_DEPENDENCIES}")
270         endif()
271     ]])
272 endif()