概述

使用ESP-IDF开发时,项目特指一个目录,其中包含了构建可执行应用程序所需的全部文件和配置,以及其他支持型文件,例如分区表、数据/文件系统分区和引导程序。
ESP-IDF 并不是项目的一部分,它独立于项目,通过 IDF_PATH 环境变量(保存 esp-idf 目录的路径)链接到项目,从而将 IDF 框架与项目分离。

项目结构

- myProject/- CMakeLists.txt- sdkconfig- components/- component1/- CMakeLists.txt- Kconfig- src1.c- component2/- CMakeLists.txt- Kconfig- src1.c- include/- component2.h- main/- src1.c- src2.c- build/
  • 顶层项目 CMakeLists.txt 文件,这是 CMake 用于学习如何构建项目的主要文件,可以在这个文件中设置项目全局的 CMake 变量。顶层项目 CMakeLists.txt 文件会导入 esp-idf/tools/cmake/project.cmake 文件,由它负责实现构建系统的其余部分。该文件最后会设置项目的名称,并定义该项目

  • sdkconfig 项目配置文件,执行 idf.py menuconfig 时会创建或更新此文件,文件中保存了项目中所有组件(包括 ESP-IDF 本身)的配置信息。 sdkconfig 文件可能会也可能不会被添加到项目的源码管理系统中。

  • 可选的 component 目录中包含了项目的部分自定义组件,并不是每个项目都需要这种自定义组件,但它组件有助于构建可复用的代码或者导入第三方(不属于 ESP-IDF)的组件。

  • main 目录是一个特殊的 伪组件,包含项目本身的源代码。main 是默认名称,CMake 变量 COMPONENT_DIRS 默认包含此组件,但您可以修改此变量。或者,您也可以在顶层 CMakeLists.txt 中设置 EXTRA_COMPONENT_DIRS 变量以查找其他指定位置处的组件。

  • build 目录是存放构建输出的地方,如果没有此目录,idf.py 会自动创建。CMake 会配置项目,并在此目录下生成临时的构建文件。随后,在主构建进程的运行期间,该目录还会保存临时目标文件、库文件以及最终输出的二进制文件。此目录通常不会添加到项目的源码管理系统中,也不会随项目源码一同发布。

参考

hello-world的项目结构分析

- hello_world/- main/- CMakeLists.txt- component.mk- hello_world_main.c- .gdbinit.ci- CMakeLists.txt- loadable_elf_example_test.py- Makefile- README.md- sdkconfig- sdkconfig.ci

main 目录

CMakeLists.txt 文件

CMakeLists.txt内容

idf_component_register(SRCS "hello_world_main.c"INCLUDE_DIRS "")

idf_component_register函数中SRC中包含所有的源文件,INCLUDE_DIRS中包含所有的头文件目录如果main中的文件结构这样

- main/- include/- hello_world.h- light_control.h- CMakeLists.txt- component.mk- hello_world_main.c- light_control.c

CMakeLists.txt中的内容应该修改成

idf_component_register(SRCS "hello_world_main.c""light_control.c"INCLUDE_DIRS "include")

component.mk 文件

GUN Make中使用的文件,通过CMake构建时可以在CMakeLists.txt设置 COMPONENT_ADD_INCLUDEDIRS 和 COMPONENT_SRCDIRS 等变量将组件添加到编译过程中。

hello_world_main.c 文件

开发的源文件

.gdbinit.ci 文件

gdb初始化配置文件

CMakeLists.txt

CMakeLists.txt 内容

# The following lines of boilerplate have to be in your project's
# CMakeLists in this exact order for cmake to work correctly
cmake_minimum_required(VERSION 3.5)include($ENV{IDF_PATH}/tools/cmake/project.cmake)
project(hello-world)
  • cmake_minimum_required(VERSION 3.5) 必须放在 CMakeLists.txt 文件的第一行,它会告诉 CMake 构建该项目所需要的最小版本号。ESP-IDF 支持 CMake 3.5 或更高的版本。

  • include($ENV{IDF_PATH}/tools/cmake/project.cmake) 会导入 CMake 的其余功能来完成配置项目、检索组件等任务。

  • project(hello-world) 会创建项目本身,并指定项目名称。该名称会作为最终输出的二进制文件的名字,即 hello-world.elf 和 hello-world.bin。每个 CMakeLists 文件只能定义一个项目。

Makefile

项目顶层 Makefile,该 Makefile 设置了 PROJECT_NAME 变量,还可以定义作用于整个项目的其它 make 变量(可选)。顶层 Makefile 会导入核心 Makefile 文件 $(IDF_PATH)/make/project.mk ,由它负责实现 ESP-IDF 构建系统的剩余部分。在CMake编译过中是不需要的。

README.md 文件

项目说明文件,markdown文本。

sdkconfig

它的功能和使用Make的KConfig文件类似,使用CMake编译时,从 sdkconfig 文件中加载项目配置信息,生成 sdkconfig.cmake 和 sdkconfig.h 文件,分别用在 CMake 和 C/C++ 中定义配置项。如果项目配置发生了更改,CMake 会自动重新运行,重新生成上述两个文件,接着重新配置项目。通过idf.py menuconfig可以修改配置项。

idf_component_register函数

idf_component_register函数在/tools/cmake/component.cmake中被定义。

# idf_component_register
#
# @brief Register a component to the build, creating component library targets etc.
#
# @param[in, optional] SRCS (multivalue) list of source files for the component
# @param[in, optional] SRC_DIRS (multivalue) list of source directories to look for source files
#                       in (.c, .cpp. .S); ignored when SRCS is specified.
# @param[in, optional] EXCLUDE_SRCS (multivalue) used to exclude source files for the specified
#                       SRC_DIRS
# @param[in, optional] INCLUDE_DIRS (multivalue) public include directories for the created component library
# @param[in, optional] PRIV_INCLUDE_DIRS (multivalue) private include directories for the created component library
# @param[in, optional] LDFRAGMENTS (multivalue) linker script fragments for the component
# @param[in, optional] REQUIRES (multivalue) publicly required components in terms of usage requirements
# @param[in, optional] PRIV_REQUIRES (multivalue) privately required components in terms of usage requirements
#                      or components only needed for functions/values defined in its project_include.cmake
# @param[in, optional] REQUIRED_IDF_TARGETS (multivalue) the list of IDF build targets that the component only supports
# @param[in, optional] EMBED_FILES (multivalue) list of binary files to embed with the component
# @param[in, optional] EMBED_TXTFILES (multivalue) list of text files to embed with the component
# @param[in, optional] KCONFIG (single value) override the default Kconfig
# @param[in, optional] KCONFIG_PROJBUILD (single value) override the default Kconfig
function(idf_component_register)set(options)set(single_value KCONFIG KCONFIG_PROJBUILD)set(multi_value SRCS SRC_DIRS EXCLUDE_SRCSINCLUDE_DIRS PRIV_INCLUDE_DIRS LDFRAGMENTS REQUIRESPRIV_REQUIRES REQUIRED_IDF_TARGETS EMBED_FILES EMBED_TXTFILES)cmake_parse_arguments(_ "${options}" "${single_value}" "${multi_value}" ${ARGN})if(NOT __idf_component_context)message(FATAL_ERROR "Called idf_component_register from a non-component directory.")endif()__component_check_target()__component_add_sources(sources)# Add component manifest to the list of dependenciesset_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS "${COMPONENT_DIR}/idf_component.yml")# Create the final target for the component. This target is the target that is# visible outside the build system.__component_get_target(component_target ${COMPONENT_ALIAS})__component_get_property(component_lib ${component_target} COMPONENT_LIB)# Use generator expression so that users can append/override flags even after call to# idf_build_processidf_build_get_property(include_directories INCLUDE_DIRECTORIES GENERATOR_EXPRESSION)idf_build_get_property(compile_options COMPILE_OPTIONS GENERATOR_EXPRESSION)idf_build_get_property(c_compile_options C_COMPILE_OPTIONS GENERATOR_EXPRESSION)idf_build_get_property(cxx_compile_options CXX_COMPILE_OPTIONS GENERATOR_EXPRESSION)idf_build_get_property(common_reqs ___COMPONENT_REQUIRES_COMMON)include_directories("${include_directories}")add_compile_options("${compile_options}")add_c_compile_options("${c_compile_options}")add_cxx_compile_options("${cxx_compile_options}")# Unfortunately add_definitions() does not support generator expressions. A new command# add_compile_definition() does but is only available on CMake 3.12 or newer. This uses# add_compile_options(), which can add any option as the workaround.## TODO: Use add_compile_definitions() once minimum supported version is 3.12 or newer.idf_build_get_property(compile_definitions COMPILE_DEFINITIONS GENERATOR_EXPRESSION)add_compile_options("${compile_definitions}")if(common_reqs) # check whether common_reqs exists, this may be the case in minimalistic host unit test buildslist(REMOVE_ITEM common_reqs ${component_lib})endif()link_libraries(${common_reqs})idf_build_get_property(config_dir CONFIG_DIR)# The contents of 'sources' is from the __component_add_sources callif(sources OR __EMBED_FILES OR __EMBED_TXTFILES)add_library(${component_lib} STATIC ${sources})__component_set_property(${component_target} COMPONENT_TYPE LIBRARY)__component_add_include_dirs(${component_lib} "${__INCLUDE_DIRS}" PUBLIC)__component_add_include_dirs(${component_lib} "${__PRIV_INCLUDE_DIRS}" PRIVATE)__component_add_include_dirs(${component_lib} "${config_dir}" PUBLIC)set_target_properties(${component_lib} PROPERTIES OUTPUT_NAME ${COMPONENT_NAME} LINKER_LANGUAGE C)__ldgen_add_component(${component_lib})else()add_library(${component_lib} INTERFACE)__component_set_property(${component_target} COMPONENT_TYPE CONFIG_ONLY)__component_add_include_dirs(${component_lib} "${__INCLUDE_DIRS}" INTERFACE)__component_add_include_dirs(${component_lib} "${config_dir}" INTERFACE)endif()# Alias the static/interface library created for linking to external targets.# The alias is the <prefix>::<component name> name.__component_get_property(component_alias ${component_target} COMPONENT_ALIAS)add_library(${component_alias} ALIAS ${component_lib})# Perform other component processing, such as embedding binaries and processing linker# script fragmentsforeach(file ${__EMBED_FILES})target_add_binary_data(${component_lib} "${file}" "BINARY")endforeach()foreach(file ${__EMBED_TXTFILES})target_add_binary_data(${component_lib} "${file}" "TEXT")endforeach()if(__LDFRAGMENTS)__ldgen_add_fragment_files("${__LDFRAGMENTS}")endif()# Set dependencies__component_set_all_dependencies()# Make the COMPONENT_LIB variable available in the component CMakeLists.txtset(COMPONENT_LIB ${component_lib} PARENT_SCOPE)# COMPONENT_TARGET is deprecated but is made available with same function# as COMPONENT_LIB for compatibility.set(COMPONENT_TARGET ${component_lib} PARENT_SCOPE)__component_set_properties()
endfunction()

ESP32 ESP-IDF 项目文件结构相关推荐

  1. Espressif IDF学习之路(1)项目文件结构的理解

    概述 对于搭建的过程通过乐鑫官方的插件我们基本做到"傻瓜式"搭建开发环境,我们在这个过程中知道安装了一堆乱七八槽的东西但是我们要自己写的时候会懵逼,所以我们需要知道整个工程的结构 ...

  2. Android_项目文件结构目录分析

    android项目文件结构目录分析 在此我们新建了一个helloworld的项目,先看一些目录结构: 这么多的文件夹和文件中,我们重点关注是res目录.src目录.AndroidManifest.xm ...

  3. spring boot 常用项目文件结构

    spring boot 常用项目文件结构 文件结构 文件结构 src/main/java 开发代码以及主程序入口 Application.java作为程序主入口,建议放在根目录下,主要用于一些框架配置 ...

  4. html项目的文件结构,项目文件结构

    是否有一种推荐的方式来组织 React 的项目文件结构呢? React 对如何将文件放入文件夹中没有意见.也就是说,你可以参考使用生态系统中一些常见的组织项目文件结构的方式. 按功能或路由组织 组织项 ...

  5. 巡风代码架构简介以及Flask的项目文件结构简介

    一.巡风: 巡风是一款什么东西,想必安全同行都不陌生吧.用它作为内网漏洞扫描管理架构是一种很好的选择,扫描快,开源,还可自己编写符合规则的POC直接放入相应目录来扩展.今天下午趁着有点时间捋了一下巡风 ...

  6. VUE项目学习(二):学习项目文件结构

    VUE项目学习(二):学习项目文件结构 VUE项目结构: index.html:主页,项目入口 App.vue:根组件 main.js:入口文件 router文件夹下的index.js:路由配置文件 ...

  7. 前端vue基础学习之vue项目文件结构

    vue项目文件结构 查看上一篇前端基础学习之vue的生命周期 build文件用于打包创建dist目录 webpack.base.conf.js alias配置别名 config index.js ho ...

  8. ESP32(IDF)EC11旋转编码器使用总结

    ESP32(IDF)EC11旋转编码器使用总结 一.调试过程中遇到的问题 二.硬件 三.电路 接线说明: 四.工作原理 正转波形 反转波形 五.判断正反转 法一 代码实现 结果 法二 法三 代码实现 ...

  9. Android项目文件结构

    大致可以认为,Android APP由两部分组成,布局.属性部分和逻辑代码部分.属性和布局负责Android APP的UI,即用户看到的部分,由XML语言编写,逻辑代码部分则由Java语言编写,负责A ...

最新文章

  1. 机器学习工业复现的 12 个要素!
  2. WPF布局控件Grid的基本使用 - 使用kaxaml
  3. logback基本入门
  4. 遍历字符串的每个字符python_Python之字符串的遍历的4种方式
  5. 从数组中间位置添加元素:unshift()方法的有一种运用
  6. linux终端按下退格键自动覆盖上一行的问题
  7. SAP ui5 control lifecycle - registration and deregistration
  8. java获取byte 长度_java获取字节的长度.
  9. 关于DP的一些解题总结
  10. .两个windowsform之间的值传递
  11. 除了人工智能,霍金还担心“游牧外星人”会摧毁人类
  12. 【Android】AsyncTask机制
  13. 名校计算机课程百度云,浙江大学计算机类专业视频课程百度云网盘
  14. 怎样搜索计算机中docx格式的文件,如何打开docx文件 打开docx文件方法
  15. 深度学习环境搭建 1 利用Anaconda安装pytorch、paddl和TensorFlow, PyQt5配置和使用
  16. nginx实现https与http共存方案
  17. AFX_EXT_CLASS的使用
  18. 信息系统分析与设计 机票预定管理系统
  19. 国产服务器(aarch64) Kettle 修改
  20. unity 画球面_unity3d第一个例子--制作一个简单的球体碰撞墙面

热门文章

  1. 解决:Gitlab上出现“You won't be able to pull or push project code via SSH until you add an SSH key to you”
  2. soft lockup问题的定位方法
  3. 雷诺手表怎么看型号?rarone型号查询的方法
  4. 手机连接不上IIS网站(站点)
  5. 如何高效学习?科学高效的方法,助你轻松提高学习效率!
  6. 类变量、成员变量、局部变量介绍说明
  7. android 仿商城瀑布流,android_waterfall
  8. Python实现照片、视频一键压缩及备份源代码
  9. 【转】JPEG压缩原理
  10. Android GMS Checklist【Android gms认证自检表】