From c170bb2cb8cb4c8b56ead018999a85480aa61f0d Mon Sep 17 00:00:00 2001 From: balintkissdev Date: Sun, 13 Aug 2023 16:53:42 +0200 Subject: [PATCH] Create AppImage instead of .tar.gz for Linux release. This fixes compatibility issues between different Linux distros. --- .github/workflows/main.yml | 68 +++++++++++++++------------ CMakeLists.txt | 46 ++++++++++++------ README.md | 2 +- cmake/modules/appimage.cmake | 91 ++++++++++++++++++++++++++++++++++++ share/icons/appimage.svg | 78 +++++++++++++++++++++++++++++++ 5 files changed, 240 insertions(+), 45 deletions(-) create mode 100644 cmake/modules/appimage.cmake create mode 100644 share/icons/appimage.svg diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 3161dda..5d54f76 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -3,56 +3,64 @@ name: Raycaster CI on: [push, pull_request] jobs: - executable-build: - runs-on: ${{ matrix.config.os }} - strategy: - matrix: - config: - - { name: "Ubuntu Latest GCC", os: ubuntu-latest, cxx: g++, cc: gcc } - - { - name: "Windows Latest MSVC", - os: windows-latest, - cxx: cl.exe, - cc: cl.exe, - } - + windows-build: + runs-on: windows-2022 steps: - uses: ilammy/msvc-dev-cmd@v1 - - - name: Set compiler environment - uses: lukka/set-shell-env@v1 - with: - CXX: ${{ matrix.config.cxx }} - CC: ${{ matrix.config.cc }} - - name: Set compiler environment for Windows - if: matrix.config.os == 'windows-latest' uses: lukka/set-shell-env@v1 with: + CXX: cl.exe + CC: cl.exe VS160COMNTOOLS: C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\Common7\Tools - - name: Checkout - uses: actions/checkout@v2.0.0 - + uses: actions/checkout@v3 - uses: lukka/get-cmake@latest - - name: Build project uses: lukka/run-cmake@v3 with: cmakeAppendedArgs: "-DCMAKE_BUILD_TYPE=Release" buildDirectory: "${{ github.workspace }}/build/" - - - name: Generate package + - name: Generate ZIP package + working-directory: build run: | - cd build cpack -C "Release" - - name: Publish release if: startsWith(github.ref, 'refs/tags/') uses: softprops/action-gh-release@v1 with: files: | - build/Raycaster-*.tar.gz build/Raycaster-*.zip env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + linux-build: + runs-on: ubuntu-22.04 + steps: + - name: Checkout + uses: actions/checkout@v3 + # https://github.com/AppImage/AppImageKit/wiki/FUSE + - name: Install FUSE + run: | + sudo add-apt-repository universe + sudo apt-get update + sudo apt-get install libfuse2 + - uses: lukka/get-cmake@latest + - name: Build project + run: | + cmake -DCMAKE_BUILD_TYPE=Release + make -j`nproc` + - name: Generate AppImage package + run: | + make install DESTDIR=. + - name: Publish release + if: startsWith(github.ref, 'refs/tags/') + uses: softprops/action-gh-release@v1 + with: + files: | + Raycaster-*.AppImage + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + +# TODO: Emscripten build + diff --git a/CMakeLists.txt b/CMakeLists.txt index 7e95f79..10baa99 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -8,7 +8,9 @@ FetchContent_MakeAvailable(SetupHunter) set(PROJECT_NAME Raycaster) project(${PROJECT_NAME} LANGUAGES CXX) -project(${PROJECT_NAME} VERSION 0.0.4) # TODO: Get version from git tag +project(${PROJECT_NAME} VERSION 0.0.5) # TODO: Get version from git tag + +list(APPEND CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake/modules") add_executable(${PROJECT_NAME} "") @@ -80,20 +82,36 @@ else() target_link_libraries(${PROJECT_NAME} SDL2::SDL2main SDL2::SDL2) endif() -set(CPACK_PACKAGE_NAME "Raycaster") -set(CPACK_PACKAGE_DESCRIPTION "C++ raycasting pseudo-3D engine") -set(CPACK_PACKAGE_VERSION_MAJOR ${PROJECT_VERSION_MAJOR}) -set(CPACK_PACKAGE_VERSION_MINOR ${PROJECT_VERSION_MINOR}) -set(CPACK_PACKAGE_VERSION_PATCH ${PROJECT_VERSION_PATCH}) -set(CPACK_RESOURCE_FILE_LICENSE "${PROJECT_SOURCE_DIR}/LICENSE") -set(CPACK_RESOURCE_FILE_README "${PROJECT_SOURCE_DIR}/README.md") - -install(FILES "${CPACK_RESOURCE_FILE_LICENSE}" "${CPACK_RESOURCE_FILE_README}" DESTINATION ".") -install(TARGETS ${PROJECT_NAME} RUNTIME CONFIGURATIONS Release DESTINATION ".") -install(DIRECTORY "${PROJECT_SOURCE_DIR}/resources/" DESTINATION "resources") +# Create distributable ZIP file for Windows releases if(WIN32) + set(CPACK_PACKAGE_NAME "Raycaster") + set(CPACK_PACKAGE_DESCRIPTION "C++ raycasting pseudo-3D engine") + set(CPACK_PACKAGE_VERSION_MAJOR ${PROJECT_VERSION_MAJOR}) + set(CPACK_PACKAGE_VERSION_MINOR ${PROJECT_VERSION_MINOR}) + set(CPACK_PACKAGE_VERSION_PATCH ${PROJECT_VERSION_PATCH}) + set(CPACK_RESOURCE_FILE_LICENSE "${PROJECT_SOURCE_DIR}/LICENSE") + set(CPACK_RESOURCE_FILE_README "${PROJECT_SOURCE_DIR}/README.md") + + install(FILES "${CPACK_RESOURCE_FILE_LICENSE}" "${CPACK_RESOURCE_FILE_README}" DESTINATION ".") + install(TARGETS ${PROJECT_NAME} RUNTIME CONFIGURATIONS Release DESTINATION ".") + install(DIRECTORY "${PROJECT_SOURCE_DIR}/resources/" DESTINATION "resources") set(CPACK_GENERATOR ZIP) + include(CPack) +# Linux releases are distributed as AppImage files instead for compatibility else() - set(CPACK_GENERATOR TGZ) + # Keep "resources" and "share" folder separate to avoid packaging icon as asset for the app + set(ICON "${PROJECT_SOURCE_DIR}/share/icons/appimage.svg") + install(CODE + "include(${PROJECT_SOURCE_DIR}/cmake/modules/appimage.cmake) + make_appimage( + EXE \"${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}\" + NAME \"${PROJECT_NAME}\" + ICON \"${ICON}\" + DIR_ICON \"${ICON}\" + OUTPUT_NAME \"${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}-${PROJECT_VERSION}-linux-${CMAKE_SYSTEM_PROCESSOR}.AppImage\" + ASSETS \"${CMAKE_CURRENT_BINARY_DIR}/resources\" + ) + " + COMPONENT Runtime + ) endif() -include(CPack) \ No newline at end of file diff --git a/README.md b/README.md index 86706b2..d8dc4e3 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ ![alt tag](https://raw.githubusercontent.com/balintkissdev/raycaster-engine/master/demo.gif) -[Live demo](https://balintkissdev.github.io/raycaster-engine) +[Live demo](https://balintkissdev.github.io/raycaster-engine) | [Windows 64-bit download](https://github.com/balintkissdev/raycaster-engine/releases/download/0.0.5/Raycaster-0.0.5-win64.zip) | [Linux 64-bit download](https://github.com/balintkissdev/raycaster-engine/releases/download/0.0.5/Raycaster-0.0.5-linux-x86_64.AppImage) My take on making a raycasting pseudo-3D engine in C++, also with my own tiny template linear algebra types. One of the goals was to make raycasting computation equations more explicit and readable. diff --git a/cmake/modules/appimage.cmake b/cmake/modules/appimage.cmake new file mode 100644 index 0000000..8a8a1f3 --- /dev/null +++ b/cmake/modules/appimage.cmake @@ -0,0 +1,91 @@ +# MIT License +# +# Copyright (c) 2021 Ravbug +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. +function(make_appimage) + set(optional) + set(args EXE NAME DIR_ICON ICON OUTPUT_NAME) + set(list_args ASSETS) + cmake_parse_arguments( + PARSE_ARGV 0 + ARGS + "${optional}" + "${args}" + "${list_args}" + ) + + if(${ARGS_UNPARSED_ARGUMENTS}) + message(WARNING "Unparsed arguments: ${ARGS_UNPARSED_ARGUMENTS}") + endif() + + + # download AppImageTool if needed (TODO: non-x86 build machine?) + SET(AIT_PATH "${CMAKE_BINARY_DIR}/AppImageTool.AppImage" CACHE INTERNAL "") + if (NOT EXISTS "${AIT_PATH}") + file(DOWNLOAD https://github.com/AppImage/AppImageKit/releases/download/continuous/appimagetool-x86_64.AppImage "${AIT_PATH}") + execute_process(COMMAND chmod +x ${AIT_PATH}) + endif() + + # make the AppDir + set(APPDIR "${CMAKE_BINARY_DIR}/AppDir") + file(REMOVE_RECURSE "${APPDIR}") # remove if leftover + file(MAKE_DIRECTORY "${APPDIR}") + + # copy executable to appdir + file(COPY "${ARGS_EXE}" DESTINATION "${APPDIR}" FOLLOW_SYMLINK_CHAIN) + get_filename_component(EXE_NAME "${ARGS_EXE}" NAME) + + # create the script that will launch the AppImage +file(WRITE "${APPDIR}/AppRun" +"#!/bin/sh +cd \"$(dirname \"$0\")\"; +./${EXE_NAME} $@" + ) + execute_process(COMMAND chmod +x "${APPDIR}/AppRun") + + # copy assets to appdir + file(COPY ${ARGS_ASSETS} DESTINATION "${APPDIR}") + + # copy icon thumbnail + file(COPY ${ARGS_DIR_ICON} DESTINATION "${APPDIR}") + get_filename_component(THUMB_NAME "${ARGS_DIR_ICON}" NAME) + file(RENAME "${APPDIR}/${THUMB_NAME}" "${APPDIR}/.DirIcon") + + # copy icon highres + file(COPY ${ARGS_ICON} DESTINATION "${APPDIR}") + get_filename_component(ICON_NAME "${ARGS_ICON}" NAME) + get_filename_component(ICON_EXT "${ARGS_ICON}" EXT) + file(RENAME "${APPDIR}/${ICON_NAME}" "${APPDIR}/${ARGS_NAME}${ICON_EXT}") + + # Create the .desktop file + file(WRITE "${APPDIR}/${ARGS_NAME}.desktop" + "[Desktop Entry] +Type=Application +Name=${ARGS_NAME} +Icon=${ARGS_NAME} +Categories=X-None;" + ) + + # Invoke AppImageTool + execute_process(COMMAND ${AIT_PATH} ${APPDIR} ${ARGS_OUTPUT_NAME}) + file(REMOVE_RECURSE "${APPDIR}") + +endfunction() + diff --git a/share/icons/appimage.svg b/share/icons/appimage.svg new file mode 100644 index 0000000..0e00a0a --- /dev/null +++ b/share/icons/appimage.svg @@ -0,0 +1,78 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file