Closed cosmotek closed 3 years ago
I've done some quick digging and not found anything useful... yet. My plan is to take the binary and libs produced by the current linux build process, add in an app icon (ideally specified in the pubspec), as well as any version info or useful metadata, and embed this into a .deb or alternatively an AppImage.
I'm willing to bet I will also need to update the doctor command to include tooling for this build process. Likely dkpg-deb and appimagetool will need to be included.
Might be able to get away with rolling .deb packages without any tooling.... which would be ideal. We'll see.
FYI, keeping this open for a little to track progress and notes in the case where someone else wants to get involved.
So far, I have gotten deb builds working using CPack. The process is pretty simple, but I'm still trying to figure out how to handle some of this CMake config (I am no expert at CMake). I'm getting an actual deb, but the deps aren't accurate, the directories embedded in the deb for the binary and libs are a bit off (they include the project path at the moment), and some of the info in the control file is coming from the wrong places.
Once I get more of this tacked down, I assume I'll need to update the flutter create
code to add my CMakeLists.txt file, as well as including a .desktop file.
Does anyone have ideas on how we should handle specifying out the desktop icon? Right now I am just dumping it into the linux directory, and including it directly via the CMakeLists.txt file. Ideally this should be set from the pubspec IMO.
At this point I have almost everything worked out, but I am trying to figure out how we're linking libflutter to the binary produced for linux. Running ldd against a flutter-produced binary gives me the following:
$ ldd spot
linux-vdso.so.1 (0x00007ffe8b9ec000)
liburl_launcher_linux_plugin.so => /home/cosmotek/code/flutter/spot/build/linux/release/_CPack_Packages/Linux/DEB/spot-0.0.0/usr/opt/spot/./lib/liburl_launcher_linux_plugin.so (0x00007facddea8000)
libgtk-3.so.0 => /usr/lib/x86_64-linux-gnu/libgtk-3.so.0 (0x00007facdd5a0000)
libgdk-3.so.0 => /usr/lib/x86_64-linux-gnu/libgdk-3.so.0 (0x00007facdd2aa000)
libpangocairo-1.0.so.0 => /usr/lib/x86_64-linux-gnu/libpangocairo-1.0.so.0 (0x00007facdd09d000)
libpango-1.0.so.0 => /usr/lib/x86_64-linux-gnu/libpango-1.0.so.0 (0x00007facdce50000)
libatk-1.0.so.0 => /usr/lib/x86_64-linux-gnu/libatk-1.0.so.0 (0x00007facdcc2a000)
libcairo-gobject.so.2 => /usr/lib/x86_64-linux-gnu/libcairo-gobject.so.2 (0x00007facdca21000)
libcairo.so.2 => /usr/lib/x86_64-linux-gnu/libcairo.so.2 (0x00007facdc704000)
libgdk_pixbuf-2.0.so.0 => /usr/lib/x86_64-linux-gnu/libgdk_pixbuf-2.0.so.0 (0x00007facdc4e0000)
libflutter_linux_gtk.so => /home/cosmotek/code/flutter/spot/build/linux/release/_CPack_Packages/Linux/DEB/spot-0.0.0/usr/opt/spot/./lib/libflutter_linux_gtk.so (0x00007facdb90d000)
liburl_launcher_linux_plugin
specifically points out the issue. The reference shown is specific to the build path. I'm not sure if this is part of the ninja build scripts or the cmake process. Hopefully I can change this in cmake.
Major progress... got working debs building and installing using the following CMakeLists.txt file. I'm sure it can be improved (pros, please make recommendations), but for now it mostly works. There's a small error that pops up related to not having the permissions to create files in /usr/share/
but somehow the deb build still works (even with a clean build). Next steps are as follows:
cpack build/linux/release
command somewhere into build process... Right now its manual after the release build is runJust some notes:
/opt
cmake_minimum_required(VERSION 3.10)
project(runner LANGUAGES CXX)
if(CMAKE_BUILD_TYPE MATCHES "Debug")
set(BINARY_NAME "spot")
set(APPLICATION_ID "com.example.spot")
cmake_policy(SET CMP0063 NEW)
set(CMAKE_INSTALL_RPATH "$ORIGIN/lib")
# Configure build options.
if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
set(CMAKE_BUILD_TYPE "Debug" CACHE
STRING "Flutter build mode" FORCE)
set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS
"Debug" "Profile" "Release")
endif()
# Compilation settings that should be applied to most targets.
function(APPLY_STANDARD_SETTINGS TARGET)
target_compile_features(${TARGET} PUBLIC cxx_std_14)
target_compile_options(${TARGET} PRIVATE -Wall -Werror)
target_compile_options(${TARGET} PRIVATE "$<$<NOT:$<CONFIG:Debug>>:-O3>")
target_compile_definitions(${TARGET} PRIVATE "$<$<NOT:$<CONFIG:Debug>>:NDEBUG>")
endfunction()
set(FLUTTER_MANAGED_DIR "${CMAKE_CURRENT_SOURCE_DIR}/flutter")
# Flutter library and tool build rules.
add_subdirectory(${FLUTTER_MANAGED_DIR})
# System-level dependencies.
find_package(PkgConfig REQUIRED)
pkg_check_modules(GTK REQUIRED IMPORTED_TARGET gtk+-3.0)
add_definitions(-DAPPLICATION_ID="${APPLICATION_ID}")
# Application build
add_executable(${BINARY_NAME}
"main.cc"
"my_application.cc"
"${FLUTTER_MANAGED_DIR}/generated_plugin_registrant.cc"
)
apply_standard_settings(${BINARY_NAME})
target_link_libraries(${BINARY_NAME} PRIVATE flutter)
target_link_libraries(${BINARY_NAME} PRIVATE PkgConfig::GTK)
add_dependencies(${BINARY_NAME} flutter_assemble)
# Only the install-generated bundle's copy of the executable will launch
# correctly, since the resources must in the right relative locations. To avoid
# people trying to run the unbundled copy, put it in a subdirectory instead of
# the default top-level location.
set_target_properties(${BINARY_NAME}
PROPERTIES
RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/intermediates_do_not_run"
)
# Generated plugin build rules, which manage building the plugins and adding
# them to the application.
include(flutter/generated_plugins.cmake)
# === Installation ===
# By default, "installing" just makes a relocatable bundle in the build
# directory.
set(BUILD_BUNDLE_DIR "${PROJECT_BINARY_DIR}/bundle")
if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT)
set(CMAKE_INSTALL_PREFIX "${BUILD_BUNDLE_DIR}" CACHE PATH "..." FORCE)
endif()
# Start with a clean build bundle directory every time.
install(CODE "
file(REMOVE_RECURSE \"${BUILD_BUNDLE_DIR}/\")
" COMPONENT Runtime)
set(INSTALL_BUNDLE_DATA_DIR "${CMAKE_INSTALL_PREFIX}/data")
set(INSTALL_BUNDLE_LIB_DIR "${CMAKE_INSTALL_PREFIX}/lib")
install(TARGETS ${BINARY_NAME} RUNTIME DESTINATION "${CMAKE_INSTALL_PREFIX}"
COMPONENT Runtime)
install(FILES "${FLUTTER_ICU_DATA_FILE}" DESTINATION "${INSTALL_BUNDLE_DATA_DIR}"
COMPONENT Runtime)
install(FILES "${FLUTTER_LIBRARY}" DESTINATION "${INSTALL_BUNDLE_LIB_DIR}"
COMPONENT Runtime)
if(PLUGIN_BUNDLED_LIBRARIES)
install(FILES "${PLUGIN_BUNDLED_LIBRARIES}"
DESTINATION "${INSTALL_BUNDLE_LIB_DIR}"
COMPONENT Runtime)
endif()
# Fully re-copy the assets directory on each build to avoid having stale files
# from a previous install.
set(FLUTTER_ASSET_DIR_NAME "flutter_assets")
install(CODE "
file(REMOVE_RECURSE \"${INSTALL_BUNDLE_DATA_DIR}/${FLUTTER_ASSET_DIR_NAME}\")
" COMPONENT Runtime)
install(DIRECTORY "${PROJECT_BUILD_DIR}/${FLUTTER_ASSET_DIR_NAME}"
DESTINATION "${INSTALL_BUNDLE_DATA_DIR}" COMPONENT Runtime)
endif()
if(CMAKE_BUILD_TYPE MATCHES "Release")
set(BINARY_NAME "spot")
set(CPACK_PACKAGE_NAME "spot")
set(APPLICATION_ID "com.example.spot")
# TODO determine how to pull these from the pubspec yaml
set(MAJOR_VERSION "0")
set(MINOR_VERSION "0")
set(PATCH_VERSION "0")
IF(EXISTS "${CMAKE_ROOT}/Modules/CPack.cmake")
INCLUDE(InstallRequiredSystemLibraries)
# not sure if this is necessary...
SET(CPACK_PACKAGE_VERSION_MAJOR "${MAJOR_VERSION}")
SET(CPACK_PACKAGE_VERSION_MINOR "${MINOR_VERSION}")
SET(CPACK_PACKAGE_VERSION_PATCH "${PATCH_VERSION}")
SET(CPACK_SET_DESTDIR "OFF")
SET(CPACK_GENERATOR "DEB")
set(CPACK_PACKAGING_INSTALL_PREFIX "/opt")
# set(CPACK_NATIVE_INSTALL_DIRECTORY "")
set(CMAKE_INSTALL_PREFIX "/opt")
# set(CPACK_INSTALL_DIRECTORY "")
SET(CPACK_PACKAGE_DESCRIPTION "A new Flutter project.")
SET(CPACK_PACKAGE_DESCRIPTION_SUMMARY "A new Flutter project.")
SET(CPACK_PACKAGE_VENDOR "Seth Moeckel")
SET(CPACK_PACKAGE_CONTACT "seth.moeckel@gmail.com")
SET(CPACK_PACKAGE_FILE_NAME "${BINARY_NAME}-${MAJOR_VERSION}.${MINOR_VERSION}.${PATCH_VERSION}")
SET(CPACK_SOURCE_PACKAGE_FILE_NAME "${BINARY_NAME}-${MAJOR_VERSION}.${MINOR_VERSION}.${PATCH_VERSION}")
SET(CPACK_DEBIAN_PACKAGE_PRIORITY "optional")
# SET(CPACK_DEBIAN_PACKAGE_SECTION "kde")
SET(CPACK_DEBIAN_ARCHITECTURE ${CMAKE_SYSTEM_PROCESSOR})
#dependencies for this service menu
# SET(CPACK_DEBIAN_PACKAGE_DEPENDS " kate , dolphin ")
SET(CPACK_COMPONENTS_ALL Libraries ApplicationData)
INCLUDE(CPack)
# Install the .desktop file and icon
INSTALL(FILES spot.desktop DESTINATION /usr/share/applications/)
INSTALL(FILES spot.png DESTINATION /usr/share/icons/hicolor/48x48/apps/)
# set(CPACK_PACKAGING_INSTALL_PREFIX "/opt")
# # set(CPACK_NATIVE_INSTALL_DIRECTORY "")
# set(CMAKE_INSTALL_PREFIX "/opt")
# Set postinstall script
# set(CPACK_DEBIAN_PACKAGE_CONTROL_EXTRA "${PROJECT_NAME}/contrib/postinst")
# set(CPACK_DEBIAN_PACKAGE_CONTROL_EXTRA "postinst")
ENDIF(EXISTS "${CMAKE_ROOT}/Modules/CPack.cmake")
cmake_policy(SET CMP0063 NEW)
# set(CMAKE_INSTALL_RPATH "$ORIGIN/lib")
# set(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/lib")
# set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE)
set(CMAKE_INSTALL_RPATH "/opt/spot/lib")
# Configure build options.
if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
set(CMAKE_BUILD_TYPE "Debug" CACHE
STRING "Flutter build mode" FORCE)
set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS
"Debug" "Profile" "Release")
endif()
# Compilation settings that should be applied to most targets.
function(APPLY_STANDARD_SETTINGS TARGET)
target_compile_features(${TARGET} PUBLIC cxx_std_14)
target_compile_options(${TARGET} PRIVATE -Wall -Werror)
target_compile_options(${TARGET} PRIVATE "$<$<NOT:$<CONFIG:Debug>>:-O3>")
target_compile_definitions(${TARGET} PRIVATE "$<$<NOT:$<CONFIG:Debug>>:NDEBUG>")
endfunction()
set(FLUTTER_MANAGED_DIR "${CMAKE_CURRENT_SOURCE_DIR}/flutter")
# Flutter library and tool build rules.
add_subdirectory(${FLUTTER_MANAGED_DIR})
# System-level dependencies.
find_package(PkgConfig REQUIRED)
pkg_check_modules(GTK REQUIRED IMPORTED_TARGET gtk+-3.0)
add_definitions(-DAPPLICATION_ID="${APPLICATION_ID}")
# Application build
add_executable(${BINARY_NAME}
"main.cc"
"my_application.cc"
"${FLUTTER_MANAGED_DIR}/generated_plugin_registrant.cc"
)
apply_standard_settings(${BINARY_NAME})
target_link_libraries(${BINARY_NAME} PRIVATE flutter)
target_link_libraries(${BINARY_NAME} PRIVATE PkgConfig::GTK)
add_dependencies(${BINARY_NAME} flutter_assemble)
# Only the install-generated bundle's copy of the executable will launch
# correctly, since the resources must in the right relative locations. To avoid
# people trying to run the unbundled copy, put it in a subdirectory instead of
# the default top-level location.
set_target_properties(${BINARY_NAME}
PROPERTIES
RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/intermediates_do_not_run"
)
# Generated plugin build rules, which manage building the plugins and adding
# them to the application.
include(flutter/generated_plugins.cmake)
# === Installation ===
# By default, "installing" just makes a relocatable bundle in the build
# directory.
set(BUILD_BUNDLE_DIR "${PROJECT_BINARY_DIR}/bundle")
if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT)
set(CMAKE_INSTALL_PREFIX "${BUILD_BUNDLE_DIR}" CACHE PATH "..." FORCE)
endif()
# Start with a clean build bundle directory every time.
install(CODE "
file(REMOVE_RECURSE \"${BUILD_BUNDLE_DIR}/\")
" COMPONENT Runtime)
set(INSTALL_BUNDLE_DATA_DIR "${BINARY_NAME}/data/")
set(INSTALL_BUNDLE_LIB_DIR "${BINARY_NAME}/lib/")
install(TARGETS ${BINARY_NAME} RUNTIME DESTINATION "${BINARY_NAME}/"
COMPONENT Runtime)
install(FILES "${FLUTTER_ICU_DATA_FILE}" DESTINATION "${INSTALL_BUNDLE_DATA_DIR}"
COMPONENT Runtime)
install(FILES "${FLUTTER_LIBRARY}" DESTINATION "${INSTALL_BUNDLE_LIB_DIR}"
COMPONENT Runtime)
if(PLUGIN_BUNDLED_LIBRARIES)
install(FILES "${PLUGIN_BUNDLED_LIBRARIES}"
DESTINATION "${INSTALL_BUNDLE_LIB_DIR}"
COMPONENT Runtime)
endif()
# Fully re-copy the assets directory on each build to avoid having stale files
# from a previous install.
set(FLUTTER_ASSET_DIR_NAME "flutter_assets")
install(CODE "
file(REMOVE_RECURSE \"${INSTALL_BUNDLE_DATA_DIR}/${FLUTTER_ASSET_DIR_NAME}\")
" COMPONENT Runtime)
install(DIRECTORY "${PROJECT_BUILD_DIR}/${FLUTTER_ASSET_DIR_NAME}"
DESTINATION "${INSTALL_BUNDLE_DATA_DIR}" COMPONENT Runtime)
install(FILES "${AOT_LIBRARY}" DESTINATION "${INSTALL_BUNDLE_LIB_DIR}"
COMPONENT Runtime)
endif()
Here's the desktop entry I used:
[Desktop Entry]
Type=Application
Encoding=UTF-8
Name=Spot
Comment=A Flutter App
Exec=/opt/spot/spot
Icon=spot.png
Terminal=false
Obviously this file needs some clean-up and modifications to make it less specific to my test case. Its late... I'll tackle this tomorrow.
Please read https://github.com/google/flutter-desktop-embedding#feedback. Closing as this has nothing to do with any of the plugins here, and is thus not on topic for this repository.
As for where this should go: Making a tool to package Flutter applications into Debian installers is definitely interesting, and something I'm glad to see someone tackling, but we currently have no plans to build all of the possible installer formats into the flutter
tool (just as the snap
support for Flutter Linux apps is not part of flutter
). I would recommend setting up a new GitHub project for a script/tool to run to package Flutter build output into your installer.
I understand this being the wrong location, but I totally disagree that this tooling should be separate. Deb installers are extremely popular and very easy to convert to different formats for distros that don't support it... but they aren't trivial to create. I really don't understand why Android, iOS and MacOS produce distributable formats but Linux shouldn't? What's the use-case for using flutter build linux --release
and getting back a set of files that you need to package... this is poor UX imo. I think a Debian image alongside the current binary output is the best solution. That being said I don't think we should implement outputs to any other formats.
I'm sure this is the wrong location for this discussion, where should this happen?
The Flutter issue tracker is where discussions about Flutter functionality should happen, per the README I linked above.
Hi! I was hoping someone could point me to docs or a part of the repo where one might modify how flutter handles building for linux. I'd like to contribute by adding support for Debian packages and AppImages. The build process for these packages is relatively simple, so if someone can help me figure out where to look, I'm sure I can get something working.