Codechange: Don't use globals for return values from vehicle command procs.
[openttd-github.git] / cmake / InstallAndPackage.cmake
blob057f0934f8786305fbf4f78cadc2085d37c1a9a2
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 install(DIRECTORY
27                 ${CMAKE_BINARY_DIR}/lang
28                 ${CMAKE_BINARY_DIR}/baseset
29                 ${CMAKE_BINARY_DIR}/ai
30                 ${CMAKE_BINARY_DIR}/game
31                 ${CMAKE_SOURCE_DIR}/bin/scripts
32         DESTINATION ${DATA_DESTINATION_DIR}
33         COMPONENT language_files
34         REGEX "ai/[^\.]+$" EXCLUDE # Ignore subdirs in ai dir
37 install(FILES
38                 ${CMAKE_SOURCE_DIR}/COPYING.md
39                 ${CMAKE_SOURCE_DIR}/README.md
40                 ${CMAKE_SOURCE_DIR}/changelog.txt
41                 ${CMAKE_SOURCE_DIR}/docs/multiplayer.md
42                 ${CMAKE_SOURCE_DIR}/known-bugs.txt
43         DESTINATION ${DOCS_DESTINATION_DIR}
44         COMPONENT docs)
46 # A Linux manual only makes sense when using FHS. Otherwise it is a very odd
47 # file with little context to what it is.
48 if(OPTION_INSTALL_FHS)
49     set(MAN_SOURCE_FILE ${CMAKE_SOURCE_DIR}/docs/openttd.6)
50     set(MAN_BINARY_FILE ${CMAKE_BINARY_DIR}/docs/${BINARY_NAME}.6)
51     install(CODE
52             "
53                 execute_process(COMMAND ${CMAKE_COMMAND} -E copy ${MAN_SOURCE_FILE} ${MAN_BINARY_FILE})
54                 execute_process(COMMAND gzip -9 -n -f ${MAN_BINARY_FILE})
55             "
56             COMPONENT manual)
57     install(FILES
58                     ${MAN_BINARY_FILE}.gz
59             DESTINATION ${MAN_DESTINATION_DIR}/man6
60             COMPONENT manual)
61 endif()
63 if(UNIX AND NOT APPLE)
64     install(DIRECTORY
65                     ${CMAKE_BINARY_DIR}/media/icons
66                     ${CMAKE_BINARY_DIR}/media/pixmaps
67             DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}
68             COMPONENT media)
70     install(FILES
71                     ${CMAKE_BINARY_DIR}/media/${BINARY_NAME}.desktop
72             DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/applications
73             COMPONENT menu)
74 endif()
76 if(CMAKE_SYSTEM_PROCESSOR STREQUAL "x86_64")
77     set(ARCHITECTURE "amd64")
78 else()
79     string(TOLOWER "${CMAKE_SYSTEM_PROCESSOR}" ARCHITECTURE)
80 endif()
82 # Windows is a bit more annoying to detect; using the size of void pointer
83 # seems to be the most robust.
84 if(WIN32)
85     # Check if the MSVC platform has been defined
86     if ("$ENV{Platform}" STREQUAL "arm64")
87         set(ARCHITECTURE "arm64")
88     else()
89         if(CMAKE_SIZEOF_VOID_P EQUAL 8)
90             set(ARCHITECTURE "win64")
91         else()
92             set(ARCHITECTURE "win32")
93         endif()
94     endif()
95 endif()
96 if(APPLE AND CMAKE_OSX_ARCHITECTURES)
97     string(TOLOWER "${CMAKE_OSX_ARCHITECTURES}" ARCHITECTURE)
98 endif()
100 set(CPACK_SYSTEM_NAME "${ARCHITECTURE}")
102 set(CPACK_PACKAGE_NAME "openttd")
103 set(CPACK_PACKAGE_VENDOR "OpenTTD")
104 set(CPACK_PACKAGE_DESCRIPTION "OpenTTD")
105 set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "OpenTTD")
106 set(CPACK_PACKAGE_HOMEPAGE_URL "https://www.openttd.org/")
107 set(CPACK_PACKAGE_CONTACT "OpenTTD <info@openttd.org>")
108 set(CPACK_PACKAGE_INSTALL_DIRECTORY "OpenTTD")
109 set(CPACK_PACKAGE_CHECKSUM "SHA256")
111 if((APPLE OR WIN32) AND EXISTS ${PANDOC_EXECUTABLE})
112     execute_process(COMMAND ${PANDOC_EXECUTABLE} "${CMAKE_SOURCE_DIR}/COPYING.md" -s -o "${CMAKE_BINARY_DIR}/COPYING.rtf")
113     set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_BINARY_DIR}/COPYING.rtf")
114 else()
115     set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_SOURCE_DIR}/COPYING.md")
116 endif()
118 set(CPACK_RESOURCE_FILE_README "${CMAKE_SOURCE_DIR}/README.md")
119 set(CPACK_MONOLITHIC_INSTALL YES)
120 set(CPACK_PACKAGE_EXECUTABLES "openttd;OpenTTD")
121 set(CPACK_STRIP_FILES YES)
122 set(CPACK_OUTPUT_FILE_PREFIX "bundles")
124 if(APPLE)
125     set(CPACK_GENERATOR "Bundle")
126     include(PackageBundle)
128     if (APPLE_UNIVERSAL_PACKAGE)
129         set(CPACK_PACKAGE_FILE_NAME "openttd-#CPACK_PACKAGE_VERSION#-macos-universal")
130     else()
131         set(CPACK_PACKAGE_FILE_NAME "openttd-#CPACK_PACKAGE_VERSION#-macos-${CPACK_SYSTEM_NAME}")
132         endif()
133 elseif(WIN32)
134     set(CPACK_GENERATOR "ZIP")
135     if(OPTION_USE_NSIS)
136         list(APPEND CPACK_GENERATOR "NSIS")
137         include(PackageNSIS)
138     endif()
140     set(CPACK_PACKAGE_FILE_NAME "openttd-#CPACK_PACKAGE_VERSION#-windows-${CPACK_SYSTEM_NAME}")
142     if(WINDOWS_CERTIFICATE_COMMON_NAME)
143       add_custom_command(TARGET openttd
144         POST_BUILD
145         COMMAND "${CMAKE_SOURCE_DIR}/os/windows/sign.bat" "$<TARGET_FILE:openttd>" "${WINDOWS_CERTIFICATE_COMMON_NAME}"
146       )
147     endif()
148 elseif(UNIX)
149     # With FHS, we can create deb/rpm/... Without it, they would be horribly broken
150     # and not work. The other way around is also true; with FHS they are not
151     # usable, and only flat formats work.
152     if(OPTION_PACKAGE_DEPENDENCIES)
153         set(CPACK_GENERATOR "TXZ")
154         set(PLATFORM "generic")
155     elseif(NOT OPTION_INSTALL_FHS)
156         set(CPACK_GENERATOR "TXZ")
157         set(PLATFORM "unknown")
158     else()
159         find_program(LSB_RELEASE_EXEC lsb_release)
160         execute_process(COMMAND ${LSB_RELEASE_EXEC} -is
161             OUTPUT_VARIABLE LSB_RELEASE_ID
162             OUTPUT_STRIP_TRAILING_WHITESPACE
163         )
164         if(LSB_RELEASE_ID)
165             if(LSB_RELEASE_ID STREQUAL "Ubuntu" OR LSB_RELEASE_ID STREQUAL "Debian")
166                 execute_process(COMMAND ${LSB_RELEASE_EXEC} -cs
167                     OUTPUT_VARIABLE LSB_RELEASE_CODENAME
168                     OUTPUT_STRIP_TRAILING_WHITESPACE
169                 )
170                 string(TOLOWER "${LSB_RELEASE_ID}-${LSB_RELEASE_CODENAME}" PLATFORM)
172                 set(CPACK_GENERATOR "DEB")
173                 include(PackageDeb)
174             else()
175                 set(UNSUPPORTED_PLATFORM_NAME "LSB-based Linux distribution '${LSB_RELEASE_ID}'")
176             endif()
177         elseif(EXISTS "/etc/os-release")
178             file(STRINGS "/etc/os-release" OS_RELEASE_CONTENTS REGEX "^ID=")
179             string(REGEX MATCH "ID=(.*)" _ ${OS_RELEASE_CONTENTS})
180             set(DISTRO_ID ${CMAKE_MATCH_1})
181             if(DISTRO_ID STREQUAL "arch")
182                 set(PLATFORM "arch")
183                 set(CPACK_GENERATOR "TXZ")
184             else()
185                 set(UNSUPPORTED_PLATFORM_NAME "Linux distribution '${DISTRO_ID}' from /etc/os-release")
186             endif()
187         else()
188             set(UNSUPPORTED_PLATFORM_NAME "Linux distribution")
189         endif()
191         if(NOT PLATFORM)
192             set(PLATFORM "generic")
193             set(CPACK_GENERATOR "TXZ")
194             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.")
195         endif()
196     endif()
198     set(CPACK_PACKAGE_FILE_NAME "openttd-#CPACK_PACKAGE_VERSION#-linux-${PLATFORM}-${CPACK_SYSTEM_NAME}")
200 else()
201     message(FATAL_ERROR "Unknown OS found for packaging; please consider creating a Pull Request to add support for this OS.")
202 endif()
204 include(CPack)
206 if(OPTION_PACKAGE_DEPENDENCIES)
207     # Install all dependencies we can resolve, with the exception of ones that
208     # every Linux machine should have. This should make this build as generic
209     # as possible, where it runs on any machine with the same or newer libc
210     # than the one this is compiled with.
211     # We copy these libraries into lib/ folder, so they can be found on game
212     # startup. See comment in root CMakeLists.txt for how this works exactly.
213     install(CODE [[
214         file(GET_RUNTIME_DEPENDENCIES
215                 RESOLVED_DEPENDENCIES_VAR DEPENDENCIES
216                 UNRESOLVED_DEPENDENCIES_VAR UNRESOLVED_DEPENDENCIES
217                 EXECUTABLES openttd
218                 POST_EXCLUDE_REGEXES "ld-linux|libc.so|libdl.so|libm.so|libgcc_s.so|libpthread.so|librt.so|libstdc...so")
219         file(INSTALL
220                 DESTINATION "${CMAKE_INSTALL_PREFIX}/lib"
221                 FILES ${DEPENDENCIES}
222                 FOLLOW_SYMLINK_CHAIN)
224         # This should not be possible, but error out when a dependency cannot
225         # be resolved.
226         list(LENGTH UNRESOLVED_DEPENDENCIES UNRESOLVED_LENGTH)
227         if(${UNRESOLVED_LENGTH} GREATER 0)
228             message(FATAL_ERROR "Unresolved dependencies: ${UNRESOLVED_DEPENDENCIES}")
229         endif()
230     ]])
231 endif()