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

laximzn5  于 5个月前  发布在  其他
关注(0)|答案(2)|浏览(94)

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

BLINK/
├── components/
│   ├── arduino/
│   ├── lib1/
│   │   ├── include/
│   │   │   └── foo.h
│   │   ├── src/
│   │   │   └── foo.c
│   │   └── CMakeLists.txt
│   └── ...
├── main/
│   └── main.c
├── CMakeLists.txt
├── sdkconfig
└── README.md

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

#include <stdio.h>
#include "sdkconfig.h"
#include "../components/lib1/include/foo.h"

void app_main() {
    printfoo(); 
    while (1) {      
    }
}


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

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

  • foo.c
#include "foo.h"

void printfoo() {
    printf("Hello from Foo\r\n");
}

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


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

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应该可以工作:

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

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

ESP-IDF v5.x

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

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


更多信息/documentatio v5.x

一般

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

#include "foo.h"

tyu7yeag

tyu7yeag2#

  • ESP-IDF v3.3.6*

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

COMPONENT_ADD_INCLUDEDIRS := .

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

BLINK/
├── components/
│   ├── arduino/
│   ├── lib1/
│   │   ├── foo.h
│   │   ├── foo.c
│   │   ├── CMakeLists.txt
│   │   └── component.mk
│   └── ...
├── main/
│   └── main.c
├── CMakeLists.txt
├── sdkconfig
└── README.md


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

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

  • foo.c
#include "foo.h"

void printfoo() {
    printf("Hello from Foo\r\n");
}

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

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


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

#include <stdio.h>
#include "sdkconfig.h"
#include "foo.h"

void app_main() {
    printfoo(); 
    while (1) {      
    }
}

相关问题