SDK介绍
qcc74xSDK 是由 Qualcomm 为 qcc74x 系列芯片提供的 IOT 和 MCU 开发套件。
代码仓库地址如下:
此仓库包含源码和编译工具,但是文档匮乏,并未描述如何编译。
我在阅读《CMake 构建实战—项目开发卷》时下载了此SDK,折腾了一番,终于摸索出如何编译此工程,仅以此文作为纪念。
编译框架介绍
编译工具链
位于 QCCSDK-QCC74x/toolchain 下的 riscv64-unknown-elf-gcc 工具链。支持 linux/windows 两个平台。
linux 下的工具链如下图所示
windows 下的工具链如下图所示:
编译方法
SDK 目录下的 README.md 文件已有说明,以编译 examples/helloword 为例;
cd examples/helloworld
make CHIP=qcc743 BOARD=qcc743dk
然而编译报错,提示 riscv64-unknown-elf-gcc 工具路径未找到。
框架介绍
虽然是从命令行调用 make 开始编译,但是这个SDK的编译框架比较复杂,从 make 读取 examples/helloworld/Makefile 开始,配置 CMake 环境,并由CMake生成 examples/helloworld/build/Makefile ,然后继续执行 Make 命令处理 examples/helloworl/build/Makefile 文件开始编译。
Linux 环境下编译
在 examples/helloworld 目录输入命令 make 报错
即所需的编译工具链 riscv64-unknown-elf-gcc 找不到。
编译工具链找不到的解决办法
export PATH=$PATH:$HOME/workspace/QCC74x/QCCSDK-QCC74x-master/toolchain/linux_x86_64/bin
再次输入命令 make 开始编译,编译成功。
编译通过,生成 elf 文件为 helloworld_gcc743.elf 并生成对应的 bin 文件。
但是不仅仅只是生成elf 和对应的 bin 文件,还执行了 post build 指定的其他几个编译产物。
Windows 环境下编译
进入 examples/helloworld 输入命令 make编译报错,找不到工具链 riscv64-unknown-elf-gcc
解决办法,临时把 riscv64-unknown-elf-gcc 所在路径添加到PATH 环境变量中。
虽然我曾更改过系统的 PATH 路径,但是奇怪的是在命令行并未生效。重新打开 VSCode 或者新打开 CMD 窗口,都不生效。只能临时添加到 PATH 变量中,此方法生效了。
编译完成生产 elf 和对应的 bin 文件。
继续执行 post build 动作,生成其他编译产物。
编译流程解析
参见我总结的流程图《QCC74x编译流程解析.png》
第一步 进入 examples/helloworld 目录,make Makefile 文件
第二步 helloworld/Makefile 引入 sdk/project.build 文件
第三步 又从 helloworld/CMakeLists.txt 文件开始处理 cmake脚本
第四步 上一步中的 helloworld/CMakeLists.txt 文件查找 qcc74xsdk 进而处理 sdk/CMakeLists.txt
编译流程总结
第一次遇见这么复杂的构建流程,总体来说是 make helloworld/Makefile 调用CMake 生成helloworld/build/Makefile make helloworld/build/Makefile。在 make 和 cmake 工具之间反复调用,生成最终的产物。
每一个示例工程目录下,例如 examples/helloworld 文件夹下都有入口 Makefile,也有 CMakeLists.txt。其中 Makefile 中传递一些参数给 project.build 文件,最终调用 cmake 处理 helloworld/CMakeList.stxt 生成最终的配置文件 helloworld/build/Makefile,所有的构建目标和编译后的 post_build 动作都在这个 Makefile 文件中。巧妙、但是复杂。
对于 CMake 新手来说,sdk/cmake 目录下的 CMake 模块文件非常巧妙,有些晦涩难懂。特别是 extension.cmake 模块,定义了很多宏和函数,宏 sdk_set_main_file 和 project 非常巧妙。
sdk_set_main_file() 宏,注意宏中定义的变量对包含这个宏的文件都有效,因此下面的宏 project() 可以直接使用变量 CURRENT_MAIN_FILE。第一次读到这段代码让人迷糊了一阵子。
需要注意的是 project() 已经重定义了,覆盖了原来的定义,但是在里面调用了 _project() 。
疑问
不知道宏定义 project 覆盖原来的 CMake 命令,再调用 _project() 这种用法是否合理。chatGPT 也没能给出满意的答案。
似乎用下面 chatGPT 推荐的方法更合适:
# 定义一个自定义宏,避免与 CMake 的 project() 冲突
macro(my_project name)
# 调用 CMake 的标准 project() 命令
project(${name})
# 这里可以加入一些自定义的逻辑,比如打印项目名称
message(STATUS "Project name set to: ${name}")
endmacro()
# 使用自定义的宏
my_project(MyApp)
《CMake 构建实战—项目开发卷》—实战分享1-QCC74x SDK 编译
SDK介绍
qcc74xSDK 是由 Qualcomm 为 qcc74x 系列芯片提供的 IOT 和 MCU 开发套件。
代码仓库地址如下:
此仓库包含源码和编译工具,但是文档匮乏,并未描述如何编译。
我在阅读《CMake 构建实战—项目开发卷》时下载了此SDK,折腾了一番,终于摸索出如何编译此工程,仅以此文作为纪念。
编译框架介绍
编译工具链
位于 QCCSDK-QCC74x/toolchain 下的 riscv64-unknown-elf-gcc 工具链。支持 linux/windows 两个平台。
linux 下的工具链如下图所示
windows 下的工具链如下图所示:
编译方法
SDK 目录下的 README.md 文件已有说明,以编译 examples/helloword 为例;
cd examples/helloworld
make CHIP=qcc743 BOARD=qcc743dk
然而编译报错,提示 riscv64-unknown-elf-gcc 工具路径未找到。
框架介绍
虽然是从命令行调用 make 开始编译,但是这个SDK的编译框架比较复杂,从 make 读取 examples/helloworld/Makefile 开始,配置 CMake 环境,并由CMake生成 examples/helloworld/build/Makefile ,然后继续执行 Make 命令处理 examples/helloworl/build/Makefile 文件开始编译。
Linux 环境下编译
在 examples/helloworld 目录输入命令 make 报错
即所需的编译工具链 riscv64-unknown-elf-gcc 找不到。
编译工具链找不到的解决办法
export PATH=$PATH:$HOME/workspace/QCC74x/QCCSDK-QCC74x-master/toolchain/linux_x86_64/bin
再次输入命令 make 开始编译,编译成功。
编译通过,生成 elf 文件为 helloworld_gcc743.elf 并生成对应的 bin 文件。
但是不仅仅只是生成elf 和对应的 bin 文件,还执行了 post build 指定的其他几个编译产物。
Windows 环境下编译
进入 examples/helloworld 输入命令 make编译报错,找不到工具链 riscv64-unknown-elf-gcc
解决办法,临时把 riscv64-unknown-elf-gcc 所在路径添加到PATH 环境变量中。
虽然我曾更改过系统的 PATH 路径,但是奇怪的是在命令行并未生效。重新打开 VSCode 或者新打开 CMD 窗口,都不生效。只能临时添加到 PATH 变量中,此方法生效了。
编译完成生产 elf 和对应的 bin 文件。
继续执行 post build 动作,生成其他编译产物。
编译流程解析
参见我总结的流程图《QCC74x编译流程解析.png》
第一步 进入 examples/helloworld 目录,make Makefile 文件
第二步 helloworld/Makefile 引入 sdk/project.build 文件
第三步 又从 helloworld/CMakeLists.txt 文件开始处理 cmake脚本
第四步 上一步中的 helloworld/CMakeLists.txt 文件查找 qcc74xsdk 进而处理 sdk/CMakeLists.txt
编译流程总结
第一次遇见这么复杂的构建流程,总体来说是 make helloworld/Makefile 调用CMake 生成helloworld/build/Makefile make helloworld/build/Makefile。在 make 和 cmake 工具之间反复调用,生成最终的产物。
每一个示例工程目录下,例如 examples/helloworld 文件夹下都有入口 Makefile,也有 CMakeLists.txt。其中 Makefile 中传递一些参数给 project.build 文件,最终调用 cmake 处理 helloworld/CMakeList.stxt 生成最终的配置文件 helloworld/build/Makefile,所有的构建目标和编译后的 post_build 动作都在这个 Makefile 文件中。巧妙、但是复杂。
对于 CMake 新手来说,sdk/cmake 目录下的 CMake 模块文件非常巧妙,有些晦涩难懂。特别是 extension.cmake 模块,定义了很多宏和函数,宏 sdk_set_main_file 和 project 非常巧妙。
sdk_set_main_file() 宏,注意宏中定义的变量对包含这个宏的文件都有效,因此下面的宏 project() 可以直接使用变量 CURRENT_MAIN_FILE。第一次读到这段代码让人迷糊了一阵子。
需要注意的是 project() 已经重定义了,覆盖了原来的定义,但是在里面调用了 _project() 。
疑问
不知道宏定义 project 覆盖原来的 CMake 命令,再调用 _project() 这种用法是否合理。chatGPT 也没能给出满意的答案。
似乎用下面 chatGPT 推荐的方法更合适:
# 定义一个自定义宏,避免与 CMake 的 project() 冲突
macro(my_project name)
# 调用 CMake 的标准 project() 命令
project(${name})
# 这里可以加入一些自定义的逻辑,比如打印项目名称
message(STATUS "Project name set to: ${name}")
endmacro()
# 使用自定义的宏
my_project(MyApp)
本文来自论坛,点击查看完整帖子内容。