Linux下C++程序常用编译命令

LinuxC++程序常用编译命令

2010-9-4

Kagula

文中涉及的命令在Ubuntu8.04.1中测试通过,本文的目的是为了以后要用的时候,只要看一下本文就马上能回忆起这此命令怎么用。

生成目标文件

#gcc –c  <XXX.cpp>

可以有多个cpp文件

编译静态库

#ar cr   <libXXX.a>   <XXX.o> 

可以有多个o文件(目标文件)

静态库名的命名方式应该是libXXX.a  其中XXX是库的名字。

编译成动态库

# gcc -shared -fPCI -o libmyhello.so hello.o

可以有多个o文件,若考虑到同个库有多个版本,参考如下命令

#gcc -shared -Wl,-soname,libhello.so.1 -o libhello.so.1.0 hello.o

另外再建立两个符号连接:

#ln -s libhello.so.1.0 libhello.so.1

#ln -s libhello.so.1 libhello.so 这样一个libhello的动态连接库就生成了。最重要的是传gcc -shared 参数使其生成是动态库而不是普通执行程序。

-Wl 表示后面的参数也就是-soname,libhello.so.1直接传给连接器ld进行处理。实际上,每一个库都有一个soname,当连接器发现它正 在查找的程序库中有这样一个名称,连接器便会将soname嵌入连结中的二进制文件内,而不是它正在运行的实际文件名,在程序执行期间,程序会查找拥有 soname名字的文件,而不是库的文件名,换句话说,soname是库的区分标志。 这样做的目的主要是允许系统中多个版本的库文件共存,习惯上在命名库文件的时候通常与soname相同 libxxxx.so.major.minor 其中,xxxx是库的名字,major是主版本号,minor 是次版本号

使用静态库

#gcc –o <输出文件名>  <目标文件名>  <静态库文件名>

使用动态库

#gcc  <源文件名>  -l<动态库文件名>  -L<动态库所在路径>

例如:

#gcc test.c -lhello -L.

把源test.c编译为a.out可执行文件,test.c所需要的函数在libhello.so文件中定义,libhello.so文件在当前目录。

直接执行a.out提示找不到动态库文件,这时需要修改当前的动态库搜索路径。

如下:

# export LD_LIBRARY_PATH=.:$LD_LIBRARY_PATH

再执行a.out,测试文件运行成功。

常用命令

[1]查看当前文件依赖于哪些库

#ldd   <库文件或可执行文件>

[2]查看文件类型

#file  <可执行文件名>

[3]查看库中符号

#nm <库文件名称>

nm列出的符号有很多,常见的有 三种,一种是在库中被调用,但并没有在库中定义(表明需要其他库支持),用U表示;一种是库中定义的函数,用T表示,这是最常见的;另外一种是所谓的“弱 态”符号,它们虽然在库中被定义,但是可能被其他库中的同名符号覆盖,用W表示。

通常和grep命令配合使用

可执行程序在执行的时候如何定位共享库文件

采用以下顺序 

[搜索elf文件的 DT_RPATH]=>

[ 环境变量LD_LIBRARY_PATH]=>

[/etc/ld.so.cache文件列表]=>

[/lib/,/usr/lib目录]

如何让执行程序顺利找到动态库

[方法一]把库文件copy/usr/lib目录或/lib目录。

[方法二]修改当前终端的LD_LIBRARY_PATH环境变量,例如:

#export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/home/WhereIsMyLibLocation

此方法只能临时改变搜索路径

[方法三]修改/etc/ld.so.conf文件,把库所在的路径加到文件末尾,并执行ldconfig刷新。这样,加入的目录下的所有库文件都可见。

常用参数(速记)

-I<头文件路径>   -L<库文件路径>  -i<头文件>   -l<库文件名>

-Wall   尽可能多的警告信息

-o     输出可执行文件名(起到重命名输出文件名的作用)

比如说用gcc编译C++文件需要加上-lstdc++参数,让编译器去找libstdc++.a静态库文件。

你可能感兴趣的:(C++,linux,gcc,Path,library,编译器)