静态库文件就是一些.o目标文件的集合,以.a结尾。
静态库在程序链接的时候使用,连接器会将程序中使用到的函数的代码从库文件拷贝到可执行文件中,一旦链接完成,
在程序执行的时候就不需要静态库了。
静态库的创建:
首先看一下源文件
fun.c
#include <stdio.h>
int foo(char* ch)
{
printf("foo: %s\n",ch);
return 0;
}
fun.h
#ifndef _FUNC_
#define _FUNC_
#ifdef __cplusplus
extern "C" { //告诉c++编译此处使用gcc编译
#endif
int foo(char* ch);
#ifdef __cplusplus
}
#endif
#endif
main.cpp
#include "fun.h"
#include <stdio.h>
#include <iostream>
using namespace::std;
int main()
{
char* ch = "我是字符串";
foo(ch);
cout << "lalalala" << endl;
return 0;
}
若需要直接使用make编译生成可执行文件,则附上makefile文件:
CC = gcc
CXX = g++
ADD_CFLAGS := -Wall -g
CFLAGS := $(ADD_CFLAGS) $(CFLAGS)
CPPFLAGS := $(ADD_CFLAGS)
LDFLAGS := $(LDFLAGS)
targets = test
.PHONY: all
all: $(targets)
test: main.o fun.o
$(CXX) $^ -o $@ $(LDFLAGS)
main.o: main.cpp
$(CXX) $(CPPFLAGS) -c $< -o $@
fun.o: fun.c fun.h
$(CC) $(CFLAGS) -c $< -o $@
.PHONY: clean
clean:
$(RM) $(targets) *.o
当前目录下执行make即可编译。
接下来看一下如何将fun.c编译成库文件:
现在要将fun.c编译成静态库,libmytest.a
1.将fun.c 和main.c 编译成目标文件,生成fun.o main.o
gcc -o fun.o -c fun.c
g++ -o mian.o -c main.cpp
2.将fun.o编译成静态库文件,libmytest.a
编译命令为: ar rcs lib库文件.a 目标文件1 目标文件2 ...
此处使用 ar rcs libmytest.a fun.o
r:表示将.o的目标文件加入到静态库中
c:表示创建静态库
s:表示生产索引
注意:生成库文件时建议在名字前加上前缀lib,及lib库文件名.a,否则后面链接时会出错。
接下来要使用静态库:
编译方式有两种:
g++ -o 可执行文件 调用者的目标文件(就是这里的fun.o和main.o) -Ldir -l库文件名(不加lib)
g++ -o 可执行文件 头文件路径 调用者的源文件(就是这里的main.c文件) -Ldir -l库文件名(不加lib)
现在开始编译,生成可执行文件test:
g++ -o test main.o -L./ -lmytest
-Ldir 指的是静态库的链接路径,由于我的就是在当前目录下,直接写./就可以了
运行./test
user@sursoft-desktop:~$ ./test
foo: 我是字符串
lalalala
当将静态库libmytest.a删除后再次运行,依然可正常运行。
动态库的创建与使用:
动态库是指在程序链接的时候并不像静态库那样拷贝使用函数中的代码,而只是做一些标记,在程序开始启动(实际上在加载程序时)运行的时候,
加载所需的函数。
动态库的创建:
源文件还是fun.c fun.h main.c
第一步:首先还是先生成fun.o main.o目标文件
第二步:使用gcc编译
gcc -shared -fPIC -o lib库文件.so 目标文件1 目标文件2 ...
编译生成libmytest.so:
gcc -shared -fPIC -o libmytest.so fun.o
若编译出错:/usr/bin/ld: fun.o: relocation R_X86_64_32 against `.rodata' can not be used when making a shared object; recompile with -fPIC
fun.o: could not read symbols: Bad value collect2: ld returned 1 exit status
此原因是系统造成的,需要重新生成一下目标文件,编译命令如下:
gcc -o fun.o -c -fPIC fun.c
然后再执行gcc -shared -fPIC -o libmytest.so fun.o即可;
动态库的使用(和静态库一样):
g++ -o 可执行文件 调用者的目标文件(就是这里的fun.o和main.o) -Ldir -l库文件名(不加lib)
g++ -o 可执行文件 头文件路径 调用者的源文件(就是这里的main.c文件) -Ldir -l库文件名(不加lib)
现在开始编译,生成可执行文件test:
g++ -o test main.o -L./ -lmytest
运行./test
结果出错:libmytest.so: cannot open shared object file: No such file or directory
需要手动配置一下路径:
第一种:cp libmytest.so /usr/lib
第二种:export LD_LIBRARY_PATH=./
然后再次运行,OK
若删除libmytest.so,运行./test将会出错。