Harmony-LibreCAD:基于 HarmonyOS 的 2D 工程制图应用项目

LibreCAD 向 HarmonyOS(OHOS arm64)的移植源码仓库:收录上游 LibreCAD 源码树(master 2.2.2 / LC_VERSION 2.2.2.6-alpha)与本平台适配改动,依 GPL-2.0 释出

分支1Tags0
文件最后提交记录最后更新时间
7 天前
7 天前
7 天前
7 天前
7 天前
7 天前
7 天前

Harmony-LibreCAD

LibreCAD 向 HarmonyOS(OHOS arm64)的移植源码仓库:收录上游 LibreCAD 源码树(本平台改动已就地合入该树)、本平台交叉构建环境脚本与工具脚本,以及一件配套的平台插件补丁。

来源与许可

项 内容
上游项目 LibreCAD(2D CAD,基于 QCAD 社区版)— 官网 https://www.librecad.org,源码 https://github.com/LibreCAD/LibreCAD
收录树 sources/librecad/,上游 master 分支快照(检出时间 2026-09-12)。版本锚点见 CMakeLists.txt:project (LibreCAD VERSION 2.2.2) 与 add_compile_definitions (LC_VERSION=2.2.2.6-alpha);CHANGELOG.md 首部为 [2.2.1-alpha] - unreleased
基线 commit 该快照未随带 git 元数据,无可引用的 commit 号;核对方式为上游 master/2.2.2 分支与上述版本串。上游要求 Qt 6.4.0+(README.md:2.2.2 分支),本移植使用 Qt 6.11 交叉栈
上游许可证 GPL-2.0(sources/librecad/LICENSE 为上游许可说明,sources/librecad/licenses/gpl-2.0.txt 为全文;本仓库根 LICENSE 即该全文副本)
本仓库许可 上游树 + 我方修改/新增文件按 GPL-2.0 释出;移植层脚本与补丁同属本仓库发布内容
上游获取渠道 https://github.com/LibreCAD/LibreCAD(GPLv2);随树内嵌的第三方库见《许可证》
版权头 上游文件的版权头与署名保持原样;我方改动的文件在改动处带 PATCH-<编号>(…) 与日期注释(共 12 个文件、52 处),新增文件 librecad/src/main/lc_ohos_menubar.cpp 头部注明其用途与出处
无担保 按 GPL 的 "no warranty" 条款释出

收录形态说明:本仓库收录的是已含本平台改动的上游树。本平台对 LibreCAD 源文件的改动是就地修改(不生成独立 .patch 序列),因此《改动指示》给出逐文件清单与可复现的标记统计;patches/ 内唯一一件补丁针对的是 Qt 的 OHOS 平台插件层(qohosintegration.cpp),不是 LibreCAD 源文件,随本仓库发布是为了完整交代渲染链上的配套改动。

移植方式

  • 库形态:OHOS_PORT=ON 时 GUI 目标由 qt_add_executable 改为 qt_add_library(librecad SHARED …),并 DEFINE_SYMBOL "" 以保证符号导出;入口 main 在 __OHOS__ 守卫下改名 extern "C" int librecad_ohos_main(int argc, char** argv)(librecad/src/main/main.cpp),由宿主 dlopen 后调用。产物为 librecad.so。
  • 菜单桥:新增 librecad/src/main/lc_ohos_menubar.cpp,导出 7 个符号供外部驱动菜单与 UI 请求:librecad_menu_snapshot(1s 快照 JSON + serial 校验)、librecad_menu_trigger、librecad_set_ui_request_handler、librecad_ui_request、librecad_qt_busy、librecad_qt_esc、librecad_qt_close_dialogs。
  • 图标引擎:LibreCAD 工具图标为私有 .lci 格式,由 libraries/lciconengine 的 QIconEnginePlugin(keys lc/lci)解析;沙箱下动态插件不可载,故在 OHOS_PORT 下把引擎源静态编入并目标级定义 QT_STATICPLUGIN=1(mocs_compilation.cpp 不吃 per-source 定义),配合 main.cpp 的 Q_IMPORT_PLUGIN 锚点与 hilog_ndk.z 链接。
  • 插件与子目标裁剪:OHOS_PORT 下跳过 lciconengine/plugins 子目录、ttf2lff 工具与 install 规则;LIBRECAD_SKIP_TRANSLATIONS=ON 跳过 LinguistTools(交叉栈无宿主 lrelease),翻译改由 scripts/ 离线生成。
  • 数据目录:librecad/src/lib/engine/rs_system.cpp 的 getDirectoryList 前插 LIBRECAD_DATA_DIR/<sub>(沙箱数据目录首位优先,覆盖 fonts/patterns/library/qm)。
  • 平台细节:lc_crash_handler.cpp 在 __OHOS__ 下排除 execinfo/backtrace 分支(musl 无 execinfo.h);main.cpp 在 __OHOS__ 下跳过 HighDPI 的 RoundPreferFloor 以保持 PassThrough、禁用启动闪窗、小屏(<1300 逻辑宽)dock/工具条裁剪与状态栏溢出治理、工具条 flyout 改轻点直激/长按弹菜单、关闭 Qt 的触摸自动合成鼠标(AA_SynthesizeMouseForUnhandledTouchEvents=false)避免双鼠标流。
  • 汉化:librecad/ts/librecad_zh_cn.ts 经 scripts/patch_zh_menu_ts.py(重建 LC_MenuFactoryMain 上下文)与 scripts/fill_zh_ts_gaps.py(去 unfinished 放行既有译文、跨上下文复用、词典补齐)填充后,由部署脚本用 lrelease -nounfinished 离线出 .qm(并把 qtbase 标准对话框翻译改名为 qt_zh_cn.qm)。
  • 依赖栈:Qt 6.11(Core/Gui/Widgets/Network/Svg/SvgWidgets/Xml/PrintSupport)交叉编译产物 + Boost 头文件(ublas/math/geometry/tuple,header-only 使用)+ 随树内嵌的 libraries/{libdxfrw,jwwlib,muparser,shapelib,lciconengine}。

仓库结构

路径 内容
README.md / LICENSE / .gitignore 本文件、GPLv2 全文(取自树内 licenses/gpl-2.0.txt)、忽略规则
sources/librecad/ 上游 LibreCAD 源码树(含就地合入的本平台改动)
env.sh OHOS NDK(aarch64-unknown-linux-ohos clang)交叉环境变量、sysroot、pkg-config、CMAKE_CROSS_ARGS 模板
scripts/build_librecad.sh LibreCAD 的 CMake 配置与构建命令(-DOHOS_PORT=ON 等全部实参)
scripts/deploy.sh 产物收集与部署:.so 条剪/strip/NEEDED 处理、librecad/support 数据包、离线 .qm 翻译、首启种子配置
scripts/patch_zh_menu_ts.py、scripts/fill_zh_ts_gaps.py 翻译上下文重建与缺口填充(改 sources/librecad/librecad/ts/librecad_zh_cn.ts)
scripts/harvest_layout.py 从宿主 QMainWindow 状态(Geometry/StateOfWidgets)收割紧凑布局,转成种子配置片段
patches/qpa-ohos-20261006-dialog-popup-interaction.patch Qt OHOS 平台插件(qohosintegration.cpp)的对话框弹层交互补丁,8 个 hunk

改动指示

按 GPL-2.0 §2(b) 履行"标注修改"义务。以下统计均可在仓库根目录复现:

grep -rl "__OHOS__" sources/librecad | wc -l      # 5   预处理级平台守卫(共 24 处守卫)
grep -ril "ohos"    sources/librecad | wc -l      # 8   含 CMake 分支与注释
grep -rl "PATCH-"   sources/librecad | wc -l      # 12  带 PATCH-<编号> 与日期注释的改动标注(52 处)
grep -c "OHOS_PORT" sources/librecad/CMakeLists.txt   # 9  单一构建开关的全部使用点

就地改动共 14 个文件(其中 1 个为新增文件),逐文件清单:

文件 新增/修改 改动要点
librecad/src/main/lc_ohos_menubar.cpp 新增 菜单快照/触发、UI 请求回调、Esc/关闭对话框等平台桥(7 个导出符号)
CMakeLists.txt 修改 新增 option(OHOS_PORT …);GUI→SHARED 库、DEFINE_SYMBOL ""、QT_STATICPLUGIN 目标级、.lci 图标引擎静态编入、链 hilog_ndk.z、跳过 LinguistTools/插件子目录/ttf2lff/install 规则
librecad/src/main/main.cpp 修改 main→librecad_ohos_main(14 处 __OHOS__ 守卫):闪窗跳过、HighDPI PassThrough、Q_IMPORT_PLUGIN 锚点、小屏 dock/工具条/状态栏裁剪、flyout 轻点直激、禁用触摸自动合成鼠标、晚期全屏重申、翻译跟随 UI 语言、窗体选项内存守卫的启动侧
librecad/src/lib/engine/rs_system.cpp 修改 沙箱数据目录 LIBRECAD_DATA_DIR 前插优先
librecad/src/main/lc_crash_handler.cpp 修改 __OHOS__ 排除 execinfo/backtrace 分支(musl)
librecad/src/ui/dialogs/main/qg_dlginitial.cpp 修改 首启向导平台化(隐藏上游 logo,单位/语言功能保留)
librecad/src/ui/dialogs/settings/options_widget/lc_widgetoptionsdialog.cpp 修改 窗体选项 accept/reject 路径的内存失控守卫(跳过运行期 setStyle/loadStyleSheet/applyIconColors,改由启动应用)
librecad/src/ui/dialogs/settings/options_widget/lc_iconcolorsoptions.{h,cpp} 修改 新增 isColorsChanged() 快照比较,取消路径按需恢复
librecad/src/ui/dialogs/settings/options_general/qg_dlgoptionsgeneral.cpp 修改 常规选项对话框的平台侧交互修正
librecad/src/cmd/rs_commands.cpp 修改 上游缺陷根修:命令查表统一使用已小写化的串(软键盘句首大写导致命令"未知")
librecad/src/cmd/lc_commandItems.h 修改 undo/redo 条目改为可翻译命令词(原为英文描述字面量)
librecad/src/lib/fileio/lc_filenameselectionservice.cpp 修改 保存/读取模式下平台文件选择器后缀补齐语义区分
librecad/ts/librecad_zh_cn.ts 修改 翻译数据填充(补 LC_MenuFactoryMain 上下文、放行既有 unfinished 译文、跨上下文复用与词典补齐;无代码级标记,处理逻辑见 scripts/ 两脚本)

上述文件之外,本仓库的移植层内容为 env.sh、scripts/(5 件)与 patches/(1 件,针对 Qt 平台插件层)。

功能状态 / 已知限制

  • 本树在 OHOS_PORT=ON 下可构建出 librecad.so(Qt6 Widgets + C++17,纯 QPainter 光栅路径,不使用 OpenGL/Vulkan),具备 2D CAD 主功能与 .lci 图标渲染、汉化界面与命令行提示、沙箱数据目录与图库/字体/图案加载。
  • 平台分支显式裁剪的能力:plugins/ 动态插件(QPluginLoader 路径)与 ttf2lff 字体转换工具不构建;翻译不在 CMake 内生成(改离线 lrelease);上游 install/打包规则在 OHOS_PORT 下跳过。
  • 崩溃回溯在 OHOS 上不由本树提供(musl 无 execinfo.h),由宿主的信号取证承担。
  • externals/Catch2 与 tests/ 相关目标在交叉构建中关闭(-DBUILD_TESTS=OFF),该 submodule 目录未初始化(空目录,不入 git)。

交叉构建

命令与参数均取自仓库内的 env.sh 与 scripts/build_librecad.sh:

source env.sh
bash scripts/build_librecad.sh [target...]

生效的 CMake 实参(scripts/build_librecad.sh,路径变量按 env.sh 展开):

  • -DCMAKE_SYSTEM_NAME=Linux -DCMAKE_SYSTEM_PROCESSOR=aarch64(交叉栈需类 Unix 语义以走 Qt6 的 find 模块)
  • -DCMAKE_C_COMPILER=$OHOS_CC -DCMAKE_CXX_COMPILER=$OHOS_CXX(aarch64-unknown-linux-ohos-clang(++))、-DCMAKE_AR=llvm-ar、-DCMAKE_RANLIB=llvm-ranlib、-DCMAKE_SYSROOT=$OHOS_SYSROOT
  • -DCMAKE_FIND_ROOT_PATH="<sysrowot>;<前缀>;<Qt 栈>;<Qt 栈备用>" 配 -DCMAKE_FIND_ROOT_PATH_MODE_PROGRAM=NEVER、..._MODE_LIBRARY=ONLY、..._MODE_INCLUDE=ONLY、..._MODE_PACKAGE=ONLY
  • -DCMAKE_BUILD_TYPE=Release、-DCMAKE_POLICY_VERSION_MINIMUM=3.5
  • -DCMAKE_C_FLAGS="-DOHOS_PLATFORM -D__OHOS__=1 -fPIC -I<prefix>/include"
  • -DCMAKE_CXX_FLAGS= 同上前导,另加 -std=c++17 -isystem <prefix>/include/QtPrintSupport -D_LIBCPP_HAS_NO_OFF_T_FUNCTIONS=0 -Wno-everything
  • -DCMAKE_EXE_LINKER_FLAGS / -DCMAKE_SHARED_LINKER_FLAGS / -DCMAKE_MODULE_LINKER_FLAGS 均为 --target=aarch64-linux-ohos -L<各前缀>/lib
  • -DQT_HOST_PATH=<宿主 Qt> -DQT_HOST_PATH_CMAKE_DIR=$QT_HOST_PATH/lib/cmake(宿主 moc/uic/rcc)
  • -DCMAKE_PREFIX_PATH="<Qt 栈>;<Qt 栈备用>" -DQt6PrintSupport_DIR=<Qt 栈备用>/lib/cmake/Qt6PrintSupport -DBoost_INCLUDE_DIR=<prefix>/include
  • -DOHOS_PORT=ON(本平台总开关)、-DBUILD_TESTS=OFF
  • 构建:cmake --build <build-dir> -j$(sysctl -n hw.ncpu)(可指定 target)

env.sh 侧的通用参数:CFLAGS/CXXFLAGS="-DOHOS_PLATFORM -D__OHOS__=1 --target=aarch64-linux-ohos -fPIC [-std=c++17]"、LDFLAGS="--target=aarch64-linux-ohos -L<prefix>/lib"、CC/CXX/AR/RANLIB/STRIP/NM/READELF 指向 NDK LLVM,PKG_CONFIG_PATH 指向前缀与 sysroot 的 aarch64-linux-ohos/pkgconfig;并把 /usr/bin:/bin 前置到 PATH(DevEco 的 toolchains 目录里的 diff 对不存在的文件比较返回 0,会毒化 autoconf 的头文件落盘)。

Boost 需以 header-only 形式置于 <prefix>/include/boost;注意不要用其它项目的前缀 include 根做 -I,其中被裁剪过的 QtPrintSupport 头树会以 QT_NO_PRINTER=1 遮蔽 QPrinter 定义。

相关资源

许可证

组件 许可
sources/librecad/(主体源码与我方改动) GPL-2.0(LICENSE)
sources/librecad/libraries/libdxfrw、libraries/jwwlib GPL-2.0("or any later version",见 libraries/libdxfrw/COPYING)
sources/librecad/libraries/muparser MIT(licenses/MIT.txt)
sources/librecad/libraries/shapelib、plugins/importshp/shapelib MIT Style / LGPLv2(上游 LICENSE 说明)
sources/librecad/libraries/lciconengine GPL-2.0(LibreCAD 本体组件)
sources/librecad/librecad/res/icons(CC0 SVG 图标) CC0(上游 LICENSE 说明)
sources/librecad/librecad/support/fonts/*(AZOmix、Amiri、Hershey、OpenGost 等) KST32B v2 / SIL OFL / 公版数据,文本见 licenses/KST32B_v2.txt、licenses/OFL.txt、licenses/lc_opengost-fonts.txt
sources/librecad/desktop/、docs/、scripts/(上游桌面与文档资产) 随上游 GPL-2.0 释出,个别艺术资产署名见 LICENSE 的 Rights holders 段
env.sh、scripts/、patches/ —— 我方移植层 GPL-2.0;其中 patches/*.patch 修改的对象属于 Qt(LGPL-3.0/GPL-2.0 双许可),补丁本身为我方贡献内容

各组件著作权归其上游项目与原作者所有(上游 LICENSE 列出的 rights holders 名单保持原样);本仓库仅主张我方修改与新增文件在 GPL-2.0 下的授权。LibreCAD 本身是 QCAD 社区版 2.0.5.0 的 fork,其 GPLv2 继承关系见 sources/librecad/LICENSE 的 History 段。

项目介绍

LibreCAD 向 HarmonyOS(OHOS arm64)的移植源码仓库:收录上游 LibreCAD 源码树(master 2.2.2 / LC_VERSION 2.2.2.6-alpha)与本平台适配改动,依 GPL-2.0 释出

定制我的领域