makefile中选项说明

-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了:

  1. --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.

  1. -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)

这几个单词之间都好分割,多个共享库名称也是用都好分割

  1. -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:

  1. Any directories specified by -rpath-link options.
  2. 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.

  1. 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".
  2. On SunOS, if the -rpath option was not used, search any directories specified using -L options.
  3. For a native linker, search the contents of the environment variable "LD_LIBRARY_PATH".
  4. 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.
  5.  The default directories, normally /lib and /usr/lib.
  6.  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.

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/257355.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Docker安装postgres最新版

1. postgres数据库 PostgreSQL是一种开源的关系型数据库管理系统&#xff08;RDBMS&#xff09;&#xff0c;它是一种高度可扩展的、可靠的、功能丰富的数据库系统。以下是关于PostgreSQL的一些介绍&#xff1a; 开源性&#xff1a;PostgreSQL是一个开源项目&#xff0c;可以…

嵌入式系统

嵌入式系统 目前国内一个普遍认同的嵌入式系统定义是&#xff1a;以应用为中心、以计算机技术为基础&#xff0c;软件硬件可裁剪&#xff0c;适应应用系统对功能、可靠性、成本、体积、功耗严格要求的专用计算机系统。&#xff08;引用自《嵌入式系统设计师教程》&#xff09; …

MangoDB数据可updata报错

报错详情 报错原因 语法错误&#xff0c;我们调整语法即可 update&#xff08;{要修改的行}&#xff0c;{$set{要修改的字段}}&#xff09;

【Java基础系列】Cron表达式入门

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…

<IBM Websphere Portal>《关于IBM的Portal和WAS的说明和总结(自用笔记)》

《关于IBM的Portal和WAS的简单总结》 1 架构1.1 说明 2 常见问题2.1 LDAP链接问题2.2 启动脚本建议2.3 日志大小保留建议2.4 启动垃圾回收日志 3 日志位置 1 架构 应用服务部署架构如上&#xff1a; &#x1f449;192.168.66.1服务器运行的server进程有&#xff1a;dmgr、nodea…

有了安卓模拟器,就能在Windows 10或11上像使用安卓操作系统一样使用安卓

你可以使用Android模拟器在Windows 11或Windows 10中运行Android应用程序。如果你喜欢的应用程序只在手机上运行,但你想在电脑上使用,这些模拟器会很有用。 BlueStacks 与整个操作系统模拟器不同,BlueStacks只在Windows上模拟Android应用程序。它真的很容易使用,所以你不需…

Linux操作系统 3.Linux用户和权限

一、认知root用户&#xff08;超级管理员&#xff09; Windows、MacOS、Linux均采用多用户的管理模式进行权限管理 在Linux系统中&#xff0c;拥有最大权限的账户名为&#xff1a;root&#xff08;超级管理员&#xff09; 之前我们一直使用的是普通的用户 root用户拥有最大的系…

Spring Boot 3 整合 Spring Cache 与 Redis 缓存实战

&#x1f680; 作者主页&#xff1a; 有来技术 &#x1f525; 开源项目&#xff1a; youlai-mall &#x1f343; vue3-element-admin &#x1f343; youlai-boot &#x1f33a; 仓库主页&#xff1a; Gitee &#x1f4ab; Github &#x1f4ab; GitCode &#x1f496; 欢迎点赞…

06_W5500_DHCP

1.DHCP协议介绍&#xff1a; DHCP&#xff08;Dynamic Host Configuration Protocol&#xff09;是一种用于自动分配IP地址和其他网络配置信息的协议。它允许网络中的设备&#xff08;如计算机、手机、打印机等&#xff09;在连接到网络时自动获取IP地址、子网掩码、默认网关、…

【技巧】RAR压缩文件如何解压?

RAR是一种文件压缩与归档的专利文件格式&#xff0c;很多时候在工作中都会使用到。既然是压缩格式&#xff0c;我们就需要解压才能得到里面的文件&#xff0c;对于电脑小白来说&#xff0c;可能不知道如何解压RAR文件&#xff0c;下面小编来分享一下。 解压压缩文件&#xff0…

CAN总线协议编程实例

1. can.h #ifndef __CAN_H #define __CAN_H#include "./SYSTEM/sys/sys.h"/******************************************************************************************/ /* CAN 引脚 定义 */#define CAN_RX_GPIO_PORT GPIOA #define CAN_RX_GPI…

MySQL系列(十):主从架构

一&#xff1a;主从架构 常见的主从架构模式有四种&#xff1a; 一主多从架构&#xff1a;适用于读大于写的场景&#xff0c;采用多个从库来分担数据库系统的读压力。多主架构&#xff1a;适用于读写参半的场景&#xff0c;采用多个主库来承载数据库系统整体的读写压力。多主…