From f631780e187a88ab78fc2f376e71c62b031d907a Mon Sep 17 00:00:00 2001 From: Juan Gilsanz Polo Date: Sat, 29 Apr 2023 01:10:58 +0200 Subject: [PATCH] Added Linux support --- .metadata | 12 +- debian/compile_deb.txt | 1 + debian/debian.yaml | 14 ++ debian/gui/adguard-home-manager.desktop | 8 ++ debian/gui/adguard-home-manager.png | Bin 0 -> 42466 bytes linux/.gitignore | 1 + linux/CMakeLists.txt | 138 +++++++++++++++++++ linux/flutter/CMakeLists.txt | 88 ++++++++++++ linux/flutter/generated_plugin_registrant.cc | 23 ++++ linux/flutter/generated_plugin_registrant.h | 15 ++ linux/flutter/generated_plugins.cmake | 26 ++++ linux/main.cc | 6 + linux/my_application.cc | 104 ++++++++++++++ linux/my_application.h | 18 +++ 14 files changed, 448 insertions(+), 6 deletions(-) create mode 100644 debian/compile_deb.txt create mode 100644 debian/debian.yaml create mode 100644 debian/gui/adguard-home-manager.desktop create mode 100644 debian/gui/adguard-home-manager.png create mode 100644 linux/.gitignore create mode 100644 linux/CMakeLists.txt create mode 100644 linux/flutter/CMakeLists.txt create mode 100644 linux/flutter/generated_plugin_registrant.cc create mode 100644 linux/flutter/generated_plugin_registrant.h create mode 100644 linux/flutter/generated_plugins.cmake create mode 100644 linux/main.cc create mode 100644 linux/my_application.cc create mode 100644 linux/my_application.h diff --git a/.metadata b/.metadata index 0b30307..656c923 100644 --- a/.metadata +++ b/.metadata @@ -4,7 +4,7 @@ # This file should be version controlled. version: - revision: 4d9e56e694b656610ab87fcf2efbcd226e0ed8cf + revision: f72efea43c3013323d1b95cff571f3c1caa37583 channel: stable project_type: app @@ -13,11 +13,11 @@ project_type: app migration: platforms: - platform: root - create_revision: 4d9e56e694b656610ab87fcf2efbcd226e0ed8cf - base_revision: 4d9e56e694b656610ab87fcf2efbcd226e0ed8cf - - platform: windows - create_revision: 4d9e56e694b656610ab87fcf2efbcd226e0ed8cf - base_revision: 4d9e56e694b656610ab87fcf2efbcd226e0ed8cf + create_revision: f72efea43c3013323d1b95cff571f3c1caa37583 + base_revision: f72efea43c3013323d1b95cff571f3c1caa37583 + - platform: linux + create_revision: f72efea43c3013323d1b95cff571f3c1caa37583 + base_revision: f72efea43c3013323d1b95cff571f3c1caa37583 # User provided section diff --git a/debian/compile_deb.txt b/debian/compile_deb.txt new file mode 100644 index 0000000..4a18706 --- /dev/null +++ b/debian/compile_deb.txt @@ -0,0 +1 @@ +https://pub.dev/packages/flutter_to_debian \ No newline at end of file diff --git a/debian/debian.yaml b/debian/debian.yaml new file mode 100644 index 0000000..8bbb6a2 --- /dev/null +++ b/debian/debian.yaml @@ -0,0 +1,14 @@ +flutter_app: + command: adguard_home_manager + arch: x64 + parent: /usr/local/lib + +control: + Package: AdGuardHomeManager + Version: 1.2.0 + Architecture: amd64 + Essential: no + Priority: optional + Depends: + Maintainer: JGeek00 + Description: AdGuard Home control app \ No newline at end of file diff --git a/debian/gui/adguard-home-manager.desktop b/debian/gui/adguard-home-manager.desktop new file mode 100644 index 0000000..a011591 --- /dev/null +++ b/debian/gui/adguard-home-manager.desktop @@ -0,0 +1,8 @@ +[Desktop Entry] +Name=AdGuard Home Manager +Comment=Manage your AdGuard Home server +Exec=adguard-home-manager +Icon=${SNAP}/meta/gui/adguard-home-manager.png +Terminal=false +Type=Application +Categories=Utilities; diff --git a/debian/gui/adguard-home-manager.png b/debian/gui/adguard-home-manager.png new file mode 100644 index 0000000000000000000000000000000000000000..5b39396df98f8c660fe3554b2a26708879d600fd GIT binary patch literal 42466 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 toLU&&kykjpr7z1`_$nrih>:-O3>") + target_compile_definitions(${TARGET} PRIVATE "$<$>:NDEBUG>") +endfunction() + +# Flutter library and tool build rules. +set(FLUTTER_MANAGED_DIR "${CMAKE_CURRENT_SOURCE_DIR}/flutter") +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}") + +# Define the application target. To change its name, change BINARY_NAME above, +# not the value here, or `flutter run` will no longer work. +# +# Any new source files that you add to the application should be added here. +add_executable(${BINARY_NAME} + "main.cc" + "my_application.cc" + "${FLUTTER_MANAGED_DIR}/generated_plugin_registrant.cc" +) + +# Apply the standard set of build settings. This can be removed for applications +# that need different build settings. +apply_standard_settings(${BINARY_NAME}) + +# Add dependency libraries. Add any application-specific dependencies here. +target_link_libraries(${BINARY_NAME} PRIVATE flutter) +target_link_libraries(${BINARY_NAME} PRIVATE PkgConfig::GTK) + +# Run the Flutter tool portions of the build. This must not be removed. +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) + +foreach(bundled_library ${PLUGIN_BUNDLED_LIBRARIES}) + install(FILES "${bundled_library}" + DESTINATION "${INSTALL_BUNDLE_LIB_DIR}" + COMPONENT Runtime) +endforeach(bundled_library) + +# 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 the AOT library on non-Debug builds only. +if(NOT CMAKE_BUILD_TYPE MATCHES "Debug") + install(FILES "${AOT_LIBRARY}" DESTINATION "${INSTALL_BUNDLE_LIB_DIR}" + COMPONENT Runtime) +endif() diff --git a/linux/flutter/CMakeLists.txt b/linux/flutter/CMakeLists.txt new file mode 100644 index 0000000..d5bd016 --- /dev/null +++ b/linux/flutter/CMakeLists.txt @@ -0,0 +1,88 @@ +# This file controls Flutter-level build steps. It should not be edited. +cmake_minimum_required(VERSION 3.10) + +set(EPHEMERAL_DIR "${CMAKE_CURRENT_SOURCE_DIR}/ephemeral") + +# Configuration provided via flutter tool. +include(${EPHEMERAL_DIR}/generated_config.cmake) + +# TODO: Move the rest of this into files in ephemeral. See +# https://github.com/flutter/flutter/issues/57146. + +# Serves the same purpose as list(TRANSFORM ... PREPEND ...), +# which isn't available in 3.10. +function(list_prepend LIST_NAME PREFIX) + set(NEW_LIST "") + foreach(element ${${LIST_NAME}}) + list(APPEND NEW_LIST "${PREFIX}${element}") + endforeach(element) + set(${LIST_NAME} "${NEW_LIST}" PARENT_SCOPE) +endfunction() + +# === Flutter Library === +# System-level dependencies. +find_package(PkgConfig REQUIRED) +pkg_check_modules(GTK REQUIRED IMPORTED_TARGET gtk+-3.0) +pkg_check_modules(GLIB REQUIRED IMPORTED_TARGET glib-2.0) +pkg_check_modules(GIO REQUIRED IMPORTED_TARGET gio-2.0) + +set(FLUTTER_LIBRARY "${EPHEMERAL_DIR}/libflutter_linux_gtk.so") + +# Published to parent scope for install step. +set(FLUTTER_LIBRARY ${FLUTTER_LIBRARY} PARENT_SCOPE) +set(FLUTTER_ICU_DATA_FILE "${EPHEMERAL_DIR}/icudtl.dat" PARENT_SCOPE) +set(PROJECT_BUILD_DIR "${PROJECT_DIR}/build/" PARENT_SCOPE) +set(AOT_LIBRARY "${PROJECT_DIR}/build/lib/libapp.so" PARENT_SCOPE) + +list(APPEND FLUTTER_LIBRARY_HEADERS + "fl_basic_message_channel.h" + "fl_binary_codec.h" + "fl_binary_messenger.h" + "fl_dart_project.h" + "fl_engine.h" + "fl_json_message_codec.h" + "fl_json_method_codec.h" + "fl_message_codec.h" + "fl_method_call.h" + "fl_method_channel.h" + "fl_method_codec.h" + "fl_method_response.h" + "fl_plugin_registrar.h" + "fl_plugin_registry.h" + "fl_standard_message_codec.h" + "fl_standard_method_codec.h" + "fl_string_codec.h" + "fl_value.h" + "fl_view.h" + "flutter_linux.h" +) +list_prepend(FLUTTER_LIBRARY_HEADERS "${EPHEMERAL_DIR}/flutter_linux/") +add_library(flutter INTERFACE) +target_include_directories(flutter INTERFACE + "${EPHEMERAL_DIR}" +) +target_link_libraries(flutter INTERFACE "${FLUTTER_LIBRARY}") +target_link_libraries(flutter INTERFACE + PkgConfig::GTK + PkgConfig::GLIB + PkgConfig::GIO +) +add_dependencies(flutter flutter_assemble) + +# === Flutter tool backend === +# _phony_ is a non-existent file to force this command to run every time, +# since currently there's no way to get a full input/output list from the +# flutter tool. +add_custom_command( + OUTPUT ${FLUTTER_LIBRARY} ${FLUTTER_LIBRARY_HEADERS} + ${CMAKE_CURRENT_BINARY_DIR}/_phony_ + COMMAND ${CMAKE_COMMAND} -E env + ${FLUTTER_TOOL_ENVIRONMENT} + "${FLUTTER_ROOT}/packages/flutter_tools/bin/tool_backend.sh" + ${FLUTTER_TARGET_PLATFORM} ${CMAKE_BUILD_TYPE} + VERBATIM +) +add_custom_target(flutter_assemble DEPENDS + "${FLUTTER_LIBRARY}" + ${FLUTTER_LIBRARY_HEADERS} +) diff --git a/linux/flutter/generated_plugin_registrant.cc b/linux/flutter/generated_plugin_registrant.cc new file mode 100644 index 0000000..8492786 --- /dev/null +++ b/linux/flutter/generated_plugin_registrant.cc @@ -0,0 +1,23 @@ +// +// Generated file. Do not edit. +// + +// clang-format off + +#include "generated_plugin_registrant.h" + +#include +#include +#include + +void fl_register_plugins(FlPluginRegistry* registry) { + g_autoptr(FlPluginRegistrar) dynamic_color_registrar = + fl_plugin_registry_get_registrar_for_plugin(registry, "DynamicColorPlugin"); + dynamic_color_plugin_register_with_registrar(dynamic_color_registrar); + g_autoptr(FlPluginRegistrar) sqlite3_flutter_libs_registrar = + fl_plugin_registry_get_registrar_for_plugin(registry, "Sqlite3FlutterLibsPlugin"); + sqlite3_flutter_libs_plugin_register_with_registrar(sqlite3_flutter_libs_registrar); + g_autoptr(FlPluginRegistrar) window_size_registrar = + fl_plugin_registry_get_registrar_for_plugin(registry, "WindowSizePlugin"); + window_size_plugin_register_with_registrar(window_size_registrar); +} diff --git a/linux/flutter/generated_plugin_registrant.h b/linux/flutter/generated_plugin_registrant.h new file mode 100644 index 0000000..e0f0a47 --- /dev/null +++ b/linux/flutter/generated_plugin_registrant.h @@ -0,0 +1,15 @@ +// +// Generated file. Do not edit. +// + +// clang-format off + +#ifndef GENERATED_PLUGIN_REGISTRANT_ +#define GENERATED_PLUGIN_REGISTRANT_ + +#include + +// Registers Flutter plugins. +void fl_register_plugins(FlPluginRegistry* registry); + +#endif // GENERATED_PLUGIN_REGISTRANT_ diff --git a/linux/flutter/generated_plugins.cmake b/linux/flutter/generated_plugins.cmake new file mode 100644 index 0000000..163e042 --- /dev/null +++ b/linux/flutter/generated_plugins.cmake @@ -0,0 +1,26 @@ +# +# Generated file, do not edit. +# + +list(APPEND FLUTTER_PLUGIN_LIST + dynamic_color + sqlite3_flutter_libs + window_size +) + +list(APPEND FLUTTER_FFI_PLUGIN_LIST +) + +set(PLUGIN_BUNDLED_LIBRARIES) + +foreach(plugin ${FLUTTER_PLUGIN_LIST}) + add_subdirectory(flutter/ephemeral/.plugin_symlinks/${plugin}/linux plugins/${plugin}) + target_link_libraries(${BINARY_NAME} PRIVATE ${plugin}_plugin) + list(APPEND PLUGIN_BUNDLED_LIBRARIES $) + list(APPEND PLUGIN_BUNDLED_LIBRARIES ${${plugin}_bundled_libraries}) +endforeach(plugin) + +foreach(ffi_plugin ${FLUTTER_FFI_PLUGIN_LIST}) + add_subdirectory(flutter/ephemeral/.plugin_symlinks/${ffi_plugin}/linux plugins/${ffi_plugin}) + list(APPEND PLUGIN_BUNDLED_LIBRARIES ${${ffi_plugin}_bundled_libraries}) +endforeach(ffi_plugin) diff --git a/linux/main.cc b/linux/main.cc new file mode 100644 index 0000000..e7c5c54 --- /dev/null +++ b/linux/main.cc @@ -0,0 +1,6 @@ +#include "my_application.h" + +int main(int argc, char** argv) { + g_autoptr(MyApplication) app = my_application_new(); + return g_application_run(G_APPLICATION(app), argc, argv); +} diff --git a/linux/my_application.cc b/linux/my_application.cc new file mode 100644 index 0000000..1f79b20 --- /dev/null +++ b/linux/my_application.cc @@ -0,0 +1,104 @@ +#include "my_application.h" + +#include +#ifdef GDK_WINDOWING_X11 +#include +#endif + +#include "flutter/generated_plugin_registrant.h" + +struct _MyApplication { + GtkApplication parent_instance; + char** dart_entrypoint_arguments; +}; + +G_DEFINE_TYPE(MyApplication, my_application, GTK_TYPE_APPLICATION) + +// Implements GApplication::activate. +static void my_application_activate(GApplication* application) { + MyApplication* self = MY_APPLICATION(application); + GtkWindow* window = + GTK_WINDOW(gtk_application_window_new(GTK_APPLICATION(application))); + + // Use a header bar when running in GNOME as this is the common style used + // by applications and is the setup most users will be using (e.g. Ubuntu + // desktop). + // If running on X and not using GNOME then just use a traditional title bar + // in case the window manager does more exotic layout, e.g. tiling. + // If running on Wayland assume the header bar will work (may need changing + // if future cases occur). + gboolean use_header_bar = TRUE; +#ifdef GDK_WINDOWING_X11 + GdkScreen* screen = gtk_window_get_screen(window); + if (GDK_IS_X11_SCREEN(screen)) { + const gchar* wm_name = gdk_x11_screen_get_window_manager_name(screen); + if (g_strcmp0(wm_name, "GNOME Shell") != 0) { + use_header_bar = FALSE; + } + } +#endif + if (use_header_bar) { + GtkHeaderBar* header_bar = GTK_HEADER_BAR(gtk_header_bar_new()); + gtk_widget_show(GTK_WIDGET(header_bar)); + gtk_header_bar_set_title(header_bar, "AdGuard Home Manager"); + gtk_header_bar_set_show_close_button(header_bar, TRUE); + gtk_window_set_titlebar(window, GTK_WIDGET(header_bar)); + } else { + gtk_window_set_title(window, "AdGuard Home Manager"); + } + + gtk_window_set_default_size(window, 1280, 720); + gtk_widget_show(GTK_WIDGET(window)); + + g_autoptr(FlDartProject) project = fl_dart_project_new(); + fl_dart_project_set_dart_entrypoint_arguments(project, self->dart_entrypoint_arguments); + + FlView* view = fl_view_new(project); + gtk_widget_show(GTK_WIDGET(view)); + gtk_container_add(GTK_CONTAINER(window), GTK_WIDGET(view)); + + fl_register_plugins(FL_PLUGIN_REGISTRY(view)); + + gtk_widget_grab_focus(GTK_WIDGET(view)); +} + +// Implements GApplication::local_command_line. +static gboolean my_application_local_command_line(GApplication* application, gchar*** arguments, int* exit_status) { + MyApplication* self = MY_APPLICATION(application); + // Strip out the first argument as it is the binary name. + self->dart_entrypoint_arguments = g_strdupv(*arguments + 1); + + g_autoptr(GError) error = nullptr; + if (!g_application_register(application, nullptr, &error)) { + g_warning("Failed to register: %s", error->message); + *exit_status = 1; + return TRUE; + } + + g_application_activate(application); + *exit_status = 0; + + return TRUE; +} + +// Implements GObject::dispose. +static void my_application_dispose(GObject* object) { + MyApplication* self = MY_APPLICATION(object); + g_clear_pointer(&self->dart_entrypoint_arguments, g_strfreev); + G_OBJECT_CLASS(my_application_parent_class)->dispose(object); +} + +static void my_application_class_init(MyApplicationClass* klass) { + G_APPLICATION_CLASS(klass)->activate = my_application_activate; + G_APPLICATION_CLASS(klass)->local_command_line = my_application_local_command_line; + G_OBJECT_CLASS(klass)->dispose = my_application_dispose; +} + +static void my_application_init(MyApplication* self) {} + +MyApplication* my_application_new() { + return MY_APPLICATION(g_object_new(my_application_get_type(), + "application-id", APPLICATION_ID, + "flags", G_APPLICATION_NON_UNIQUE, + nullptr)); +} diff --git a/linux/my_application.h b/linux/my_application.h new file mode 100644 index 0000000..72271d5 --- /dev/null +++ b/linux/my_application.h @@ -0,0 +1,18 @@ +#ifndef FLUTTER_MY_APPLICATION_H_ +#define FLUTTER_MY_APPLICATION_H_ + +#include + +G_DECLARE_FINAL_TYPE(MyApplication, my_application, MY, APPLICATION, + GtkApplication) + +/** + * my_application_new: + * + * Creates a new Flutter-based application. + * + * Returns: a new #MyApplication. + */ +MyApplication* my_application_new(); + +#endif // FLUTTER_MY_APPLICATION_H_