【Android笔记】记一次 CMake 构建 Filament Android 库的完整排错过程(安卓交叉编译、CMake、Ninja)
写在前面的话,为了保持Sceneform-EQR始终是采用最新的filament,每隔一段时间我都会编译filament,并根据新增内容完善Sceneform-EQR。
现由于更换电脑,环境需重新配置。简单记录下编译出错和解决方式。
Sceneform-EQR 是EQ对谷歌“sceneform-android-sdk”的扩展,适用于图形和视频,以及增强现实(AR)和虚拟现实(VR)相关领域。它目前集成了 ARCore、AREngine 和 ORB-SLAM,提供多种场景选项,包括 AR 场景、VR 场景和自定义背景场景,以满足不同的原生三维开发需求。
文章目录
- 从坑中走出:一次 CMake 构建 Filament Android 库的完整排错过程
- 一、项目背景与目标
- 二、构建命令初稿
- 三、连续踩坑全过程
- 1. 混用生成器导致缓存冲突
- 2. source directory 错误
- 3. 找不到 Ninja 和编译器
- 4. toolchain 文件语法错误
- 5. CMAKE\_TOOLCHAIN\_FILE 未生效
- 6. 成功配置但路径错乱
- 四、构建成功后的目录结构
- 五、总结与建议
- 六、参考文档
从坑中走出:一次 CMake 构建 Filament Android 库的完整排错过程
本文将详细记录我在构建 Google Filament Android 库的过程中,遇到的各种 CMake 报错与环境配置问题,以及逐一解决的思路与方法,希望对使用 CMake 构建跨平台 C++ 工程的你有所帮助。
一、项目背景与目标
Filament 是 Google 开源的跨平台实时渲染引擎,广泛用于安卓、高性能图形渲染、AR/VR 等领域。
我的目标是:
- 编译出适用于 Android 平台的
aarch64
架构的 Filament 动态链接库(如libfilament.so
); - 使用官方提供的 CMake toolchain 文件进行交叉编译;
- 最终产出可用于 Android 应用集成的
.so
动态库及头文件。
二、构建命令初稿
初始的构建命令如下(位于 filament-1.53.4/out/cmake-android-release-aarch64
目录):
cmake ^-G Ninja ^-DCMAKE_BUILD_TYPE=Release ^-DCMAKE_INSTALL_PREFIX=..\android-release\filament ^-DCMAKE_TOOLCHAIN_FILE=..\..\build\toolchain-aarch64-linux-android.cmake ^..\..
期望:
通过这个命令使用 Ninja 生成 Android 用的 Makefile 构建配置,并交叉编译出适用于 ARM64 的 Android 库。
三、连续踩坑全过程
1. 混用生成器导致缓存冲突
错误信息:
CMake Error: Error: generator : NMake Makefiles
Does not match the generator used previously: Visual Studio 17 2022
原因分析:此前使用过 Visual Studio 构建,并在相同的输出目录下(如 out/cmake-release
)使用了不同的构建生成器。
解决方法:
- 删除缓存:
rd /s /q CMakeCache.txt CMakeFiles
- 或者换一个新的构建输出目录(推荐):
mkdir out/cmake-android-release-aarch64
cd out/cmake-android-release-aarch64
2. source directory 错误
错误信息:
CMake Error: The source directory "/" does not appear to contain CMakeLists.txt.
原因分析:
命令行中没有指定有效的源码目录,或者路径拼接出现问题导致 ..\..
被误解释为 /
。
解决方法:
确保当前目录是 filament/out/cmake-android-release-aarch64
,并用相对路径指向 filament
根目录:
cmake ..\.. # 即指向 filament 根目录
3. 找不到 Ninja 和编译器
错误信息:
CMake was unable to find a build program corresponding to "Ninja"
CMAKE_C_COMPILER not set, after EnableLanguage
原因分析:
- 本机未正确安装 Ninja;
- 或者
PATH
中未包含 Ninja 可执行路径; - Toolchain 设置未正确配置 NDK 和交叉编译工具。
解决方法:
- 下载 Ninja 并加入环境变量(推荐使用官方预编译);
- 确保你的 NDK 路径设置正确,并传递给
toolchain
文件; - 也可以使用
ANDROID_NDK
、ANDROID_TOOLCHAIN
显式指定编译工具。
4. toolchain 文件语法错误
错误信息:
file FILE([TO_CMAKE_PATH|TO_NATIVE_PATH] path result) must be called with exactly three arguments
list GET given empty list
get_filename_component called with incorrect number of arguments
原因分析:
说明你传入的 NDK 路径、TOOLCHAIN 或系统路径变量未被正确设置,导致 CMake 脚本中的变量为空。
解决方法:
检查 toolchain-aarch64-linux-android.cmake
中前几行,是否读取了环境变量如:
file(TO_CMAKE_PATH "$ENV{ANDROID_NDK}" ANDROID_NDK)
此处 $ENV{ANDROID_NDK}
为空,后续 list/get_filename_component 就会失败。
建议:
- 设置环境变量:
set ANDROID_NDK=C:\Android\sdk\ndk\25.1.8937393
- 或者手动替换 toolchain 中的相关行,直接写死路径调试。
5. CMAKE_TOOLCHAIN_FILE 未生效
现象描述:
Manually-specified variables were not used by the project:CMAKE_TOOLCHAIN_FILE
原因分析:
你可能在已有的 CMake 缓存目录中重新执行构建命令,但 CMake 不会重新读取 CMAKE_TOOLCHAIN_FILE
,因为该值只在第一次 configure 时生效。
解决方法:
删除缓存后重新 configure:
rd /s /q CMakeCache.txt CMakeFiles
6. 成功配置但路径错乱
构建路径:
D:\filament-1.53.4\out\cmake-release\out\cmake-android-release-aarch64
原因分析:
你在 out/cmake-release
中再次 cd out/cmake-android-release-aarch64
,导致路径变成 out/cmake-release/out/cmake-android-release-aarch64
,路径层级错误。
建议:
统一使用清晰路径:
D:\filament-1.53.4\out\cmake-android-release-aarch64
四、构建成功后的目录结构
配置成功后,会看到类似如下结构:
out/
├── cmake-android-release-aarch64/
│ ├── CMakeFiles/
│ ├── build.ninja
│ ├── lib/
│ │ ├── libfilament.so
│ │ └── ...
│ └── ...
└── android-release/└── filament/├── include/└── lib/
执行构建命令:
ninja
ninja install
五、总结与建议
问题类型 | 关键点 | 建议 |
---|---|---|
生成器冲突 | 混用了 NMake / Ninja / Visual Studio | 每次构建新平台前清理缓存 |
Ninja 未安装 | 构建器不可用 | 下载并配置环境变量 |
NDK 未配置 | toolchain 报错 | 设置 ANDROID_NDK 环境变量或写死路径 |
toolchain 变量为空 | list/get_filename 错误 | 打印调试变量确认路径是否为空 |
CMAKE_TOOLCHAIN_FILE 未生效 | 被缓存忽略 | 删除 CMakeCache.txt 重新生成 |
路径错乱 | 输出路径嵌套混乱 | 使用绝对路径或统一的输出目录结构 |
六、参考文档
- Filament 官方文档
- CMake Toolchain 配置指南
- Ninja 官方地址
- CMake 常见报错解读与解决方案
相关文章:

【Android笔记】记一次 CMake 构建 Filament Android 库的完整排错过程(安卓交叉编译、CMake、Ninja)
写在前面的话,为了保持Sceneform-EQR始终是采用最新的filament,每隔一段时间我都会编译filament,并根据新增内容完善Sceneform-EQR。 现由于更换电脑,环境需重新配置。简单记录下编译出错和解决方式。 Sceneform-EQR 是EQ对谷歌“…...

C#中的BeginInvoke和EndInvoke:异步编程的双剑客
文章目录 引言1. BeginInvoke和EndInvoke的基本概念1.1 什么是BeginInvoke和EndInvoke1.2 重要概念解释 2. 委托中的BeginInvoke和EndInvoke2.1 BeginInvoke方法2.2 EndInvoke方法2.3 两者的关系 3. 使用方式与模式3.1 等待模式3.2 轮询模式3.3 等待句柄模式3.4 回调模式 4. 底…...

告别延迟!modbus tcp转profine网关助力改造电厂改造升级
发电需求从未如此旺盛。无论您是为客户发电还是为自身运营发电,您都需要提高运营效率,并在资产老化、资源萎缩的情况下,紧跟不断变化的法规。如今,智能系统和技术能够帮助您实现运营转型,提高可视性并实现关键流程自动…...

《软件工程》第 5 章 - 需求分析模型的表示
目录 5.1需求分析与验证 5.1.1 顺序图 5.1.2 通信图 5.1.3 状态图 5.1.4 扩充机制 5.2 需求分析的过程模型 5.3 需求优先级分析 5.3.1 确定需求项优先级 5.3.2 排定用例分析的优先顺序 5.4 用例分析 5.4.1 精化领域概念模型 5.4.2 设置分析类 5.4.3 构思分析类之间…...
解释k8s种ConfigMap和Secret的作用,如何在Pod中挂载环境变
一、ConfigMap & Secret 核心定位 属于Kubernetes的配置管理特性,用于解耦应用与配置 1. ConfigMap 作用:存储非敏感配置数据 存储内容: 环境变量命令行参数配置文件(如JSON/XML/YAML)系统参数(如J…...

阿里云国际版香港轻量云服务器:CN2 GIA加持,征服海外网络的“速度与激情”!
阿里云国际版香港轻量云服务器:CN2 GIA加持,征服海外网络的“速度与激情”! 面对全球化业务拓展对网络连接的严苛要求,阿里云国际版香港轻量云服务器正成为出海企业和开发者的新宠。其核心优势在于搭载了CN2 GIA(Glob…...

Qt6无法识别OpenCV(Windows端开发)
这段时间在Windows 10上进行Qt6的开发。结果在build过程中,出现了如下错误: 但实际上,我明明安装了OpenCV4.10.0, 并且也在CMakeLists.txt中加入了相关内容。 但是,注意自己的编译输出: [1/5 1.4/sec] Automatic MOC and UIC for target R…...

二、网络安全常见编码及算法-(2)
该文章主要介绍古典密码和隐写常用的密码和编码,日常中很少见,主要用于ctf比赛和考试学习一、古典密码 1、古典密码概念概述 古典密码是密码学发展早期所使用的一系列加密技术,这些密码主要依靠手工操作或简单的机械装置来实现信息的加密和…...

Windows系统安装MySQL Connector 使用C++ VS2022连接MySQL
1. 官网及版本 1.1. 网址 官方文档 - 安装编译构建: https://dev.mysql.com/doc/connector-cpp/9.3/en/ 官方文档 - 使用案例: https://dev.mysql.com/doc/dev/connector-cpp/latest/ 下载地址: https://dev.mysql.com/downloads/connector/…...

D2000平台上Centos使用mmap函数遇到的陷阱
----------原创不易,欢迎点赞收藏。广交嵌入式开发的朋友,讨论技术和产品------------- 在飞腾D2000平台上,安装了麒麟linux系统,我写了个GPIO点灯的程序,在应用层利用mmap函数将内核空间映射到用户态,然后…...

Elasticsearch索引机制与Lucene段合并策略深度解析
引言 在现代分布式搜索引擎Elasticsearch中,文档的索引、更新和删除操作不仅是用户交互的核心入口,更是底层存储架构设计的关键挑战。本文围绕以下核心链路展开: 文档生命周期管理:从客户端请求路由到分片定位,从内存…...
BPE、WordPiece 与 Unigram:三种主流子词分词算法对比
BPE、WordPiece 与 Unigram:三种主流子词分词算法对比 在构建现代自然语言处理模型时,Tokenizer 是连接文本与模型之间的桥梁。而在 tokenizer 的设计中,BPE(Byte Pair Encoding)、WordPiece 和 Unigram 三种子词&…...
青少年编程与数学 02-020 C#程序设计基础 11课题、可视化编程
青少年编程与数学 02-020 C#程序设计基础 11课题、可视化编程 一、可视化编程1. 降低学习门槛2. 提高学习兴趣3. 便于学习和掌握4. 为后续学习打下基础5. 适合不同年龄段和背景的初学者6. 适合初学者的可视化编程工具 二、可视化编程适合初学者1. 降低学习门槛2. 提高学习兴趣3…...
AI时代新词-AI驱动的自动化(AI - Driven Automation)
一、什么是AI驱动的自动化? AI驱动的自动化(AI - Driven Automation)是指利用人工智能技术实现各种流程和任务的自动化。这种自动化不仅包括简单的重复性任务,还涵盖了复杂的决策和优化任务。AI驱动的自动化通过机器学习、深度学…...

整合Jdk17+Spring Boot3.2+Elasticsearch9.0+mybatis3.5.12的简单用法
Elasticsearch是一个基于Lucene的分布式搜索和分析引擎,广泛应用于全文搜索、日志分析等场景。结合Spring Boot可以快速构建强大的搜索应用。本文将介绍如何在Spring Boot项目中集成和使用Elasticsearch。 ES9.0.1目前支持的包只有 elasticsearch-rest-client/ …...
Starrocks 物化视图的实现以及在刷新期间能否读数据
背景 本司在用Starrocks做一些业务上的分析的时候,用到了物化视图,并且在高QPS的情况下,RT也没有很大的波动,所以在此研究一下Starrock的实现,以及在刷新的时候是不是原子性的 本文基于Starrocks 3.3.5 结论 Starro…...
前后端传输 Long 类型数据时(时间戳,雪花算法ID),精度丢失的根本原因
前后端传输 Long 类型数据时,精度丢失的根本原因是 JavaScript 的 Number 类型无法精确表示超过 53 位(64 位双精度浮点数)的整数,而 Java 的 Long 类型是 64 位整数。当后端返回的 Long 值超过 2^53-1(即 90071992547…...
探索容器技术:Docker与Kubernetes的实践指南
随着云计算和微服务架构的兴起,容器技术已经成为软件开发和部署的新标准。容器技术以其轻量级、可移植性和灵活性等特点,为应用程序的快速部署、扩展和管理提供了强大的支持。在众多容器技术中,Docker和Kubernetes无疑是最受欢迎的两种。本文…...

Ubuntu从0到1搭建监控平台:本地部署到公网访问实战教程Cpolar穿透与Docker部署全过程
文章目录 前言1.关于Ward2.Docker部署3.简单使用ward4.安装cpolar内网穿透5. 配置ward公网地址6. 配置固定公网地址总结 前言 IT运维人员是否常为服务器管理系统的复杂操作所困扰?当海量性能指标图表与密集预警信号同时涌现时,这种信息过载往往让专业团…...

vscode java debug terminal 中文乱码
现象 解决 快捷键 ctrl , 进入setting 配文件添加 "terminal.integrated.automationProfile.windows": {"path": "cmd","args": ["/k","chcp","65001"]}terminal 启动时,活动也改为 utf-…...

3D PDF如何制作?SOLIDWORKS MBD模板定制技巧
SOLIDWORKS制作3D PDF模版 SOLIDWORKS MBD能够帮助工程师以清晰直观的方式描述产品尺寸信息。在3D PDF文件中,用户可以自由旋转和移动视图,方便查看模型的各个尺寸细节。 本文将带您一步步学习如何使用SOLIDWORKS MBD制作专业的3D PDF模板,…...

Qt DateTimeEdit(时间⽇期的微调框)
使⽤ QDateEdit 作为⽇期的微调框. 使⽤ QTimeEdit 作为时间的微调框 使⽤ QDateTimeEdit 作为时间⽇期的微调框. 这⼏个控件⽤法⾮常相似, 我们以 QDateTimeEdit 为例进⾏介绍. QDateTimeEdit 核⼼属性 属性说明dateTime时间⽇期的值. 形如 2000/1/1 0:00:00date单纯⽇期…...

C# 类和继承(屏蔽基类的成员)
屏蔽基类的成员 虽然派生类不能删除它继承的任何成员,但可以用与基类成员名称相同的成员来屏蔽(mask) 基类成员。这是继承的主要功能之一,非常实用。 例如,我们要继承包含某个特殊方法的基类。该方法虽然适合声明它的…...
基于qt5和stk10开发的互联调试
基于qt5和stk10开发的互联调试程序 QTSTK_Test_yuanwenjian/CppIncludes/AgAsHpopPlugin.tlb , 110080 QTSTK_Test_yuanwenjian/CppIncludes/agashpopplugin.tlh , 108623 QTSTK_Test_yuanwenjian/CppIncludes/AgAttrAutomation.tlb , 11408 QTSTK_Test_yuanwenjian/CppInclude…...
matlab雷达定位仿真
一、边扫描边跟踪雷达仿真 边扫描边跟踪(BISTAR)雷达仿真是一种实时雷达信号处理的技术,用于模拟雷达系统的操作过程,特别是那些具备连续扫描能力的雷达。它的基本原理和流程可以分为以下几个步骤: (1&…...

基于vue框架的动物园饲养管理系统a7s60(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面。
系统程序文件列表 项目功能:饲养员,健康登记,工作进度,动物信息,进食信息,动物健康,动物医治,饲料信息,工作留言 开题报告内容 基于Vue框架的动物园饲养管理系统开题报告 一、研究背景与意义 (一)研究背景 随着城市化进程加快和公众对生…...
MySQL 索引和事务
目录 前言 一、MySQL 索引介绍 1. 索引概述 2. 索引作用 3. 索引的分类 3.1 普通索引 3.2 唯一索引 3.3 主键索引 3.4 组合索引 (最左前缀) 3.5 全文索引 (FULLTEXT) 3.6 创建索引的原则依据 3.7 查看索引 3.8 删除索引 二、MySQL 事务 1. 事务的 ACID 原则 MYS…...
BERT分类器和朴素贝叶斯分类器比较
一、核心原理对比 维度预训练模型(如BERT)朴素贝叶斯分类器模型类型深度学习模型,基于Transformer架构,通过大规模无监督预训练学习语言表示。传统机器学习模型,基于贝叶斯定理和特征条件独立假设。特征表示自动学习文本的上下文相关表示(contextual embeddings),捕捉长…...

WPS自动换行
换行前 换行后 快捷键 第一步:启用「自动换行」功能 选中目标单元格/区域:点击需要设置的单元格(或拖动选中多个单元格)。开启自动换行(3种方式任选): 快捷按钮:在顶部菜单栏点击「…...
C#面向对象核心:类继承详解
类继承是什么? 继承是面向对象编程的三大特性之一,允许新类(派生类)基于已有类(基类)进行扩展。通过继承,派生类可以“免费”获得基类的字段、方法等成员,并添加自身独有的功能。 …...