如何使库 .a 文件可与 gcc/g++ 链接
How to make a library .a file linkable with gcc/g++
当我想编译使用 libspotify 的东西时,我可以通过在编译命令中包含术语 -lspotify
来 link 反对 libspotify 库,然后一切正常。
如果我正在编写和安装我自己的库,我应该将 .a 文件放在哪里(或者在任何情况下我该做什么)以便能够以相同的方式link 针对我的库?
如果重要的话,这个问题涉及 Posix 系统。目前我对 Windows.
中是如何完成的不感兴趣
只要 linker (ld
) 知道去哪里找,你就可以把你的图书馆放在任何地方
为此。
linker 如何知道去哪里寻找图书馆?
您可以通过出现一次或多次命令行选项来告诉它在哪里查看
-L<directory>
.
如果您link选择
-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
,linker 就不再寻找,并且在每个目录中
在查找的位置,默认情况下它会在查找 libfoo.a
.
之前查找 libfoo.so
通常我们不会link直接调用ld
。我们 link 通过调用一个
language-specific 工具 drivers、gcc
、g++
、gfortran
等,通过
它的选项指示它执行 linking,而不是 pre-processing 或编译。
在这种情况下,工具 driver 代表我们在幕后调用 ld
添加额外的 linker 选项,这些选项对于语言是不变的
有问题,使我们不必在命令行上记住和重复样板文件。
然而,ld
本身有一个 built-in 每个体系结构的默认 -L
目录列表
它支持。这些是由构建你的 ld
的人配置的,通常是你的发行版,
在这种情况下,您会发现默认位置是库所在的目录
通常由您的发行版的包管理器安装。
因此,如果您想 link 一个位于默认位置之一的库,您不需要
需要自己指定任何 -L
选项。 -lfoo
可以。
相反,如果您希望能够 link libfoo.a
通过在 linkage 命令行中提及 -lfoo
,然后您需要将其放入
linker 的默认位置之一。如果你想分发 libfoo.a
这样的
其他用户可以用同样的方式 link 的方式,那么你需要分发
它在一个包中,将把它安装在默认位置之一(在目标上
系统,无论它是什么)。
为此,您需要知道默认位置是什么。对于 Posix 系统,
您可以依赖 /usr/local/lib
、/lib
和 /usr/lib
。但不要安装在 /lib
中。
这是为重要的系统库保留的。看看linker的默认搜索是什么
目录实际上在你自己的系统上,你可以 运行:
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,按顺序排列。
请注意,您必须选择 linkage 的 64/32 位风格
很关心。将 -m64
替换为 -m32
,你会得到一些东西
不同的。可移植的 Posix 选项,不包括 /lib
,是 /usr/local/lib
和 /usr/lib
.
这回答了你的问题,但你还没有完成。据推测,你的图书馆
附带一个或多个 header 文件,程序可以通过这些文件导入其 API。
如果库将位于 linker 的默认搜索路径中,则 header(s)
最好在 编译器的 默认搜索路径中,以便程序可以
只是 #include <foo.h>
或 #include <foo/bar.h>
并让编译器
无需在编译器命令行中编写 -I/foo/headers/are/here
即可找到 header。
要查看编译器的默认搜索路径,对于 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 选项
header 是 /usr/local/include
和 /usr/include
.
所以这是/usr/local/{include|lib}
和/usr/{include|lib}
之间的选择。但考虑到
在 /usr/{include|lib}
下安装您的文件,您将更改
以不受控制的方式清点发行版的库和 header 文件
通过其包管理系统。如果是,比方说,Debian 8.2,它就不会再存在了。
一旦你开始这样做,一旦你犯了错误的一步并破坏了你的包裹,
这完全是你的问题。
Unix 和 Linux 对安装您构建的软件有一个约定
你自己或来自你的发行版包管理不受控制的源包
系统,明智地捍卫您的发行版的稳定性。惯例是:
安装在 /usr/local/{include|bin|lib}
中。这正是 /usr/local
的意思
为了。
底线:在 /usr/local/lib
下安装你的库,在 header 下安装你的库
/usr/local/include
。如果你有多个 header,那么更喜欢 /usr/local/include/foo
在程序源码中写上#include <foo/bar.h>
之类的。那么你也能
编译时没有特殊 -I
选项,link 库没有特殊 -L
选项,只是 -lfoo
.
当我想编译使用 libspotify 的东西时,我可以通过在编译命令中包含术语 -lspotify
来 link 反对 libspotify 库,然后一切正常。
如果我正在编写和安装我自己的库,我应该将 .a 文件放在哪里(或者在任何情况下我该做什么)以便能够以相同的方式link 针对我的库?
如果重要的话,这个问题涉及 Posix 系统。目前我对 Windows.
中是如何完成的不感兴趣只要 linker (ld
) 知道去哪里找,你就可以把你的图书馆放在任何地方
为此。
linker 如何知道去哪里寻找图书馆?
您可以通过出现一次或多次命令行选项来告诉它在哪里查看
-L<directory>
.
如果您link选择
-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
,linker 就不再寻找,并且在每个目录中
在查找的位置,默认情况下它会在查找 libfoo.a
.
libfoo.so
通常我们不会link直接调用ld
。我们 link 通过调用一个
language-specific 工具 drivers、gcc
、g++
、gfortran
等,通过
它的选项指示它执行 linking,而不是 pre-processing 或编译。
在这种情况下,工具 driver 代表我们在幕后调用 ld
添加额外的 linker 选项,这些选项对于语言是不变的
有问题,使我们不必在命令行上记住和重复样板文件。
ld
本身有一个 built-in 每个体系结构的默认 -L
目录列表
它支持。这些是由构建你的 ld
的人配置的,通常是你的发行版,
在这种情况下,您会发现默认位置是库所在的目录
通常由您的发行版的包管理器安装。
因此,如果您想 link 一个位于默认位置之一的库,您不需要
需要自己指定任何 -L
选项。 -lfoo
可以。
相反,如果您希望能够 link libfoo.a
通过在 linkage 命令行中提及 -lfoo
,然后您需要将其放入
linker 的默认位置之一。如果你想分发 libfoo.a
这样的
其他用户可以用同样的方式 link 的方式,那么你需要分发
它在一个包中,将把它安装在默认位置之一(在目标上
系统,无论它是什么)。
为此,您需要知道默认位置是什么。对于 Posix 系统,
您可以依赖 /usr/local/lib
、/lib
和 /usr/lib
。但不要安装在 /lib
中。
这是为重要的系统库保留的。看看linker的默认搜索是什么
目录实际上在你自己的系统上,你可以 运行:
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,按顺序排列。
请注意,您必须选择 linkage 的 64/32 位风格
很关心。将 -m64
替换为 -m32
,你会得到一些东西
不同的。可移植的 Posix 选项,不包括 /lib
,是 /usr/local/lib
和 /usr/lib
.
这回答了你的问题,但你还没有完成。据推测,你的图书馆
附带一个或多个 header 文件,程序可以通过这些文件导入其 API。
如果库将位于 linker 的默认搜索路径中,则 header(s)
最好在 编译器的 默认搜索路径中,以便程序可以
只是 #include <foo.h>
或 #include <foo/bar.h>
并让编译器
无需在编译器命令行中编写 -I/foo/headers/are/here
即可找到 header。
要查看编译器的默认搜索路径,对于 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 选项
header 是 /usr/local/include
和 /usr/include
.
所以这是/usr/local/{include|lib}
和/usr/{include|lib}
之间的选择。但考虑到
在 /usr/{include|lib}
下安装您的文件,您将更改
以不受控制的方式清点发行版的库和 header 文件
通过其包管理系统。如果是,比方说,Debian 8.2,它就不会再存在了。
一旦你开始这样做,一旦你犯了错误的一步并破坏了你的包裹,
这完全是你的问题。
Unix 和 Linux 对安装您构建的软件有一个约定
你自己或来自你的发行版包管理不受控制的源包
系统,明智地捍卫您的发行版的稳定性。惯例是:
安装在 /usr/local/{include|bin|lib}
中。这正是 /usr/local
的意思
为了。
底线:在 /usr/local/lib
下安装你的库,在 header 下安装你的库
/usr/local/include
。如果你有多个 header,那么更喜欢 /usr/local/include/foo
在程序源码中写上#include <foo/bar.h>
之类的。那么你也能
编译时没有特殊 -I
选项,link 库没有特殊 -L
选项,只是 -lfoo
.