跳转至

静态库编译和使用指南

静态库编译和使用指南*

第一章 概述*

为了方便用户,在SDK默认的工程结构里,把自己的C代码编译打包成静态库。

适合场景:

  • 自己的核心代码不想开放给应用层,需要封装成静态库
  • 关键算法不想开放源代码,需要封装成静态库

我们提供了示例。参考:apus\apps\lib_sample。

编译:

make app=lib_sample

编译成功后,编译脚本会自动删除 apus\apps\lib_sample\lib 里面的 libtest.a 文件,然后把最新编译出的 libtest.a 文件拷贝到该目录下。同时把库的头文件 libtest.h 也拷贝到该目录下。

同时也会成功编译出 app 应用 apus.bin。这个应用通过链接静态库 libtest.a 的方式编译。

烧录 apus.bin,开机可以看到如下打印:

Hello Apus: v1.2.0-rc5-1711959899, Bank: 0x2000
Chip Label: GX8302B-66c2660ec983b2ce
Build Target: lib_sample-rtthread-gx8302b_dev
Hello World // app的打印
call libtest_function // 库函数内部的打印
msh >

第二章 静态库生成*

参考:apus\apps\lib_sample\app.mk

APP_DIR := $(dir $(lastword $(MAKEFILE_LIST)))

BUILD_BLE_ENABLE := 0
BUILD_BLE_FWLIB_MODEL := 0
BUILD_AUDIO_IN_ENABLE := 0
BUILD_AUDIO_OUT_ENABLE := 0
BUILD_AUDIO_CODEC_ADPCM_ENABLE := 0
BUILD_AUDIO_DUMP_ENABLE := 0
BUILD_AUDIO_LVP_ENABLE := 0
BUILD_KVS_ENABLE := 0

.PHONY: build_applib

APP_LIB_TARGET_DIR := $(APP_DIR)lib/
APP_LIB_TARGET_NAME := libtest.a

APPLIB := libtest.a
LIBS_INCS += -I$(APP_LIB_TARGET_DIR)
LDPATHS += -L$(APP_LIB_TARGET_DIR)
LDLIBS += -Wl,--whole-archive -l:$(APPLIB) -Wl,--no-whole-archive

# .c files
#APP_SRCS := $(shell find $(APP_DIR) -type f -name '*.c' -not -path '*/\.*')
APP_SRCS := $(APP_DIR)main.c
APP_OBJS := $(addprefix $(OBJ_DIR),$(APP_SRCS:.c=.o))

LIB_SRCS := $(APP_DIR)libtest.c
LIB_OBJS := $(addprefix $(OBJ_DIR),$(LIB_SRCS:.c=.o))

APP_EXTRA_FLAGS :=

$(APP_OBJS):EXTRA_FLAGS := $(APP_EXTRA_FLAGS)

build_applib: $(LIB_OBJS)
    @rm -f $(APP_LIB_TARGET_DIR)$(APP_LIB_TARGET_NAME)
    @$(AR) $(ARFLAGS) $(APP_LIB_TARGET_DIR)$(APP_LIB_TARGET_NAME) $(LIB_OBJS)
    @cp $(APP_DIR)libtest.h $(APP_LIB_TARGET_DIR)
    @echo [$(ARFLAGS) $(APP_LIB_TARGET_DIR)$(APP_LIB_TARGET_NAME) installed]

build_libs: build_applib

关注 LIB_SRCS 和 LIB_OBJS,这个是我们需要编译为库的C文件。

关注 build_applib,里面会先删除老的库文件,然后编译新的库文件。最后再把库文件和头文件拷贝到指定的目录下。

libtest.h

#ifndef __LIBTEST_H__
#define __LIBTEST_H__

void libtest_function(void);

#endif

libtest.c

#include <stdio.h>
#include "libtest.h"

void libtest_function(void)
{
    printf("call libtest_function\n");
}

第三章 应用使用静态库*

参考:apus\apps\lib_sample\app.mk

APP_DIR := $(dir $(lastword $(MAKEFILE_LIST)))

BUILD_BLE_ENABLE := 0
BUILD_BLE_FWLIB_MODEL := 0
BUILD_AUDIO_IN_ENABLE := 0
BUILD_AUDIO_OUT_ENABLE := 0
BUILD_AUDIO_CODEC_ADPCM_ENABLE := 0
BUILD_AUDIO_DUMP_ENABLE := 0
BUILD_AUDIO_LVP_ENABLE := 0
BUILD_KVS_ENABLE := 0

.PHONY: build_applib

APP_LIB_TARGET_DIR := $(APP_DIR)lib/
APP_LIB_TARGET_NAME := libtest.a

APPLIB := libtest.a
LIBS_INCS += -I$(APP_LIB_TARGET_DIR)
LDPATHS += -L$(APP_LIB_TARGET_DIR)
LDLIBS += -Wl,--whole-archive -l:$(APPLIB) -Wl,--no-whole-archive

# .c files
#APP_SRCS := $(shell find $(APP_DIR) -type f -name '*.c' -not -path '*/\.*')
APP_SRCS := $(APP_DIR)main.c
APP_OBJS := $(addprefix $(OBJ_DIR),$(APP_SRCS:.c=.o))

LIB_SRCS := $(APP_DIR)libtest.c
LIB_OBJS := $(addprefix $(OBJ_DIR),$(LIB_SRCS:.c=.o))

APP_EXTRA_FLAGS :=

$(APP_OBJS):EXTRA_FLAGS := $(APP_EXTRA_FLAGS)

build_applib: $(LIB_OBJS)
    @rm -f $(APP_LIB_TARGET_DIR)$(APP_LIB_TARGET_NAME)
    @$(AR) $(ARFLAGS) $(APP_LIB_TARGET_DIR)$(APP_LIB_TARGET_NAME) $(LIB_OBJS)
    @cp $(APP_DIR)libtest.h $(APP_LIB_TARGET_DIR)
    @echo [$(ARFLAGS) $(APP_LIB_TARGET_DIR)$(APP_LIB_TARGET_NAME) installed]

build_libs: build_applib

关注 APP_SRCS 和 APP_OBJS,这个是我们app编译需要的C文件。

LIBS_INCS:指定链接静态库的头文件目录

LDPATHS :指定链接静态库的文件目录

APPLIB:需要链接的静态库的名字

LDLIBS:链接静态库的命令

main.c

#include <stdio.h>
#include "lib/libtest.h"

int main(void)
{
    printf("Hello World\n");
    libtest_function();
    return 0;
}