diff options
-rw-r--r-- | .github/workflows/release.yml | 91 | ||||
-rw-r--r-- | CMakeLists.txt | 21 | ||||
-rw-r--r-- | cmake/InstallAndPackage.cmake | 39 | ||||
-rw-r--r-- | cmake/Options.cmake | 5 |
4 files changed, 149 insertions, 7 deletions
diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 4003787fc..1faaacfb3 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -265,7 +265,93 @@ jobs: retention-days: 5 linux: - name: Linux + name: Linux (Generic) + needs: source + + runs-on: ubuntu-20.04 + container: + # manylinux2014 is based on CentOS 7, but already has a lot of things + # installed and preconfigured. It makes it easier to build OpenTTD. + image: quay.io/pypa/manylinux2014_x86_64 + + steps: + - name: Download source + uses: actions/download-artifact@v2 + with: + name: internal-source + + - name: Unpack source + run: | + tar -xf source.tar.gz --strip-components=1 + + - name: Install dependencies + run: | + echo "::group::Install dependencies" + yum install -y \ + fontconfig-devel \ + freetype-devel \ + libicu-devel \ + libpng-devel \ + libpng-devel \ + lzo-devel \ + SDL2-devel \ + wget \ + xz-devel \ + zlib-devel \ + # EOF + echo "::endgroup::" + + # The yum variant of fluidsynth depends on all possible audio drivers. + # This is not really useful for us, as that would require a user to + # have them all before he can start OpenTTD. Instead, compile a + # version that can only use SDL2. As OpenTTD does sound via SDL2, + # this simply means we either have sound and music, or have none. + echo "::group::Install fluidsynth" + wget https://github.com/FluidSynth/fluidsynth/archive/v2.1.6.tar.gz + tar xf v2.1.6.tar.gz + ( + cd fluidsynth-2.1.6 + mkdir build + cd build + cmake .. -DCMAKE_BUILD_TYPE=RelWithDebInfo -DCMAKE_INSTALL_PREFIX=/usr + make -j$(nproc) + make install + ) + echo "::endgroup::" + + - name: Install GCC problem matcher + uses: ammaraskar/gcc-problem-matcher@master + + - name: Build + run: | + mkdir -p build + cd build + + echo "::group::CMake" + cmake ${GITHUB_WORKSPACE} \ + -DCMAKE_BUILD_TYPE=RelWithDebInfo \ + -DOPTION_PACKAGE_DEPENDENCIES=ON \ + # EOF + echo "::endgroup::" + + echo "::group::Build" + echo "Running on $(nproc) cores" + make -j$(nproc) package + echo "::endgroup::" + + # Remove the sha256 files CPack generates; we will do this ourself at + # the end of this workflow. + rm -f bundles/*.sha256 + + - name: Store bundles + uses: actions/upload-artifact@v2 + with: + name: openttd-linux-generic + path: build/bundles + retention-days: 5 + + linux-distro: + name: Linux (Distros) needs: source if: needs.source.outputs.is_tag == 'true' @@ -633,6 +719,7 @@ jobs: - source - docs - linux + - linux-distro - macos - windows @@ -641,7 +728,7 @@ jobs: # "always()" is important here, it is the keyword to use to stop skipping # this job if any dependency is skipped. It looks a bit silly, but it is # how GitHub Actions work ;) - if: always() && needs.source.result == 'success' && needs.docs.result == 'success' && (needs.linux.result == 'success' || needs.linux.result == 'skipped') && needs.macos.result == 'success' && needs.windows.result == 'success' + if: always() && needs.source.result == 'success' && needs.docs.result == 'success' && needs.linux.result == 'success' && (needs.linux-distro.result == 'success' || needs.linux-distro.result == 'skipped') && needs.macos.result == 'success' && needs.windows.result == 'success' runs-on: ubuntu-20.04 diff --git a/CMakeLists.txt b/CMakeLists.txt index d273937a3..1ac5be5be 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -167,6 +167,27 @@ if(APPLE) endif() endif() +if(OPTION_PACKAGE_DEPENDENCIES) + if(NOT UNIX) + message(FATAL_ERROR "Can only package dependencies on Linux") + endif() + if(OPTION_INSTALL_FHS) + message(FATAL_ERROR "Cannot install in FHS folders when we are packaging dependencies") + endif() + if(${CMAKE_VERSION} VERSION_LESS "3.16.0") + message(FATAL_ERROR "OPTION_PACKAGE_DEPENDENCIES can only work with CMake 3.16+; you are using ${CMAKE_VERSION}") + endif() + + # If we are packaging dependencies, we do two things: + # 1) set the RPATH to include $ORIGIN/lib; $ORIGIN (that literal string) + # is a Linux indicator for "path where application is". In CMake, we + # have to do this before add_executable() is executed. + # 2) copy the libraries that we compile against to the "lib" folder. + # This is done in InstallAndPackage.cmake. + set(CMAKE_INSTALL_RPATH "\$ORIGIN/lib") + set(CMAKE_BUILD_WITH_INSTALL_RPATH ON) +endif() + include(SourceList) # Needed by rev.cpp diff --git a/cmake/InstallAndPackage.cmake b/cmake/InstallAndPackage.cmake index b54c8131a..5c56d2d6d 100644 --- a/cmake/InstallAndPackage.cmake +++ b/cmake/InstallAndPackage.cmake @@ -123,8 +123,12 @@ elseif(UNIX) # With FHS, we can create deb/rpm/... Without it, they would be horribly broken # and not work. The other way around is also true; with FHS they are not # usable, and only flat formats work. - if(NOT OPTION_INSTALL_FHS) + if(OPTION_PACKAGE_DEPENDENCIES) set(CPACK_GENERATOR "TXZ") + set(PLATFORM "generic") + elseif(NOT OPTION_INSTALL_FHS) + set(CPACK_GENERATOR "TXZ") + set(PLATFORM "unknown") else() find_program(LSB_RELEASE_EXEC lsb_release) execute_process(COMMAND ${LSB_RELEASE_EXEC} -is @@ -149,7 +153,7 @@ elseif(UNIX) string(REGEX MATCH "ID=(.*)" _ ${OS_RELEASE_CONTENTS}) set(DISTRO_ID ${CMAKE_MATCH_1}) if(DISTRO_ID STREQUAL "arch") - set(PLATFORM "generic") + set(PLATFORM "arch") set(CPACK_GENERATOR "TXZ") else() set(UNSUPPORTED_PLATFORM_NAME "Linux distribution '${DISTRO_ID}' from /etc/os-release") @@ -163,12 +167,39 @@ elseif(UNIX) set(CPACK_GENERATOR "TXZ") 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.") endif() - - set(CPACK_PACKAGE_FILE_NAME "openttd-#CPACK_PACKAGE_VERSION#-linux-${PLATFORM}-${CPACK_SYSTEM_NAME}") endif() + set(CPACK_PACKAGE_FILE_NAME "openttd-#CPACK_PACKAGE_VERSION#-linux-${PLATFORM}-${CPACK_SYSTEM_NAME}") + else() message(FATAL_ERROR "Unknown OS found for packaging; please consider creating a Pull Request to add support for this OS.") endif() include(CPack) + +if(OPTION_PACKAGE_DEPENDENCIES) + # Install all dependencies we can resolve, with the exception of ones that + # every Linux machine should have. This should make this build as generic + # as possible, where it runs on any machine with the same or newer libc + # than the one this is compiled with. + # We copy these libraries into lib/ folder, so they can be found on game + # startup. See comment in root CMakeLists.txt for how this works exactly. + install(CODE [[ + file(GET_RUNTIME_DEPENDENCIES + RESOLVED_DEPENDENCIES_VAR DEPENDENCIES + UNRESOLVED_DEPENDENCIES_VAR UNRESOLVED_DEPENDENCIES + EXECUTABLES openttd + POST_EXCLUDE_REGEXES "ld-linux|libc.so|libdl.so|libm.so|libgcc_s.so|libpthread.so|librt.so|libstdc...so") + file(INSTALL + DESTINATION "${CMAKE_INSTALL_PREFIX}/lib" + FILES ${DEPENDENCIES} + FOLLOW_SYMLINK_CHAIN) + + # This should not be possible, but error out when a dependency cannot + # be resolved. + list(LENGTH UNRESOLVED_DEPENDENCIES UNRESOLVED_LENGTH) + if(${UNRESOLVED_LENGTH} GREATER 0) + message(FATAL_ERROR "Unresolved dependencies: ${UNRESOLVED_DEPENDENCIES}") + endif() + ]]) +endif() diff --git a/cmake/Options.cmake b/cmake/Options.cmake index c94a193b3..42d112790 100644 --- a/cmake/Options.cmake +++ b/cmake/Options.cmake @@ -44,7 +44,9 @@ endfunction() # set_options() # function(set_options) - if(UNIX AND NOT APPLE) + option(OPTION_PACKAGE_DEPENDENCIES "Copy dependencies into lib/ for easy packaging (Linux only)" OFF) + + if(UNIX AND NOT APPLE AND NOT OPTION_PACKAGE_DEPENDENCIES) set(DEFAULT_OPTION_INSTALL_FHS ON) else() set(DEFAULT_OPTION_INSTALL_FHS OFF) @@ -76,6 +78,7 @@ endfunction() # show_options() # function(show_options) + message(STATUS "Option Package Dependencies - ${OPTION_PACKAGE_DEPENDENCIES}") message(STATUS "Option Dedicated - ${OPTION_DEDICATED}") message(STATUS "Option Install FHS - ${OPTION_INSTALL_FHS}") message(STATUS "Option Use assert - ${OPTION_USE_ASSERTS}") |