一句话总结:静态库在链接阶段集成于程序中,程序生成可删除;动态库在程序运行时在/usr/lib/目录下查找调用,删除后错误,编译链接均需加上-fPIC。
实验代码
fun.h
#ifndef _FUN_H_
#define _FUN_H_
#define ver 2.0
void print();
#endif
fun.cpp
#include <iostream>
#include "fun.h"
using namespace std;
void print()
{
cout << "print fun" << endl;
}
main.cpp
#include <iostream>
#include "fun.h"
using namespace std;
int main()
{
print();
return 0;
}
1、静态库
zjy@ubuntu:~/libaray$ ls
fun.cpp fun.h main.cpp
zjy@ubuntu:~/libaray$ g++ -c fun.cpp
zjy@ubuntu:~/libaray$ ls
fun.cpp fun.h fun.o main.cpp
zjy@ubuntu:~/libaray$ ar -cr libfun.a fun.o
zjy@ubuntu:~/libaray$ ls
fun.cpp fun.h fun.o libfun.a main.cpp
zjy@ubuntu:~/libaray$ g++ main.cpp -lfun
/usr/bin/ld: cannot find -lfun
collect2: error: ld returned 1 exit status
zjy@ubuntu:~/libaray$ g++ main.cpp -L. -lfun
zjy@ubuntu:~/libaray$ ls
a.out fun.cpp fun.h fun.o libfun.a main.cpp
zjy@ubuntu:~/libaray$ ./a.out
print fun
zjy@ubuntu:~/libaray$ g++ -o main main.cpp -L. -lfun
zjy@ubuntu:~/libaray$ ls
a.out fun.cpp fun.h fun.o libfun.a main main.cpp
zjy@ubuntu:~/libaray$ ./main
print fun
zjy@ubuntu:~/libaray$
ar是用来创建静态库的命令
ar - create, modify, and extract from archives
2、动态库
zjy@ubuntu:~/libaray$ ls
fun.cpp fun.h main.cpp
zjy@ubuntu:~/libaray$ g++ -c -fPIC fun.cpp
zjy@ubuntu:~/libaray$ ls
fun.cpp fun.h fun.o main.cpp
zjy@ubuntu:~/libaray$ g++ -shared -fPIC -o libfun.so fun.o
zjy@ubuntu:~/libaray$ ls
fun.cpp fun.h fun.o libfun.so main.cpp
zjy@ubuntu:~/libaray$ g++ main.cpp -lfun
/usr/bin/ld: cannot find -lfun
collect2: error: ld returned 1 exit status
zjy@ubuntu:~/libaray$ g++ main.cpp -lfun -L.
zjy@ubuntu:~/libaray$ ls
a.out fun.cpp fun.h fun.o libfun.so main.cpp
zjy@ubuntu:~/libaray$ ./a.out
./a.out: error while loading shared libraries: libfun.so: cannot open shared object file: No such file or directory
zjy@ubuntu:~/libaray$ g++ -o main main.cpp -L. -lfun
zjy@ubuntu:~/libaray$ ls
a.out fun.cpp fun.h fun.o libfun.so main main.cpp
zjy@ubuntu:~/libaray$ ./main
./main: error while loading shared libraries: libfun.so: cannot open shared object file: No such file or directory
zjy@ubuntu:~/libaray$ sudo cp libfun.so /usr/lib/
[sudo] password for zjy:
zjy@ubuntu:~/libaray$ ./a.out
print fun
zjy@ubuntu:~/libaray$ ./main
print fun
zjy@ubuntu:~/libaray$ sudo rm /usr/lib/libfun.so
zjy@ubuntu:~/libaray$ ./a.out
./a.out: error while loading shared libraries: libfun.so: cannot open shared object file: No such file or directory
zjy@ubuntu:~/libaray$ ./main
./main: error while loading shared libraries: libfun.so: cannot open shared object file: No such file or directory
zjy@ubuntu:~/libaray$
-shared 该选项指定生成动态连接库(让连接器生成T类型的导出符号表,有时候也生成弱连接W类型的导出符号),不用该标志外部程序无法连接。相当于一个可执行文件
-fPIC:表示编译为位置独立的代码,不用此选项的话编译后的代码是位置相关的所以动态载入时是通过代码拷贝的方式来满足不同进程的需要,而不能达到真正代码段共享的目的。(实验时Ubuntu下面编译的时候不带这个选项链接时会发生错误)
zjy@ubuntu:~/libaray$ g++ -shared -fPIC -o libfun.so fun.o
zjy@ubuntu:~/libaray$ g++ -c fun.cpp
zjy@ubuntu:~/libaray$ g++ -shared -fPIC -o libfun.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: error adding symbols: Bad value
collect2: error: ld returned 1 exit status
zjy@ubuntu:~/libaray$