gcc用法以及静态/动态链接

2017-09-18  本文已影响296人  第八区

安装

yum install gcc gcc-c++

选项

-E:只进行预处理,不编译
-S:只编译,不汇编
-c:只编译、汇编,不链接
-g:编译器在编译的时候产生调试信息。
-I:指定include包含文件的搜索目录
-o:输出成指定文件名,如果缺省则输出位a.out
-L:搜索库的路径
-l:指定程序要链接的库
-w:忽略所有警告
-shared:指定生成动态链接库。
-static:指定生成静态链接库。
-fPIC:表示编译为位置独立的代码,用于编译共享库。目标文件需要创建成位置无关码,概念上就是在可执行程序装载它们的时候,它们可以放在可执行程序的内存里的任何地方。

-l参数和-L参数

-I参数

Linux下的标准头文件路径为/usr/include/usr/local/include

2.png 1.png

.a 和.so

静态函数库

静态函数库,这类库的名字一般是libxxx.a
利用静态函数库编译成的文件比较大,因为整个函数库的所有数据都会被整合进目标代码中。
优点就显而易见了,即编译后的执行程序不需要外部的函数库支持,因为所有使用的函数都已经被编译进去了。当然这也会成为缺点如果静态函数库改变了,那么你的程序必须重新编译。

共享函数库

这类库的名字一般是libxxx.so
相对于静态函数库,共享函数库在编译的时候 并没有被编译进目标代码中。当程序执行到相关函数时才调用共享函数库里相应的函数,因此共享函数库所产生的可执行文件比较小。
由于共享函数库没有被整合进你的程序,而是在程序运行时动态地申请并调用,所以程序的运行环境中必须提供相应的库.
共享函数库的改变并不影响你的程序,所以共享函数库的升级比较方便.

示例

先上头文件hello.h

#ifndef HELLO_H
#define  HELLO_H
void show();
#endif

分别做两个实现,hello_static.cpp和hello_dynamic.cpp。代码很简单就是打印一句话做一个区分,方便我们后面测试链接的哪个库。
hello_static.cpp

#include "hello.h"
#include <iostream>
using namespace std;
void show(){
  cout<<"hello static"<<endl;
}

hello_dynamic.cpp

#include "hello.h"
#include <iostream>
using namespace std;
void show(){
  cout<<"hello dynamic"<<endl;
}

测试主程序main.cpp

#include "hello.h"
int main(){
  show();
  return 0;
}

下面我们写Makefile然后进行编译:

all : hello_static.o libhello.a libhello.so  main_s main_d

hello_static.o : hello_static.cpp
    g++ -c hello_static.cpp
    
libhello.a : hello_static.o
    ar crs libhello.a hello_static.o

libhello.so : hello_dynamic.cpp
    g++ -o $@ $+  -fPIC -shared

main_s : main.cpp
    g++  -static -o $@ $+ -I. -lhello -L.

main_d : main.cpp
    g++ -o $@ $+ -I. -lhello -L.

.PHONY : clean
clean :
    -rm hello_static.o libhello.a libhello.so main_s main_d

在链接hello时,会以共享库文件优先. 如果同时存在静态库和共享库,可以使用-static强制使用静态库。当然也可以直接指定libhello.a。如:

g++ -o $@ $+ -I.  -L.  libhello.a

完成Makefile后,就可以进行编译,执行make命令,生成hello_static.olibhello.alibhello.somain_smain_d等文件。而main_s是我们静态链接生成的,main_d是动态链接。我们分别运行后:

[root@localhost gcc]# ./main_d 
hello dynamic
[root@localhost gcc]# ./main_s
hello static

与我们预期一致。

问题

静态链接使用-static出现错误:
/usr/bin/ld: cannot find -lm
collect2: ld 返回 1
make: *** [main_s] 错误 1

安装glibc-devel即可

找不到动态库
./main_d: error while loading shared libraries: libhello.so: cannot open shared object file: No such file or directory

这里是需要设置环境变量,可参考Linux环境变量介绍和区别。也就是我们需要将so文件设置到环境变量中。直接编辑.bashrc文件

vim ~/.bashrc

添加:

export LD_LIBRARY_PATH=/code/gcc

保存退出后,使其生效。

source ~/.bashrc
上一篇下一篇

猜你喜欢

热点阅读