ESP32 (静态库的生成)-IDF生成.a文件(11)

提示:本博客作为学习笔记,有错误的地方希望指正

一、ESP32生成静态库介绍

  参考资料:ESP IDF编程手册V4.4

1.1、为什么要生成静态库?

  在开始学习之前我们需要明白为什么要生成.a固件,生成库文件可以分享与他人的协同开发,协同的人只需要调用你编写好的库函数即可,不需要了解整个函数的实现的具体流程,此外可以防止他人在使用你的库的时候无意间修改到库的源文件,造成意想不到的BUG,因此我们可以将我们的.c文件生成.a。.a文件是静态库,静态库在链接时,静态库会被完整地复制到可执行文件中, 被多次使用就有多份冗余拷贝。

1.2、ESP-IDF生成静态库的方法

1.2.1、使用指令生成.a固件

  第一种方法是根据指令生成静态库

xtensa-esp32-elf-gcc -o hello.o -c hello.c  # 将源文件生成目标文件
xtensa-esp32-elf-ar rcs libhello.a hello.o  # 将目标文件生成静态库

  其中xtens代表esp32的内核,esp32代表型号,如果是esp32s3系列的化需要换成esp32s3 ,esp32c3系列是RISCV 内核的,hello.c,表示编译的工程文件;因此这些配置需要根据自己当前使用芯片的型号来配置,首先将.c文件编译成.o目标文件,接着将.o文件编译成我们所需要的.a文件。
  好了,指令我是知道是啥指令了,但是我怎么运行指令呢?运行指令这个Vscode给我们集成了终端,就相当与windows的那个小黑窗一样的功能。或者IDF插件本身就已经集成终端指令。
在这里插入图片描述

  我们只需要使用linux指令到达我们当前组件下的位置,然后输入上述的指令回车执行即可生成对应的.a文档。首先可以使用ls命令列出该工程下所有文件,然后使用cd命令到指定的TestOne文件夹下,接着执行我们的指令即可生成对应的.a文件和.o文件。
在这里插入图片描述
  上述测试文件中的TestOne.c的文件中的内容为:

#include "TestOne.h"
void TestOneFunction(void)
{
    printf("\n\rTestOneFunction\n\r");
}

  在上述中我们生成了对应的.a文件了,然后我们怎样使用我们静态库的文件呢?这里我们的工程文件的架构图是这样的。其中CMakeLists.txt里面的配置已经和.c文件之前的配置不一样了,component.mk是新建的文件。

components
└── TestOne
    ├── CMakeLists.txt
    ├── component.mk
    ├── include
    │   └── TestOne.h
    └── lib
        └── libTestOne.a

  其中CMakeLists.txt内对应的内容为

set(COMPONENT_SRCS "")
set(COMPONENT_ADD_INCLUDEDIRS . include)
register_component()
target_link_libraries(${COMPONENT_TARGET} INTERFACE "-L ${CMAKE_CURRENT_SOURCE_DIR}/lib")
target_link_libraries(${COMPONENT_TARGET} INTERFACE TestOne)

  component.mk内对应的内容为

COMPONENT_ADD_INCLUDEDIRS := include
LIBS := TestOne
COMPONENT_ADD_LDFLAGS := $(COMPONENT_PATH)/lib/libTestOne.a
COMPONENT_ADD_LINKER_DEPS := $(patsubst %,$(COMPONENT_PATH)/lib/lib%.a,$(LIBS))

  使用这种方法需要注意的是只能包含C的库函数的头文件和.c文件和.h文件只能在同一目录下,一旦包含ESP32的头文件或者.c、.h文件不在同一父目录下的时候就会出现找不到头文件的说法。我目前还没有找到其他方法解决这个问题,或许是我的设置不对或许本身编译就不能不支持以两种情况。
在这里插入图片描述

1.2.2、在编译build下找到对应的.a文件

  在我们使用idf编译以后,IDF会在工程文件下新建一个build的文件夹,在build/esp-idf文件中会有许多的文件夹,在这些文件夹中就是我们整个工程使用到组件编译生成对应的.a文件,其中生成规律就和我们components组件下的各个组件名称一致,例如我们在components组件下有个名为TestTwo的文件夹文件夹中有TestTwo.c和TestTwo.h,最后在build/esp-idf中也会包含一个TestTwo文件夹,问价中有一个libTestTwo.a的文件。我们就可以将该文件复制到我们的工程文件中。
  我们的TestTwo工程文件中也是和TestOne中一样的架构。在原来.c文件中函数内容有一下所示,里面包含有ESP32的一些系统文件的log文件我们使用上述的第一种方法就行不通,因此我们可以使用.c文件编译下在build/esp-idf文件中复制生成的.a文件到我们的工程文件中即可。

#include "TestTwo.h"
const static char * TAG = "TestTwo";
void TestTwoFunction(void)
{
    ESP_LOGI(TAG,"TestTwoFunction");
    vTaskDelay(100/portTICK_PERIOD_MS);
}

  工程构架图
在这里插入图片描述
  值得注意的是在我们每次使用.c文件生成对应的.a文件以后我们都要麻烦的跑到build文件下找复制,这样挺麻烦的,有没有一种方法不需要我们手动去找,要是整个工程比较大的话,每次去找就比较头疼了,答案是有的,那就是我们写一个简单的脚本文件,然后我们只要在Vscode的终端运行脚本即可实现帮助我们将文件复制过来。在windows中可以使用.bat的脚本。mac linux可以使用.sh的脚本。我这里简单的写了一个复制脚本copy_aFile_shell.bat,window双击即可运行。此外我们可以配合强大的脚本实现.c文件和.a工程文件的切换。

copy F:\ESP32Learn\code\IDF\TestProject\build\esp-idf\TestTwo\libTestTwo.a    F:\ESP32Learn\code\IDF\TestProject\components\TestTwo\lib\libTestTwo.a

二、硬件

  这里我是随便使用的一块esp32s3的开发板测试的,这个静态库的生成和我们的硬件关系不大。

三、打印输出

在这里插入图片描述

四、工程文件下载

  参考工程文件下载

  • 3
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值