索引:
(1) Linux下环境变量相关的问题
(2) Linux下GNU工具链相关的问题(GNU Toolchain)(gcc/g++/ld/make等等工具)
(3) Linux下可执行文件的格式(主要是ELF格式,还有a.out/coff等)和可执行文件的加载
(4) 可执行程序执行加载动态库的搜索路径问题
Linux编译环境变量(LD_LIBRARY_PATH。。。)
http://www.cnwing.net/more.asp?name=linuxroot&id=252144
(1) Linux下环境变量相关的问题
1. Linux下如何设置环境变量
A. 在终端输入export设置环境变量
export var=value
export var=“value”
特点:临时的,只对当前shell有效(即当前的命令行,如果在命令行中运行其它的shell脚本,脚本文件中定义的export环境变量在脚本执行完后对“当前"shell无效,因为运行脚本会开一个新的shell进程,当然,这里只是简单提示一下这一点)。
说明:
1. var和=之间不能有空格。测试如下:
- $export xx =
- bash: export: `=': 不是有效的标识符
- $
export var=value中,value的写法一般有两种,用引号和不使用引号。如果value的值不包含空格,那么value可以直接写,否则,var的值遇到空格就停止了,后面的会被忽略;如果value的值包含空格,那么可以对value使用引号,如果使用了多对引号,那么就是对字符串链接了,引号都不包括在value中。测试如下:
- $export var=abc
- $echo $var
- abc
- $export var= abc
- $echo $var
- $export var=abc def
- $echo $var
- abc
- $export var="abc"
- $echo $var
- abc
- $export var= "abc"
- $echo $var
- $export var="abc" def
- $echo $var
- abc
- $export var="abc" "def"
- $echo $var
- abc
- $export var="abc def"
- $echo $var
- abc def
- $export var=" abc def g"
- $echo $var
- abc def g
- $export var="abc"def"g"h
- $echo $var
- abcdefgh
- $export var="abc"def"g"h"
- > xx"
- $echo $var
- abcdefgh xx
- $
- $export var=abc\"def
- $echo $var
- abc"def
- $export var=abc\"def\"
- $echo $var
- abc"def"
- $export var="abc\"def\"""gh"
- $echo $var
- abc"def"gh
- $
B、在/etc/profile里添加环境变量
就是打开文件,在其中添加export的内容,export的使用和上面的一样。
特点:永久的,且对所有用户有效。
说明:如果在命令行下修改文件,退出编辑后,设置不会马上生效,需要运行source /etc/profile,如果不运行source,那么下次启动登录此用户的时候会生效。参考Linux的source命令的用法。
C、在用户目录下的.bash_profile(~/.bash_profile)里添加环境变量
和/etc/profile里添加的方法一样,
特点:永久的,但是只对当前用户有效。
说明:和/etc/profile是对应的,所以同样,设置后使用source才会马上生效,否则,需要重新登录此用户。
D、其它方法
上面三种是常见的设置环境变量的方法,对于BC两种方法,如果不使用source命令则需要重新登录用户才能生效,对应的其实还有一些其他的bash配置文件也可以设置,这里主要说的是用户目录下的.bashrc文件(~/.bashrc),其对应于.bash_profile的设置,区别在于,.bashrc在每次重启shell(命令行)就会生效,不需要重新登录用户。当然,对应的还有其它一下文件可能也可以设置环境变量,但是原理方法是一样的,参考相关内容比较这些配置文件的区别和理解其原理。
说明:个人习惯使用的方式是export和~/.bashrc的方法,这也应该是比较常见的使用方式。
2. 如何引用(表示)另一个环境变量
定义了一个环境变量后,用$var就表示引用这个环境变量了。
2. Linux下如何显示环境变量(的值)
A、使用echo显示单个环境变量
上面已经涉及到了,直接echo就可以输出单个环境变量的值,其实,这只是引用环境变量的一个例子而已了,环境变量用$var引用就可以了,shell会将其“翻译"为其vaue,所以,自然,下面也是可以的:
- $export var=test
- $echo $var"add something"
- testadd something
- $echo $var add something
- test add something
- $
B、使用env显示所有环境变量和其值
相当于对所有环境变量使用echo $var,直接命令行输入env命令即可。
C、使用set显示所有的用户变量
set命令可以显示的是用户变量,关于环境变量和用户变量,参考相关内容。(提示:用户变量直接定义即可,比如var=value,对用户变量的引用也是$var,更多内容参考shell编程相关知识)(用户的环境变量也是用户变量的一部分)。
说明:unset可以删除用户变量,如unset var。注意:不是unset $var!unset可以删除用户变量和函数等,环境变量只是其中的一小部分。当然,所谓的”删除“变量,其实,将其设置为空,效果也是一样的了(如何设置?直接赋值!如$var=newvalue,同样也是适用于环境变量和普通的用户变量。
(2) Linux下GNU工具链相关的问题
1. GNU工具链介绍(包含的内容)
Wiki:http://zh.wikipedia.org/wiki/GNU_toolchain
GNU工具链(GNU toolchain)是一个包含了由GNU项目所产生的各种编程工具的集合。这些工具形成了一条工具链(串行使用的一组工具),用于开发应用程序和操作系统。 GNU工具链中包含的项目有:
GNU make:用于编译和构建的自动工具;
GNU编译器集合(GCC):一组多种编程语言的编译器;
GNU Binutils:包含链接器、汇编器和其它工具的工具集;
GNU Debugger(GDB):代码调试工具;
GNU构建系统(autotools):
Autoconf
Autoheader
Automake
Libtool
由于工具很多,所以不一一说明。注意:GNU toolchain并不只是指gcc、g++、ld这些。
2. Linux下程序的编译的过程(windows类似)
参考:http://blog.csdn.net/gengshenghong/article/details/7096709
3. Linux下可执行文件的格式(主要是ELF格式,还有a.out/coff等)和可执行文件的加载
Linux下的可执行文件的格式,目前的Linux上的可执行程序基本其实都是ELF了,包括.so共享动态链接库其实也是ELF格式的。
利用file命令可以查看Linux上文件的格式,下面是对两个测试文件使用file的结果:
- a.out: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.32, not stripped
- libBox2D.so.2.1.0: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, not stripped
http://www.cnblogs.com/lidp/articles/1696071.html
http://club.topsage.com/thread-1221240-1-1.html
http://www.linuxsir.org/bbs/printthread.php?t=206356
http://www.sudu.cn/info/html/edu/20080428/302819.html
等。
至少,我们要知道,对于Linux上可执行程序运行之前有一个加载的过程,而加载,包括了动态链接库的加载(动态链接dynamic linking),即加载动态链接库,参考http://www.linuxsir.org/bbs/printthread.php?t=206356进行详细的了解。另外,Linux中动态链接库的加载器(loader)是由ld.so完成的(http://zh.wikipedia.org/wiki/Ld.so),注意,不是链接器ld!关于ld.so参考http://www.cnblogs.com/cornsea/archive/2009/12/09/1620470.html进行了解。如下:
- ##/lib/ld-linux.so.2
- Usage: ld.so [OPTION]... EXECUTABLE-FILE [ARGS-FOR-PROGRAM...]
- You have invoked `ld.so', the helper program for shared library executables.
- This program usually lives in the file `/lib/ld.so', and special directives
- in executable files using ELF shared libraries tell the system's program
- loader to load the helper program from this file. This helper program loads
- the shared libraries needed by the program executable, prepares the program
- to run, and runs it. You may invoke this helper program directly from the
- command line to load and run an ELF executable file; this is like executing
- that file itself, but always uses this helper program from the file you
- specified, instead of the helper program file specified in the executable
- file you run. This is mostly of use for maintainers to test new versions
- of this helper program; chances are you did not intend to run this program.
- --list list all dependencies and how they are resolved
- --verify verify that given object really is a dynamically linked
- object we can handle
- --library-path PATH use given PATH instead of content of the environment
- variable LD_LIBRARY_PATH
- --inhibit-rpath LIST ignore RUNPATH and RPATH information in object names
- in LIST
- --audit LIST use objects named in LIST as auditors
- ##
相关的命令:
file xxx:查看文件xxx的文件类型
ldd xxx:查看可执行文件xxx依赖的动态链接库。
nm:列举文件中的符号(symbols)。
4. 可执行程序执行加载动态库的搜索路径问题
参考:http://blog.csdn.net/benben8901/article/details/6714160
http://blog.163.com/hotman_x.vip/blog/static/4895013320096122147961/
需要注意的是:LD_LIBRARY_PATH,这个环境变量是被ld.so使用的,所以和编译器的链接阶段并没有关系。