一、.so的生成
目标是生成hello.so文件,输出到lib/下:
①hello.c
#include "hello.h"
#include <stdio.h>
void hello_func(void)
{
printf("hello i am lk\n");
return 0;
}
②hello.h
#ifndef HELLO_H
#define HELLO_H
void hello_func(void);
#endif
③makefile
OUTPUT_DIR := ./lib
TARGET_ARCH1 := arm
ifneq ($(shell uname -m | grep -c 'x86'), 0)
TARGET_ARCH1 := x86
endif
ifeq ($(TARGET_ARCH1),arm)
CXX = g++
CC = gcc
else
CXX = arm-linux-gnueabihf-g++
CC = arm-linux-gnueabihf-gcc
endif
#-------------------------------------------------------------------
#CFLAGS编译选项
#-fPIC 确保生成的目标文件可以正确地在任意内存地址加载和执行。
#-Wall:启用所有警告。
#-O3:开启优化等级 3。
#-mfloat-abi=hard:设置浮点 ABI 为硬件浮点。
#-mfpu=neon:使用 NEON SIMD 指令集。
#-mtune=cortex-a9:为 ARM Cortex-A9 处理器进行调优。
CFLAGS=-fPIC \
-Wall -O3 -mfloat-abi=hard -mfpu=neon -mtune=cortex-a9
LDFLAGS=-shared #告诉编译器生成共享库
SRC = $(wildcard ./*.c) #获取所有 C 源文件
OBJS = $(SRC:.c=.o) #将 .c 文件列表转换为 .o 文件列表
TARGET=libhello.so
#-------------------------------------------------------------------
all:$(TARGET)
$(OBJS):%.o: %.c
$(CC) $(CFLAGS) -c $< -o $@ #编译
$(TARGET):$(OBJS)
$(CC) $(LDFLAGS) -o $@ $(OBJS) #链接生成动态库
mv $@ $(OUTPUT_DIR)
clean:
rm -f $(OBJS) $(OUTPUT_DIR)/$(TARGET)
④执行指令:make
二、.so的调用
调用的工程目录如下:
①调用的c文件
#include "hello.h"
void main(void)
{
hello_func();
return 0;
}
②makefile
BASE_PATH=./
TARGET_ARCH1 := arm
ifneq ($(shell uname -m | grep -c 'x86'), 0)
TARGET_ARCH1 := x86
endif
ifeq ($(TARGET_ARCH1),arm)
CXX = g++
CC = gcc
else
CXX = arm-linux-gnueabihf-g++
CC = arm-linux-gnueabihf-gcc
endif
SRC = $(wildcard ./*.c) #wildcard把指定目录下的所有后缀是cpp的文件全部展开
OBJS=$(patsubst %.c,%.o,$(SRC)) #所有.o的变量
TARGET = app #生成的目标变量
CFLAGS = -Wall -O3 -mfloat-abi=hard -mfpu=neon -mtune=cortex-a9
LK_INCLUDE = $(BASE_PATH)/include
LIBS = -L$(BASE_PATH)/lib -lhello
INCLUDE += -I$(LK_INCLUDE)
CFLAGS += $(INCLUDE)
LIBVAR += $(LIBS) #指明需要链接静态库.a、动态库.so名称
all:$(TARGET) permission
permission:
@chmod 777 run.sh
$(TARGET):$(OBJS)
@echo Linking $(notdir $@)
@$(CC) -rdynamic -o $@ $^ $(LIBVAR) #rdynamic
%.o:%.cpp
@echo Compiling $<
@$(CC) $(CFLAGS) -c $< -o $@ -fpermissive
.PHONY:clean
clean:
rm -rf ./$(TARGET)
rm -rf ./*.o
③run.sh
#!/bin/bash
BASE_PATH=./
export LD_LIBRARY_PATH=$BASE_PATH/lib
./app
④程序执行
./run.sh
额外技能:
有些动态库的后缀有版本号,但是我们调用的时候有些系统设置了调用的动态库后缀是.so,因此需要进行软连接。
eg:需要创建软链接libjpeg.so链接到libjpeg.so.9.2.0:
ln -s libjpeg.so.9.2.0 libjpeg.so