Repository navigation
Add cross-compilation support for tools and data builds - #1501
ghostflyby wants to merge 2 commits into
Conversation
3a7ea8c to
8fad261
Compare
frankslin
left a comment
There was a problem hiding this comment.
Thanks for picking up #615 — the overall direction (host-tool overrides, copy_libopencc_to_dir_of_opencc_dict moving into src/, BUNDLE DESTINATION, failing ENABLE_GTEST early) looks good. A few issues before this can go in, the first one being a CI failure.
1. MSVC ARM64 job fails (regression in the shared runnability logic)
build-and-test (amd64_arm64, ARM64, arm64, false) fails in the very step this PR changes:
Building CJK_Compatibility_Ideographs.ocd2
This version of ...\opencc_dict.exe is not compatible with the version of Windows you're running.
error MSB8066 ...
Generating Release/jieba_dict/jieba_merged.ocd2 <- also fails
and the "BUILD_DATA defaulted to OFF" warning never appears at configure time. With the Visual Studio generator, -A ARM64 on an x64 host does not set CMAKE_CROSSCOMPILING (no CMAKE_SYSTEM_NAME). The original jieba code ran the WIN32 host/target arch comparison outside the CMAKE_CROSSCOMPILING check; the extracted cmake/OpenCCRunnability.cmake nests it inside, so OPENCC_CAN_RUN_TARGET_TOOLS is always TRUE here. This also regresses the jieba plugin, which used to skip jieba_merged.ocd2 correctly in this job. See inline comments.
2. Host tools are not used for the jieba merged dictionary
- Integrated build, cross compiling (e.g. iOS) with
OPENCC_DICT_EXECUTABLE/OPENCC_CLI_EXECUTABLEandBUILD_OPENCC_JIEBA_PLUGIN=ON:OPENCC_CAN_RUN_CPPJIEBA_DICTis FALSE, sojieba_merged.ocd2is silently not built while the plugin and*_jieba.jsonconfigs are still installed — they break at runtime. - Native build with
BUILD_TOOLS=OFF+ host tools + jieba: hits the new FATAL_ERROR whose message suggests "or provide host tools", even though host tools are provided.
In integrated mode, when OPENCC_USING_HOST_TOOLS is set, the plugin should use OPENCC_DICT_EXECUTABLE as OPENCC_DICT_COMMAND (and not require BUILD_TOOLS).
3. Auto-OFF BUILD_DATA gets stuck in the cache
On the first configure without host tools, option() caches BUILD_DATA=OFF. If the user then re-configures adding -DOPENCC_DICT_EXECUTABLE=... -DOPENCC_CLI_EXECUTABLE=..., BUILD_DATA stays OFF (the cache entry now counts as "provided"), the host tools are silently ignored, and the warning no longer prints. Consider not caching the auto-derived default, or at least warning when host tools are set while BUILD_DATA is OFF.
4. Unprefixed option names
BUILD_TOOLS / BUILD_DATA are very common names. When OpenCC is consumed via FetchContent / add_subdirectory and the parent project already has BUILD_TOOLS=OFF in its cache, OpenCC inherits it, BUILD_DATA defaults to ON, and configuration hits FATAL_ERROR. Suggest OPENCC_BUILD_TOOLS / OPENCC_BUILD_DATA, in line with OPENCC_ENABLE_INSTALL.
5. Smaller points
- Host tools are only checked for existence. A host tool from a different OpenCC version may generate inconsistent dictionaries or fail mid-build; the standalone jieba build already probes
opencc_dict --helpfor capability — something similar (or at least documenting that host tools must match the source version) would help. - On non-Windows,
data/runs host tools directly; a dynamically linked host tool installed in a non-default prefix won't findlibopencc. The standalone jieba path already handles this withLD_LIBRARY_PATH/DYLD_LIBRARY_PATH. BUILD_DATA=OFFalso skips installingdata/config/*.json, but the warning only mentions dictionaries. With jieba on,*_jieba.jsonare still installed and point to dictionaries that don't exist.- Optional: don't auto-disable data when
CMAKE_CROSSCOMPILING_EMULATORis set — CMake prepends the emulator for executable targets used asCOMMAND(note--opencc $<TARGET_FILE:opencc>is passed as an argument, so it would need separate handling).
| opencc_normalize_arch(OPENCC_TARGET_ARCH "${_OPENCC_TARGET_ARCH_RAW}") | ||
| opencc_normalize_arch(OPENCC_HOST_ARCH "${CMAKE_HOST_SYSTEM_PROCESSOR}") | ||
|
|
||
| set(OPENCC_CAN_RUN_TARGET_TOOLS TRUE) |
There was a problem hiding this comment.
The WIN32 host/target arch comparison was outside the CMAKE_CROSSCOMPILING check in the original jieba code. VS generator + -A ARM64 on x64 leaves CMAKE_CROSSCOMPILING FALSE, so with this nesting OPENCC_CAN_RUN_TARGET_TOOLS stays TRUE and the ARM64 opencc_dict.exe is executed on the x64 runner (this is the MSVC ARM64 CI failure). Please move the WIN32 comparison out of this if to restore the previous semantics.
| set(_OPENCC_BUILD_DATA_DEFAULT ON) | ||
| set(_OPENCC_BUILD_DATA_AUTO_OFF OFF) | ||
| if(NOT _OPENCC_BUILD_DATA_PROVIDED | ||
| AND CMAKE_CROSSCOMPILING AND NOT OPENCC_CAN_RUN_TARGET_TOOLS |
There was a problem hiding this comment.
Requiring CMAKE_CROSSCOMPILING here means the Windows -A ARM64 case never auto-disables data either. Once OPENCC_CAN_RUN_TARGET_TOOLS is fixed, this can probably just check NOT OPENCC_CAN_RUN_TARGET_TOOLS.
| NOT BUILD_TOOLS) | ||
| message(FATAL_ERROR | ||
| "Building the merged Jieba dictionary requires the opencc_dict build " | ||
| "tool: set BUILD_TOOLS=ON or provide host tools.") |
There was a problem hiding this comment.
"or provide host tools" doesn't help here: in integrated mode the plugin always uses the build-tree opencc_dict target and ignores OPENCC_DICT_EXECUTABLE. Likewise when cross compiling with host tools, OPENCC_CAN_RUN_CPPJIEBA_DICT is FALSE and the merged dictionary is silently skipped. When OPENCC_USING_HOST_TOOLS is set, the integrated branch should use OPENCC_DICT_EXECUTABLE instead.
ac2f4d7 to
7ea2fb7
Compare
Building the dictionaries executes the just-built opencc_dict and opencc tools at build time, so configuring for a target architecture the host cannot execute (iOS, Android, Windows ARM64 on x64, ...) always failed mid-build. Add BUILD_TOOLS/BUILD_DATA options and host-tool overrides so cross builds either skip data generation automatically or generate the architecture-independent dictionaries with host-built tools, as proposed in BYVoid#615. Detailed Changes: **Build options** - BUILD_TOOLS (default ON) gates src/tools; BUILD_DATA (default ON) gates data/. Cross compiling to an architecture the host cannot execute now defaults BUILD_DATA to OFF with a warning instead of failing later in the build; host-runnable cross configurations (x86 on x64 Windows) keep building data, and emulation setups (Rosetta 2) can force -DBUILD_DATA=ON. - ENABLE_GTEST now fails configuration when tools or data are disabled, since the conversion tests execute the opencc CLI against the built dictionaries. **Host tools** - OPENCC_DICT_EXECUTABLE and OPENCC_CLI_EXECUTABLE accept host-built tool paths; dictionaries generated with host tools are byte-identical to target-built ones. **Shared runnability helpers** - The jieba plugin's architecture normalization and can-run-on-host logic moved to cmake/OpenCCRunnability.cmake and is reused by the top level; the plugin keeps an inline fallback for standalone builds without the parent source tree. **Windows and iOS build fixes** - copy_libopencc_to_dir_of_opencc_dict moved next to the tools (data/ and jieba/ both use it) so it survives BUILD_DATA=OFF; tool executables now install with a BUNDLE destination so MACOSX_BUNDLE (iOS) installs work. - The MSVC ARM64 job no longer needs an explicit compile-only target list.
(BYVoid#1) 可运行性判断嵌套回归(MSVC ARM64 CI 失败)+ 复审 blocking:提升分支 gate CMAKE_HOST_WIN32: WIN32 宿主/目标架构对比为平级独立 if(在 CMAKE_CROSSCOMPILING 检查外,附注释)。按复审 blocking 修正提升方向:不可运行恒降 FALSE;可运行仅在 CMAKE_HOST_WIN32 时回 TRUE(架构对比的 WOW64 语义只对 Windows 宿主成立,非 Windows 宿主交叉到 Windows(mingw triplet)即使架构相同也维持 FA (BYVoid#2) 自动关 DATA 的条件不应叠加 CMAKE_CROSSCOMPILING: 顶层默认值判断条件仅 NOT OPENCC_CAN_RUN_TARGET_TOOLS 且未提供宿主工具;CMAKE_CROSSCOMPILING 不再出现于条件(复审判定放行,未改动)。 (BYVoid#3) jieba 集成模式接入宿主工具: 集成模式 + OPENCC_USING_HOST_TOOLS 时 OPENCC_CAN_RUN_CPPJIEBA_DICT 置 TRUE,OPENCC_DICT_COMMAND 用宿主 OPENCC_DICT_EXECUTABLE 经 opencc_host_tool_command 包裹(非 WIN32 走 cmake -E env LD/DYLD_LIBRARY_PATH,前缀取工具上两级), (BYVoid#4) 自动 OFF 不应写入 cache: get_property(... CACHE OPENCC_BUILD_DATA PROPERTY TYPE SET) 探测;未提供设普通变量每次重算、完全不落 cache;提供则尊重 cache;宿主工具已设置但显式 OFF 时输出警告(复审判定放行,未改动)。 (BYVoid#5) 选项加 OPENCC_ 前缀: 全局改名覆盖所有 CMake 文件、注释、错误文案、NEWS.md 与 PR 草稿(复审判定放行,未改动)。 (BYVoid#6) 宿主工具能力探测与版本说明: 存在性检查后以(env 包裹后的)命令执行 opencc_dict --help,非零退出 FATAL;两个 cache 文档字符串注明须与同一份 OpenCC 源码版本同源(复审判定达标,未改动;复审次要观察的 CLI 探测为可选增强,未做)。 (BYVoid#7) 非 Windows 宿主工具的动态库路径: opencc_host_tool_env(仅 cmake -E env + LD/DYLD_LIBRARY_PATH 前缀,Windows 为空)+ opencc_host_tool_command(前缀+工具)两个共享辅助函数;data/ 直接命令与 jieba 集成/standalone 宿主工具命令复用;ST 生成器例外:env 前缀包住整个 Python 调用(spawn 的 CLI 继承 (BYVoid#8) 警告涵盖 configs;DATA=OFF 时不安装指向缺失字典的 jieba 配置: 警告文案同时提及 dictionaries 与 config files(逐字包含 OPENCC_BUILD_DATA defaulted to OFF);*_jieba.json 安装门控为 CAN_RUN 且(standalone 或 OPENCC_BUILD_DATA);NEWS 说明行为(复审判定放行,未改动)。 (BYVoid#9) CMAKE_CROSSCOMPILING_EMULATOR 不自动关 data + 复审 blocking:jieba merged 字典也加 emulator 前缀: 模块末尾 if(CMAKE_CROSSCOMPILING_EMULATOR) 置 TRUE(fallback 同步)。data/:直接命令冠 ${CMAKE_CROSSCOMPILING_EMULATOR} 前缀,转换器以重复 --opencc=<token> 选项(emulator 与目标路径各一项,foreach 构造)传给 ST 生成器,脚本 --opencc 为 action=append (follow-up P1) 宿主工具动态库环境误用目标平台变量:opencc_host_tool_env 及 jieba 内联回退改用 CMAKE_HOST_WIN32/CMAKE_HOST_APPLE —— 工具在宿主执行,macOS 交叉编译到 Linux 目标时也应设置 DYLD_LIBRARY_PATH(单元级复现验证:模拟 Linux 目标 + macOS 宿主,修复前给 LD、修复后给 DYLD)。 (follow-up P2) OPENCC_BUILD_DATA 显式探测只查 cache、漏普通变量:补 DEFINED 普通 变量判断(CMP0077=NEW 下父项目 add_subdirectory 前的 set 不再被自动默认值覆写;单元级验证:父项目同时设 DATA/TOOLS=OFF 经 add_subdirectory 消费,配置成功无 FATAL)。自动默认不落 cache 的行为保持不变。全部 13 个构建验证门回归通过。
7ea2fb7 to
ca5da29
Compare
Building the dictionaries runs the just-built
opencc_dictandopenccbinaries at build time (data/CMakeLists.txt), so configuring for a target architecture the host cannot execute — iOS, Android, Windows ARM64 on x64 — always failed mid-build (#615). The MSVC CI works around this today by compiling an explicit ARM64 target list that avoids the data targets.This adds
OPENCC_BUILD_TOOLS/OPENCC_BUILD_DATAoptions plus host-tool overrides, following the runnability idiom already established by the jieba plugin (OPENCC_CAN_RUN_CPPJIEBA_DICT):OPENCC_BUILD_DATAdefaults to OFF with aWARNINGexplaining the escape hatches; the build completes (library + tools) instead of failing. The automatic default is not written to the cache, so adding host tools later and reconfiguring picks them up instead of treating the first automatic OFF as user-provided; conversely, providing host tools whileOPENCC_BUILD_DATAis explicitly OFF draws its own warning.-DOPENCC_BUILD_DATA=ONoverrides for emulation setups such as Rosetta 2. Host-runnable cross configurations keep building data via the host/target architecture comparison, which upgrades the verdict only on a Windows host (WOW64 — x86 on x64, including the Visual Studio generator's-Aplatforms, which do not setCMAKE_CROSSCOMPILING); cross builds to Windows from non-Windows hosts (mingw triplets) stay unrunnable and auto-disable data. SettingCMAKE_CROSSCOMPILING_EMULATOR(e.g. qemu) also keeps data enabled: the build-time tool invocations — the dictionary and jieba merged-dict commands, and the converter passed to the ST phrase generator as repeated--opencc=<token>options — are prefixed with the emulator, whichadd_custom_commanddoes not do on its own.OPENCC_DICT_EXECUTABLE+OPENCC_CLI_EXECUTABLE— the ST phrase generator also executes theopenccCLI), dictionaries are generated by the host tools and installed as usual; the tools are probed withopencc_dict --helpat configure time (their cache doc strings note they must come from the same OpenCC source version), and on non-Windows hosts they run wrapped inLD_LIBRARY_PATH/DYLD_LIBRARY_PATHpointing at the lib dir of their installation prefix, shared bydata/and the jieba plugin. Dictionaries are architecture-independent data: host-generated and target-built files are byte-identical (shasum-verified).jieba_merged.ocd2with the hostopencc_dicteven withOPENCC_BUILD_TOOLS=OFF. When data is not built (auto-OFF cross builds, or explicitOPENCC_BUILD_DATA=OFF), no*_jieba.jsonconfigs are installed either — they would point at dictionaries that do not exist.Detailed Changes:
OPENCC_BUILD_TOOLS(default ON) gatessrc/tools;OPENCC_BUILD_DATA(default ON, auto-OFF as above, uncached) gatesdata/. Both areOPENCC_-prefixed likeOPENCC_ENABLE_INSTALLso FetchContent /add_subdirectorybuilds cannot inherit a parent project's same-named cache values.ENABLE_GTESTnow fails configuration when tools or data are disabled, since the conversion tests execute the opencc CLI against the built dictionaries.OPENCC_BUILD_DATAwithoutOPENCC_BUILD_TOOLSor host tools is likewise a configure-time error, as are nonexistent or half-provided host-tool paths.opencc_normalize_arch/opencc_can_run_target_on_hostlogic moved tocmake/OpenCCRunnability.cmakeand is reused by the top level, together with a newopencc_host_tool_commandhelper that wraps host-built tools with the dynamic-library path env. The host/target architecture comparison sits outside theCMAKE_CROSSCOMPILINGcheck so it also covers the Visual Studio generator, upgrades only on a Windows host (WOW64), andCMAKE_CROSSCOMPILING_EMULATORforces the verdict back to runnable. The plugin keeps an inline fallback for standalone builds without the parent tree, and only fails when neitherOPENCC_BUILD_TOOLSnor host tools can provideopencc_dict.copy_libopencc_to_dir_of_opencc_dictmoved next to the tools insrc/(bothdata/andplugins/jieba/reference it) so it survivesOPENCC_BUILD_DATA=OFF; tool executables install with aBUNDLEdestination soMACOSX_BUNDLE(iOS) installs work.--openccis now repeatable (action="append"), and the CMake data build passes the converter command as repeated--opencc=<token>options so an emulator or env-wrapper prefix (whose tokens may start with-, e.g.cmake -E env) survives being passed as an argument; the Bazel genrule's single-path invocation is unchanged.Testing (macOS, arm64 host):
ENABLE_GTEST=ONCMAKE_SYSTEM_NAME=iOS) defaultWARNING, data auto-OFF, arm64 library + tools buildsha256-identical to the native build-DCMAKE_OSX_ARCHITECTURES=x86_64(arm64 host)CMAKE_CROSSCOMPILING; data built, tools run under Rosetta 2-DCMAKE_CROSSCOMPILING_EMULATOR=...(iOS)OPENCC_BUILD_TOOLS=OFF+ host tools + jieba pluginjieba_merged.ocd2via the host tool (configure-verified)-DOPENCC_BUILD_DATA=OFF-DOPENCC_BUILD_TOOLS=OFF, or-DENABLE_GTEST=ON -DOPENCC_BUILD_DATA=OFFFATAL_ERROR, as intendedFATAL_ERROR, as intendedBazel and Node builds are untouched; dictionary files and test cases are unchanged, so the CONTRIBUTING dictionary checklist does not apply. The CMake test suite passes (21/21).
Example — shipping full dictionaries for a cross target via vcpkg's host-dependency mechanism:
{ "name": "opencc", "host": true, "features": ["tools"] }Implements the build flag requested in #615, extended with host-tool support.