【鸿蒙PC适配踩坑帖】KDiff3 真实问题×对症解法——从 register 关键字到 libqohos.so 双份的全程记录
【鸿蒙PC适配踩坑帖】KDiff3 真实问题×对症解法——从 register 关键字到 libqohos.so 双份的全程记录
欢迎加入开源鸿蒙 PC 社区:https://harmonypc.csdn.net/
本文是 KDiff3 0.9.98 适配鸿蒙 PC 全程踩过的坑 的速查手册——重点不是"怎么把 KDiff3 跑起来"(那篇完整流程文已经写过),而是 “你照着流程做,会在哪一步炸,怎么救”。
项目信息
| 项 | 内容 |
|---|---|
| 本文性质 | 单项目深度踩坑 FAQ(KDiff3 = 仓库第一个 KDE 系开源软件适配) |
| 样本来源 | 已完成适配/Kdiff3test/(含 6 张终端截图 + 6 份原始 .txt 输出)+ 已完成适配/Kdiff3Ohos/ |
| 覆盖坑类型 | 选型 1 个 / 编译期 4 个 / 链接期 1 个 / 产物期 2 个 / HAP 集成期 3 个 / 真机调试 1 个 |
| 使用方式 | 遇到错误信息原文 → Ctrl+F 关键字 → 找解法 |

这篇文章的独特价值
| 维度 | 已有的 KDiff3 实战文 | 本篇(踩坑帖) |
|---|---|---|
| 文体 | 一气呵成的流程叙事 | 坑卡片化拆解,按出现频率排序 |
| 视角 | “我是怎么一步步做的” | “你做到这一步会炸,这样救” |
| 阅读时长 | 30+ 分钟 | 2-5 分钟跳查 |
| 信息密度 | 完整但稀释 | 每条坑独立完整 |
〇、快速导航
按你正在做的事对号入座:
| 你在哪一步 | 高发坑编号 |
|---|---|
| 🟦 选 KDiff3 版本 | #01 |
| 🟦 CMake 改写阶段 | #02 #03 |
| 🟥 第一次 ninja 编译 | #04 #05 #06 |
| 🟧 链接阶段 | #07 |
| 🟨 ELF 产物体检 | #08 #09 |
| 🟦 Runtime 收集 | #10 |
| 🟧 HAP 集成 + DevEco | #11 |
| 🟥 真机点开闪退 | #12 |
🟦=工具链 / 🟥=阻塞型 / 🟨=校验 / 🟧=细节。
一、选型类(1 个)⚠️ 一开始决定走多少弯路
🕳️ #01 拿最新版 KDiff3 1.10.x 开干 → KF5 巨型依赖让人崩溃
关键字:KF5::KIO / KF5::KParts / KCrash / find_package(KF5 REQUIRED)
现象:
CMake 第一行就炸:
CMake Error at CMakeLists.txt:23 (find_package):
Could not find a package configuration file provided by "KF5" with any
of the following names:
KF5Config.cmake / KF5KIO / KF5XmlGui / KF5Crash / KF5I18n / ...
根因:
KDiff3 1.x 版本深度耦合 KDE Frameworks 5,KIO、KParts、KCrash、KXmlGui、KI18n、KCoreAddons 一个都跑不掉——整个 KF5 在鸿蒙 PC 上没有任何现成移植。
如果你硬要走 1.x,你前两周都在交叉编译 KDE Frameworks——而且大概率失败。
解决:
降级到 KDiff3 0.9.98(2014 年的老版本):
wget https://master.dl.sourceforge.net/project/kdiff3/kdiff3/0.9.98/kdiff3-0.9.98.tar.gz
tar xzf kdiff3-0.9.98.tar.gz
cd kdiff3-0.9.98/src-QT4/ # ← 用这个子目录,不是顶层
0.9.98 的优势:
src-QT4/kreplacements/ ← 30+ KDE 类的桩代码
├── kaboutdata.h ← 假的 KAboutData
├── kaction.h
├── kapplication.h
├── kcmdlineargs.h
├── kdialogbase.h
├── klocale.h
├── kmainwindow.h
├── ...
└── kreplacements.cpp
只需要 Qt5 Core/Gui/Widgets/PrintSupport 4 个模块,零第三方 C 库——这是个移植级别的梦幻起点。
| 版本 | 发布 | 依赖 | 移植难度 |
|---|---|---|---|
| 1.10.0(最新) | 2024 | KF5 全家桶 | ⭐⭐⭐⭐⭐ 极高 |
| 1.9.x | 2022 | KF5 强依赖 | ⭐⭐⭐⭐ 高 |
| 0.9.98 | 2014 | 纯 Qt5 | ⭐ 低 |
一句话经验:移植 KDE 系开源软件时,永远先翻一翻老版本——很多项目早年都有"non-KDE 版"或"Qt-only fork",能省下 1-2 周 KDE Frameworks 移植工作。
同理适用:KGet、Kate、Konsole、Krusader、KMyMoney 等 KDE 老项目。
二、CMake 改写类(2 个)
🕳️ #02 用源码自带的 CMakeLists.txt → 编出来是 KDE4 KParts 插件
关键字:KParts / kdiff3_KDEINIT_LIB / add_library(kdiff3 ... KIND PLUGIN)
现象:
你照着源码 src-QT4/CMakeLists.txt 跑 cmake -B build——配置过了,编译过了,但产物不是 libkdiff3.so 业务库,是个 libkdeinit4_kdiff3.so 插件——HAP 壳工程 dlopen 完全找不到 main 符号。
根因:
KDiff3 源码自带的 src-QT4/CMakeLists.txt 是给 KDE4 KParts 插件框架用的,会调 kde4_add_kdeinit_executable 这种 KDE 私有宏,输出符合 KDE 插件规范但不符合鸿蒙 HAP 期望的产物。
解决:
不要改源码自带的 CMakeLists.txt,新建一个干净的:
# 新建一个 CMakeLists.txt 放到 src-QT4/ 下覆盖(或者放别处再 -S 指过去)
cmake_minimum_required(VERSION 3.18)
project(kdiff3 CXX C)
set(CMAKE_CXX_STANDARD 14) # 见 #04
set(CMAKE_CXX_VISIBILITY_PRESET default) # 见 #03
set(CMAKE_AUTOMOC ON)
find_package(Qt5 REQUIRED COMPONENTS Core Gui Widgets PrintSupport)
include_directories(
${CMAKE_CURRENT_SOURCE_DIR}
${CMAKE_CURRENT_SOURCE_DIR}/kreplacements
)
set(KDIFF3_SRCS
main.cpp diff.cpp difftextwindow.cpp kdiff3.cpp
merger.cpp mergeresultwindow.cpp optiondialog.cpp
pdiff.cpp directorymergewindow.cpp fileaccess.cpp
progress.cpp smalldialogs.cpp kdiff3_shell.cpp
kdiff3_part.cpp gnudiff_analyze.cpp gnudiff_io.cpp
gnudiff_xmalloc.cpp common.cpp stable.cpp
kreplacements/kreplacements.cpp
kreplacements/ShellContextMenu.cpp
)
# ⭐ 核心:SHARED 库,不是 executable
add_library(kdiff3 SHARED ${KDIFF3_SRCS})
target_link_libraries(kdiff3 PRIVATE
Qt5::Core Qt5::Gui Qt5::Widgets Qt5::PrintSupport
)
一句话经验:KDE 系老项目自带的 CMakeLists.txt 99% 不能用,自己重写一个最小的覆盖即可。
🕳️ #03 add_library(kdiff3 SHARED ...) 但 main 符号不导出
关键字:-fvisibility=hidden / dlsym main not found / nm 看不到 T main
现象:
CMake 改完了,编译过了,file libkdiff3.so 显示 AArch64 ELF——但:
nm -D libkdiff3.so | grep " main$"
# 什么都没有
# 或者
00000000000a2740 t main ← ⚠️ 小写 t(local symbol)
HAP 壳 dlopen 成功但 dlsym("main") 返回 NULL——闪退。
根因:
OHOS clang 默认带 -fvisibility=hidden——所有符号都默认 hidden,包括 main 函数。
解决:
CMake 显式开放符号可见性:
# 全局开关
set(CMAKE_CXX_VISIBILITY_PRESET default)
set(CMAKE_C_VISIBILITY_PRESET default)
set(CMAKE_VISIBILITY_INLINES_HIDDEN OFF)
# 项目级编译选项
target_compile_options(kdiff3 PRIVATE -fvisibility=default)
或者只导出 main(更精细但更易出错):
// main.cpp 加属性
extern "C" __attribute__((visibility("default")))
int main(int argc, char *argv[]) {
// ...
}
自查:
$OHOS_SDK_ROOT/native/llvm/bin/llvm-nm -D libkdiff3.so | grep " main$"
# 期望:xxxxxx T main ← 大写 T = 全局符号
# 错误:xxxxxx t main ← 小写 t = local
# 错误:什么都没有 ← 被 hidden 掉
一句话经验:鸿蒙 HAP 通过 dlsym(“main”) 找入口,CMake 必须显式 CMAKE_CXX_VISIBILITY_PRESET default 让 main 是 T 符号。
三、Ninja 编译类(3 个)
🕳️ #04 error: ISO C++17 does not allow 'register' storage class specifier ⚠️ 致命
关键字:register / -Wregister / gnudiff_analyze.cpp:472:7 / ISO C++17 does not allow
现象:
CMake 配置秒过,ninja 编译到 12/24 个文件时炸:
[12/24] Building CXX object CMakeFiles/kdiff3.dir/gnudiff_analyze.cpp.o
FAILED: CMakeFiles/kdiff3.dir/gnudiff_analyze.cpp.o
/root/.../gnudiff_analyze.cpp:472:7: error: ISO C++17 does not allow
'register' storage class specifier [-Wregister]
register char *discards = discarded[f];
^~~~~~~~~
/root/.../gnudiff_analyze.cpp:482:8: error: ISO C++17 does not allow
'register' storage class specifier [-Wregister]
register lin j;
^~~~~~~~~
3 errors generated.
ninja: build stopped: subcommand failed.

根因:
KDiff3 的 gnudiff_*.cpp 文件直接搬自 GNU diff 的 1990 年代 C 代码,里面到处是 register int i 这种古早写法。
- C++03/11/14:
register是 deprecated keyword(警告但能编) - C++17 起:
register被 reserved(保留字,必须报错)
OHOS clang 默认 C++17,所以炸。
解决:
两条路(强烈建议都走):
# 方案 A:降到 C++14(推荐)
set(CMAKE_CXX_STANDARD 14)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
# 方案 B:强制把 register 错误降级为警告(兜底)
target_compile_options(kdiff3 PRIVATE
-Wno-register
-Wno-deprecated-register
-Wno-error=register
)
两条都加最稳。
为什么不直接改源码:
KDiff3 0.9.98 里有 3+ 处 register,但都在 GNU diff 的 gnudiff_*.cpp 里——改了就破坏了上游同步,每次升级要重做。编译标志全局规避才是对的方法。
一句话经验:移植 1990s 代码的 C++17 项目,CMake 永远先写 set(CMAKE_CXX_STANDARD 14)——register 不是唯一的老语言问题。
🕳️ #05 GNU diff 老代码一堆其它 warning 升级为 error
关键字:-Werror=deprecated-declarations / -Werror=narrowing / -Werror=writable-strings
现象:
修完 register 重新编,又炸:
error: assigning to 'char *' from a string literal of type 'const char[5]'
is deprecated [-Werror,-Wdeprecated]
error: narrowing conversion of '256' from 'int' to 'char'
[-Werror=narrowing]
error: ISO C++ forbids converting a string constant to 'char *'
[-Werror=writable-strings]
根因:
GNU diff 1990s 代码的"标配老问题"——同源于"那个年代允许写、现在不允许的"语言特性。
解决:
CMakeLists.txt 里把这一坨警告全部降级:
target_compile_options(kdiff3 PRIVATE
-Wno-deprecated-declarations
-Wno-unused-parameter
-Wno-unused-variable
-Wno-unused-but-set-variable
-Wno-narrowing
-Wno-deprecated-copy
-Wno-format-security
-Wno-register
-Wno-deprecated-register
-Wno-error=register
-Wno-null-dereference
-Wno-mismatched-new-delete
-Wno-writable-strings
)
这 12 个开关是 KDiff3 移植的"祖传配方"——不要试图省,会被各种新警告打回来重编。
一句话经验:移植老 C++ 代码到 OHOS clang,编译标志这一坨 -Wno-... 是版本红利,照抄即可。
🕳️ #06 kreplacements/ 头文件找不到
关键字:fatal error: 'kreplacements/kaction.h' file not found
现象:
src-QT4/main.cpp:23:10: fatal error: 'kreplacements/kaction.h' file not found
#include "kreplacements/kaction.h"
^~~~~~~~~~~~~~~~~~~~~~~~~
但 ls src-QT4/kreplacements/kaction.h 文件分明存在。
根因:
CMake 没把 kreplacements/ 加进 include 路径——而 KDiff3 源码里 #include "kreplacements/xxx.h" 走的是相对源文件路径。
解决:
CMakeLists.txt 里加:
include_directories(
${CMAKE_CURRENT_SOURCE_DIR} # ← 让 #include "xxx.h" 能找到
${CMAKE_CURRENT_SOURCE_DIR}/kreplacements
)
或者用 target 级别:
target_include_directories(kdiff3 PRIVATE
${CMAKE_CURRENT_SOURCE_DIR}
${CMAKE_CURRENT_SOURCE_DIR}/kreplacements
)
一句话经验:移植带"桩代码目录"的项目,永远把这个目录也加进 include path。
四、链接类(1 个)
🕳️ #07 链接 0 errors 但产物体积异常(200KB 或 50MB)
关键字:链接成功但 .so 大小不对 / __cxa_atexit undefined / 缺少链接器选项
现象:
ls -lh libkdiff3.so
# 情况 A:-rwxr-xr-x 1 root root 200K libkdiff3.so ← 太小,肯定缺东西
# 情况 B:-rwxr-xr-x 1 root root 50M libkdiff3.so ← 太大,肯定多链了静态库
根因:
- 太小:链接时没把所有 .o 都包含进去,可能 source list 漏了 cpp 文件
- 太大:链了静态库的 Qt(应该用 SHARED Qt 链接)
KDiff3 0.9.98 期望的产物大小是 1.6-1.7 MB(编译输出 + autogen MOC + 4 个 Qt 模块的符号引用)。
自查:
file libkdiff3.so
# 期望:ELF 64-bit LSB shared object, ARM aarch64, ...,
# BuildID[...], with debug_info, not stripped
ls -lh libkdiff3.so
# 期望:1.6-1.7 MB(带 debug_info)
# strip 之后:500-700 KB
readelf -d libkdiff3.so | grep NEEDED
# 期望 6 行:
# libQt5PrintSupport.so / Widgets / Gui / Core
# libc++_shared.so
# libc.so
解决:
确保 source list 完整(20 个 cpp 文件全部列出,参考 #02 的 KDIFF3_SRCS 数组)。
确保链接到 SHARED Qt(这是 Qt-OHOS 默认行为,无需特殊设置)。
一句话经验:KDiff3 0.9.98 产物的"健康体重"= 1.6-1.7 MB(debug_info)/ 500-700 KB(stripped)——偏离 ±50% 都不正常。
五、ELF 产物校验类(2 个)
🕳️ #08 T main 缺失 / 是 t main ⚠️ 致命
关键字:nm -D / T main vs t main / dlsym fails
现象:
$OHOS_SDK_ROOT/native/llvm/bin/llvm-nm -D libkdiff3.so | grep " main$"
# 错误 1:什么都没有 ← 完全没导出
# 错误 2:xxxxxx t main ← 小写 t(local),HAP 壳找不到

根因:见 #03——-fvisibility=hidden 默认导致。
解决:见 #03 的 CMake 配置。
正确产物应该是:
0000000000094274 T main ← 大写 T = global text
一句话经验:这是鸿蒙 HAP 加载的"生死门"——T main 没有就一切免谈。
🕳️ #09 LOAD 段对齐 ≠ 0x1000 / 启动 SIGSEGV(SEGV_MAPERR)
关键字:LOAD / 0x10000 / 0x4000 / Align / SIGSEGV(SEGV_MAPERR) / run_loadtasks
现象:
ELF 体检:
$OHOS_SDK_ROOT/native/llvm/bin/llvm-readelf -l libkdiff3.so | grep LOAD
LOAD 0x000000 0x0000000000000000 0x000000 R 0x10000 ← ❌ 应该是 0x1000
LOAD 0x0863b4 0x00000000000873b4 0x0a7f4c R E 0x10000
或者 HAP 装上设备后启动闪退,hilog 报:
F C03f00/Runtime: SIGSEGV(SEGV_MAPERR) in run_loadtasks
根因:
鸿蒙 PC 的 musl loader 要求所有 .so 的 LOAD 段按 4KB(0x1000)对齐——但某些工具链链接器默认 16KB(0x10000)或 64KB(0x40000),就会拉黑。
解决:
跑 fix_elf_align_v2.py 兜底修:
python3 fix_elf_align_v2.py libkdiff3.so
# 输出 1:✓ libkdiff3.so: 已对齐,无需修复 ← 正常
# 输出 2:⚠ libkdiff3.so: 已修复 (0x10000 → 0x1000) ← 修复了
链接期预防——CMakeLists.txt 加:
target_link_options(kdiff3 PRIVATE
"-Wl,-z,max-page-size=0x1000"
)
正确产物应该是:
LOAD 0x000000 ... R 0x1000
LOAD 0x0863b4 ... R E 0x1000
LOAD 0x12e300 ... RW 0x1000
LOAD 0x138480 ... RW 0x1000
↑ 全部 0x1000 = 4KB
一句话经验:永远跑 fix_elf_align_v2.py 兜底,永远在 link flags 加 -Wl,-z,max-page-size=0x1000。
六、Runtime 收集类(1 个)
🕳️ #10 libqohos.so 必须放两份且 md5 要一致
关键字:libqohos.so / platforms/libqohos.so / QPA platform plugin not found / 启动黑屏
现象:
dist/ 目录里你只放了 libqohos.so 一份:
dist/
├── libkdiff3.so
├── libQt5Core.so
├── libqohos.so ← 只有这里有
└── platforms/ ← platforms 目录是空的!
HAP 装上设备,启动后黑屏——hilog 报:
E A0c0d0/Qt: Failed to find the platform plugin "ohos"
E A0c0d0/Qt: Available platforms are: minimal, offscreen

根因:
Qt 的 QPA platform 插件加载机制要求:
Qt5 在初始化时会找 ./platforms/libqohos.so
但 dlopen 时 NEEDED 又要求 ./libqohos.so(同级目录)
两个位置都要有 libqohos.so,且必须是同一个文件(同 md5)。
解决:
mkdir -p dist/platforms
cp $QT_OHOS_ROOT/plugins/platforms/libqohos.so dist/
cp $QT_OHOS_ROOT/plugins/platforms/libqohos.so dist/platforms/
# 验证 md5 一致
md5sum dist/libqohos.so dist/platforms/libqohos.so
# 期望两行 md5 完全相同
KDiff3 的实测 md5(与 DiffPDF / IronLog 都一致):
1c3e3b940a9a2f14986e924f7d8fa62b libqohos.so
1c3e3b940a9a2f14986e924f7d8fa62b platforms/libqohos.so
一句话经验:Qt-OHOS 应用启动黑屏 99% 是 libqohos.so 漏放或漏一份——永远双份。
七、HAP 集成类(3 个)
🕳️ #11 把 dist/ 倒进 HAP 后改完所有配置仍报 “no signature file”
关键字:error: no signature file / 签名失败 / 个人证书 / build-profile.json5
现象:
hdc install -r Kdiff3Ohos.hap
# error: no signature file in app
或 DevEco Run 时报签名错误。
根因:
- 你复制了别人的 HAP 工程(如
DiffPdfOhos/)改名成Kdiff3Ohos/——原 build-profile.json5 里的签名指向别人的本地证书路径 - 或者你换了一台机器但没重新生成签名
解决:
DevEco Studio →
File → Project Structure → Signing Configs →
❌ 取消勾选 "Manual"
✅ 勾选 "Automatically generate signature"
→ 登录华为账号
→ 几秒钟自动签名
或手动清空 build-profile.json5:
- "signingConfigs": [
- {
- "name": "default",
- "material": { "certpath": "/Users/zhanghao/.ohos/..." }
- }
- ]
+ "signingConfigs": []
然后让 DevEco 重新生成。
一句话经验:任何复制别人 HAP 工程后的第一件事都是清空 signingConfigs + 自动签名重生。
八、真机调试类(1 个)
🕳️ #12 HAP 装上点开闪退 - dlopen failed: library xxx.so not found
关键字:dlopen failed / library not found / 缺少的依赖 / hilog
现象:
hdc install -r Kdiff3Ohos.hap # 安装成功
# 桌面点图标 → 闪一下 → 退出
hdc shell hilog | grep -iE "kdiff3|dlopen|library"
# E A0c0d0/Runtime: dlopen libkdiff3.so failed:
# E A0c0d0/Runtime: library "libQt5PrintSupport.so" not found
根因:
libkdiff3.so 的 NEEDED 依赖里有 libQt5PrintSupport.so——但你 entry/libs/arm64-v8a/ 下没放这个 .so。
解决:
做"反向闭包检查"——拿 NEEDED 列表把所有 .so 都补上:
$OHOS_SDK_ROOT/native/llvm/bin/llvm-readelf -d libkdiff3.so | grep NEEDED
# 应该列出 6 行:
# libQt5PrintSupport.so
# libQt5Widgets.so
# libQt5Gui.so
# libQt5Core.so
# libc++_shared.so
# libc.so (鸿蒙系统库,自带)
# 验证每个文件都在
for so in libQt5PrintSupport.so libQt5Widgets.so libQt5Gui.so libQt5Core.so libc++_shared.so; do
if [ -f "entry/libs/arm64-v8a/$so" ]; then
echo "✅ $so"
else
echo "❌ $so 缺失!从 Qt-OHOS 拷贝过来"
fi
done
KDiff3 真机部署的最小 .so 清单(已校验):
entry/libs/arm64-v8a/
├── libkdiff3.so 业务库(1.7 MB)
├── libQt5Core.so 34 MB
├── libQt5Gui.so 38 MB
├── libQt5Widgets.so 37 MB
├── libQt5PrintSupport.so 2.7 MB ← KDiff3 特有,DiffPDF 也用
├── libQt5Network.so 12 MB ← Qt-OHOS 启动连带,建议放
├── libQt5OhosExtras.so 5.1 MB ← Qt-OHOS QPA 配套
├── libqohos.so 17 MB ← 双份之一
├── libc++_shared.so 1.3 MB
├── platforms/
│ └── libqohos.so 17 MB ← 双份之二,必须同 md5
├── styles/
│ └── libqohosstyle.so 1.9 MB
└── imageformats/
└── (9 个图像插件) 约 6.7 MB
总计约 74 MB(压缩 21 MB)
一句话经验:部署前永远跑反向闭包检查——把 NEEDED 列表每个 .so 都验一遍。
九、4 条带回家的经验
把上面 12 个坑提炼成 4 条铁律:
铁律 1:移植 KDE 系软件,永远先翻一翻有没有"前 KF5 时代"的老版本
KDiff3 0.9.98 + kreplacements 让这次适配从"两周搞 KDE Frameworks 移植"变成"两小时改 CMakeLists.txt"。
适用同类项目:KGet / Kate / Konsole / Krusader / KMyMoney / Konqueror。
铁律 2:移植 1990s C++ 老代码,CMake 永远先写 C++14 + 一坨 -Wno-...
register、writable-strings、narrowing——这些"祖传警告"早晚都要踩。一开始就把 KDiff3 这套配方抄进 CMake,避免边踩边补。
铁律 3:CMake 永远 CMAKE_CXX_VISIBILITY_PRESET default
OHOS clang 默认 -fvisibility=hidden。T main 缺失是鸿蒙 HAP 加载的死亡之吻——必须显式放开。
铁律 4:libqohos.so 永远双份,永远 md5 校验
启动黑屏 99% 是这个原因。写进部署脚本,每次自动做这件事:
cp $QT_OHOS_ROOT/plugins/platforms/libqohos.so dist/
cp $QT_OHOS_ROOT/plugins/platforms/libqohos.so dist/platforms/
md5sum dist/libqohos.so dist/platforms/libqohos.so # 必须完全一致
十、KDiff3 项目对仓库知识体系的 3 个原创贡献
KDiff3 是仓库第一个 KDE 系开源软件适配——它独家贡献了 3 个仓库前序文档(DiffPDF / NotePad-- 那批纯 Qt 项目)没记录过的坑:
| # | 坑 | 关键修复 | 撞过的项目 |
|---|---|---|---|
| 原创 A | register 关键字 C++17 禁用 |
CMAKE_CXX_STANDARD 14 + -Wno-error=register |
KDiff3(首次) |
| 原创 B | -fvisibility=hidden 让 main 不导出 |
CMAKE_CXX_VISIBILITY_PRESET default |
KDiff3(首次精确诊断) |
| 原创 C | KDE 老项目优先选"前 KF5 版本" | 选 0.9.98 + kreplacements 桩 | KDiff3(首次) |
更多推荐




所有评论(0)