只要链接器 (ld) 知道在哪里查找,您就可以将您的库放在任何地方
为它。
链接器如何知道在哪里寻找库?
您可以通过出现一次或多次的命令行选项来告诉它在哪里查找
-L<directory>.
如果你链接选项
-L/look/here/first -L/look/here/second -lfoo
然后ld 查找库,libfoo.so(共享)或libfoo.a(静态),首先进入
/look/here/first;在/look/here/second 中失败了;失败了
它将查看配置的默认位置列表,并失败任何
他们会失败,抱怨找不到-lfoo。虽然顺序
-L 选项很重要,-l 选项相对于 `-L 选项的顺序
没关系:
-lfoo -L/look/here/first -L/look/here/second
意思相同。
一旦它在某处找到libfoo,链接器就不会再寻找,并且在每个目录中
它在哪里查找,默认情况下它会先查找libfoo.so,然后再查找libfoo.a。
通常我们不会通过直接调用ld 来链接。我们通过调用一个链接
特定语言的工具驱动程序,gcc、g++、gfortran 等,通过
它选项指示它进行链接,而不是预处理或编译。
在这种情况下,工具驱动程序代表我们调用ld,并在幕后调用
附加附加的链接器选项,这些选项对于语言是不变的
有问题,使我们不必在命令行上记住和重复样板。
ld 本身,但是,每个架构都有一个内置的默认-L 目录列表
它支持。这些是由构建您的ld 的人配置的,通常是您的发行版,
在这种情况下,您会发现默认位置是库所在的目录
通常由发行版的包管理器安装。
因此,如果您想链接位于默认位置之一的库,您不需要
需要自己指定任何-L 选项。 -lfoo 可以。
相反,如果您希望能够简单地链接libfoo.a
通过在链接命令行上提及-lfoo,然后您需要将其放入
链接器的默认位置之一。如果你想在这样的地方分发libfoo.a
其他用户可以以相同方式链接它的方式,然后您需要分发
它在一个包中,它将安装在默认位置之一(在目标上
系统,不管它是什么)。
为此,您需要知道默认位置是什么。对于 Posix 系统,
您可以依赖/usr/local/lib、/lib 和/usr/lib。但不要安装在/lib。
这是为重要的系统库保留的。查看链接器的默认搜索
目录实际上在您自己的系统上,您可以运行:
gcc -m64 -Xlinker --verbose 2>/dev/null | grep SEARCH_DIR
它会发出类似:
SEARCH_DIR("=/usr/local/lib/x86_64-linux-gnu"); \
SEARCH_DIR("=/lib/x86_64-linux-gnu"); \
SEARCH_DIR("=/usr/lib/x86_64-linux-gnu"); \
SEARCH_DIR("=/usr/local/lib64"); \
SEARCH_DIR("=/lib64"); \
SEARCH_DIR("=/usr/lib64"); \
SEARCH_DIR("=/usr/local/lib"); \
SEARCH_DIR("=/lib"); \
SEARCH_DIR("=/usr/lib"); \
SEARCH_DIR("=/usr/x86_64-linux-gnu/lib64"); \
SEARCH_DIR("=/usr/x86_64-linux-gnu/lib");
告诉你这些目录是默认的-L-options,按这个顺序。
请注意,您必须选择您想要的 64/32 位链接风格
很担心。将-m64 替换为-m32,你会得到一些东西
不同的。可移植的 Posix 选项(不包括 /lib)是 /usr/local/lib 和 /usr/lib。
这回答了你的问题,但你还没有完成。大概,你的图书馆
带有一个或多个头文件,程序可以通过这些头文件导入其 API。
如果库将位于链接器的默认搜索路径中,则标头
最好在编译器的默认搜索路径中,这样程序就可以
只需#include <foo.h> 或#include <foo/bar.h> 并拥有编译器
无需在编译器命令行中编写 -I/foo/headers/are/here 即可找到标头。
要查看编译器的默认搜索路径,对于 C,运行:
echo | gcc -xc -E -v -
相关的输出将类似于:
#include "..." search starts here:
#include <...> search starts here:
/usr/lib/gcc/x86_64-linux-gnu/5/include
/usr/local/include
/usr/lib/gcc/x86_64-linux-gnu/5/include-fixed
/usr/include/x86_64-linux-gnu
/usr/include
或者对于 C++:
echo | gcc -xc++ -E -v -
显示,例如:
#include "..." search starts here:
#include <...> search starts here:
/usr/include/c++/5
/usr/include/x86_64-linux-gnu/c++/5
/usr/include/c++/5/backward
/usr/lib/gcc/x86_64-linux-gnu/5/include
/usr/local/include
/usr/lib/gcc/x86_64-linux-gnu/5/include-fixed
/usr/include/x86_64-linux-gnu
/usr/include
与图书馆的案例相呼应,可移植的 Posix 选项
标头为/usr/local/include 和/usr/include。
所以这是/usr/local/{include|lib} 和/usr/{include|lib} 之间的选择。但考虑到
在/usr/{include|lib} 下安装您的文件,您将更改
以不受控制的方式清点发行版的库和头文件
通过其包管理系统。如果它是,比如说,Debian 8.2,它就不会再有了。
一旦你开始这样做,一旦你做了一个错误的步骤并破坏了你的包裹,
这完全是你的问题。
Unix 和 Linux 对安装您构建的软件有一个约定
自己或来自不受发行版包管理控制的源包
系统,它明智地保护了您的发行版的稳定性。约定是:
安装在/usr/local/{include|bin|lib}。这正是/usr/local 是什么
为了。
底线:将您的库安装在/usr/local/lib 下,并将您的标题安装在
/usr/local/include。如果您有多个标题,则更喜欢/usr/local/include/foo
并在程序源中写#include <foo/bar.h>之类的。那么你就可以
编译没有特殊的-I 选项并链接库没有特殊的-L
选项,只需-lfoo。