-
-
Save hbirchtree/afada1b4886a79abac3e2771773059e3 to your computer and use it in GitHub Desktop.
CMake, GTK+ 3 and AppImage
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
[Desktop Entry] | |
Version=1.0 | |
Type=Application | |
Name=@APPIMAGE_TITLE@ | |
Exec=@APPIMAGE_EXEC@ | |
StartupWMClass=@APPIMAGE_EXEC_WM@ | |
Icon=@APPIMAGE_ICON_REF@ |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Set the name and the supported language of the project | |
PROJECT(hello-world C) | |
# Set the minimum version of cmake required to build this project | |
CMAKE_MINIMUM_REQUIRED(VERSION 3.0) | |
### We need this in order to find CMake modules located in this directory | |
set ( CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_SOURCE_DIR} ) | |
include ( LinuxAppImageBuild ) | |
# Use the package PkgConfig to detect GTK+ headers/library files | |
FIND_PACKAGE(PkgConfig REQUIRED) | |
PKG_CHECK_MODULES(GTK3 REQUIRED gtk+-3.0) | |
# Setup CMake to use GTK+, tell the compiler where to look for headers | |
# and to the linker where to look for libraries | |
INCLUDE_DIRECTORIES(${GTK3_INCLUDE_DIRS}) | |
LINK_DIRECTORIES(${GTK3_LIBRARY_DIRS}) | |
# Add other flags to the compiler | |
ADD_DEFINITIONS(${GTK3_CFLAGS_OTHER}) | |
# Add an executable compiled from hello.c | |
ADD_EXECUTABLE(hello hello.c) | |
# Link the target to the GTK+ libraries | |
TARGET_LINK_LIBRARIES(hello ${GTK3_LIBRARIES}) | |
### We now generate the AppImage | |
APPIMAGE_PACKAGE(hello "Hello GTK+ 3" "" "" "") |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <gtk/gtk.h> | |
static void | |
activate(GtkApplication *app, | |
gpointer user_data) { | |
GtkWidget *window; | |
window = gtk_application_window_new(app); | |
gtk_window_set_title(GTK_WINDOW(window), "Hello GNOME"); | |
gtk_widget_show_all(window); | |
} | |
int | |
main(int argc, char **argv) { | |
GtkApplication *app; | |
int status; | |
app = gtk_application_new("org.gtk.example", | |
G_APPLICATION_FLAGS_NONE); | |
g_signal_connect(app, "activate", | |
G_CALLBACK(activate), NULL); | |
status = g_application_run(G_APPLICATION(app), argc, argv); | |
g_object_unref(app); | |
return (status); | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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" ) | |
set ( APPIMAGE_DEFAULT_ICON_FILE "${CMAKE_SOURCE_DIR}/icon.svg" CACHE FILEPATH "Default icon for AppImages" ) | |
macro( APPIMAGE_PACKAGE TARGET APPIMAGE_TITLE 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 ) | |
# 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}.svg" ) | |
# 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 "$<TARGET_FILE:${LIB}>" "${APPIMAGE_LIBRARY_DIR}" | |
) | |
endforeach() | |
# Copy the binary to AppDir | |
add_custom_command ( TARGET ${TARGET} | |
POST_BUILD | |
COMMAND ${CMAKE_COMMAND} -E copy "$<TARGET_FILE:${TARGET}>" "${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() |
@probonopd, I was not able to reproduce your issue with spaces. A sufficient amount of quotes seems to have been applied in the script to avoid this. I tested this with CMake 3.5.1 and Ubuntu 16.04, where the only issue I know of is that "make clean" will not wipe the generated files. (Which will be added soon)
Same goes for permissions, but I could add an extra step to ensure these permissions are set.
Edit:
I retraced your steps, and I would like to point out that the AppImageAssistant executable you used does not want to move the AppImage file into another directory. (Instead placing it under deploy/, not packaged/) I used a freshly compiled AppImageAssistant without issues.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Thank you very much, may I place this as an example into the AppImageKit repository?
Currently fails due to 2 minor issues:
/Hello\ GTK+\ 3.AppImage
- are there quotes missing?deploy/linux-appimage/hello_gtk__3/AppRun
doesn't have the execute bit setTwo more non-fatal issues:
make clean
seems not to be implementedNote to self: I did