cmake ESP-IDF项目结构问题:“未定义对函数的引用”错误

laximzn5  于 2024-01-09  发布在  其他
关注(0)|答案(2)|浏览(326)

我已经开始了一个基于ESP-IDF示例“blink”的项目,并试图将其重组为更结构化的格式。我的目标是拥有这样的项目结构:

  1. BLINK/
  2. ├── components/
  3. ├── arduino/
  4. ├── lib1/
  5. ├── include/
  6. └── foo.h
  7. ├── src/
  8. └── foo.c
  9. └── CMakeLists.txt
  10. └── ...
  11. ├── main/
  12. └── main.c
  13. ├── CMakeLists.txt
  14. ├── sdkconfig
  15. └── README.md

字符串
我在main文件夹中修改了main.c,如下所示:

  1. #include <stdio.h>
  2. #include "sdkconfig.h"
  3. #include "../components/lib1/include/foo.h"
  4. void app_main() {
  5. printfoo();
  6. while (1) {
  7. }
  8. }


以下是我的lib1组件中的文件内容:

  • foo.h
  1. #include <stdio.h>
  2. void printfoo();

  • foo.c
  1. #include "foo.h"
  2. void printfoo() {
  3. printf("Hello from Foo\r\n");
  4. }

  • BLINK/components/lib1/中的CMakeLists.txt
  1. set(COMPONENT_SRCS "foo.c")
  2. set(COMPONENT_ADD_INCLUDEDIRS "." "include")
  3. register_component()


当我编译项目时,我得到以下错误:

  1. main.c:6: undefined reference to `printfoo'


我知道这个错误输出意味着链接器找不到位于foo. c中的函数 printfoo 的定义
有什么建议可能导致此错误以及如何解决它?

  • 更新 *:我使用的是ESP-IDF v3.3.6。

我已经遵循了ESP 32关于组件CMakeLists文件的指南,但仍然遇到这个问题。

bfnvny8b

bfnvny8b1#

一般

我认为问题是你把源代码设置为foo.c,但是那个文件在src/foo.c。因此,源文件没有被添加,结果,函数没有被实现。

ESP-IDF v3.3.6

在ESP-IDF v3.3.6中,以下CMakeLists.txt应该可以工作:

  1. set(COMPONENT_SRCS "src/foo.c")
  2. set(COMPONENT_ADD_INCLUDEDIRS "include")
  3. register_component()

字符串
更多信息/documentatio v3.3.6

ESP-IDF v5.x

在v5.x版本中,通常使用SRCSINCLUDE_DIRS分别代替COMPONENT_SRCSCOMPONENT_ADD_INCLUDEDIRS。在ESP-IDF v5.x中,以下CMakeLists.txt应该可以工作:

  1. idf_component_register(SRCS "src/foo.c"
  2. INCLUDE_DIRS "include")


更多信息/documentatio v5.x

一般

然后,在main中,您应该能够以以下方式包含foo.h

  1. #include "foo.h"

展开查看全部
tyu7yeag

tyu7yeag2#

  • ESP-IDF v3.3.6*

我解决了这个问题,通过添加一个名为component.mk的文件到项目中,内容如下:

  1. COMPONENT_ADD_INCLUDEDIRS := .

字符串
除此之外,我还修改了项目结构,如下所示:

  1. BLINK/
  2. ├── components/
  3. ├── arduino/
  4. ├── lib1/
  5. ├── foo.h
  6. ├── foo.c
  7. ├── CMakeLists.txt
  8. └── component.mk
  9. └── ...
  10. ├── main/
  11. └── main.c
  12. ├── CMakeLists.txt
  13. ├── sdkconfig
  14. └── README.md


在项目的lib1组件中,文件的最终内容应如下所示:

  • foo.h
  1. #include <stdio.h>
  2. void printfoo();

  • foo.c
  1. #include "foo.h"
  2. void printfoo() {
  3. printf("Hello from Foo\r\n");
  4. }

  • BLINK/components/lib1/中的CMakeLists.txt
  1. set(COMPONENT_SRCS "foo.c")
  2. set(COMPONENT_ADD_INCLUDEDIRS "." )
  3. register_component()

  • BLINK/components/lib1/中的component.mk
  1. COMPONENT_ADD_INCLUDEDIRS := .


最后,BLINK/main/main.c中的主应用程序代码(app_main)应该包括必要的头文件,并按如下方式调用printfoo()

  1. #include <stdio.h>
  2. #include "sdkconfig.h"
  3. #include "foo.h"
  4. void app_main() {
  5. printfoo();
  6. while (1) {
  7. }
  8. }

展开查看全部

相关问题