Herbert Poul
5 years ago
13 changed files with 352 additions and 10 deletions
@ -0,0 +1,90 @@ |
|||||||
|
cmake_minimum_required(VERSION 3.10) |
||||||
|
project(runner LANGUAGES CXX) |
||||||
|
|
||||||
|
set(BINARY_NAME "argon2_ffi_example") |
||||||
|
|
||||||
|
cmake_policy(SET CMP0063 NEW) |
||||||
|
|
||||||
|
set(CMAKE_INSTALL_RPATH "\$ORIGIN") |
||||||
|
|
||||||
|
# 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}) |
||||||
|
|
||||||
|
# Application build |
||||||
|
add_executable(${BINARY_NAME} |
||||||
|
"main.cc" |
||||||
|
"window_configuration.cc" |
||||||
|
"${FLUTTER_MANAGED_DIR}/generated_plugin_registrant.cc" |
||||||
|
) |
||||||
|
apply_standard_settings(${BINARY_NAME}) |
||||||
|
target_link_libraries(${BINARY_NAME} PRIVATE flutter flutter_wrapper_app) |
||||||
|
add_dependencies(${BINARY_NAME} flutter_assemble) |
||||||
|
|
||||||
|
# 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() |
||||||
|
|
||||||
|
# BundleUtilities doesn't re-copy changed files, so 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) |
||||||
|
|
||||||
|
file(GLOB FLUTTER_PLUGIN_DIRS "${PROJECT_BINARY_DIR}/plugins/*") |
||||||
|
|
||||||
|
INSTALL(CODE " |
||||||
|
include(BundleUtilities) |
||||||
|
fixup_bundle(\"\${CMAKE_INSTALL_PREFIX}/${BINARY_NAME}\" \"\" |
||||||
|
\"${FLUTTER_PLUGIN_DIRS};${FLUTTER_LIBRARY_DIR}\") |
||||||
|
" COMPONENT Runtime) |
||||||
|
|
||||||
|
INSTALL(FILES "${FLUTTER_ICU_DATA_FILE}" DESTINATION "${INSTALL_BUNDLE_DATA_DIR}" |
||||||
|
COMPONENT Runtime) |
||||||
|
|
||||||
|
# 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 lib directory on non-Debug builds only. |
||||||
|
if (NOT CMAKE_BUILD_TYPE MATCHES "Debug") |
||||||
|
INSTALL(DIRECTORY "${PROJECT_BUILD_DIR}/lib" |
||||||
|
DESTINATION "${CMAKE_INSTALL_PREFIX}" COMPONENT Runtime) |
||||||
|
endif() |
@ -0,0 +1,108 @@ |
|||||||
|
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. |
||||||
|
set(WRAPPER_ROOT "${EPHEMERAL_DIR}/cpp_client_wrapper_glfw") |
||||||
|
|
||||||
|
# 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 === |
||||||
|
set(FLUTTER_LIBRARY "${EPHEMERAL_DIR}/libflutter_linux_glfw.so") |
||||||
|
|
||||||
|
# Published to parent scope for install step. |
||||||
|
set(FLUTTER_LIBRARY_DIR "${EPHEMERAL_DIR}" PARENT_SCOPE) |
||||||
|
set(FLUTTER_ICU_DATA_FILE "${EPHEMERAL_DIR}/icudtl.dat" PARENT_SCOPE) |
||||||
|
set(PROJECT_BUILD_DIR "${PROJECT_DIR}/build/" PARENT_SCOPE) |
||||||
|
|
||||||
|
list(APPEND FLUTTER_LIBRARY_HEADERS |
||||||
|
"flutter_export.h" |
||||||
|
"flutter_glfw.h" |
||||||
|
"flutter_messenger.h" |
||||||
|
"flutter_plugin_registrar.h" |
||||||
|
) |
||||||
|
list_prepend(FLUTER_LIBRARY_HEADERS "${EPHEMERAL_DIR}/") |
||||||
|
add_library(flutter INTERFACE) |
||||||
|
target_include_directories(flutter INTERFACE |
||||||
|
"${EPHEMERAL_DIR}" |
||||||
|
) |
||||||
|
target_link_libraries(flutter INTERFACE "${FLUTTER_LIBRARY}") |
||||||
|
add_dependencies(flutter flutter_assemble) |
||||||
|
|
||||||
|
# === Wrapper === |
||||||
|
list(APPEND CPP_WRAPPER_SOURCES_CORE |
||||||
|
"engine_method_result.cc" |
||||||
|
"standard_codec.cc" |
||||||
|
) |
||||||
|
list_prepend(CPP_WRAPPER_SOURCES_CORE "${WRAPPER_ROOT}/") |
||||||
|
list(APPEND CPP_WRAPPER_SOURCES_PLUGIN |
||||||
|
"plugin_registrar.cc" |
||||||
|
) |
||||||
|
list_prepend(CPP_WRAPPER_SOURCES_PLUGIN "${WRAPPER_ROOT}/") |
||||||
|
list(APPEND CPP_WRAPPER_SOURCES_APP |
||||||
|
"flutter_engine.cc" |
||||||
|
"flutter_window_controller.cc" |
||||||
|
) |
||||||
|
list_prepend(CPP_WRAPPER_SOURCES_APP "${WRAPPER_ROOT}/") |
||||||
|
|
||||||
|
# Wrapper sources needed for a plugin. |
||||||
|
add_library(flutter_wrapper_plugin STATIC |
||||||
|
${CPP_WRAPPER_SOURCES_CORE} |
||||||
|
${CPP_WRAPPER_SOURCES_PLUGIN} |
||||||
|
) |
||||||
|
apply_standard_settings(flutter_wrapper_plugin) |
||||||
|
set_target_properties(flutter_wrapper_plugin PROPERTIES |
||||||
|
POSITION_INDEPENDENT_CODE ON) |
||||||
|
set_target_properties(flutter_wrapper_plugin PROPERTIES |
||||||
|
CXX_VISIBILITY_PRESET hidden) |
||||||
|
target_link_libraries(flutter_wrapper_plugin PUBLIC flutter) |
||||||
|
target_include_directories(flutter_wrapper_plugin PUBLIC |
||||||
|
"${WRAPPER_ROOT}/include" |
||||||
|
) |
||||||
|
add_dependencies(flutter_wrapper_plugin flutter_assemble) |
||||||
|
|
||||||
|
# Wrapper sources needed for the runner. |
||||||
|
add_library(flutter_wrapper_app STATIC |
||||||
|
${CPP_WRAPPER_SOURCES_CORE} |
||||||
|
${CPP_WRAPPER_SOURCES_APP} |
||||||
|
) |
||||||
|
apply_standard_settings(flutter_wrapper_app) |
||||||
|
target_link_libraries(flutter_wrapper_app PUBLIC flutter) |
||||||
|
target_include_directories(flutter_wrapper_app PUBLIC |
||||||
|
"${WRAPPER_ROOT}/include" |
||||||
|
) |
||||||
|
add_dependencies(flutter_wrapper_app 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} |
||||||
|
${CPP_WRAPPER_SOURCES_CORE} ${CPP_WRAPPER_SOURCES_PLUGIN} |
||||||
|
${CPP_WRAPPER_SOURCES_APP} |
||||||
|
${CMAKE_CURRENT_BINARY_DIR}/_phony_ |
||||||
|
COMMAND ${CMAKE_COMMAND} -E env |
||||||
|
${FLUTTER_TOOL_ENVIRONMENT} |
||||||
|
"${FLUTTER_ROOT}/packages/flutter_tools/bin/tool_backend.sh" |
||||||
|
linux-x64 ${CMAKE_BUILD_TYPE} |
||||||
|
) |
||||||
|
add_custom_target(flutter_assemble DEPENDS |
||||||
|
"${FLUTTER_LIBRARY}" |
||||||
|
${FLUTTER_LIBRARY_HEADERS} |
||||||
|
${CPP_WRAPPER_SOURCES_CORE} |
||||||
|
${CPP_WRAPPER_SOURCES_PLUGIN} |
||||||
|
${CPP_WRAPPER_SOURCES_APP} |
||||||
|
) |
@ -0,0 +1,12 @@ |
|||||||
|
//
|
||||||
|
// Generated file. Do not edit.
|
||||||
|
//
|
||||||
|
|
||||||
|
#include "generated_plugin_registrant.h" |
||||||
|
|
||||||
|
#include <argon2_ffi_plugin.h> |
||||||
|
|
||||||
|
void RegisterPlugins(flutter::PluginRegistry* registry) { |
||||||
|
Argon2FfiPluginRegisterWithRegistrar( |
||||||
|
registry->GetRegistrarForPlugin("Argon2FfiPlugin")); |
||||||
|
} |
@ -0,0 +1,13 @@ |
|||||||
|
//
|
||||||
|
// Generated file. Do not edit.
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef GENERATED_PLUGIN_REGISTRANT_ |
||||||
|
#define GENERATED_PLUGIN_REGISTRANT_ |
||||||
|
|
||||||
|
#include <flutter/plugin_registry.h> |
||||||
|
|
||||||
|
// Registers Flutter plugins.
|
||||||
|
void RegisterPlugins(flutter::PluginRegistry* registry); |
||||||
|
|
||||||
|
#endif // GENERATED_PLUGIN_REGISTRANT_
|
@ -0,0 +1,8 @@ |
|||||||
|
list(APPEND FLUTTER_PLUGIN_LIST |
||||||
|
argon2_ffi |
||||||
|
) |
||||||
|
|
||||||
|
foreach(plugin ${FLUTTER_PLUGIN_LIST}) |
||||||
|
add_subdirectory(flutter/ephemeral/.plugin_symlinks/${plugin}/linux plugins/${plugin}) |
||||||
|
target_link_libraries(${BINARY_NAME} PRIVATE ${plugin}_plugin) |
||||||
|
endforeach(plugin) |
@ -0,0 +1,64 @@ |
|||||||
|
#include <flutter/flutter_engine.h> |
||||||
|
#include <flutter/flutter_window_controller.h> |
||||||
|
#include <linux/limits.h> |
||||||
|
#include <unistd.h> |
||||||
|
|
||||||
|
#include <cstdlib> |
||||||
|
#include <iostream> |
||||||
|
#include <memory> |
||||||
|
#include <vector> |
||||||
|
|
||||||
|
#include "flutter/generated_plugin_registrant.h" |
||||||
|
#include "window_configuration.h" |
||||||
|
|
||||||
|
namespace { |
||||||
|
|
||||||
|
// Runs the application in headless mode, without a window.
|
||||||
|
void RunHeadless(const std::string& icu_data_path, |
||||||
|
const std::string& assets_path, |
||||||
|
const std::vector<std::string>& arguments, |
||||||
|
const std::string& aot_library_path) { |
||||||
|
flutter::FlutterEngine engine; |
||||||
|
engine.Start(icu_data_path, assets_path, arguments, aot_library_path); |
||||||
|
RegisterPlugins(&engine); |
||||||
|
while (true) { |
||||||
|
engine.RunEventLoopWithTimeout(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
int main(int argc, char **argv) { |
||||||
|
std::string data_directory = "data"; |
||||||
|
std::string assets_path = data_directory + "/flutter_assets"; |
||||||
|
std::string icu_data_path = data_directory + "/icudtl.dat"; |
||||||
|
|
||||||
|
std::string lib_directory = "lib"; |
||||||
|
std::string aot_library_path = lib_directory + "/libapp.so"; |
||||||
|
|
||||||
|
// Arguments for the Flutter Engine.
|
||||||
|
std::vector<std::string> arguments; |
||||||
|
|
||||||
|
flutter::FlutterWindowController flutter_controller(icu_data_path); |
||||||
|
flutter::WindowProperties window_properties = {}; |
||||||
|
window_properties.title = kFlutterWindowTitle; |
||||||
|
window_properties.width = kFlutterWindowWidth; |
||||||
|
window_properties.height = kFlutterWindowHeight; |
||||||
|
|
||||||
|
// Start the engine.
|
||||||
|
if (!flutter_controller.CreateWindow(window_properties, assets_path, |
||||||
|
arguments, aot_library_path)) { |
||||||
|
if (getenv("DISPLAY") == nullptr) { |
||||||
|
std::cout << "No DISPLAY; falling back to headless mode." << std::endl; |
||||||
|
RunHeadless(icu_data_path, assets_path, arguments, aot_library_path); |
||||||
|
return EXIT_SUCCESS; |
||||||
|
} |
||||||
|
return EXIT_FAILURE; |
||||||
|
} |
||||||
|
RegisterPlugins(&flutter_controller); |
||||||
|
|
||||||
|
// Run until the window is closed.
|
||||||
|
while (flutter_controller.RunEventLoopWithTimeout()) { |
||||||
|
} |
||||||
|
return EXIT_SUCCESS; |
||||||
|
} |
@ -0,0 +1,5 @@ |
|||||||
|
#include "window_configuration.h" |
||||||
|
|
||||||
|
const char *kFlutterWindowTitle = "argon2_ffi_example"; |
||||||
|
const unsigned int kFlutterWindowWidth = 1280; |
||||||
|
const unsigned int kFlutterWindowHeight = 720; |
@ -0,0 +1,15 @@ |
|||||||
|
#ifndef WINDOW_CONFIGURATION_ |
||||||
|
#define WINDOW_CONFIGURATION_ |
||||||
|
|
||||||
|
// This is a temporary approach to isolate common customizations from main.cpp,
|
||||||
|
// where the APIs are still in flux. This should simplify re-creating the
|
||||||
|
// runner while preserving local changes.
|
||||||
|
//
|
||||||
|
// Longer term there should be simpler configuration options for common
|
||||||
|
// customizations like this, without requiring native code changes.
|
||||||
|
|
||||||
|
extern const char *kFlutterWindowTitle; |
||||||
|
extern const unsigned int kFlutterWindowWidth; |
||||||
|
extern const unsigned int kFlutterWindowHeight; |
||||||
|
|
||||||
|
#endif // WINDOW_CONFIGURATION_
|
Loading…
Reference in new issue