Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
132 changes: 132 additions & 0 deletions .github/workflows/build-native.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
name: 构建 LVGL 原生库

on:
push:
branches: [main, develop, master]
pull_request:
branches: [main, master]
workflow_dispatch:
workflow_call:

jobs:
build:
name: 构建 ${{ matrix.rid }}
runs-on: ${{ matrix.os }}
permissions:
contents: read
strategy:
fail-fast: false
matrix:
include:
# Windows — 通过 MSVC -A 参数构建多架构
- rid: win-x64
os: windows-latest
cmake_generator: "Visual Studio 17 2022"
cmake_arch: x64
- rid: win-x86
os: windows-latest
cmake_generator: "Visual Studio 17 2022"
cmake_arch: Win32
- rid: win-arm64
os: windows-latest
cmake_generator: "Visual Studio 17 2022"
cmake_arch: ARM64

# Linux — 原生 x64(与 LVGL 官方 CI 一致,使用 ubuntu-24.04)
- rid: linux-x64
os: ubuntu-24.04
cmake_extra: ""

# Linux — ARM 交叉编译(硬浮点)
- rid: linux-arm
os: ubuntu-24.04
apt_packages: gcc-arm-linux-gnueabihf g++-arm-linux-gnueabihf
cmake_extra: >-
-DCMAKE_TOOLCHAIN_FILE=$GITHUB_WORKSPACE/libs/cmake/toolchains/arm-linux-gnueabihf.cmake

# Linux — ARM64 交叉编译
- rid: linux-arm64
os: ubuntu-24.04
apt_packages: gcc-aarch64-linux-gnu g++-aarch64-linux-gnu
cmake_extra: >-
-DCMAKE_TOOLCHAIN_FILE=$GITHUB_WORKSPACE/libs/cmake/toolchains/aarch64-linux-gnu.cmake

steps:
- name: 检出代码
uses: actions/checkout@v4
with:
submodules: recursive

# ─── 将 lv_conf.h 复制到 lvgl 源码目录 ────────────────────────────────
# LVGL 的 CMake 在 CMAKE_SOURCE_DIR(libs/lvgl/)中查找 lv_conf.h,
# 而该文件位于上一级 libs/lv_conf.h,因此需要复制到正确位置。
- name: 复制 lv_conf.h 到 lvgl 源码目录
shell: bash
run: cp libs/lv_conf.h libs/lvgl/lv_conf.h

# ─── Linux:安装构建依赖(参考 LVGL 官方 CI)──────────────────────────
# 参考:https://github.com/lvgl/lvgl/blob/master/.github/workflows/ccpp.yml
# 基础依赖:cmake、ninja-build;交叉编译时额外安装对应工具链
- name: 安装 Linux 构建依赖
if: runner.os == 'Linux'
run: |
sudo apt-get update -qq
sudo apt-get install -y cmake ninja-build ${{ matrix.apt_packages }}

# ─── Windows 构建 ────────────────────────────────────────────────────────
- name: CMake 配置(Windows)
if: runner.os == 'Windows'
shell: bash
run: |
cmake -S libs/lvgl -B libs/lvgl/build_shared \
-G "${{ matrix.cmake_generator }}" \
-A "${{ matrix.cmake_arch }}" \
-DCONFIG_LV_BUILD_EXAMPLES=OFF \
-DCONFIG_LV_BUILD_DEMOS=OFF \
-DCONFIG_LV_USE_THORVG_INTERNAL=OFF \
-DBUILD_SHARED_LIBS=ON \
-DCONFIG_LV_USE_PRIVATE_API=ON

- name: 编译(Windows)
if: runner.os == 'Windows'
shell: bash
run: cmake --build libs/lvgl/build_shared --config Release

# ─── Linux 构建(使用 Ninja,参考 LVGL 官方 CI)─────────────────────────
- name: CMake 配置(Linux)
if: runner.os == 'Linux'
run: |
cmake -S libs/lvgl -B libs/lvgl/build_shared \
-G Ninja \
-DCMAKE_BUILD_TYPE=Release \
${{ matrix.cmake_extra }} \
-DCONFIG_LV_BUILD_EXAMPLES=OFF \
-DCONFIG_LV_BUILD_DEMOS=OFF \
-DCONFIG_LV_USE_THORVG_INTERNAL=OFF \
-DBUILD_SHARED_LIBS=ON \
-DCONFIG_LV_USE_PRIVATE_API=ON

- name: 编译(Linux)
if: runner.os == 'Linux'
run: cmake --build libs/lvgl/build_shared

# ─── 收集输出文件 ────────────────────────────────────────────────────────
- name: 收集原生库文件
shell: bash
run: |
mkdir -p native_output
# Windows:从 Release 子目录复制 DLL
find libs/lvgl/build_shared -name "lvgl.dll" | head -1 | xargs -I{} cp {} native_output/ 2>/dev/null || true
# Linux:复制 SO 文件(优先无版本号的符号链接)
so=$(find libs/lvgl/build_shared -name "liblvgl.so" | head -1)
if [ -n "$so" ]; then
cp "$so" native_output/liblvgl.so
fi
ls -la native_output/

- name: 上传原生库制品
uses: actions/upload-artifact@v4
with:
name: native-${{ matrix.rid }}
path: native_output/
if-no-files-found: error
193 changes: 193 additions & 0 deletions .github/workflows/nuget-publish.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,193 @@
name: 打包并发布 NuGet 包

on:
release:
types: [published]
workflow_dispatch:
inputs:
version:
description: "包版本号(如 9.3.0)"
required: true
default: "9.3.0"
publish_nuget:
description: "发布到 NuGet.org"
type: boolean
default: true
publish_github:
description: "发布到 GitHub Packages"
type: boolean
default: true

env:
# 版本来源:优先使用 workflow_dispatch 输入,其次使用 release 标签,最后使用分支名。
# 注意:该值可能含有 'v' 前缀(如 v9.3.0),打包时会在 Normalise version 步骤中去除。
PACKAGE_VERSION: ${{ github.event.inputs.version || github.event.release.tag_name || github.ref_name }}

jobs:
# ──────────────────────────────────────────────────────────────────────────
# 1. 为各平台构建原生库
# ──────────────────────────────────────────────────────────────────────────
build-native:
uses: ./.github/workflows/build-native.yml
permissions:
contents: read

# ──────────────────────────────────────────────────────────────────────────
# 2. 组装 LVGLSharp.Native NuGet 包及托管代码包
# ──────────────────────────────────────────────────────────────────────────
pack:
needs: build-native
runs-on: ubuntu-latest
permissions:
contents: read

steps:
- name: 检出代码
uses: actions/checkout@v4
with:
submodules: false # 仅托管代码,无需构建 C 库

- name: 规范化版本号(去除 'v' 前缀)
id: ver
run: |
VER="${{ env.PACKAGE_VERSION }}"
VER="${VER#v}"
echo "version=${VER}" >> "$GITHUB_OUTPUT"

# ── 下载所有原生库制品 ────────────────────────────────────────────────
- name: 下载所有原生库制品
uses: actions/download-artifact@v4
with:
pattern: native-*
path: native_artifacts

# ── 按 runtimes/{rid}/native/ 结构组织原生库 ──────────────────────────
- name: 整理原生库到 runtimes 目录结构
shell: bash
run: |
declare -A LIB_NAME=(
[win-x64]="lvgl.dll"
[win-x86]="lvgl.dll"
[win-arm64]="lvgl.dll"
[linux-x64]="liblvgl.so"
[linux-arm]="liblvgl.so"
[linux-arm64]="liblvgl.so"
)
missing=()
for rid in "${!LIB_NAME[@]}"; do
src_dir="native_artifacts/native-${rid}"
dst_dir="src/LVGLSharp.Native/runtimes/${rid}/native"
mkdir -p "$dst_dir"
lib="${LIB_NAME[$rid]}"
placed=false
if [ -f "${src_dir}/${lib}" ]; then
cp "${src_dir}/${lib}" "${dst_dir}/"
echo "已放置 ${lib} -> ${dst_dir}/"
placed=true
else
# 回退:查找制品目录中的第一个 .so 或 .dll
first=$(find "$src_dir" \( -name "*.dll" -o -name "*.so" \) | head -1)
if [ -n "$first" ]; then
cp "$first" "${dst_dir}/${lib}"
echo "已放置(回退)$(basename "$first") -> ${dst_dir}/${lib}"
placed=true
fi
fi
if [ "$placed" = "false" ]; then
echo "错误:在 ${src_dir} 中找不到 ${rid} 的原生库"
missing+=("$rid")
fi
done
if [ ${#missing[@]} -ne 0 ]; then
echo "以下 RID 缺少原生库:${missing[*]}"
exit 1
fi

# ── 打包 LVGLSharp.Native ─────────────────────────────────────────────
- name: 打包 LVGLSharp.Native
run: |
dotnet pack src/LVGLSharp.Native/LVGLSharp.Native.csproj \
-c Release \
-p:Version=${{ steps.ver.outputs.version }} \
--output nupkgs

# ── 注册本地 NuGet 源,供 Interop 打包时解析 LVGLSharp.Native 依赖 ────
# CI 环境中 $(CI)==true 会激活 LVGLSharp.Native 包引用,
# 此时该包尚未发布到 NuGet.org,需要指向本地 nupkgs/ 目录。
- name: 注册本地 NuGet 源
run: dotnet nuget add source "$(pwd)/nupkgs" --name local-packages

# ── 打包 LVGLSharp.Interop ────────────────────────────────────────────
- name: 打包 LVGLSharp.Interop
run: |
dotnet pack src/LVGLSharp.Interop/LVGLSharp.Interop.csproj \
-c Release \
-p:Version=${{ steps.ver.outputs.version }} \
--output nupkgs

# ── 打包 LVGLSharp.Forms ──────────────────────────────────────────────
- name: 打包 LVGLSharp.Forms
run: |
dotnet pack src/LVGLSharp.WinForms/LVGLSharp.Forms.csproj \
-c Release \
-p:Version=${{ steps.ver.outputs.version }} \
--output nupkgs

# ── 将打包好的 NuGet 包上传为制品 ────────────────────────────────────
- name: 上传 NuGet 包制品
uses: actions/upload-artifact@v4
with:
name: nuget-packages
path: nupkgs/*.nupkg

# ──────────────────────────────────────────────────────────────────────────
# 3. 发布
# ──────────────────────────────────────────────────────────────────────────
publish:
needs: pack
runs-on: ubuntu-latest
permissions:
packages: write
# 仅在真实发布时执行(手动触发且两个发布选项都禁用时跳过)
if: |
github.event_name == 'release' ||
github.event.inputs.publish_nuget == 'true' ||
github.event.inputs.publish_github == 'true'

steps:
- name: 下载 NuGet 包制品
uses: actions/download-artifact@v4
with:
name: nuget-packages
path: nupkgs

# ── 发布到 NuGet.org ──────────────────────────────────────────────────
- name: 发布到 NuGet.org
if: |
github.event_name == 'release' ||
github.event.inputs.publish_nuget == 'true'
env:
NUGET_API_KEY: ${{ secrets.NUGET_API_KEY }}
run: |
dotnet nuget push nupkgs/*.nupkg \
--source https://api.nuget.org/v3/index.json \
--api-key "$NUGET_API_KEY" \
--skip-duplicate

# ── 发布到 GitHub Packages ────────────────────────────────────────────
- name: 发布到 GitHub Packages
if: |
github.event_name == 'release' ||
github.event.inputs.publish_github == 'true'
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
dotnet nuget add source \
"https://nuget.pkg.github.com/${{ github.repository_owner }}/index.json" \
--name github \
--username "${{ github.actor }}" \
--password "$GITHUB_TOKEN" \
--store-password-in-clear-text
dotnet nuget push nupkgs/*.nupkg \
--source github \
--skip-duplicate
21 changes: 21 additions & 0 deletions Directory.Build.props
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<Project>
<PropertyGroup>
<!-- Shared NuGet metadata inherited by every project in the repo. -->
<Authors>IoTSharp</Authors>
<Company>IoTSharp</Company>
<Copyright>Copyright © IoTSharp contributors</Copyright>
<PackageProjectUrl>https://github.com/IoTSharp/LVGLSharp.Forms</PackageProjectUrl>
<RepositoryUrl>https://github.com/IoTSharp/LVGLSharp.Forms</RepositoryUrl>
<RepositoryType>git</RepositoryType>
<PackageLicenseExpression>MIT</PackageLicenseExpression>
<PackageReadmeFile>README.md</PackageReadmeFile>
<PackageTags>lvgl;embedded;ui;winforms;cross-platform</PackageTags>
<!-- Default version; overridden by CI via -p:Version=... -->
<Version>9.3.0</Version>
</PropertyGroup>

<!-- Include the repo-level README in every NuGet package. -->
<ItemGroup Condition="'$(IsPackable)' != 'false' And Exists('$(MSBuildThisFileDirectory)README.md')">
<None Include="$(MSBuildThisFileDirectory)README.md" Pack="true" PackagePath="\" Visible="false" />
</ItemGroup>
</Project>
11 changes: 11 additions & 0 deletions libs/cmake/toolchains/aarch64-linux-gnu.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
set(CMAKE_SYSTEM_NAME Linux)
set(CMAKE_SYSTEM_PROCESSOR aarch64)

set(CMAKE_C_COMPILER aarch64-linux-gnu-gcc)
set(CMAKE_CXX_COMPILER aarch64-linux-gnu-g++)
set(CMAKE_STRIP aarch64-linux-gnu-strip)

set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)
11 changes: 11 additions & 0 deletions libs/cmake/toolchains/arm-linux-gnueabihf.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
set(CMAKE_SYSTEM_NAME Linux)
set(CMAKE_SYSTEM_PROCESSOR arm)

set(CMAKE_C_COMPILER arm-linux-gnueabihf-gcc)
set(CMAKE_CXX_COMPILER arm-linux-gnueabihf-g++)
set(CMAKE_STRIP arm-linux-gnueabihf-strip)

set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)
8 changes: 8 additions & 0 deletions libs/lv_conf.h
Original file line number Diff line number Diff line change
Expand Up @@ -1192,7 +1192,11 @@
#endif

/** Driver for /dev/fb */
#if defined(__linux__)
#define LV_USE_LINUX_FBDEV 1
#else
#define LV_USE_LINUX_FBDEV 0
#endif
#if LV_USE_LINUX_FBDEV
#define LV_LINUX_FBDEV_BSD 0
#define LV_LINUX_FBDEV_RENDER_MODE LV_DISPLAY_RENDER_MODE_PARTIAL
Expand Down Expand Up @@ -1245,7 +1249,11 @@
#define LV_USE_TFT_ESPI 0

/** Driver for evdev input devices */
#if defined(__linux__)
#define LV_USE_EVDEV 1
#else
#define LV_USE_EVDEV 0
#endif

/** Driver for libinput input devices */
#define LV_USE_LIBINPUT 0
Expand Down
Loading
Loading