jasmine Documentation

A comic browser,support Android / iOS / MacOS / Windows / Linux.

5,492 stars Dart Dart 2 files · ~16,138 tokens #acg#comic#cosplay#flutter#hentai#ios#jmcomic#pica
RAW Doc

File: README.md

A comic browser,support Android / iOS / MacOS / Windows / Linux.

  1. This APP has restricted content
  2. Please know local laws before using these codes
  3. The owner of the repo will not release these codes and its assets to the community outside github

Screenshot

Browser

Reader

Features

  • Comics
    • Comic categories
    • Comic reader
    • Comic search
    • Comic favours
    • Histories
    • Cache comic
  • Games
  • Community
    • List comments
    • Send comments
  • User
    • Login / Register
  • Devices adaptation
    • Android's high frequency screen

Technical architecture

Flutter: high-performance UI

Rust: High performance service

Please follow the rules

  • These codes can only be learned and used, and are prohibited for commercial use
  • Do not send Assets to anyone

File: analysis_options.yaml

This file configures the analyzer, which statically analyzes Dart code to

check for errors, warnings, and lints.

The issues identified by the analyzer are surfaced in the UI of Dart-enabled

IDEs (https://dart.dev/tools#ides-and-editors). The analyzer can also be

invoked from the command line by running `flutter analyze`.

packages, and plugins designed to encourage good coding practices.

include: package:flutter_lints/flutter.yaml

linter:

The lint rules applied to this project can be customized in the

section below to disable rules from the `package:flutter_lints/flutter.yaml`

included above or to enable additional rules. A list of all available lints

and their documentation is published at

https://dart-lang.github.io/linter/lints/index.html.

Instead of disabling a lint rule for the entire project in the

section below, it can also be suppressed for a single line of code

or a specific dart file by using the `// ignore: name_of_lint` and

`// ignore_for_file: name_of_lint` syntax on the line or in the file

producing the lint.

rules:
# avoid_print: false # Uncomment to disable the avoid_print rule
# prefer_single_quotes: true # Uncomment to enable the prefer_single_quotes rule

Additional information about this file can be found at

https://dart.dev/guides/language/analysis-options


File: pubspec.yaml

name: jasmine
publish_to: 'none'

version: 1.7.21+49

environment:
sdk: ">=2.17.0 <3.0.0"

dependencies:
flutter:
sdk: flutter
cupertino_icons: ^1.0.2
flutter_svg: ^1.0.0
flutter_styled_toast: ^2.0.0
photo_view: ^0.14.0
event: ^2.1.2
modal_bottom_sheet: ^3.0.0-pre
another_xlider: ^1.0.1+2
scrollable_positioned_list: ^0.2.3
clipboard: ^0.1.3
filesystem_picker: ^4.1.0
window_manager: ^0.3.2
file_picker: ^10.3.10
image_picker: ^1.2.0
permission_handler: ^12.0.1
zoomable_positioned_list: ^1.1.0
flutter_inappwebview: ^6.1.5
url_launcher: ^6.3.2

dev_dependencies:
flutter_test:
sdk: flutter
flutter_lints: ^1.0.0

flutter:
uses-material-design: true
assets:
- lib/assets/


File: README-zh.md

一个简单易用的二次元浏览器,同时支持支持 Android / iOS / MacOS / Windows.

  1. 此APP内容存在限制级别内容(露骨/血腥/暴力)。
  2. 您在下载使用代码或安装包之前,请务必悉知当地法规,是否允许使用或传播包含上述内容的软件。
  3. 仓库作者不会在除Github以外的地方发布软件的代码或安装包,不对分发代码或软件承担责任。因传播载造成的法律问题或纠纷, 需行为人自行处理。

软件截图

浏览器

阅读器

实现功能

  • 漫画
    • 漫画分类检索
    • 阅读漫画
    • 搜索漫画
    • 收藏漫画
    • 浏览记录
    • 下载漫画
  • 游戏
  • 社区
    • 获取评论
    • 发布评论
  • 用户
    • 登录/注册
  • 设备优化
    • 安卓的高刷新率屏幕的支持

技术架构

flutter + rust

flutter实现了高性能的跨平台界面渲染,rust实现了安全以及高效的业务调度。

请您遵守使用规则

软件副本分发以及代码使用规则规则

  • 本仓库代码供学习交流使用, 个人或企业不可用于商业用途, 不可上架任何商店。
  • 本软fork或者其他方式产生的仓库或复制了本仓库代码releases。
  • 不要在任何其他 二次元软件 的 聊天社区 或 开发社区 内, 发布有关本软件的链接或信息, 对于观点不同产生的分歧作者不站队任何立场。
  • 不要发送本软件安装包到 任何社区内 , 不要将APK/IPA/ZIP/DMG发送包括任何聊天软件内的群聊功能。 分享本软件时, 在社区中使用Github中提供的Releases页面的链接, 或使用私聊窗口发送。

源代码使用规则

  • 对本仓库的fork需要保留本仓库的链接, 以引导用户在主要仓库进行讨论。

责任声明

  • 作者仅分享编程技术, 不分发软件, 不对分发软件承担任何后果。 因传播载造成的法律问题或纠纷, 需行为人自行承担, 请您遵守当地法以及副本接受方(社区或人)所在地区的法律。

File: ci/version.code.txt

v1.7.21


File: ci/version.info.txt

v1.7.21


File: ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json

{
"images" : [
{
"size" : "20x20",
"idiom" : "iphone",
"filename" : "[email protected]",
"scale" : "2x"
},
{
"size" : "20x20",
"idiom" : "iphone",
"filename" : "[email protected]",
"scale" : "3x"
},
{
"size" : "29x29",
"idiom" : "iphone",
"filename" : "[email protected]",
"scale" : "1x"
},
{
"size" : "29x29",
"idiom" : "iphone",
"filename" : "[email protected]",
"scale" : "2x"
},
{
"size" : "29x29",
"idiom" : "iphone",
"filename" : "[email protected]",
"scale" : "3x"
},
{
"size" : "40x40",
"idiom" : "iphone",
"filename" : "[email protected]",
"scale" : "2x"
},
{
"size" : "40x40",
"idiom" : "iphone",
"filename" : "[email protected]",
"scale" : "3x"
},
{
"size" : "60x60",
"idiom" : "iphone",
"filename" : "[email protected]",
"scale" : "2x"
},
{
"size" : "60x60",
"idiom" : "iphone",
"filename" : "[email protected]",
"scale" : "3x"
},
{
"size" : "20x20",
"idiom" : "ipad",
"filename" : "[email protected]",
"scale" : "1x"
},
{
"size" : "20x20",
"idiom" : "ipad",
"filename" : "[email protected]",
"scale" : "2x"
},
{
"size" : "29x29",
"idiom" : "ipad",
"filename" : "[email protected]",
"scale" : "1x"
},
{
"size" : "29x29",
"idiom" : "ipad",
"filename" : "[email protected]",
"scale" : "2x"
},
{
"size" : "40x40",
"idiom" : "ipad",
"filename" : "[email protected]",
"scale" : "1x"
},
{
"size" : "40x40",
"idiom" : "ipad",
"filename" : "[email protected]",
"scale" : "2x"
},
{
"size" : "76x76",
"idiom" : "ipad",
"filename" : "[email protected]",
"scale" : "1x"
},
{
"size" : "76x76",
"idiom" : "ipad",
"filename" : "[email protected]",
"scale" : "2x"
},
{
"size" : "83.5x83.5",
"idiom" : "ipad",
"filename" : "[email protected]",
"scale" : "2x"
},
{
"size" : "1024x1024",
"idiom" : "ios-marketing",
"filename" : "[email protected]",
"scale" : "1x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}


File: ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md

Launch Screen Assets

You can customize the launch screen with your own desired assets by replacing the image files in this directory.

You can also do it by opening your Flutter project's Xcode project with open ios/Runner.xcworkspace, selecting Runner/Assets.xcassets in the Project Navigator and dropping in the desired images.


File: ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json

{
"images" : [
{
"idiom" : "universal",
"filename" : "LaunchImage.png",
"scale" : "1x"
},
{
"idiom" : "universal",
"filename" : "[email protected]",
"scale" : "2x"
},
{
"idiom" : "universal",
"filename" : "[email protected]",
"scale" : "3x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}


File: linux/CMakeLists.txt

cmake_minimum_required(VERSION 3.10)
project(runner LANGUAGES CXX)

set(BINARY_NAME "jasmine")
set(APPLICATION_ID "com.example.jasmine")

cmake_policy(SET CMP0063 NEW)

link_directories("${CMAKE_SOURCE_DIR}")

set(CMAKE_INSTALL_RPATH "$ORIGIN/lib")

Root filesystem for cross-building.

if(FLUTTER_TARGET_PLATFORM_SYSROOT)
set(CMAKE_SYSROOT ${FLUTTER_TARGET_PLATFORM_SYSROOT})
set(CMAKE_FIND_ROOT_PATH ${CMAKE_SYSROOT})
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
endif()

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"
"methods_plugin.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)
target_link_libraries(${BINARY_NAME} PRIVATE rust dl pthread)
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)

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()


File: linux/flutter/CMakeLists.txt

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)

Some projects may have stale/partial generated config that doesn't set

FLUTTER_TARGET_PLATFORM, which causes tool_backend.dart to crash due to

missing arguments. Provide a sensible default based on architecture.

if(NOT FLUTTER_TARGET_PLATFORM)
if(CMAKE_SYSTEM_PROCESSOR MATCHES "^(x86_64|amd64)$")
set(FLUTTER_TARGET_PLATFORM "linux-x64")
elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "^(aarch64|arm64)$")
set(FLUTTER_TARGET_PLATFORM "linux-arm64")
else()
message(WARNING "FLUTTER_TARGET_PLATFORM was not set; defaulting to linux-x64 for processor: ${CMAKE_SYSTEM_PROCESSOR}")
set(FLUTTER_TARGET_PLATFORM "linux-x64")
endif()
endif()

=== 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}
)


File: macos/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json

{
"images" : [
{
"size" : "16x16",
"idiom" : "mac",
"filename" : "app_icon_16.png",
"scale" : "1x"
},
{
"size" : "16x16",
"idiom" : "mac",
"filename" : "app_icon_32.png",
"scale" : "2x"
},
{
"size" : "32x32",
"idiom" : "mac",
"filename" : "app_icon_32.png",
"scale" : "1x"
},
{
"size" : "32x32",
"idiom" : "mac",
"filename" : "app_icon_64.png",
"scale" : "2x"
},
{
"size" : "128x128",
"idiom" : "mac",
"filename" : "app_icon_128.png",
"scale" : "1x"
},
{
"size" : "128x128",
"idiom" : "mac",
"filename" : "app_icon_256.png",
"scale" : "2x"
},
{
"size" : "256x256",
"idiom" : "mac",
"filename" : "app_icon_256.png",
"scale" : "1x"
},
{
"size" : "256x256",
"idiom" : "mac",
"filename" : "app_icon_512.png",
"scale" : "2x"
},
{
"size" : "512x512",
"idiom" : "mac",
"filename" : "app_icon_512.png",
"scale" : "1x"
},
{
"size" : "512x512",
"idiom" : "mac",
"filename" : "app_icon_1024.png",
"scale" : "2x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}


File: ohos/AppScope/resources/base/element/string.json

{
"string": [
{
"name": "app_name",
"value": "jasmine"
}
]
}


File: ohos/entry/src/main/resources/base/element/color.json

{
"color": [
{
"name": "start_window_background",
"value": "#FFFFFF"
}
]
}


File: ohos/entry/src/main/resources/base/element/string.json

{
"string": [
{
"name": "module_desc",
"value": "module description"
},
{
"name": "EntryAbility_desc",
"value": "description"
},
{
"name": "EntryAbility_label",
"value": "jasmine"
}
]
}


File: ohos/entry/src/main/resources/base/profile/main_pages.json

{
"src": [
"pages/Index"
]
}


File: ohos/entry/src/main/resources/en_US/element/string.json

{
"string": [
{
"name": "module_desc",
"value": "module description"
},
{
"name": "EntryAbility_desc",
"value": "description"
},
{
"name": "EntryAbility_label",
"value": "jasmine"
}
]
}


File: ohos/entry/src/main/resources/zh_CN/element/string.json

{
"string": [
{
"name": "module_desc",
"value": "模块描述"
},
{
"name": "EntryAbility_desc",
"value": "description"
},
{
"name": "EntryAbility_label",
"value": "jasmine"
}
]
}


File: ohos/entry/src/ohosTest/resources/base/element/color.json

{
"color": [
{
"name": "start_window_background",
"value": "#FFFFFF"
}
]
}


File: ohos/entry/src/ohosTest/resources/base/element/string.json

{
"string": [
{
"name": "module_test_desc",
"value": "test ability description"
},
{
"name": "TestAbility_desc",
"value": "the test ability"
},
{
"name": "TestAbility_label",
"value": "test label"
}
]
}


File: ohos/entry/src/ohosTest/resources/base/profile/test_pages.json

{
"src": [
"testability/pages/Index"
]
}


File: scripts/ohos-pubspec.yaml

modal_bottom_sheet:
git:
url: https://github.com/niuhuan/modal_bottom_sheet.git
ref: ohos
path: modal_bottom_sheet


File: windows/CMakeLists.txt

cmake_minimum_required(VERSION 3.14)
project(jasmine LANGUAGES CXX)

set(BINARY_NAME "jasmine")

cmake_policy(SET CMP0063 NEW)

set(CMAKE_INSTALL_RPATH "$ORIGIN/lib")

Configure build options.

get_property(IS_MULTICONFIG GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG)
if(IS_MULTICONFIG)
set(CMAKE_CONFIGURATION_TYPES "Debug;Profile;Release"
CACHE STRING "" FORCE)
else()
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()
endif()

set(CMAKE_EXE_LINKER_FLAGS_PROFILE "${CMAKE_EXE_LINKER_FLAGS_RELEASE}")
set(CMAKE_SHARED_LINKER_FLAGS_PROFILE "${CMAKE_SHARED_LINKER_FLAGS_RELEASE}")
set(CMAKE_C_FLAGS_PROFILE "${CMAKE_C_FLAGS_RELEASE}")
set(CMAKE_CXX_FLAGS_PROFILE "${CMAKE_CXX_FLAGS_RELEASE}")

Use Unicode for all projects.

add_definitions(-DUNICODE -D_UNICODE)

Compilation settings that should be applied to most targets.

function(APPLY_STANDARD_SETTINGS TARGET)
target_compile_features(${TARGET} PUBLIC cxx_std_17)
target_compile_options(${TARGET} PRIVATE /W4 /WX /wd"4100")
target_compile_options(${TARGET} PRIVATE /EHsc)
target_compile_definitions(${TARGET} PRIVATE "_HAS_EXCEPTIONS=0")
target_compile_definitions(${TARGET} PRIVATE "$<$CONFIG:Debug:_DEBUG>")
endfunction()

set(FLUTTER_MANAGED_DIR "${CMAKE_CURRENT_SOURCE_DIR}/flutter")

Flutter library and tool build rules.

add_subdirectory(${FLUTTER_MANAGED_DIR})

Application build

add_subdirectory("runner")

Generated plugin build rules, which manage building the plugins and adding

them to the application.

include(flutter/generated_plugins.cmake)

=== Installation ===

Support files are copied into place next to the executable, so that it can

run in place. This is done instead of making a separate bundle (as on Linux)

so that building and running from within Visual Studio will work.

set(BUILD_BUNDLE_DIR "$<TARGET_FILE_DIR:${BINARY_NAME}>")

Make the "install" step default, as it's required to run.

set(CMAKE_VS_INCLUDE_INSTALL_TO_DEFAULT_BUILD 1)
if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT)
set(CMAKE_INSTALL_PREFIX "${BUILD_BUNDLE_DIR}" CACHE PATH "..." FORCE)
endif()

set(INSTALL_BUNDLE_DATA_DIR "${CMAKE_INSTALL_PREFIX}/data")
set(INSTALL_BUNDLE_LIB_DIR "${CMAKE_INSTALL_PREFIX}")

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)

Install the AOT library on non-Debug builds only.

install(FILES "${AOT_LIBRARY}" DESTINATION "${INSTALL_BUNDLE_DATA_DIR}"
CONFIGURATIONS Profile;Release
COMPONENT Runtime)


File: windows/flutter/CMakeLists.txt

cmake_minimum_required(VERSION 3.14)

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")

=== Flutter Library ===

set(FLUTTER_LIBRARY "${EPHEMERAL_DIR}/flutter_windows.dll")

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/windows/app.so" PARENT_SCOPE)

list(APPEND FLUTTER_LIBRARY_HEADERS
"flutter_export.h"
"flutter_windows.h"
"flutter_messenger.h"
"flutter_plugin_registrar.h"
"flutter_texture_registrar.h"
)
list(TRANSFORM FLUTTER_LIBRARY_HEADERS PREPEND "${EPHEMERAL_DIR}/")
add_library(flutter INTERFACE)
target_include_directories(flutter INTERFACE
"${EPHEMERAL_DIR}"
)
target_link_libraries(flutter INTERFACE "${FLUTTER_LIBRARY}.lib")
add_dependencies(flutter flutter_assemble)

=== Wrapper ===

list(APPEND CPP_WRAPPER_SOURCES_CORE
"core_implementations.cc"
"standard_codec.cc"
)
list(TRANSFORM CPP_WRAPPER_SOURCES_CORE PREPEND "${WRAPPER_ROOT}/")
list(APPEND CPP_WRAPPER_SOURCES_PLUGIN
"plugin_registrar.cc"
)
list(TRANSFORM CPP_WRAPPER_SOURCES_PLUGIN PREPEND "${WRAPPER_ROOT}/")
list(APPEND CPP_WRAPPER_SOURCES_APP
"flutter_engine.cc"
"flutter_view_controller.cc"
)
list(TRANSFORM CPP_WRAPPER_SOURCES_APP PREPEND "${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.

set(PHONY_OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/phony")
set_source_files_properties("${PHONY_OUTPUT}" PROPERTIES SYMBOLIC TRUE)
add_custom_command(
OUTPUT ${FLUTTER_LIBRARY} ${FLUTTER_LIBRARY_HEADERS}
${CPP_WRAPPER_SOURCES_CORE} ${CPP_WRAPPER_SOURCES_PLUGIN}
${CPP_WRAPPER_SOURCES_APP}
${PHONY_OUTPUT}
COMMAND ${CMAKE_COMMAND} -E env
${FLUTTER_TOOL_ENVIRONMENT}
"${FLUTTER_ROOT}/packages/flutter_tools/bin/tool_backend.bat"
windows-x64 $
VERBATIM
)
add_custom_target(flutter_assemble DEPENDS
"${FLUTTER_LIBRARY}"
${FLUTTER_LIBRARY_HEADERS}
${CPP_WRAPPER_SOURCES_CORE}
${CPP_WRAPPER_SOURCES_PLUGIN}
${CPP_WRAPPER_SOURCES_APP}
)


File: windows/runner/CMakeLists.txt

cmake_minimum_required(VERSION 3.14)
project(runner LANGUAGES CXX)

link_directories("../")

add_executable(${BINARY_NAME} WIN32
"flutter_window.cpp"
"main.cpp"
"utils.cpp"
"win32_window.cpp"
"${FLUTTER_MANAGED_DIR}/generated_plugin_registrant.cc"
"Runner.rc"
"runner.exe.manifest"
"methods_plugin.cpp"
)
apply_standard_settings(${BINARY_NAME})
target_compile_definitions(${BINARY_NAME} PRIVATE "NOMINMAX")
target_link_libraries(${BINARY_NAME} PRIVATE flutter flutter_wrapper_app flutter_wrapper_plugin rust
ntdll.lib advapi32.lib bcrypt.lib cfgmgr32.lib credui.lib crypt32.lib cryptnet.lib fwpuclnt.lib kernel32.lib mswsock.lib ncrypt.lib ntdll.lib secur32.lib synchronization.lib user32.lib ws2_32.lib kernel32.lib ws2_32.lib bcrypt.lib advapi32.lib userenv.lib kernel32.lib msvcrt.lib)
target_include_directories(${BINARY_NAME} PRIVATE "${CMAKE_SOURCE_DIR}")
add_dependencies(${BINARY_NAME} flutter_assemble)


File: .github/workflows/Build.yml

name: Build

on:
workflow_dispatch:

env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
RUST_TOOLCHAIN: nightly-2024-12-02
NDK_VERSION: 25.2.9519653

jobs:

ci-pass:
name: CI is green
runs-on: ubuntu-latest
needs:
- build_release_assets
steps:
- run: exit 0

build_release_assets:
name: Build release assets
strategy:
fail-fast: false
matrix:
config:
- target: linux
host: ubuntu-latest
flutter_version: '3.29.3'
flutter_channel: 'stable'
- target: windows
host: windows-2022
flutter_version: '3.29.3'
flutter_channel: 'stable'
- target: macos
host: macos-14
flutter_version: '3.29.3'
flutter_channel: 'stable'
- target: ios
host: macos-14
flutter_version: '3.29.3'
flutter_channel: 'stable'
- target: android-arm32
host: ubuntu-latest
flutter_version: '3.29.3'
flutter_channel: 'stable'
- target: android-arm64
host: ubuntu-latest
flutter_version: '3.29.3'
flutter_channel: 'stable'
- target: android-x86_64
host: ubuntu-latest
flutter_version: '3.29.3'
flutter_channel: 'stable'
# - target: ohos-arm64
# host: macos-latest
# flutter_version: '3.29.3'
# flutter_channel: 'stable'

text
runs-on: ${{ matrix.config.host }}
container: ${{ matrix.config.container }}

env:
  TARGET: ${{ matrix.config.target }}
  flutter_version: ${{ matrix.config.flutter_version }}
  flutter_channel: ${{ matrix.config.flutter_channel }}

steps:

  - name: Checkout
    uses: actions/checkout@v3

  - name: Cargo cache
    uses: actions/cache@v3
    with:
      path: |
        ~/.cargo/bin/
        ~/.cargo/registry/index/
        ~/.cargo/registry/cache/
        ~/.cargo/git/db/
      key: ${{ runner.os }}-cargo-

  - name: Install rust toolchain
    uses: actions-rs/toolchain@v1
    with:
      toolchain: ${{ env.RUST_TOOLCHAIN }}

  - id: check_asset
    name: Check asset
    run: |
      echo "::set-output name=skip_build::false"

  - name: checkout core
    if: steps.check_asset.outputs.skip_build != 'true'
    uses: actions/checkout@v3
    with:
      token: ${{ secrets.GH_TOKEN }}
      path: 'native'

  - name: Cache Flutter dependencies (Linux/Android)
    if: steps.check_asset.outputs.skip_build != 'true' && matrix.config.host == 'ubuntu-latest'
    uses: actions/cache@v3
    with:
      path: /opt/hostedtoolcache/flutter
      key: ${{ runner.os }}-flutter

  - name: Setup flutter
    if: steps.check_asset.outputs.skip_build != 'true'
    uses: subosito/flutter-action@v2
    with:
      channel: ${{ env.flutter_channel }}
      flutter-version: ${{ env.flutter_version }}
      architecture: x64

  - if: matrix.config.target == 'ohos-arm64'
    name: Setup OpenHarmony SDK
    shell: bash
    run: |
      rm -rf "/usr/local/share/boost"
      rm -rf "$AGENT_TOOLSDIRECTORY"
      rm -rf /usr/share/dotnet
      rm -rf /opt/ghc
      cd $(dirname $(dirname $(realpath $(which flutter))))
      git config --global --add safe.directory ${{ env.FLUTTER_ROOT }}
      git remote set-url origin https://gitcode.com/openharmony-sig/flutter_flutter.git
      git fetch
      git checkout 3.22.0-ohos
      git remote prune origin
  
  # git gc --prune=now --aggressive

  - name: Install cargo tools (non-android)
    if: steps.check_asset.outputs.skip_build != 'true' && ( matrix.config.target == 'macos' || matrix.config.target == 'windows' || matrix.config.target == 'linux' || matrix.config.target == 'ios' )
    run: |
      cargo install --force cbindgen

  - name: Install cargo tools (Android)
    if: steps.check_asset.outputs.skip_build != 'true' && ( matrix.config.target == 'android-arm32' || matrix.config.target == 'android-arm64' || matrix.config.target == 'android-x86_64' )
    run: |
      cargo install --force cargo-ndk

  - name: Setup java (Android)
    if: steps.check_asset.outputs.skip_build != 'true' && ( matrix.config.target == 'android-arm32' || matrix.config.target == 'android-arm64' || matrix.config.target == 'android-x86_64' )
    uses: actions/setup-java@v3
    with:
      java-version: '17'
      distribution: 'temurin'

  - name: Setup android tools (Android)
    if: steps.check_asset.outputs.skip_build != 'true' && ( matrix.config.target == 'android-arm32' || matrix.config.target == 'android-arm64' || matrix.config.target == 'android-x86_64' )
    uses: android-actions/setup-android@v3
    with:
      cmdline-tools-version: 8512546
      packages: 'platform-tools platforms;android-32 build-tools;30.0.2 ndk;${{ env.NDK_VERSION }}'

  - name: Install libfuse2 (Linux)
    if: steps.check_asset.outputs.skip_build != 'true' && matrix.config.target == 'linux'
    run: |
      sudo apt update
      sudo apt install -y libfuse2

  - name: Set-Version (All)
    if: steps.check_asset.outputs.skip_build != 'true'
    run: |
      cd ci
      cp version.code.txt ../lib/assets/version.txt


  - name: Append application-identifier (ios)
    if: steps.check_asset.outputs.skip_build != 'true' && ( matrix.config.target == 'ios')
    run: |
      /usr/libexec/PlistBuddy -c 'Add :application-identifier string opensource.jasmine' ios/Runner/Info.plist

  - name: Install rust target and build (ios)
    if: steps.check_asset.outputs.skip_build != 'true' && ( matrix.config.target == 'ios')
    run: |
      rustup target install aarch64-apple-ios
      cargo build --manifest-path native/jmbackend/platforms/ios/Cargo.toml --features= --lib --release --target=aarch64-apple-ios
      cp native/jmbackend/platforms/ios/target/aarch64-apple-ios/release/librust.a ios/
      cbindgen native/jmbackend/src/lib.rs -l c > ios/rust.h
      flutter build ios --no-simulator --no-codesign --release
      cd build
      rm -rf Payload
      mkdir Payload
      mv ios/iphoneos/Runner.app Payload/
      sh ../scripts/thin-payload.sh Payload
      zip -r -9 nosign.ipa Payload
      cd ..

tar zxvf pdfium-ios-device-arm64.tgz --strip-components=1 -C ios/Runner lib/libpdfium.dylib

flutter build ios --no-simulator --no-codesign --release

text
# if ios-sim
  # cargo build --manifest-path native/jmbackend/platforms/ios-sim/Cargo.toml --features= --lib --release --target=aarch64-apple-ios-sim
  # cargo build --manifest-path native/jmbackend/platforms/ios-sim/Cargo.toml --features= --lib --release --target=x86_64-apple-ios
  # lipo -create -output ios/librust.a native/jmbackend/platforms/ios-sim/target/x86_64-apple-ios/release/librust.a native/jmbackend/platforms/ios-sim/target/aarch64-apple-ios-sim/release/librust.a
  # cbindgen native/jmbackend/src/lib.rs -l c > ios/rust.h

  # - if: matrix.config.target == 'ohos-arm64'
  #   name: Setup OpenHarmony SDK
  #   uses: openharmony-rs/[email protected]
  #   id: setup-ohos
  #   with:
  #     version: "5.0.1"
  
  - if: matrix.config.target == 'ohos-arm64'
    name: Install rust target and build (ohos)
    run: |
      export PATH=/opt/harmonyos-tools/command-line-tools/ohpm/bin:$PATH
      export PATH=/opt/harmonyos-tools/command-line-tools/bin:$PATH
      export OHOS_NDK_HOME=/opt/harmonyos-tools/command-line-tools/sdk/default/openharmony
      export OHOS_BASE_SDK_HOME=$OHOS_NDK_HOME
      export OHOS_SDK_NATIVE=$OHOS_NDK_HOME
      export HOS_SDK_HOME=$OHOS_NDK_HOME
      export OHOS_SDK_HOME=$OHOS_NDK_HOME

      rustup target add aarch64-unknown-linux-ohos
      cargo install ohrs
      bash scripts/ohos-native.sh
      rm -rf native

      sed -i 's/  modal_bottom_sheet: \^3.0.0-pre/  modal_bottom_sheet:\n    git:\n      url: https:\/\/github.com\/niuhuan\/modal_bottom_sheet.git\n      branch: ohos\n      path: modal_bottom_sheet/g' pubspec.yaml
      flutter build hap --target-platform ohos-arm64

  - name: Install rust target and build (Android-arm64)
    if: steps.check_asset.outputs.skip_build != 'true' && ( matrix.config.target == 'android-arm64')
    run: |
      export ANDROID_NDK_HOME=$ANDROID_HOME/ndk/${{ env.NDK_VERSION }}
      rustup target install aarch64-linux-android
      cd native/jmbackend/platforms/android
      cargo ndk -o ../../../../android/app/src/main/jniLibs -t arm64-v8a build --release
      cd ../../../..
      flutter build apk --target-platform android-arm64

  - name: Install rust target and build (Android-arm32)
    if: steps.check_asset.outputs.skip_build != 'true' && ( matrix.config.target == 'android-arm32')
    run: |
      export ANDROID_NDK_HOME=$ANDROID_HOME/ndk/${{ env.NDK_VERSION }}
      rustup target install armv7-linux-androideabi
      cd native/jmbackend/platforms/android
      cargo ndk -o ../../../../android/app/src/main/jniLibs -t armeabi-v7a build --release
      cd ../../../..
      flutter build apk --target-platform android-arm

  - name: Install rust target and build (Android-x86_64)
    if: steps.check_asset.outputs.skip_build != 'true' && ( matrix.config.target == 'android-x86_64')
    run: |
      export ANDROID_NDK_HOME=$ANDROID_HOME/ndk/${{ env.NDK_VERSION }}
      rustup target install x86_64-linux-android
      cd native/jmbackend/platforms/android
      cargo ndk -o ../../../../android/app/src/main/jniLibs -t x86_64 build --release
      cd ../../../..
      flutter build apk --target-platform android-x64

  - name: Install dependencies and build (Linux)
    if: steps.check_asset.outputs.skip_build != 'true' && matrix.config.target == 'linux'
    run: |
      sudo apt-get update
      sudo apt install -y ninja-build liblzma-dev libgtk-3-dev libgl1-mesa-dev xorg-dev
      curl -JOL https://github.com/AppImage/AppImageKit/releases/download/continuous/appimagetool-x86_64.AppImage
      chmod a+x appimagetool-x86_64.AppImage
      mv appimagetool-x86_64.AppImage appimagetool

      cargo build --manifest-path native/jmbackend/platforms/linux/Cargo.toml --features= --lib --release --target=x86_64-unknown-linux-gnu
      cp native/jmbackend/platforms/linux/target/x86_64-unknown-linux-gnu/release/librust.a linux/
      cbindgen native/jmbackend/src/lib.rs -l c++ > linux/rust.h
      
      cbindgen native/jmbackend/platforms/linux/src/lib.rs -l c++ > linux/rust1.h

      flutter config --enable-linux-desktop
      flutter build linux --release
      mv build/linux/x64/release/bundle/{jasmine,AppRun}
      cp linux/appimage/* build/linux/x64/release/bundle/
      ./appimagetool build/linux/x64/release/bundle/
      mv *.AppImage build/linux.AppImage


  - name: build (windows)
    if: steps.check_asset.outputs.skip_build != 'true' && matrix.config.target == 'windows'
    run: |
      cargo build --manifest-path native/jmbackend/platforms/windows/Cargo.toml --release --target x86_64-pc-windows-msvc
      cp native/jmbackend/platforms/windows/target/x86_64-pc-windows-msvc/release/rust.lib windows/          
      cbindgen native/jmbackend/src/lib.rs -l c++ > windows/rust.h
      flutter config --enable-windows-desktop
      flutter build windows
      cd build/windows/x64/runner/Release
      Compress-Archive * ../../../../../build/windows.zip
      cd ../../../../..

  - name: Build (macos)
    if: steps.check_asset.outputs.skip_build != 'true' && matrix.config.target == 'macos'
    run: |
      rustup target install x86_64-apple-darwin
      rustup target install aarch64-apple-darwin
      cargo build --manifest-path native/jmbackend/platforms/macos/Cargo.toml --release --target x86_64-apple-darwin
      cargo build --manifest-path native/jmbackend/platforms/macos/Cargo.toml --release --target aarch64-apple-darwin
      lipo -create -output macos/librust.a native/jmbackend/platforms/macos/target/x86_64-apple-darwin/release/librust.a native/jmbackend/platforms/macos/target/aarch64-apple-darwin/release/librust.a
      cbindgen native/jmbackend/src/lib.rs -l c > macos/rust.h
      flutter config --enable-macos-desktop
      flutter build macos
      cd build
      mkdir appimage
      mv macos/Build/Products/Release/jasmine.app appimage/
      ln -sf /Applications appimage/
      hdiutil create -volname jasmine -srcfolder appimage -ov -format UDBZ macos.dmg
      cd ..

  - name: Sign APK (Android)
    if: steps.check_asset.outputs.skip_build != 'true' && ( matrix.config.target == 'android-arm32' || matrix.config.target == 'android-arm64' || matrix.config.target == 'android-x86_64' )
    env:
      KEY_FILE_BASE64: ${{ secrets.KEY_FILE_BASE64 }}
      KEY_PASSWORD: ${{ secrets.KEY_PASSWORD }}
    run: |
      echo $KEY_FILE_BASE64 > key.jks.base64
      base64 -d key.jks.base64 > key.jks
      echo $KEY_PASSWORD | $ANDROID_HOME/build-tools/30.0.2/apksigner sign --ks key.jks build/app/outputs/flutter-apk/app-release.apk


  - if: steps.check_asset.outputs.skip_build != 'true' && matrix.config.target == 'ios'
    name: 'Upload Artifact (iOS)'
    uses: actions/upload-artifact@v4
    with:
      name: 'nosign.ipa'
      path: 'build/nosign.ipa'
      retention-days: 3
  - if: steps.check_asset.outputs.skip_build != 'true' && matrix.config.target == 'ohos-arm64'
    name: 'Upload Artifact (ohos-arm64)'
    uses: actions/upload-artifact@v4
    with:
      name: 'entry-default-unsigned.hap'
      path: 'ohos/entry/build/default/outputs/default/entry-default-unsigned.hap'
      retention-days: 3
  - if: steps.check_asset.outputs.skip_build != 'true' && startsWith(matrix.config.target, 'android')
    name: 'Upload Artifact (Android)'
    uses: actions/upload-artifact@v4
    with:
      name: ${{matrix.config.target}}.apk
      path: 'build/app/outputs/flutter-apk/app-release.apk'
      retention-days: 3
  - if: steps.check_asset.outputs.skip_build != 'true' && matrix.config.target == 'linux'
    name: 'Upload Artifact (Linux)'
    uses: actions/upload-artifact@v4
    with:
      name: 'build.AppImage'
      path: 'build/linux.AppImage'
      retention-days: 3
  - if: steps.check_asset.outputs.skip_build != 'true' && matrix.config.target == 'macos'
    name: 'Upload Artifact (MacOS)'
    uses: actions/upload-artifact@v4
    with:
      name: 'build.dmg'
      path: 'build/macos.dmg'
  - if: steps.check_asset.outputs.skip_build != 'true' && matrix.config.target == 'windows'
    name: 'Upload Artifact (Windows)'
    uses: actions/upload-artifact@v4
    with:
      name: 'windows.zip'
      path: 'build/windows.zip'

File: .github/workflows/BuildForOhos.yml

name: Build for ohos

on:
workflow_dispatch:

env:
RUST_TOOLCHAIN: nightly-2025-02-15

jobs:
build:
runs-on: ubuntu-latest
container: ghcr.io/niuhuan/harmony-next-flutter-pipeline-docker/image:3.22.0-ohos
steps:
- name: Checkout code
uses: actions/checkout@v3
- name: checkout core
uses: actions/checkout@v3
with:
token: ${{ secrets.GH_TOKEN }}
path: 'native'
- name: Install rust toolchain
uses: actions-rs/toolchain@v1
with:
toolchain: ${{ env.RUST_TOOLCHAIN }}
- name: build-core
run: |
apt update
apt install -y build-essential rsync
rustup target add aarch64-unknown-linux-ohos
cargo install ohrs
export OHOS_NDK_HOME=$OHOS_BASE_SDK_HOME
cd native/jmbackend/platforms/ohos
make
find dist -type f -name "*.so" ! -name "librust" -exec rm -f {} ;
- name: rsync
run: |
rsync -av --exclude oh-package.json5 native/jmbackend/platforms/ohos/dist/ ohos/entry/libs/
rm -rf native
- name: build hap
run: |
sed -i 's/ modal_bottom_sheet: ^3.0.0-pre/ modal_bottom_sheet:\n git:\n url: https://github.com/niuhuan/modal_bottom_sheet.git\n ref: ohos\n path: modal_bottom_sheet/g' pubspec.yaml
cp scripts/ohos.images.bak lib/screens/components/images.dart
cp ci/version.code.txt lib/assets/version.txt
flutter build hap --target-platform=ohos-arm64
cd ohos
hvigorw assembleHap --release
- name: Upload Build Output
uses: actions/upload-artifact@v4
with:
name: entry-default-unsigned.hap
path: ohos/entry/build/default/outputs/default/entry-default-unsigned.hap


File: .github/workflows/Release.yml

name: Release

permissions:
contents: write

on:
workflow_dispatch:

env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
RUST_TOOLCHAIN: nightly-2025-02-26
NDK_VERSION: 27.2.12479018
FLUTTER_CHANNEL: stable
FLUTTER_VERSION: '3.29.3'
JDK_VERSION: 17

jobs:

ci-pass:
name: CI is green
runs-on: ubuntu-latest
needs:
- check_release
- build_release_assets
steps:
- run: exit 0

check_release:
name: Check release
runs-on: ubuntu-latest
outputs:
matrix: ${{ steps.check-release.outputs.matrix }}
steps:
- name: Checkout
uses: actions/checkout@v3

text
- name: Check and create release
    id: check-release
    env:
      GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
    run: |
      export VERSION=$(cat ci/version.code.txt | xargs echo)
      echo "VERSION : $VERSION"
      declare -A asset_dict
      asset_dict["ios"]="${{ github.event.repository.name }}-$VERSION-nosign.ipa"
      asset_dict["android-arm64"]="${{ github.event.repository.name }}-arm64-$VERSION.apk"
      asset_dict["android-arm32"]="${{ github.event.repository.name }}-arm32-$VERSION.apk"
      asset_dict["android-core"]="${{ github.event.repository.name }}-android-core-$VERSION.zip"
      asset_dict["windows"]="${{ github.event.repository.name }}-$VERSION-windows-x86_64.zip"
      asset_dict["linux"]="${{ github.event.repository.name }}-$VERSION.AppImage"
      asset_dict["macos"]="${{ github.event.repository.name }}-$VERSION.dmg"
      declare -A host_dict
      host_dict["ios"]="macos-14"
      host_dict["android-arm64"]="ubuntu-latest"
      host_dict["android-arm32"]="ubuntu-latest"
      host_dict["android-core"]="ubuntu-latest"
      host_dict["windows"]="windows-2022"
      host_dict["linux"]="ubuntu-latest"
      host_dict["macos"]="macos-14"
      export RELEASE=$(gh release view $VERSION --json id -q .id || echo "NOT_FOUND")
      echo "RELEASE : $RELEASE"
      if [ "$RELEASE" == "NOT_FOUND" ]; then
        echo "Release does not exist. Creating release $VERSION."
        gh release create $VERSION -t $VERSION -F ci/version.info.txt --target ${{ github.sha }}
      else
        echo "Release $VERSION already exists."
      fi
      gh release view $VERSION --json assets > release_assets.json
      echo release_assets.json :
      cat release_assets.json
      matrix='['
      for key in "${!asset_dict[@]}"; do
        asset_name=${asset_dict[$key]}
        asset_exists=$(jq ".assets[].label" release_assets.json | grep -Fx "\"$asset_name\"" || echo "NOT_FOUND")
        if [ "$asset_exists" == "NOT_FOUND" ]; then
          echo "Asset $asset_name does not exist. Upload is required."
          matrix+="{\"target\": \"$key\", \"host\": \"${host_dict[$key]}\"},"
        else
          echo "Asset $asset_name already exists. No upload is required."
        fi
      done
      matrix=${matrix%,} # Remove trailing comma
      matrix+=']'
      echo matrix=$matrix >> $GITHUB_OUTPUT
      echo "GITHUB_OUTPUT : $GITHUB_OUTPUT :"
      cat $GITHUB_OUTPUT

build_release_assets:
name: Build release assets
needs:
- check_release
strategy:
fail-fast: false
matrix:
config: ${{ fromJson(needs.check_release.outputs.matrix) }}

text
runs-on: ${{ matrix.config.host }}

steps:
  - name: Checkout
    uses: actions/checkout@v3

  - name: Cargo cache
    uses: actions/cache@v3
    with:
      path: |
        ~/.cargo/bin/
        ~/.cargo/registry/index/
        ~/.cargo/registry/cache/
        ~/.cargo/git/db/
      key: ${{ runner.os }}-cargo-

  - name: Install rust toolchain
    uses: actions-rs/toolchain@v1
    with:
      toolchain: ${{ env.RUST_TOOLCHAIN }}

  - name: checkout core
    uses: actions/checkout@v3
    with:
      token: ${{ secrets.GH_TOKEN }}
      path: 'native'

  - name: Cache Flutter dependencies (Linux/Android)
    if: matrix.config.host == 'ubuntu-latest'
    uses: actions/cache@v3
    with:
      path: /opt/hostedtoolcache/flutter
      key: ${{ runner.os }}-flutter

  - name: Setup flutter
    uses: subosito/flutter-action@v2
    with:
      channel: ${{ env.FLUTTER_CHANNEL }}
      flutter-version: ${{ env.FLUTTER_VERSION }}
      architecture: x64

  - name: Install cargo tools (non-android)
    if: ( matrix.config.target == 'macos' || matrix.config.target == 'windows' || matrix.config.target == 'linux' || matrix.config.target == 'ios' )
    run: |
      cargo install --force cbindgen

  - name: Install cargo tools (Android)
    if: startsWith(matrix.config.target, 'android-')
    run: |
      cargo install --force cargo-ndk

  - name: Setup java (Android)
    if: ( matrix.config.target == 'android-arm32' || matrix.config.target == 'android-arm64' || matrix.config.target == 'android-x86_64'  || matrix.config.target == 'android-core')
    uses: actions/setup-java@v3
    with:
      java-version: ${{ env.JDK_VERSION }}
      distribution: 'temurin'

  - name: Setup android tools (Android)
    if: ( matrix.config.target == 'android-arm32' || matrix.config.target == 'android-arm64' || matrix.config.target == 'android-x86_64'  || matrix.config.target == 'android-core')
    uses: android-actions/setup-android@v3
    with:
      cmdline-tools-version: 8512546
      packages: 'platform-tools platforms;android-32 build-tools;30.0.2 ndk;${{ env.NDK_VERSION }}'

  - name: Install libfuse2 (Linux)
    if: matrix.config.target == 'linux'
    run: |
      sudo apt update
      sudo apt install -y libfuse2

  - name: Set-Version (All)
    run: |
      cd ci
      cp version.code.txt ../lib/assets/version.txt

  - name: Append application-identifier (ios)
    if: ( matrix.config.target == 'ios')
    run: |
      /usr/libexec/PlistBuddy -c 'Add :application-identifier string opensource.jasmine' ios/Runner/Info.plist

  - name: Install rust target and build (ios)
    if: ( matrix.config.target == 'ios')
    run: |
      rustup target install aarch64-apple-ios
      cargo build --manifest-path native/jmbackend/platforms/ios/Cargo.toml --features= --lib --release --target=aarch64-apple-ios
      cp native/jmbackend/platforms/ios/target/aarch64-apple-ios/release/librust.a ios/
      cbindgen native/jmbackend/src/lib.rs -l c > ios/rust.h

      flutter build ios --no-simulator --no-codesign --release
      cd build
      rm -rf Payload
      mkdir Payload
      mv ios/iphoneos/Runner.app Payload/
      sh ../scripts/thin-payload.sh Payload
      zip -r -9 nosign.ipa Payload
      cd ..
  

  # if ios-sim
  # rustup target install aarch64-apple-ios-sim
  # rustup target install x86_64-apple-ios
  # cargo build --manifest-path native/jmbackend/platforms/ios-sim/Cargo.toml --features= --lib --release --target=aarch64-apple-ios-sim
  # cargo build --manifest-path native/jmbackend/platforms/ios-sim/Cargo.toml --features= --lib --release --target=x86_64-apple-ios
  # lipo -create -output ios/librust.a native/jmbackend/platforms/ios-sim/target/x86_64-apple-ios/release/librust.a native/jmbackend/platforms/ios-sim/target/aarch64-apple-ios-sim/release/librust.a
  # cbindgen native/jmbackend/src/lib.rs -l c > ios/rust.h

  - name: Install rust target and build (Android-core)
    if: ( matrix.config.target == 'android-core')
    run: |
      export ANDROID_NDK_HOME=$ANDROID_HOME/ndk/${{ env.NDK_VERSION }}
      rustup target install aarch64-linux-android
      rustup target install armv7-linux-androideabi
      rustup target install x86_64-linux-android
      cd native/jmbackend/platforms/android
      cargo ndk -o ../../../../android/app/src/main/jniLibs -t arm64-v8a build --release
      cargo ndk -o ../../../../android/app/src/main/jniLibs -t armeabi-v7a build --release
      cargo ndk -o ../../../../android/app/src/main/jniLibs -t x86_64 build --release
      cd ../../../..
      zip -r -9 android-core.zip android/app/src/main/jniLibs

  - name: Install rust target and build (Android-arm64)
    if: ( matrix.config.target == 'android-arm64')
    run: |
      export ANDROID_NDK_HOME=$ANDROID_HOME/ndk/${{ env.NDK_VERSION }}
      rustup target install aarch64-linux-android
      cd native/jmbackend/platforms/android
      cargo ndk -o ../../../../android/app/src/main/jniLibs -t arm64-v8a build --release
      cd ../../../..
      flutter build apk --target-platform android-arm64

  - name: Install rust target and build (Android-arm32)
    if: ( matrix.config.target == 'android-arm32')
    run: |
      export ANDROID_NDK_HOME=$ANDROID_HOME/ndk/${{ env.NDK_VERSION }}
      rustup target install armv7-linux-androideabi
      cd native/jmbackend/platforms/android
      cargo ndk -o ../../../../android/app/src/main/jniLibs -t armeabi-v7a build --release
      cd ../../../..
      flutter build apk --target-platform android-arm

  - name: Install rust target and build (Android-x86_64)
    if: ( matrix.config.target == 'android-x86_64')
    run: |
      export ANDROID_NDK_HOME=$ANDROID_HOME/ndk/${{ env.NDK_VERSION }}
      rustup target install x86_64-linux-android
      cd native/jmbackend/platforms/android
      cargo ndk -o ../../../../android/app/src/main/jniLibs -t x86_64 build --release
      cd ../../../..
      flutter build apk --target-platform android-x64

  - name: Install dependencies and build (Linux)
    if: matrix.config.target == 'linux'
    run: |
      sudo apt-get update
      sudo apt install -y ninja-build liblzma-dev libgtk-3-dev libgl1-mesa-dev xorg-dev
      curl -JOL https://github.com/AppImage/AppImageKit/releases/download/continuous/appimagetool-x86_64.AppImage
      chmod a+x appimagetool-x86_64.AppImage
      mv appimagetool-x86_64.AppImage appimagetool

      cargo build --manifest-path native/jmbackend/platforms/linux/Cargo.toml --features= --lib --release --target=x86_64-unknown-linux-gnu
      cp native/jmbackend/platforms/linux/target/x86_64-unknown-linux-gnu/release/librust.a linux/
      cbindgen native/jmbackend/src/lib.rs -l c++ > linux/rust.h
      
      cbindgen native/jmbackend/platforms/linux/src/lib.rs -l c++ > linux/rust1.h

      flutter config --enable-linux-desktop
      flutter build linux --release
      mv build/linux/x64/release/bundle/{jasmine,AppRun}
      cp linux/appimage/* build/linux/x64/release/bundle/
      ./appimagetool build/linux/x64/release/bundle/
      mv *.AppImage build/linux.AppImage


  - name: build (windows)
    if: matrix.config.target == 'windows'
    run: |
      cargo build --manifest-path native/jmbackend/platforms/windows/Cargo.toml --release --target x86_64-pc-windows-msvc
      cp native/jmbackend/platforms/windows/target/x86_64-pc-windows-msvc/release/rust.lib windows/          
      cbindgen native/jmbackend/src/lib.rs -l c++ > windows/rust.h
      flutter config --enable-windows-desktop
      flutter build windows
      cd build/windows/x64/runner/Release
      Compress-Archive * ../../../../../build/windows.zip
      cd ../../../../..

  - name: Build (macos)
    if: matrix.config.target == 'macos'
    run: |
      rustup target install x86_64-apple-darwin
      rustup target install aarch64-apple-darwin
      cargo build --manifest-path native/jmbackend/platforms/macos/Cargo.toml --release --target x86_64-apple-darwin
      cargo build --manifest-path native/jmbackend/platforms/macos/Cargo.toml --release --target aarch64-apple-darwin
      lipo -create -output macos/librust.a native/jmbackend/platforms/macos/target/x86_64-apple-darwin/release/librust.a native/jmbackend/platforms/macos/target/aarch64-apple-darwin/release/librust.a
      cbindgen native/jmbackend/src/lib.rs -l c > macos/rust.h
      flutter config --enable-macos-desktop
      flutter build macos
      cd build
      mkdir appimage
      mv macos/Build/Products/Release/jasmine.app appimage/
      ln -sf /Applications appimage/
      hdiutil create -volname jasmine -srcfolder appimage -ov -format UDBZ macos.dmg
      cd ..

  - name: Sign APK (Android)
    if: ( matrix.config.target == 'android-arm32' || matrix.config.target == 'android-arm64' || matrix.config.target == 'android-x86_64' )
    env:
      KEY_FILE_BASE64: ${{ secrets.KEY_FILE_BASE64 }}
      KEY_PASSWORD: ${{ secrets.KEY_PASSWORD }}
    run: |
      echo $KEY_FILE_BASE64 > key.jks.base64
      base64 -d key.jks.base64 > key.jks
      echo $KEY_PASSWORD | $ANDROID_HOME/build-tools/30.0.2/apksigner sign --ks key.jks build/app/outputs/flutter-apk/app-release.apk

  - name: Upload Asset (windows)
    if: matrix.config.target == 'windows'
    env:
      GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
    run: |
      $VERSION = (Get-Content -Path "ci/version.code.txt").Trim()
      $asset_path = "build/windows.zip"
      $asset_name = "${{ github.event.repository.name }}-$VERSION-windows-x86_64.zip"
      echo "Uploading asset $asset_name from $asset_path"
      mv $asset_path $asset_name
      gh release upload $VERSION $asset_name#$asset_name --clobber

  - name: Upload Asset (android , linux)
    if: startsWith(matrix.config.target, 'android') || startsWith(matrix.config.target, 'linux')
    env:
      GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
    shell: bash
    run: |
      export VERSION=$(cat ci/version.code.txt | xargs echo)
      declare -A asset_dict
      asset_dict["ios"]="${{ github.event.repository.name }}-$VERSION-nosign.ipa"
      asset_dict["android-arm64"]="${{ github.event.repository.name }}-arm64-$VERSION.apk"
      asset_dict["android-arm32"]="${{ github.event.repository.name }}-arm32-$VERSION.apk"
      asset_dict["windows"]="${{ github.event.repository.name }}-$VERSION-windows-x86_64.zip"
      asset_dict["linux"]="${{ github.event.repository.name }}-$VERSION.AppImage"
      asset_dict["macos"]="${{ github.event.repository.name }}-$VERSION.dmg"
      asset_dict["android-core"]="${{ github.event.repository.name }}-android-core-$VERSION.zip"
      declare -A asset_path_dict
      asset_path_dict["ios"]="build/nosign.ipa"
      asset_path_dict["android-arm64"]="build/app/outputs/flutter-apk/app-release.apk"
      asset_path_dict["android-arm32"]="build/app/outputs/flutter-apk/app-release.apk"
      asset_path_dict["windows"]="build/windows.zip"
      asset_path_dict["linux"]="build/linux.AppImage"
      asset_path_dict["macos"]="build/macos.dmg"
      asset_path_dict["android-core"]="android-core.zip"
      
      asset_name=${asset_dict["${{ matrix.config.target }}"]}
      asset_path=${asset_path_dict["${{ matrix.config.target }}"]}
      
      echo "Uploading asset $asset_name from $asset_path"
      mv $asset_path $asset_name
      gh release upload $VERSION "${asset_name}#${asset_name}" --clobber 

  - name: Upload Asset (macos , ios)
    if: startsWith(matrix.config.target, 'macos') || startsWith(matrix.config.target, 'ios')
    env:
      GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
    run: |
      export VERSION=$(cat ci/version.code.txt | xargs echo)
      if [ "${{ matrix.config.target }}" == "ios" ]; then
        asset_name="${{ github.event.repository.name }}-$VERSION-nosign.ipa"
        asset_path="build/nosign.ipa"
      else
        asset_name="${{ github.event.repository.name }}-$VERSION.dmg"
        asset_path="build/macos.dmg"
      fi
      echo "Uploading asset $asset_name from $asset_path"
      mv $asset_path $asset_name
      gh release upload $VERSION "${asset_name}#${asset_name}" --clobber

File: .github/workflows/ReleaseForOhos.yml

name: Release for ohos

permissions:
contents: write

on:
workflow_dispatch:

env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
RUST_TOOLCHAIN: nightly-2025-02-15

jobs:
build-core:
runs-on: ubuntu-latest
container: ghcr.io/niuhuan/harmony-next-flutter-pipeline-docker/image:3.22.0-ohos
steps:
- name: checkout core
uses: actions/checkout@v3
with:
token: ${{ secrets.GH_TOKEN }}
path: 'native'
- name: Install rust toolchain
uses: actions-rs/toolchain@v1
with:
toolchain: ${{ env.RUST_TOOLCHAIN }}
- name: build-core
run: |
apt update
apt install -y build-essential
rustup target add aarch64-unknown-linux-ohos
cargo install ohrs
export OHOS_NDK_HOME=$OHOS_BASE_SDK_HOME
cd native/jmbackend/platforms/ohos
make
find dist -type f -name "*.so" ! -name "librust" -exec rm -f {} ;
- name: Upload Build Output
uses: actions/upload-artifact@v4
with:
name: core-build-output
path: native/jmbackend/platforms/ohos/dist

build-and-upload-hap:
needs: build-core
runs-on: ubuntu-latest
container: ghcr.io/niuhuan/harmony-next-flutter-pipeline-docker/image:latest
steps:
- name: Checkout code
uses: actions/checkout@v3
- name: Download Build Output
uses: actions/download-artifact@v4
with:
name: core-build-output
path: native/jmbackend/platforms/ohos/dist
- name: rsync
run: |
apt update
apt install -y rsync build-essential pkg-config libssl-dev
rsync -av --exclude oh-package.json5 native/jmbackend/platforms/ohos/dist/ ohos/entry/libs/
- name: build hap
run: |
sed -i 's/ modal_bottom_sheet: ^3.0.0-pre/ modal_bottom_sheet:\n git:\n url: https://github.com/niuhuan/modal_bottom_sheet.git\n ref: ohos\n path: modal_bottom_sheet/g' pubspec.yaml
cp scripts/ohos.images.bak lib/screens/components/images.dart
cp ci/version.code.txt lib/assets/version.txt
flutter build hap --target-platform=ohos-arm64
cd ohos
hvigorw assembleHap --release
- name: Install rust toolchain
uses: actions-rs/toolchain@v1
with:
toolchain: ${{ env.RUST_TOOLCHAIN }}

text
- name: Upload Asset
    env:
      GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
    run: |

      (type -p wget >/dev/null || (apt update && apt-get install wget -y)) \
      && mkdir -p -m 755 /etc/apt/keyrings \
      && out=$(mktemp) && wget -nv -O$out https://cli.github.com/packages/githubcli-archive-keyring.gpg \
      && cat $out | tee /etc/apt/keyrings/githubcli-archive-keyring.gpg > /dev/null \
      && chmod go+r /etc/apt/keyrings/githubcli-archive-keyring.gpg \
      && echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/githubcli-archive-keyring.gpg] https://cli.github.com/packages stable main" | tee /etc/apt/sources.list.d/github-cli.list > /dev/null \
      && apt update \
      && apt install curl gh -y
      
      git config --global --add safe.directory $GITHUB_WORKSPACE
      
      export VERSION=$(cat ci/version.code.txt | xargs echo)
      asset_path=ohos/entry/build/default/outputs/default/entry-default-unsigned.hap
      asset_name="${{ github.event.repository.name }}-$VERSION-unsigned.hap"
      echo "Uploading asset $asset_name from $asset_path"
      mv "$asset_path" "$asset_name"
      gh release upload $VERSION "${asset_name}#${asset_name}" --clobber