Linux下和编译器、程序的运行、环境变量等相关的常见问题

来源:互联网 发布:windows 加入域 编辑:程序博客网 时间:2024/06/04 17:47

(不断更新)

索引:

(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: `=': 不是有效的标识符$
2. value是可选的,如果没有value,那么var的值就是空的。(当然,一般不会这么用)
export var=value中,value的写法一般有两种,用引号和不使用引号。如果value的值不包含空格,那么value可以直接写,否则,var的值遇到空格就停止了,后面的会被忽略;如果value的值包含空格,那么可以对value使用引号,如果使用了多对引号,那么就是对字符串链接了,引号都不包括在value中。测试如下:
$export var=abc$echo $varabc$export var= abc$echo $var$export var=abc def$echo $varabc$export var="abc"$echo $varabc$export var= "abc"$echo $var$export var="abc" def$echo $varabc$export var="abc" "def"$echo $varabc$export var="abc def"$echo $varabc def$export var=" abc def g"$echo $varabc def g$export var="abc"def"g"h$echo $varabcdefgh$export var="abc"def"g"h"> xx"$echo $varabcdefgh xx$
这里只是一些测试,其实这些应该是shell对字符串的一些要求了,比如"abc"def"gh"得到的是abcdefgh这样的字符串。如果引号不配对,就会认为没有输入完成,会让继续输入的。那么,如果value中必须要包含引号呢?那就是反义字符了。如下:
$export var=abc\"def$echo $varabc"def$export var=abc\"def\"$echo $varabc"def"$export var="abc\"def\"""gh"$echo $varabc"def"gh$
总之,看看这些测试的就很容易理解了,一般也不会用到这些。主要知道引号的作用就可以了,它是不会被包含在var的值中的

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 somethingtest 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
这是一个hello,world编译后得到的a.out使用file a.out的结果,下面是对一个动态链接库使用file得到的结果:

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 directivesin executable files using ELF shared libraries tell the system's programloader to load the helper program from this file.  This helper program loadsthe shared libraries needed by the program executable, prepares the programto run, and runs it.  You may invoke this helper program directly from thecommand line to load and run an ELF executable file; this is like executingthat file itself, but always uses this helper program from the file youspecified, instead of the helper program file specified in the executablefile you run.  This is mostly of use for maintainers to test new versionsof 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 linkedobject we can handle  --library-path PATH   use given PATH instead of content of the environmentvariable LD_LIBRARY_PATH  --inhibit-rpath LIST  ignore RUNPATH and RPATH information in object namesin 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使用的,所以和编译器的链接阶段并没有关系。