使用g++对c++进行编译链接

静态库

  1. 静态库的生成
    静态库实际就是多个.o的归档(文件夹)
  //在bash终端执行依次执行以下g++命令.
  
  g++  -c src1.cpp src2.cpp
     
  ar crv libmy.a src1.o src2.o

查看静态库内容:

  //输出src1.0,src2.0,这也验证了静态库.a文件实际就是个归档目录
  ar -t libmy.a
  1. 静态库链接
g++ main.cpp -I./mylibdir -L./mylibdir -lmy -o out1

//-lmy优先匹配mylibdir目录下的动态库libmy.so
//如果mylibdir目录下的动态库libmy.so和静态库libmy.a都存在
//则应该通过-l:libmy.a进行精确指定
g++ -I./mylibdir -L./mylibdir -l:libmy.a -o out1

动态库

  1. 动态库生成
//-shared -fPIC生成与位置无关的动态库
g++ -shared -fPIC src1.cpp src2.cpp -o libmy.so

//等价下面两步:
//有别于静态库,这里必须指定-fPIC,以生成位置无关的代码(.o)
g++  -c -fPIC src1.cpp src2.cpp
//-shared:位置无关的.o整合成一个动态库文件
g++ -shared srcfile1.o srcfile2.o -o libmy.so
  1. 动态库链接:
g++ main.cpp -I./mylibdir -L./mylibdir -lmy -o out2
  1. ldd查看可执行文件(运行时)依赖哪些动态库?
//out2可以看到依赖动态库libmy.so
ldd out2
//out1使用的是静态库libmy.a。不依赖动态库
ldd out1
  1. 可执行文件运行时找不到相应动态库?
    上面提到g++库链接生成可执行文件,均是编译时链接:
    对于静态库,编译时链接通过静态链接器ld就将静态库合并到可执行文件了,运行时不再需要该库了。
    对于动态库,编译时链接只是做了简单的符号分析以确保符号引用存在对应的定义。它还是加载时链接:动态库链接器ld_linux.so加载动态库libmy.so
//执行out2,报“找不到libmy.so或libmy.so未定义”
./out2 

原因:
g++ -I./mylibdir -L./mylibdir -lmy -o out2中是编译时链接,对动态库而言这只是确保了可执行文件能编译通过。
还需指定动态库的运行时路径:

1, 编译代码中指定的动态库搜索路径(-rpath)
2, 环境变量LD_LIBRARY_PATH中指定的搜索路径。
3, 配置文件/etc/ld.so.conf中指定的搜索路径。
4, 默认的搜索路径/lib, /usr/lib/

g++ main.o libtest.so -Wl, -rpath=/path/to/libs/

另外也可以设置LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/path/to/libs/
posted @ 2024-07-04 15:51  旅行者2号  阅读(9)  评论(0编辑  收藏  举报