报错描述:
新创建的platformIO项目中,在ESP32项目编译时经常会出现类似于下面的报错,从而无法完成编译:
in function ‘myFunction(int, int)’: E:\aa/lib/bbbb/bbbb.cpp:4:
undefined reference to ‘afunction()’
collect2.exe: error: ld returned 1 exit status
——对此网上解决方案花里胡哨,这里补上新手(啊对就是我)可能出现该错误的另外的两个原因以及解决方法:
开头报错原因一:main.cpp中include头文件所处的位置
platformIO下,esp-arduino的项目结构可参考:
我们主要关注以上三个文件夹。
分析:如果把lib下的自定义库里的.h文件,放在include目录下了,再在main文件里引用,就会发生开头的报错。
这个报错跟ESPIDF里的某些报错一个尿性:文本编辑器里ctrl+点击依然能进入.h文件,但是编译就是过不去。这时候就会让人感觉到一种莫名其妙的窒息:VSCODE是不是在玩我 。
解决方法:
其实是因为include目录下只能存放src目录下源文件的头文件。你的.h文件如果想要放在这个include目录下,那么相对应的源文件需要放在src目录中。之所以会踩到这个坑,是因为一开始只是草草看了include/README的描述,没有注意到开头的一段话:
A header file is a file containing C declarations and macro definitions to be shared between several project source files. You request the use of a header file in your project source file (C, C++, etc) located in
src
folder by including it, with the C preprocessing directive `#include’.
这里着重提到了“located in src
folder”。结果没看到,以为啥目录下的头文件都能往里扔。
补充:后来经过测试,正常引用.h文件,编译时不报错的场景有:
lib目录下,库与库之间的.h可以正常相互引用(正常是不搞循环引用什么的幺蛾子);lib中源文件的.h还是老实跟源文件呆在一起吧。
src目录下,可以放置.h文件,并且该目录下.h文件也可以正常相互引用;
include目录下的.h文件,只供src文件夹引用,lib中的源文件无法引用;
以上,就是在默认不设置library.json等其它配置文件下,.h文件之间能正常引用的关系,热切期待指正和补充。
另注:有一点不太明白的是:
把.h文件放在src下也是可以的。放在include下有什么意义呢?或许是节省编译时间?当然了,把.h放include下还是能清晰项目结构的。
开头报错原因二:C/C++混合编程时不当引用C风格头文件
如果从上一个错误过来(比如我).h和源文件位置都放对了,在C/C++混合编程时,main.cpp作为一个C++文件,它如果引用了一个.C文件的.h文件,那么,如果不使用以下与语法导入的话,也会发生开头的报错。esp的官方库很多都是C语言写的,它原生扩展ESPIDF是得配置配置才能写C++,默认是C,所以搁它那没问题;搁platformIO用的是ESP-Arduino的模式,所以它一上来就是C++。
extern "C"
{
#include "dddd.h"
}