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