网站功能开发费用多少钱,衣服网站建设方案,九江市建设监理有限公司网站,直播app开发价格1、ESP32工程结构 本文中使用的是乐鑫官方推出的ESP-IDF v5.1对ESP32S3设备开发#xff0c;并非是Arduino、Micro-python等第三方工具开发。在ESP-IDF框架中#xff0c;乐鑫官方已经将CMake 和 Ninja 编译构建工具集成到了ESP-IDF中。 ESP-IDF 即乐鑫物联网开发框架#xff…1、ESP32工程结构 本文中使用的是乐鑫官方推出的ESP-IDF v5.1对ESP32S3设备开发并非是Arduino、Micro-python等第三方工具开发。在ESP-IDF框架中乐鑫官方已经将CMake 和 Ninja 编译构建工具集成到了ESP-IDF中。 ESP-IDF 即乐鑫物联网开发框架可为在 Windows、Linux 和 macOS 系统平台上开发 ESP32-S3 应用程序提供工具链、API、组件和工作流程的支持。 ESP32的项目实例工程文件结构 - myProject/- CMakeLists.txt- sdkconfig- components/ - component1/ - CMakeLists.txt- Kconfig- src1.c- component2/ - CMakeLists.txt- Kconfig- src1.c- include/ - component2.h- main/ - CMakeLists.txt- src1.c- src2.c- build/ ESP32的示例工程项目 “myProject” 包含以下组成部分 ①、顶层CMakeLists.txt 文件这是 CMake 用于学习如何构建项目的主要文件可以在这个文件中设置项目全局的 CMake 变量。 ②、“sdkconfig” 项目配置文件执行 idf.py menuconfig 时会创建或更新此文件文件中保存了项目中所有组件包括 ESP-IDF 本身的配置信息。 ③、可选的 “components” 目录包含了项目的部分自定义组件并不是每个项目都需要这种自定义组件但它有助于构建可复用的代码或者导入第三方不属于 ESP-IDF的组件。也可以在顶层 CMakeLists.txt 中设置 EXTRA_COMPONENT_DIRS 变量以查找其他指定位置处的组件。 ④、“main” 目录这是一个特殊的组件它包含项目本身的源代码。”main” 是默认名称CMake 变量 COMPONENT_DIRS 默认包含此组件但也可以修改此变量。如果项目中源文件较多建议将其归于组件中而不是全部放在 “main” 中。 ⑤、“build” 目录存放构建输出的地方如果没有此目录idf.py 会自动创建。CMake 会配置项目并在此目录下生成临时的构建文件。 每个组件目录都包含一个 CMakeLists.txt 文件里面会定义一些变量以控制该组件的构建过程以及其与整个项目的集成。
每个组件还可以包含一个 Kconfig 文件它用于定义 menuconfig 时展示的 组件配置 选项。某些组件可能还会包含 Kconfig.projbuild 和 project_include.cmake 特殊文件它们用于 覆盖项目的部分设置。
2、CMake基础 CMake是一个开源的、跨平台的安装编译工具用于控制软件编译过程并生成可在所选编译器环境中使用的项目文件。它使用平台无关的配置文件通常是CMakeLists.txt文件并可以输出各种makefile或project文件。 因乐鑫官方的ESP-IDF高度集成CMake工具因此需要使用ESP-IDF去开发ESP32设备必须要掌握CMake基础以实现对ESP32工程项目自由的扩展操作。如项目工程中添加、减少模块代码加入第三方的SDK库等都是通过CMake工具来实现的。 对于CMake的使用在乐鑫官网的ESP32开发指南中有较为详细的教程但乐鑫官方的CMake教程过于繁琐不利于初学者理解且容易迷失方向、抓不住核心知识。因此本文对一些在ESP32开发中常用的CMake知识进行简单的整理。
构建系统 - ESP32-S3 - — ESP-IDF 编程指南 v5.1.2 文档 (espressif.com)https://docs.espressif.com/projects/esp-idf/zh_CN/v5.1.2/esp32s3/api-guides/build-system.html乐鑫ESP32对CMake讲解的部分文档 在CMake管理的项目工程中时常都能看到CMakeLists.txt这个文件的影子这是一个用于描述 CMake 构建过程和项目配置的文件。这个文件包含了一系列 CMake 命令、变量设置和流程控制结构用于告诉 CMake 如何生成适合特定平台和编译器的构建系统文件。 CMakeLists.txt 文件通常包含以下几个部分 1、项目设置这里指定了项目的名称、版本、编程语言版本等信息。 2、编译选项配置编译类型如 Debug 或 Release、编译器选项、警告等级等。 3、源文件指定项目中的源文件可以包括多个目录和文件。 4、头文件目录添加头文件的搜索路径。 5、库文件链接外部库文件包括静态库和动态库。 6、编译目标定义编译目标如可执行文件、静态库或动态库。 7、测试编写和执行测试程序以确保项目的正确性。 8、安装和打包指定如何安装和打包项目。 CMakeLists.txt 文件的结构和命令可以根据项目的具体需求进行调整。通过编辑这个文件可以灵活地配置项目的构建过程以适应不同的平台和编译器。
最小的CMakeLists.txt文件示例
cmake_minimum_required(VERSION 3.16)
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
project(myProject)
在任意的CMakeLists.txt文件中上面三行代码是必须存在的
cmake_minimum_required(VERSION 3.16)必须放在 CMakeLists.txt 文件的第一行它会告诉 CMake 构建该项目所需要的最小版本号。ESP-IDF 支持 CMake 3.16 或更高的版本。
include($ENV{IDF_PATH}/tools/cmake/project.cmake)会导入 CMake 的其余功能来完成配置项目、检索组件等任务。
project(myProject)会创建项目本身并指定项目名称。该名称会作为最终输出的二进制文件的名字即 myProject.elf 和 myProject.bin。每个 CMakeLists 文件只能定义一个项目。
最小组件的 CMakeLists.txt 文件此文件存在于顶层CMakeLists.txt文件下的components或自定义的组件内。
最小组件 CMakeLists.txt 文件通过使用 idf_component_register 将组件添加到构建系统中。
idf_component_register(SRCS “car.c” “engine.c”INCLUDE_DIRS “include” REQUIRES mbedtls)
SRCS: 是源文件列表*.c、*.cpp、*.cc、*.S里面所有的源文件都将会编译进组件库中。
INCLUDE_DIRS: 是目录列表里面的路径会被添加到所有需要该组件的组件包括 main 组件全局 include 搜索路径中。
REQUIRES: 实际上并不是必需的但通常需要它来声明该组件需要使用哪些其它组件也就是当前组件有对其它组件存在依赖时用于声明该依赖防止报错。上述命令会构建生成与组件同名的库并最终被链接到应用程序中。
3、ESP32常见的CMake函数 cmake_minimum_required( ) include( ) project( ) idf_component_register( ) 除了之前在上面讲解的这几个CMake函数外在ESP32中常用的CMake函数命令还有
①、set、unset : 用于设置变量的值、用于清空变量的值。 set(variable value... [PARENT_SCOPE]) variable要被赋值的变量 value要赋给变量的值 set(data Hello, World!) #设置变量data的值为Hello World! unset(variable... [PARENT_SCOPE]) variable要被清空的变量 unset(data) #清空变量data的值 set 、unset的值可以为 一般变量(Normal Variable) 缓存变量(Cache Variable) 环境变量(Environment Variable) ②、message 为用户显示一条消息。 message( [STATUS | WARNING | AUTHOR_WARNING | FATAL_ERROR | SEND_ERROR] message to display ...) 可以用下述可选的关键字指定消息的类型 (无) 重要消息STATUS 非重要消息WARNING CMake 警告, 但会继续执行AUTHOR_WARNING CMake 警告 (dev), 会继续执行SEND_ERROR CMake 错误, 继续执行但是会跳过生成的步骤FATAL_ERROR CMake 错误, 终止所有处理过程 set(AUTHOR, 牛马大师兄) message(STATUS Author ${AUTHOR}.) ③、file 用于执行各种文件操作的。
file的功能十分丰富它支持多种操作包括但不限于读取文件、写入文件、追加到文件、计算文件的散列值等。 写入文件file(WRITE filename message to write...) 追加到文件file(APPEND filename message to append...) 读取文件file(READ filename variable [LIMIT numBytes] [OFFSET offset] [HEX]) ④、include_directories 用于向构建过程中添加包含目录。 include_directories([AFTER | BEFORE] [SYSTEM] [DIR1、DIR2 ...]) AFTER | BEFORE这两个参数是可选的并决定新添加的目录是追加到默认还是插入到现有的包含目录列表的开头。默认情况下include_directories将目录添加到列表的末尾。 SYSTEM这个可选参数用于标记目录为系统目录。 DIR1、DIR2 ...这些是要添加的头文件搜索路径。 include_directories命令将指定的目录添加到当前CMakeLists.txt文件的INCLUDE_DIRECTORIES目录属性中并且也添加到当前CMakeLists.txt文件中每个目标的INCLUDE_DIRECTORIES目标属性中。这意味着这些目录将被用于搜索头文件无论是在编译源代码时还是在链接库文件时。 include_directories(/usr/include/hello) ⑤、add_executable 用于指定一个可执行文件目标的命令。 add_executable(targetName [source1] [source2] ...) targetName 这是想要生成的可执行文件的名称通常是不带文件扩展名的名称。 [source1] [source2] ... 想要编译成可执行文件的源文件列表。可以指定多个源文件它们之间用空格分隔。 add_executable 命令会创建一个构建目标这个目标代表了最终的可执行文件。当运行构建系统例如通过执行 make或 ninja 命令时这个目标会被构建。 add_executable(my_program main.cpp) ⑥、add_library 用于创建一个库目标的命令。
add_library 告诉 CMake 你想要从哪些源文件构建一个库并给这个库指定一个名称。这个库可以是静态库.a 或 .lib 文件、共享库.so、.dylib 或 .dll 文件或模块。 add_library(targetName [STATIC | SHARED | MODULE] [EXCLUDE_FROM_ALL] source1 [source2 ...]) targetName库的逻辑名称不带文件扩展名。 [STATIC | SHARED | MODULE]这个可选参数用于指定库的类型。 STATIC ---创建静态库 SHARED ---创建共享库 MODULE ---创建可以被动态加载的库 默认为 STATIC [EXCLUDE_FROM_ALL]: 可选参数如果指定了那么这个库就不会被默认构建。 source1 [source2 ...]想要编译成库的源文件列表可以指定多个源文件它们之间用空格分隔 add_library(mylib STATIC mylib.cpp) add_library(mylib SHARED mylib.cpp) 对于静态库CMake 会自动添加 .a在 Unix 上或 .lib在 Windows 上扩展名对于共享库CMake 会自动添加适当的平台相关扩展名。
⑦、target_link_libraries用于指定目标比如可执行文件或库应该链接哪些库。 target_link_libraries(target PRIVATE|PUBLIC|INTERFACE lib1 [lib2 ...]) target这是你想要链接库的目标可以是一个可执行文件或库。 PRIVATE|PUBLIC|INTERFACE这些关键字用于指定库链接的范围和传递性。 PRIVATE库仅对目标私有不会传递给其他目标。 PUBLIC库对目标是公共的并且还会传递给依赖该目标的其他目标。 INTERFACE库仅对其他目标可见但对当前目标不可见。 lib1 [lib2 ...这是你想要链接的库列表。 add_executable(my_program main.cpp) add_library(my_library my_library.cpp) target_link_libraries(my_program my_library) 在这个例子中my_program 可执行文件会被链接到 my_library 库。 对于外部SDK库需要提供库的完整路径如果库不在标准库路径中 target_link_libraries(my_program /path/to/external/libfoo.a) 4、ESP32链接第三方SDK库 在项目开发中大多情况为团队内部合作或者跨公司进行合作为了保证代码的安全及项目的正常进展往往会将负责的部分代码编译成一个SDK库文件可以是静态库或动态库文件以库和开发手册的方式交付程序代码。因此ESP32开发中非常有必要掌握链接第三方SDK库到项目工程中。 在顶层的CMakeLists.txt文件中加入以下代码引入链接第三方库。
#全路径引入库
#link_libraries 表示将具体的库文件引入到当前工程中所填入的路径必须是全路径。
方法一直接填入全部的路径可移植性较差移动文件位置或修改文件夹名字后需要重新修改
#link_libraries(/home/tony/Desktop/gm_algorithm/lib/gm/libsm_esp32c3.a)
方法二使用Cmake变量获取当前文件所在路径填充到文件中
link_libraries(${CMAKE_CURRENT_SOURCE_DIR}/lib/gm/libsm_esp32c3.a)
不能使用相对路径
#link_libraries(./lib/gm/libsm_esp32c3.a) #错误示例
使用message打印CMAKE_CURRENT_SOURCE_DIR所指的路径值message(STATUS The CMAKE_CURRENT_SOURCE_DIR is: ${CMAKE_CURRENT_SOURCE_DIR})
链接SDK库测试工程的顶层CMakeLists.txt文件源码
cmake_minimum_required(VERSION 3.16)
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
message(STATUS The CMAKE_CURRENT_SOURCE_DIR is: ${CMAKE_CURRENT_SOURCE_DIR})
#包含第三方SDK库头文件所在的路径
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include/gm)
#链接第三方SDK静态库文件
link_libraries(${CMAKE_CURRENT_SOURCE_DIR}/lib/gm/libsm_esp32c3.a)
project(gm)
提醒link_libraries( ) 函数中填入的库路径必须是绝对路径采用相对路径会报错。
①、手动填入绝对路径 采用这种方法移植性较差一但更改了文件路径或工程文件名编译必定会报错需要手动去修改CMakeLists.txt文件中的链接库文件路径因此不推荐采用此方法但可以学习了解一下。 ②、自动获取补全库的绝对路径 建议使用CMake设置的宏变量去实现路径的填写这样可移植性较好可以减少开发过程的工作量。 ③、第三方的SDK包、链接库成功编译顺利通过 ④、相对路径报错SDK包链接不通过