From fc0a67ffb6a70e2a90fda417f23df7da9762dcf1 Mon Sep 17 00:00:00 2001 From: Mathieu Schroeter Date: Sat, 25 Feb 2017 17:01:04 +0100 Subject: [PATCH] Add initial support for AppImage on Linux --- CMakeLists.txt | 12 +++ cmake/LinuxAppImageBuild.cmake | 144 +++++++++++++++++++++++++ resources/linux/application.desktop.in | 7 ++ resources/linux/icon.svg | 47 ++++++++ 4 files changed, 210 insertions(+) create mode 100644 cmake/LinuxAppImageBuild.cmake create mode 100644 resources/linux/application.desktop.in create mode 100644 resources/linux/icon.svg diff --git a/CMakeLists.txt b/CMakeLists.txt index e4e5bf8..6ba1a48 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,6 +1,8 @@ cmake_minimum_required (VERSION 3.2) +set (CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake") + include (${CMAKE_ROOT}/Modules/ExternalProject.cmake) include_directories (${CMAKE_INSTALL_PREFIX}/include) @@ -135,3 +137,13 @@ install (DIRECTORY resources/image DESTINATION share/planetblupi) install (DIRECTORY resources/movie DESTINATION share/planetblupi) install (DIRECTORY resources/sound DESTINATION share/planetblupi) install (DIRECTORY resources/music DESTINATION share/planetblupi) + +######### +## Deploy +######### + +if (APPIMAGE_APPRUN_PROGRAM AND APPIMAGE_ASSISTANT_PROGRAM) + include (LinuxAppImageBuild) + set (CMAKE_PACKAGED_OUTPUT_PREFIX ${CMAKE_INSTALL_PREFIX}) + APPIMAGE_PACKAGE (planetblupi "planetblupi" "resources/linux" "share" "" "") +endif () diff --git a/cmake/LinuxAppImageBuild.cmake b/cmake/LinuxAppImageBuild.cmake new file mode 100644 index 0000000..349ae17 --- /dev/null +++ b/cmake/LinuxAppImageBuild.cmake @@ -0,0 +1,144 @@ +set ( APPIMAGE_CONFIG_DIR "${CMAKE_SOURCE_DIR}" ) # Specifies where to find template files, in this case this same directory + +set ( APPIMAGE_ASSISTANT_PROGRAM CACHE FILEPATH "AppImageAssistant executable" ) +set ( APPIMAGE_APPRUN_PROGRAM CACHE FILEPATH "AppImage AppRun executable" ) + +set ( APPIMAGE_WORKING_DIRECTORY "${CMAKE_BINARY_DIR}/deploy/linux-appimage" CACHE PATH "Where to put the AppDir items" ) +set ( APPIMAGE_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/package/linux-appimage" CACHE PATH "AppImage output directory" ) +set ( APPIMAGE_FOLLOW_STANDARD OFF CACHE BOOL "Whether generator should follow the spec" ) + +macro( APPIMAGE_PACKAGE TARGET APPIMAGE_TITLE CONFIGDIR DATA LIBRARIES LIBRARY_FILES ) + string ( TOLOWER "${APPIMAGE_TITLE}" APPIMAGE_INTERNALNAME ) + string ( MAKE_C_IDENTIFIER "${APPIMAGE_INTERNALNAME}" APPIMAGE_INTERNALNAME ) + + # Some prerequisites + # TITLE here is used as the name of the final AppImage as well as the desktop entry's name + set ( APPIMAGE_TITLE "${APPIMAGE_TITLE}" ) + set ( APPIMAGE_INTERNALNAME "${APPIMAGE_INTERNALNAME}" ) + set ( APPIMAGE_LIBRARIES ) + set ( APPIMAGE_DATA ) + set ( APPIMAGE_CONFIG_DIR "${APPIMAGE_CONFIG_DIR}/${CONFIGDIR}" ) + set ( APPIMAGE_DEFAULT_ICON_FILE "${APPIMAGE_CONFIG_DIR}/icon.svg" ) + + # Icon file to be used for the AppImage, only one in this case, preferrably SVG + set ( APPIMAGE_ICON "${APPIMAGE_DEFAULT_ICON_FILE}" ) + # We define a way to reference this icon based on where it is located + set ( APPIMAGE_ICON_REF "${APPIMAGE_INTERNALNAME}" ) + + # This helps the window manager to recognize the program even if it has no embedded or loaded icon + set ( APPIMAGE_EXEC_WM ${TARGET} ) + + # Sets the launch variable in .desktop entry + set ( APPIMAGE_EXEC ${TARGET} ) + + # This directory is used for temporary files, might get messy + set ( APPIMAGE_CACHE_DIR "${APPIMAGE_WORKING_DIRECTORY}/${APPIMAGE_INTERNALNAME}_cache" ) + # Where the AppDir is generated + set ( APPIMAGE_INTERMEDIATE_DIR "${APPIMAGE_WORKING_DIRECTORY}/${APPIMAGE_INTERNALNAME}" ) + set ( APPIMAGE_ICON_TARGET "${APPIMAGE_INTERMEDIATE_DIR}/${APPIMAGE_ICON_REF}" ) + set ( APPIMAGE_BINARY_DIR "${APPIMAGE_INTERMEDIATE_DIR}/usr/bin" ) + set ( APPIMAGE_ASSET_DIR "${APPIMAGE_INTERMEDIATE_DIR}/usr/share" ) + set ( APPIMAGE_LIBRARY_DIR "${APPIMAGE_INTERMEDIATE_DIR}/usr/lib" ) + set ( APPIMAGE_FINAL_NAME "${APPIMAGE_OUTPUT_DIRECTORY}/${APPIMAGE_TITLE}.AppImage" ) + + list ( APPEND APPIMAGE_LIBRARIES + ${LIBRARIES} ) + list ( APPEND APPIMAGE_DATA + ${DATA} ) + + # Remove the previous AppImage file to avoid confusion when generating a new one + add_custom_command ( TARGET ${TARGET} + PRE_BUILD + COMMAND ${CMAKE_COMMAND} -E remove "${APPIMAGE_FINAL_NAME}" + ) + + # Create some necessary directory structure in AppDir + add_custom_command ( TARGET ${TARGET} + PRE_BUILD + COMMAND ${CMAKE_COMMAND} -E make_directory "${APPIMAGE_OUTPUT_DIRECTORY}" + ) + add_custom_command ( TARGET ${TARGET} + PRE_BUILD + COMMAND ${CMAKE_COMMAND} -E make_directory "${APPIMAGE_BINARY_DIR}" + ) + add_custom_command ( TARGET ${TARGET} + PRE_BUILD + COMMAND ${CMAKE_COMMAND} -E make_directory "${APPIMAGE_CACHE_DIR}" + ) + add_custom_command ( TARGET ${TARGET} + PRE_BUILD + COMMAND ${CMAKE_COMMAND} -E make_directory "${APPIMAGE_LIBRARY_DIR}" + ) + add_custom_command ( TARGET ${TARGET} + PRE_BUILD + COMMAND ${CMAKE_COMMAND} -E make_directory "${APPIMAGE_ASSET_DIR}" + ) + + # Copy and configure some data for the AppDir + configure_file ( + "${APPIMAGE_ICON}" + "${APPIMAGE_ICON_TARGET}" + COPYONLY + ) + configure_file ( + "${APPIMAGE_ICON}" + "${APPIMAGE_INTERMEDIATE_DIR}/.DirIcon" + COPYONLY + ) + configure_file ( + "${APPIMAGE_CONFIG_DIR}/application.desktop.in" + "${APPIMAGE_INTERMEDIATE_DIR}/${APPIMAGE_INTERNALNAME}.desktop" + @ONLY + ) + configure_file ( + "${APPIMAGE_APPRUN_PROGRAM}" + "${APPIMAGE_INTERMEDIATE_DIR}/AppRun" + COPYONLY + ) + + # Copy resources into AppDir + foreach ( RESC ${DATA} ) + add_custom_command ( TARGET ${TARGET} + PRE_BUILD + COMMAND ${CMAKE_COMMAND} -E copy_directory "${RESC}" "${APPIMAGE_ASSET_DIR}" + ) + endforeach() + + # Copy bundled libraries into AppDir + foreach ( LIB ${LIBRARY_FILES} ) + add_custom_command ( TARGET ${TARGET} + PRE_BUILD + COMMAND ${CMAKE_COMMAND} -E copy "${LIB}" "${APPIMAGE_LIBRARY_DIR}" + ) + endforeach() + + foreach ( LIB ${LIBRARIES} ) + add_custom_command ( TARGET ${TARGET} + PRE_BUILD + COMMAND ${CMAKE_COMMAND} -E copy "$" "${APPIMAGE_LIBRARY_DIR}" + ) + endforeach() + + # Copy the binary to AppDir + add_custom_command ( TARGET ${TARGET} + POST_BUILD + COMMAND ${CMAKE_COMMAND} -E copy "$" "${APPIMAGE_BINARY_DIR}" + ) + + # Do the actual packaging step with AppImageKit + add_custom_command ( TARGET ${TARGET} + POST_BUILD + COMMAND "${APPIMAGE_ASSISTANT_PROGRAM}" "${APPIMAGE_INTERMEDIATE_DIR}" "${APPIMAGE_FINAL_NAME}" + ) + + install ( + FILES + "${APPIMAGE_FINAL_NAME}" + + DESTINATION + "${CMAKE_PACKAGED_OUTPUT_PREFIX}/linux-appimage" + + PERMISSIONS + OWNER_READ OWNER_WRITE OWNER_EXECUTE + ) +endmacro() diff --git a/resources/linux/application.desktop.in b/resources/linux/application.desktop.in new file mode 100644 index 0000000..765ab05 --- /dev/null +++ b/resources/linux/application.desktop.in @@ -0,0 +1,7 @@ +[Desktop Entry] +Version=1.0 +Type=Application +Name=@APPIMAGE_TITLE@ +Exec=@APPIMAGE_EXEC@ +StartupWMClass=@APPIMAGE_EXEC_WM@ +Icon=@APPIMAGE_ICON_REF@ diff --git a/resources/linux/icon.svg b/resources/linux/icon.svg new file mode 100644 index 0000000..c444546 --- /dev/null +++ b/resources/linux/icon.svg @@ -0,0 +1,47 @@ + + + + + + image/svg+xml + + + + + + + +