éta*_*ogy 4 c linux bash gcc dynamic-linking
如何"注册"我的库foo.c,编译到libfoo.so,链接它-lfoo?是通过追加它的路径LD_LIBRARY_PATH?是跑步sudo ldconfig吗?
为了好奇,我该把它"注册"给谁?也就是说,哪个应用程序"需要知道"是什么-lfoo意思才能gcc bar.c -lfoo工作?这是bash环境吗?是gcc吗?是内核吗?
静态库(例如libfoo.a)是否有任何不同之处?
如果您的库不在(例如.或)的" 标准 "库目录中,那么在链接它时您需要告诉编译器它的位置:/usr/local/lib/usr/lib-L-l
$ gcc -L/home/username/foo -Wall -o test main.c -lfoo
| |
|__ location of libfoo.so or libfoo.a |__ link libfoo.so or libfoo.a
Run Code Online (Sandbox Code Playgroud)
GCC假设所有库都以'lib'开头,以.so或.a结尾(.so用于共享对象或共享库,.a用于存档或静态链接库).
-L 是搜索链接到可执行文件的库的位置
-l将库链接到可执行文件(-lfoo可以翻译为"链接库libfoo.so")
使用共享库时,有时仅仅链接它们是不够的(例如,如果库未安装在标准位置,例如上面显示的示例).这是使用LD_LIBRARY_PATH,rpath或ldcondig进场.静态库路径不需要像共享库一样设置,因为它们是使用可执行文件编译的.
$ export LD_LIBRARY_PATH=/home/username/foo:$LD_LIBRARY_PATH
Run Code Online (Sandbox Code Playgroud)
导出此变量会通知运行时链接程序在指定位置查找libfoo.so与可执行文件关联的库.LD_LIBRARY_PATH或多或少是设置图书馆位置的临时或便捷方式.
$ gcc -L/home/username/foo -Wl,-rpath=/home/username/foo -Wall -o test main.c -lfoo
Run Code Online (Sandbox Code Playgroud)
rpath类似于LD_LIBRARY_PATH(因为库几乎可以驻留在userland中的任何位置),但是,rpath它在编译时链接到可执行文件,并设置"固定"库位置.
最终可能是最佳解决方案是使用ldconfig,它为标准库位置和您可以指定的最新共享库创建必要的链接和缓存.它确实需要提升权限(例如sudo)以这种方式设置路径,并且应该在一定程度上谨慎使用.
$ sudo cp /home/username/foo/libfoo.so /usr/local/lib
$ sudo chmod 0755 /usr/local/lib/libfoo.so
Run Code Online (Sandbox Code Playgroud)
这会将库复制到/usr/local/lib设置为每个人都可读的权限.
$ sudo ldconfig
$ ldconfig -p | grep foo
libfoo.so (libc6) => /usr/local/lib/libfoo.so
Run Code Online (Sandbox Code Playgroud)
然后我们更新加载器缓存,并验证路径是否设置正确.
$ gcc -Wall -o test main.c -lfoo
Run Code Online (Sandbox Code Playgroud)
通过使用ldconfig,-L选项,LD_LIBRARY_PATH或rpath现在不应该需要.
附加信息