当我想编译使用libspotify的东西时,我可以通过在编译命令中包含术语-lspotify
来链接libspotify库,然后一切正常。
如果我正在编写和安装我自己的库,我在哪里放置.a文件(或者无论如何我都可以)以相同的方式链接到我的库?
如果重要,这个问题涉及Posix系统。目前我对如何在Windows中完成这项工作不感兴趣。
答案 0 :(得分:1)
只要链接器(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
- 选项。
请注意,您必须选择64/32位的链接风格
关心。将-m64
替换为-m32
,您就可以得到一些东西
不同。除/lib
之外的便携式Posix选项为/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
。