新闻中心

EEPW首页 > 嵌入式系统 > 设计应用 > esp8266/esp32基于RTOS_SDK(idf框架)制作自己的静态库

esp8266/esp32基于RTOS_SDK(idf框架)制作自己的静态库

作者:嵌入式笔记v 时间:2025-03-27 来源:今日头条 收藏

引言

前段时间因公司内部业务调整,需要将自己的手头上的有关的相关项目移交出去,为了保护核心代码,应领导要求需将一些核心的代码打包成静态库(有关静态库和动态库的概念,我在之前的文章中都有介绍,以及如何在linux和windows中如何制作)。那么今天我们就来介绍下如何基于ESP8266_RTOS_SDK(idf框架,这里以为例,完全同样的原理)制作我们自己的静态库,既能提供他人使用,又能隐藏自己的源代码。相信大家在日常开发中,常常会见到以.a结尾的文件,这并是我们今天的目标——静态库,往往第三方组件就是以.a和.h的方式提供给我们使用。 好了,话不多说,进入我们的主题~

本文引用地址:https://www.eepw.com.cn/article/202503/468702.htm

第一种:自己手工打包制作

首先需要说明的是,文章中我会介绍2种方式制作我们的静态库,第一种是自己手动使用工具链中的ar工具来制作;第二种是利用(或)工程编译完成自动生成静态库的方式。

OK,先来介绍下第一种方式~

1)提供静态库的原材料,即.c和.h,这里我以简单的实现加,减,乘为例,具体如下:

//simplecal.h 内容#ifndef _SIMPLE_CAL_H__#define _SIMPLE_CAL_H__int  myadd(int a, int b);int  mysub(int a, int b);int  mymul(int a, int b);#endif/******************************分割线****************************************///simplecal.c 内容#include "simple_cal.h"int myadd(int a, int b){	return (a+b);
}int mysub(int a, int b){ return (a-b);
}int mymul(int a, int b){ return (a*b);
}

2)接着我们使用工具链中的ar工具来打包,需要说明的是如果esp8266环境则使用的是xtensa-lx106-elf工具链,如果是esp32则使用的是xtensa-esp32-elf工具链,相信大家在搭建开发环境的时候就已熟悉(如果不清楚的小伙伴请参考我的开发环境搭建相关视频)。这里我编写了一个简单的makefile来管理制作过程,具体内容如下:

PRO_SRC := $(wildcard *.c)PRO_OBJ := $(patsubst %.c,%.o,$(PRO_SRC))CC := xtensa-lx106-elf-           #若是esp32,请改为 “xtensa-esp32-elf”${make_lib}.a:$(PRO_OBJ)
@echo ${PRO_SRC}
@echo ${PRO_OBJ} $(CC)ar -rc lib$(make_lib).a $^
strip $(addprefix lib, $@) --strip-debug --strip-unneeded
${PRO_OBJ}:%.o:%.c
$(CC)gcc -c lt; -I .             #-nostdlib -nostdinc .PHONY:cleanclean:
rm -rf lib*.a *.o

我们将以上makefile和原材料.c和.h放在一个目录中,如下:

然后打开msys32(这里我以windows环境为例,linux环境也是同样操作), 并cd到该目录中,然后命令行输入:

make make_lib=simplecal

在上图红框标注的libsimplecal.a就是我们的制作的静态库。

3)接着我们我们把libsimplecal.a 和 simple.h加入到工程中测试。我们创建一个third_components的文件夹,具体目录层级如下图(需要说明的是大家不用和我一样创建各个目录存放相应的文件,这里我是强迫症,按正规实际项目规范来,根据不同的文件存放相应的目录中):


最后在include文件夹中存放了simple.h , 在lib文件夹中存放了libsimlecal.a。

重点:在third_components顶层目录中创建了一个componet.mk文件,内容如下:

COMPONENT_ADD_INCLUDEDIRS := .
COMPONENT_SRCDIRS := .

COMPONENT_ADD_INCLUDEDIRS += . myapp/includeCOMPONENT_SRCDIRS += . myapp

LIBS += simplecal

COMPONENT_ADD_LDFLAGS += -L $(COMPONENT_PATH)/myapp/lib $(addprefix -l,$(LIBS))

说明:

COMPONENT_ADD_INCLUDEDIRS += myapp/include //为工程添加自己的头文件路径

COMPONENT_SRCDIRS += myapp //为工程添加自己的源文件路径(这里我们没有源文件,因此无关紧要,可写可不写)

LIBS += simplecal

COMPONENT_ADD_LDFLAGS += -L $(COMPONENT_PATH)/myapp/lib $(addprefix -l,$(LIBS)) //为工程添加链接属性,即指定我们的静态库名, 和静态库的路径


4)最后我们尝试编译, 命令行输入make

出现以上内容,说明我们编译通过,接着就可以下载到板子上看程序跑起来验证结果是否正确(因板子没带回来,放公司了,故这里就不给大家演示了,结果是正确的,大家可以自己验证下)

测试主函数

重点!!! 使用上述的方法是完全正确的, 但是在实际应用过程,我发现制作的静态库会链接到esp8266内部的irom中,因为irom本身空间较小,当我们的源代码再增多点,就会出现重定位超过范围,报错:“dangerous relocation :.....out of range”

期间我粗略分析了下esp8266工程框架的makefile 以及一些相关链接脚本,

但是未能找到相关的链接的处理方式, 使其链接到外部的flash中, 之后我也咨询了乐鑫的技术支持,也未能得到很好的解释。于是乎我暂时先把这问题搁置一下(因为最近个人事比较多 - -!),回头抽时间再完整分析下乐鑫的整体框架Makefile和链接脚本,看看能否找到解决的方法。

接下来介绍第二种方式,这个亲测有效,而且更适合大众,不需要考虑复杂的Makefile和链接脚本和gcc工具链等等因素,直接上手就能用。OK,开始行动~

第二种:利用现有的工程

首先还是在工程目录中创建一个文件夹如simplecal(名称随意,但是如果不是叫components,则需要在工程主Makefile中添加EXTRA_COMPONENT_DIRS,来指定自己的额外增加的组件),并把源文件simple.c 和simple.h放到simple目录中:


同时创建了一个component.mk文件,其内容:

COMPONENT_ADD_INCLUDEDIRS += . 
COMPONENT_SRCDIRS += .

再次提醒,在工程主Makefile中添加以下内容:

EXTRA_COMPONENT_DIRS := ./simplecal


好了,接着我们直接make编译,编译完成后,会在工程路径中自动生成了build文件夹, 我们进入找到simplecal文件夹:


然后我们进去simplecal中, 可以看到自动为我们生成了libsimplecal.a静态链接库


接着我们还是按照上面的方式测试下是否可用,将工程目录中的simplecal文件中的simple_cal.c源文件删除,然后把静态库libsimplecal.a拷贝进来:

同时我们需要修改下component.mk文件,内容如下:

COMPONENT_ADD_INCLUDEDIRS := .
COMPONENT_SRCDIRS := .

COMPONENT_ADD_LDFLAGS += -L . $(COMPONENT_PATH)/libsimplecal.a

接着我们我们删除build整个文件夹,再次make,全编译:

可以看到是编译成功,接着就是下载到开发板中实际验证咯~

总结

以上2种方式都能制作esp8266/esp32平台的静态库,当我们制作完成并应用工程中,这里有个关键的地方,即为工程添加链接参数COMPONENT_ADD_LDFLAGS,格式的话请参考上面。在第一种方式可能在链接重定位时有点问题,大家可以亲测下。



评论


相关推荐

技术专区

关闭