动态库编译选项相关知识

-L选项 -l -Wl,-rpath

前言

编译项目时需要用到动态库。而又因为监控程序的存在,编完之后使用动态库的位置在另一个地方,因此在编写makefile文件的时候,就需要在编译的时候指定动态库的位置,而实际可执行程序使用的动态库又在另一个位置。因此需要了解一下编译时与动态库相关的编译选项。

正文

CC = gcc
INCDIR = ../include
BLDINCPATH = -I $(INCDIR)
TARGET = test
LIBS = -lpthread -ldl -L ../lib -llibname -Wl,-rpath='$$ORIGIN/pathname'

着重看一下最后一个LIBS变量,里面包含了编译时需要用到的与库有关的编译选项,其中第一个是与多线程有关的库,第二个在之前博客中有提到,这里不再说。后面的则全部跟动态库的编译有关,今天要说的就是后面几个编译选项:

选项 说明
-llibrary 链接时在标准搜索目录中寻找库文件,搜索名为liblibrary.aliblibrary.so
-Ldir 用于把新目录添加到库搜索路径上,可以使用相对和绝对路径,“-L.”、“-L./include”、“-L/opt/include”
-Wl,option 把选项 option 传递给连接器,如果 option 中含有逗号,就在逗号处分割成多个选项

这里的option 一般为vpath='pathname'pathname 是程序在运行时动态库所在路径。也就是说,编译时,编译器从-L -l选项中提到的目录中搜索动态库,编译成功后,可执行程序运行时要从后面的-Wl、vpath提到的路径中搜索动态库。注意vpath后面跟的是字符串。

ORIGIN 令牌在创建之后保留在程序中,并且当运行时链接程序开始运行程序时,它将用调用程序的当前路径替换ORIGIN。即使已将程序复制到其他位置,也是如此。因此,如果以/usr/local/bin/myprogram身份运行程序,则运行时链接程序会将ORIGIN替换为/usr/local/bin。如果将其复制到/opt/mystuff/libexec/myprogram,则运行时链接程序会将ORIGIN替换为/opt/mystuff/libexec。

但是为了将文字传递给make配方调用的命令,必须通过将加倍来对其进行转义:$。否则,make将视为引入了make变量或函数。请记住,如果make变量是单个字符(请注意,@,<等),则避免括号等是完全合法的。

因此,当编写-Wl,-rpath='ORIGIN/'时,make会将ORIGIN中的$O解释为扩展名为O的变量,该变量为空。

另外,必须通过转义字符从外壳中转出,否则它将尝试将ORIGIN扩展为不需要的外壳变量。这也是为什么makefile文件中是ORIGIN而不是ORIGIN。

项目目录:

.
├── bin
├── etc
│   └── %.cfg
├── include
│   ├──API
├── lib
│   ├── %.so
├── src
│   ├──%.c
│   └──makefile
├── README
├──makefile

标题:动态库编译选项相关知识
作者:staymeloo7
联系方式:staycoolsun@gmail.com

    评论
    0 评论
avatar

取消