Crucial env and paramters for c/c++ compiling

主要介绍Linux使用中的几种关键的环境变量,包括PATH,LD_LIBRARY_PATH,gcc的-I参数以及-L参数

c/c++的程序在编译的时候就是一件很麻烦的事情,往往需要各种环境变量的设置找到对应的库。

PATH

PATH是系统范围的变量,每个shell都有自己的path,系统会从path所指定的路径下面寻找execuatble file。修改的时候一种是临时使用export PATH=$PATH:<new path> 添加,另外一种是将export命令放在.bashrc之类的配置文件中。还有一个问题,多个同名称的excuatable在不同的路径下面,如何保证系统执行的是最新的版本。比如这个问题,根据其中的回答,系统是按照先来后到的顺序查找excutable的,这样可以使用export PATH = <new path>:$PATH 来保证将自己需要的path放在变量的最前面的部分。

LD_LIBRARY_PATH

这个变量用来设置在程序加载运行的时候寻找动态链接库的路径,使用ldd <二进制文件> 可以查看到这个excutable file使用的动态链接库在哪个路径下。使用了LD_LIBRARY_PATH之后,系统再找动态链接文件的时候就会从LD_LIBRARY_PATH所指定的路径中查找。

还有一个变量是LIBRARY_PATH是在程序编译期间用来查找动态链接库的路径,也可以使用gcc的-L参数来指定。

直接设置LD_LIBRARY_PATH可能不是一个好的方式(比较hack的方式),可以设置/etc/ld.so.conf.d(比如Ubuntu)在这个文件中设置需要添加的library所在的路径,之后可以通过sudo ldconfig来升级system更新到最新的libs,具体可以参考这个

Other key parameters from the system aspects

One good example is the spck env setting. Ensentally, it will modify these key variables after we loading a new spack environment (a set of variables under the spack view will be set into these key variables).

I copy this form from the spack official documents:

Variable Paths
PATH bin
MANPATH man, share/man
ACLOCAL_PATH share/aclocal
LD_LIBRARY_PATH lib, lib64
LIBRARY_PATH lib, lib64
CPATH include
PKG_CONFIG_PATH lib/pkgconfig, lib64/pkgconfig, share/pkgconfig
CMAKE_PREFIX_PATH .

This table contains typical system level env, we disucssed the PATH, LD_PATH and LD_LIBRARY_PATH. The CPATH is easy to understand, we need to find the header files. In particular, it specifies a list of directories to be searched as if specified with -I, but after any paths given with -I options on the command line. This environment variable is used regardless of which language is being preprocessed.

PKG_CONFIG_PATH is a environment variable that specifies additional paths in which pkg-config will search for its .pc files. The pkg-config’s searching path can be specified by this env. The .pc file that describes the information of the package will be put into the search dir of the pkg-config search path.

linking的时候设置.so文件的查询路径

若果在编译链接时加入-L参数,在实际运行的时候可能会出现类似如下的情况:

-bash-4.2$ ldd metaserver
linux-vdso.so.1 => (0x00007ffef8fb1000)
libprotobuf.so.19 => not found
libgrpc++.so.1 => not found
libgrpc.so.7 => not found
libgrpc++_reflection.so.1 => not found
libpthread.so.0 => /lib64/libpthread.so.0 (0x00007f0dae8aa000)

这是一种情况就是将.so所在的文件添加到LD_LIBRARY_PATH中,将如下命令export LD_LIBRARY_PATH=<path_to_dir_of_libs>:$LD_LIBRARY_PATH放在./profile中,每次自动执行,另一种是set the linking path explicitly, such as this.

这里有一点要特别注意,就是在修改ld library path的时候,最好把所需要的library放在最前面,这样就能保证找到正确的library。如果library path中已经有一些关于某个library的path,但是这个是旧的或者不是我满所希望link过去的,这样把最新的lib放在前面就能确保运行的时候link过去的是正确的path。

Adding following info when linking:

for example:

-L$(PATH_GRPC)/lib -L$(PATH_PROTO)/lib -Wl,-rpath $(PATH_GRPC)/lib -Wl,-rpath $(PATH_PROTO)/lib

这里的rpath就是指定运行的时候查找lib的path,这里也说了很多相关的细节。   

这样编译出来的binary在通过ldd查看时,就会直接找到.so文件的位置了。(实际debug的时候不要想当然以为正确的.so文件一定会被link过去,最好是有意识地通过.so确认一下才比较好,明确是这个executable所link到的shared library是expected的正确版本)

gcc -L -l 与 -I(big i)

具体的可以参考这个或者gcc的参数说明文档

-larchive Add archive file archive to the list of files to link. ld will search its path-list for occurrences of libarchive.a for every archive specified. 也就是说在编译的时候如果使用了某个动态链接库可以通过-l参数设置进来

-Lsearchdir Add path searchdir to the list of paths that ld will search for archive libraries and ld control scripts. 如果使用-L参数,则会在指定的目录下搜索,之后在link的时候从对应的目录下找到需要的文件

-I dir 表示include path, Add the directory dir to the list of directories to be searched for header files during preprocessing,使用了-I参数之后就会从这个路径下找头文件。There are two system level variable that can specify the - I used by compiler, C_INCLUDE_PATH (for C header files) or CPLUS_INCLUDE_PATH (for C++ header files). If we can not find specific .h or .hpp file during the compiling, it usually means we did not set the -I parameters correctly in the cmake or make file.

-shared Produce a shared object which can then be linked with other objects to form an executable. Not all systems support this option. You must also specify -fpic or -fPIC on some systems when you specify this option.

参考资料

介绍PATH/LD_LIBRARY_PATH

https://blog.csdn.net/wangeen/article/details/8159500

为什么不建议用LD_LIBRARY_PATH

http://xahlee.info/UnixResource_dir/_/ldpath.html

option for linking
https://gcc.gnu.org/onlinedocs/gcc/Link-Options.html

这个资料很好 有全部的gcc参数
https://gcc.gnu.org/onlinedocs/gcc/Option-Index.html#Option-Index_op_letter-I

推荐文章