HarmonyOS鸿蒙Next中cmake项目能否独立于整个项目,为何cmake配置的中间文件和编译的文件位置固定

HarmonyOS鸿蒙Next中cmake项目能否独立于整个项目,为何cmake配置的中间文件和编译的文件位置固定 一般使用deveco新建模块时会选择har / hsp / hap这三种,同时还可以启用native层。cmakelists.txt文件一般都在src/main/cpp路径下,但配置和编译的产物分别位于.cxx/default/default/架构目录/ 下和build/default/intermediate/libs/default/架构目录/ 下。

为何不把cmake的配置构建直接放在和cmakelists.txt同级的build目录下而是固定.cxx下的子目录?是否允许在src/main/cpp目录下创建自己的cmake项目,编译不依赖hvigor而是手动编译,编译后的产物直接作为arkts的外部导入库?从哪里查看deveco对cmake使用的命令行参数?


更多关于HarmonyOS鸿蒙Next中cmake项目能否独立于整个项目,为何cmake配置的中间文件和编译的文件位置固定的实战教程也可以访问 https://www.itying.com/category-93-b0.html

7 回复

CMake可以独立,CMake构建工程编译工具链参考:CMake构建工程配置HarmonyOS编译工具链-编译工具链-NDK开发 - 华为HarmonyOS开发者

1. 为何构建目录固定为.cxx下的子目录,而非与CMakeLists.txt同级的build目录?

  • 工程结构统一性:为了保持项目整洁,避免源码目录被污染。
  • IDE集成:Deveco Studio等IDE依赖于这套固定的目录结构来定位CMake的构建输出(如生成的.so文件),以便正确打包到HAP中。如果随意更改,可能导致IDE无法正确识别Native库。
  • 构建缓存与性能:将构建目录固定在.cxx下有助于利用增量编译和缓存,提升构建速度。如果随意更改,可能导致每次构建都重新生成,影响效率。

2. 是否允许在src/main/cpp目录下创建独立的CMake项目,手动编译后作为ArkTS的外部导入库?

目前支持在src/main/cpp目录下创建独立的CMake项目,同时支持手动编译后作为ArkTS的外部导入库。

3. 从哪里查看Deveco对CMake使用的命令行参数?

您可以通过以下几种方式查看Deveco Studio(或hvigor)调用CMake时使用的命令行参数:

  • 构建日志:在Deveco Studio中执行构建(例如编译HAP),然后在“Build”或“Run”窗口查看详细的构建输出日志。日志中通常会显示完整的CMake命令,包括-D参数、工具链文件路径、构建目录等。例如,您可能会看到类似如下的命令:

    /path/to/cmake -H/path/to/src/main/cpp -B/path/to/.cxx/default/default/arm64-v8a -DOHOS_ARCH=arm64-v8a -DCMAKE_TOOLCHAIN_FILE=/path/to/ohos.toolchain.cmake ...
    
  • CMake缓存文件:构建完成后,在构建目录(如.cxx/default/default/arm64-v8a/CMakeCache.txt)中查看CMake缓存。该文件记录了CMake配置的所有变量及其值,包括由构建工具传递的参数。

更多关于HarmonyOS鸿蒙Next中cmake项目能否独立于整个项目,为何cmake配置的中间文件和编译的文件位置固定的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


.cxx 和 intermediate/libs 目录是 DevEco/Hvigor 接管 native 构建后的工作区,不放在 src/main/cpp/build 里主要是为了按 product、buildMode、target、ABI 隔离。否则同一份 CMakeLists.txt 在 debug/release、不同 ABI 下容易互相污染。

可以独立维护一个 CMake 项目,但要注意两点:

  1. 最终产物必须按 HarmonyOS native ABI、toolchain、sysroot 编译,不能拿普通桌面平台的 so 直接给 ArkTS 调。

  2. 如果要随 HAP/HSP 打包,最好还是让 Hvigor 知道这些 so 的来源和复制路径,否则发布构建、清理、增量编译都容易失控。

想看 DevEco 实际调用参数,可以查看 .cxx 下生成的构建文件、compile_commands.json,以及构建日志中的 cmake/ninja 命令。

.cxx 目录是 DevEco/Hvigor 接管 CMake 后的构建工作区,通常会按 product、buildMode、target、ABI 等维度隔离。这样做的好处是同一份 CMakeLists.txt 可以被不同模块、不同构建模式复用,产物也能被 Hvigor 后续打包到对应 hap/har/hsp 的 native libs 中。

不放在 src/main/cpp 同级 build 目录,主要是为了避免源码目录被不同 ABI 和构建模式污染,也便于 IDE 清理、增量构建和索引。

如果你想独立构建 native 库,也可以用外部 CMake/NDK 工具链先生成 .so,再按 ABI 放到模块约定的 libs 目录并在工程里引用。但只要最终要跟 HarmonyOS 模块一起打包,仍建议让 Hvigor 管理一次完整构建链路。

可以独立。最后编译成鸿蒙能用的库就行。
题主的几个需求都是可以满足的,鸿蒙的native用的cmake也基本符合cmake的那一套。
参考《CMake构建工程编译工具链》
想在构建过程中参与更多,可以研究下《配置构建流程》《定制构建》等。

这个问题本质上涉及 DevEco Studio + Hvigor + CMake 集成机制,很多做过纯 CMake、Qt、Linux、Android NDK 的开发者都会有同样的疑问。

1. 为什么中间文件固定生成到 .cxx 目录?

这是 DevEco Studio 参考 Android Studio 的设计。

例如:

src/main/cpp/CMakeLists.txt

不会直接在:

src/main/cpp/build

生成构建目录。

而是生成到:

.cxx/default/default/debug/arm64-v8a/
.cxx/default/default/release/arm64-v8a/

原因有几个:

避免污染源码目录

如果直接:

src/main/cpp/build

会导致:

cpp
├── include
├── src
├── build
│   ├── CMakeCache.txt
│   ├── ninja
│   ├── obj
│   └── ...

源码和构建文件混杂。


支持多 Product

HarmonyOS支持:

default
phone
tablet
car

等 Product。

所以:

.cxx
 └── default
      └── default

实际上对应:

product
buildMode

支持多架构

例如:

arm64-v8a
x86_64

同时存在。

因此 DevEco 统一管理:

.cxx

而不是让开发者自行管理 build 目录。


2. 能否在 src/main/cpp 下建立自己的独立 CMake 工程?

答案:

可以

例如:

src/main/cpp
├── sdk
│   ├── CMakeLists.txt
│   └── src
│
├── engine
│   ├── CMakeLists.txt
│   └── src
│
└── CMakeLists.txt

主工程:

add_subdirectory(sdk)
add_subdirectory(engine)

这是完全支持的。


3. 能否完全脱离 Hvigor 自己编译?

也可以。

例如:

cmake -B build
cmake --build build

生成:

libxxx.so

然后放入:

entry/libs/arm64-v8a/

或者:

src/main/libs/arm64-v8a/

再在:

add_library(xxx SHARED IMPORTED)

set_target_properties(
    xxx
    PROPERTIES
    IMPORTED_LOCATION
    ${CMAKE_CURRENT_SOURCE_DIR}/../libs/arm64-v8a/libxxx.so
)

作为预编译库导入。

这种方式很多大型项目都在用。


4. 是否必须通过 Hvigor 编译 Native?

不是。

Hvigor只是:

ArkTS构建系统

Native部分本质仍然:

CMake
+
Ninja
+
clang

你完全可以:

第三方CI
↓
编译so
↓
提交仓库
↓
ArkTS引用

5. 从哪里查看 DevEco 调用 CMake 的参数?

最直接的方法:

方法1

查看:

.cxx/default/default/debug/arm64-v8a/CMakeCache.txt

里面有:

CMAKE_C_COMPILER
CMAKE_CXX_COMPILER
CMAKE_TOOLCHAIN_FILE

等完整配置。


方法2

查看:

compile_commands.json

你前面提到过这个文件。

里面直接记录:

{
  "command": "clang++ ...",
  "file": "xxx.cpp"
}

是最完整的编译命令。


方法3

打开 Build 日志

DevEco:

Build
→ Build Output

或者:

.hvigor/outputs/build-logs

能看到类似:

cmake
  -GNinja
  -DCMAKE_BUILD_TYPE=Debug
  -DOHOS_ARCH=arm64-v8a
  ...

的参数。


方法4

直接查看 hvigor 生成脚本

例如:

build/default/intermediates/cmake/

附近目录中会生成:

cmake_configure.log
ninja_build.log

具体路径会随版本变化。


6. 能否修改 .cxx 输出目录?

理论上 CMake 支持:

set(CMAKE_BINARY_DIR ...)

但在 DevEco 环境下:

不建议

因为:

Hvigor
↓
自动同步
↓
重新生成配置

很可能覆盖你的设置。

目前:

.cxx
build/default/intermediates

属于 IDE 管理目录。

开发者基本无法稳定修改。


实际项目推荐

如果项目比较大(例如:

音视频SDK
推理引擎
OpenCV
FFmpeg
ONNX Runtime

这种级别):

推荐:

独立CMake工程
↓
CI编译so
↓
Harmony工程只负责引用

而不是把全部源码塞进:

src/main/cpp

交给 Hvigor 管理。

这样:

  • 编译更快
  • IDE索引更稳定
  • CMake自由度更高
  • 不受 DevEco 升级影响

也是很多商业 SDK 在 HarmonyOS NEXT 上的实际做法。

HarmonyOS鸿蒙Next中,cmake项目默认作为native模块嵌入整体项目,不能独立于项目运行,但可通过修改CMakeLists.txt和项目配置实现独立构建。中间文件和编译文件位置固定,是因为鸿蒙构建系统(hvigor)为统一管理依赖和产物,强制指定输出目录(如build目录),避免路径冲突并优化缓存机制。

在DevEco Studio中,C++编译的中间产物和最终库文件放在 .cxxbuild 的固定子目录下,是为了与 DevEco 的 hvigor 构建系统深度集成,实现多模块依赖管理、增量编译与统一缓存,保证构建的一致性和自动化,避免用户手动干预破坏工程结构。

你完全可以在 src/main/cpp 下创建独立的 CMake 工程并手动编译,不依赖 hvigor。手动编译时需指定鸿蒙 NDK 工具链(OHOS_STLOHOS_ARCH 等)和系统库路径,编译产物需按约定放到 模块/libs/${target_arch}/ 下,并在 build-profile.json5hvigorfile.ts 中正确引用,这样 ArkTS 就能作为外部导入库加载。

想查看 DevEco 实际调用的 CMake 命令行参数,最简单的方法是查看 .cxx/default/debug/${arch}/cmake_build_command.txt 文件,其中完整记录了所有参数;也可开启构建日志(hvigor --info)从终端抓取。

回到顶部