-C
gcc的-c选项表示只编译不链接。不带-c选项则默认既编译又链接。
CFLAGS编译参数
LDFLAGS链接参数
指定LIBS是要链接的库的目录。LDFLAGS告诉链接器从哪里寻找库文件。
LDFLAGS指定-L虽然能让链接器找到库进行链接,但是运行时链接器却找不到这个库,如果要让软件运行时库文件的路径也得到扩展,那么我们需要增加这两个库给"-Wl,R"
-Wl, -rpath=dir
链接阶段查找库的位置和运行时查找库的位置是两码事。
-L 指定编译链接时库的搜索目录。
-Wl,-rpath 指定程序运行时库搜索目录。
Add a directory to the runtime library search path. This is used when linking an ELF executable with shared objects. All -rpath arguments are concatenated and passed to the runtime linker, which uses them to locate shared objects at runtime.
The -rpath option is also used when locating shared objects which are needed by shared objects explicitly included in the link; see the description of the -rpath-link option. If -rpath is not used when linking an ELF executable, the contents of the environment variable "LD_RUN_PATH" will be used if it is defined.
The -rpath option may also be used on SunOS. By default, on SunOS, the linker will form a runtime search path out of all the -L options it is given. If a -rpath option is used, the runtime search path will be formed exclusively using the -rpath options, ignoring the -L options. This can be useful when using gcc, which adds many -L options which may be on NFS mounted file systems.
For compatibility with other ELF linkers, if the -R option is followed by a directory name, rather than a file name, it is treated as the -rpath option.
-Wl, --rpath-link
-L: “链接”的时候,去找的目录,也就是所有的 -lFOO 选项里的库,都会先从 -L 指定的目录去找,然后是默认的地方。
-rpath-link:这个也是用于“链接”的时候的,例如你显示指定的需要 FOO.so,但是 FOO.so 本身是需要 BAR.so 的,后者你并没有指定,而是 FOO.so 引用到它,这个时候,会先从 -rpath-link 给的路径里找。也就是说-rpath-link只对哪些隐式链接的库生效,因为显式链接的库已经通过-L指定查找路径了。
-rpath: “运行”的时候,去找的目录。运行的时候,要找 .so 文件,会从这个选项里指定的地方去找。对于交叉编译,只有配合 --sysroot 选项才能起作用。
也就是说,-rpath指定的路径会被记录在生成的可执行程序中,用于运行时。
-rpath-link 则只用于链接时。
清楚了这两个option的含义之后,来看用法,要在gcc的命令行中直接使用这两个option,必须遵循语法:-Wl,......。比 如:-Wl,--rpath-link/opt/alp/lib。-Wl就是告诉gcc,后面的内容是传递给linker的option。如果直接使用ld的话,就不需要-Wl,了。所以,上面我们的编译命令就变成这样,就OK了:
- --sysroot指定头文件和库文件的根目录
--sysroot=<directory> Use <directory> as the root directory for headers
and libraries
如果在编译时指定了-sysroot=dir 就是为编译时指定了逻辑目录。编译过程中需要引用的库,头文件,如果要到/usr/include目录下去找的情况下,则会在前面加上逻辑目录。
如此处我们指定 -sysroot=/home/shell.albert/tools/toolschain_arm/4.4.3/arm-none-linux-gnueabi/sys-root
将dir作为逻辑根目录(搜索头文件和库文件)。比如编译器通常会在 /usr/include 和 /usr/lib 中搜索头文件和库,使用这个选项后将在 dir/usr/include 和 dir/usr/lib 目录中搜索。如果使用这个选项的同时又使用了 -isysroot 选项,则此选项仅作用于库文件的搜索路径,而 -isysroot 选项将作用于头文件的搜索路径。这个选项与优化无关,但是在 CLFS 中有着神奇的作用。
Gcc 链接器ld选项参数解释: -shared: 该选项指定生成动态连接库(让连接器生成T类型的导出符号表,有时候也生成弱连接W类型的导出符号)。不用该标志外部程序无法连接。
相当于一个可运行文件
-fpic: 表示编译为位置独立的代码。不用此选项的话编译后的代码是位置相关的所以动态加载时是通过代码拷贝的方式来满足不同进程的须要,而不能达到真正代码段共享的目的。
-l 选项告诉编译器要使用hello这个库。奇怪的地方是动态库的名字是libhello.so,这里却使用hello. 但这样还不行。编译会出错。
In function `main': test.c:(.text+0x1d): undefined reference to `hello' collect2: ld returned 1 exit status 这是由于hello这个库在我们自己的路径中,编译器找不到。
须要使用-L选项,告诉hello库的位置 gcc test.c -lhello -L. -o test -L .告诉编译器在当前文件夹中查找库文件
-Wl选项告诉编译器将后面的参数传递给链接器。(给编译器用的)
-soname则指定了动态库的soname(简单共享名,Short for shared object name)
当要升级系统中的一个库时,并且新库的soname和老库的soname一样,用旧库链接生成的程序使用新库依然能正常运行。这个特性使得在Linux下,升级使得共享库的程序和定位错误变得十分容易。
-Wl,rpath=<your_lib_dir>选项
gcc编译链接动态库时,很有可能编译通过,但是执行时,找不到动态链接库,那是
因为-L选项指定的路径只在编译时有效,编译出来的可执行文件不知道-L选项后面的值,
当然找不到。可以用ldd <your_execute>看看是不有 ‘not found’在你链接的库后面,
解决方法是通过-Wl,rpath=<your_lib_dir>,使得execute记住链接库的位置
-nostdlib:不链接C语言的标准库 仅搜索那些在命令行上显式指定的库路径. 在连接脚本中(包含在命令行上指定的连接脚本)指定的库路径都被忽略.
-fno-builtin -fno-builtin-function 不接受没有 __builtin_ 前缀的函数作为内建函数。
对于-L指定的目录,是不会在前面添加--sysroot中指定的路径的,只有在查找默认路径的时候才会添加该逻辑路径。
在编译syspara时,如果Makefile中没有指定--sysroot,则会报如下错误:
在Makefile中指定sysroot后问题解决:
Man ld时对该选项的解释为:
--sysroot=directory
Use directory as the location of the sysroot, overriding the configure-time default. This option is only supported by linkers that were configured using --with-sysroot.
- -Wl,-soname选项
-Wl选项告诉编译器将后面的参数传递给链接器。
-soname则指定了动态库的soname(简单共享名,Short for shared object name)
默认情况下,GCC/G++链接时优先链接动态库,如果没有动态库,则链接相应的静态库。同时,GCC/G++也提供了链接选项 -Wl,-Bstatic 和 -Wl,-Bdynamic 供用户指定链接动态库或者静态库。
-Wl,-Bstatic指示跟在后面的-lxxx选项链接的都是静态库,-Wl,-Bdynamic指示跟在后面的-lxxx选项链接的都是动态库。
-Wl,-Bstatic -llog4cplus -lpcap -lpgm -lxerces-c -Wl,-Bdynamic -lnl-3 -ldbus-1 -libverbs -lcurl -lhiredis -Wl,--as-needed
-Wl,-Bstatic 后面的库是静态链接的; -Wl,-Bdynamic 后面的都是动态链接的。
原理上讲,Wl后面的东西是作为参数传递给链接器ld
The -Wl,xxx option for gcc passes a comma-separated list of tokens as a space-separated list of arguments to the linker. So
"gcc -Wl,aaa,bbb,ccc" eventually becomes a linker call "ld aaa bbb ccc"
$(TARGET) : $(OBJS)
$(CC) -fPIC -shared $(LDFLAGS) -lnvram -Wl,-soname,$(TARGET) -o $(TARGET) $(OBJS)
这几个单词之间都好分割,多个共享库名称也是用都好分割
- -O选项输出文件名字及路径
通过-o选项也可以将可执行文件输出到其他目录
Man ld -rpath -rpath-link
-rpath=dir
Add a directory to the runtime library search path. This is used when linking an ELF executable with shared objects. All-rpath arguments are concatenated and passed to the runtime linker, which uses them to locate shared objects at runtime.
The -rpath option is also used when locating shared objects which are needed by shared objects explicitly included in the link; see the description of the -rpath-link option. If -rpath is not used when linking an ELF executable, the contents of the environment variable "LD_RUN_PATH" will be used if it is defined.
The -rpath option may also be used on SunOS. By default, on SunOS, the linker will form a runtime search path out of all the -L options it is given. If a -rpath option is used, the runtime search path will be formed exclusively using the -rpath options, ignoring the -L options. This can be useful when using gcc, which adds many -L options which may be on NFS mounted file systems.
For compatibility with other ELF linkers, if the -R option is followed by a directory name, rather than a file name, it is treated as the -rpath option.
-rpath-link=dir
When using ELF or SunOS, one shared library may require another. This happens when an "ld -shared" link includes a shared library as one of the input files.
When the linker encounters such a dependency when doing a non-shared, non-relocatable link, it will automatically try to locate the required shared library and include it in the link, if it is not included explicitly. In such a case, the -rpath-link option specifies the first set of directories to search. The -rpath-link option may specify a sequence of directory names either by specifying a list of names separated by colons, or by appearing multiple times.
This option should be used with caution as it overrides the search path that may have been hard compiled into a shared library. In such a case it is possible to use unintentionally a different search path than the runtime linker would do.
The linker uses the following search paths to locate required shared libraries:
- Any directories specified by -rpath-link options.
- Any directories specified by -rpath options. The difference between -rpath and -rpath-link is that directories specified by -rpath options are included in the executable and used at runtime, whereas the -rpath-link option is only effective at link time. Searching -rpath in this way is only supported by native linkers and cross linkers which have been configured with the --with-sysroot option.
- On an ELF system, for native linkers, if the -rpath and -rpath-link options were not used, search the contents of the environment variable "LD_RUN_PATH".
- On SunOS, if the -rpath option was not used, search any directories specified using -L options.
- For a native linker, search the contents of the environment variable "LD_LIBRARY_PATH".
- For a native ELF linker, the directories in "DT_RUNPATH" or "DT_RPATH" of a shared library are searched for shared libraries needed by it. The "DT_RPATH" entries are ignored if "DT_RUNPATH" entries exist.
- The default directories, normally /lib and /usr/lib.
- For a native linker on an ELF system, if the file /etc/ld.so.conf exists, the list of directories found in that file.
If the required shared library is not found, the linker will issue a warning and continue with the link.
-shared
-Bshareable
Create a shared library. This is currently only supported on ELF, XCOFF and SunOS platforms. On SunOS, the linker will automatically create a shared library if the -e option is not used and there are undefined symbols in the link.