zoukankan      html  css  js  c++  java
  • 【转】链接任意目录下库文件(解决错误“/usr/bin/ld: cannot find -lxxx”

    netbeans构建项目也出现了同样的问题。猜测是netbeans内部就用的是-l 这种编译方式,所以需要把***.a手动改为lib***.a

    g++ 编译中链接库文件选项有: -L **  -lxxx

    其中 -L 告诉编译器哪里去寻找库文件,** 指的是库文件所在路径,xxx 是库文件的名称,那么-lxxx 告诉编译器去找库文件libxxx.a(而不是xxx.a)。

    如果生成的库文件时bplus.a ,就需要将其重命名为libbplus.a 这样才会找到该文件。否则,报如下错误

    /usr/bin/ld: cannot find -lbplus
    collect2: ld returned 1 exit status

    PS 

    1、linux库文件分为静态库和动态库两种。静态库习惯以.a 结尾,而动态库习惯以.so(shared object)结尾。而且必须以lib开头。

    2、静态库的原则是“以空间换时间”,增加程序体积,减少运行时间;

    生成:在编译时候,先生成目标文件.o,然后用ar文件对目标文件归档,生成静态库文件。

    例如:ar -rc libtest.a myalib.o (注意:ar -rc 目标 .o文件名),目标一定要以lib开头。

    3、使用时候,在链接时候,加上选项 -l 后接库文件名,注意:必须是文件名去掉后缀和lib,
    如:gcc -o main main.o -ltest 。而且-ltest必须放在main.o的后面,(规则是,越底层的库越要放在后面)。

    4、gcc的其他常用的选项,

    -c 编译成目标文件 如:gcc -c main.c 就是编译main.c成目标文件main.o

    -I 头文件的查找路径,如:gcc -c main.c -I./inc 意思是:头文件的查找路径除了默认的之外,再加上./inc目录下的。

    -L 库文件的查找路径,如:gcc -o main main.o -L./lib -ltest 说明:libtest.a 或者 libtest.so 库文件的查找路径除了默认之外,再加上./lib目录。

    -MM 导出文件的依赖关系(用#include 中的内容)如:gcc -MM main.c找出main.c的所依赖的头文件

    -o 生成最终目标

    -D宏定义 相当于在C中些语句#define ... 如:-DPI=3.14 就相当于在文件里面写语句#define PI 3.14

    5、动态库

    (1)、生成:在链接时,用如下选项:-shared -fpic 如: gcc -fpic -shared -o libtest.so myalib.c

    (2)、使用:有隐式使用和显示使用,隐式使用就是共享方式,程序一开始运行就调进去。在链接时候用如下:
    gcc -o main main.o -L./lib -ltest(像静态库的一样)

    显示使用就是在程序中用语句把动态库调进来,用系统调用:dlopen、dlsym、dlerror、dlclose函数,那样在编译链接时候,不用加上:-L./lib -ltest了。不过要使用dl*系列函数在编译链接时要加上 -ldl

    6、如果同一目录下,既有静态库也有动态库,比如libtest.a libtest.so都存在,那么dl程序(等一下介绍)就把动态库调进去,没有动态的,就找静态的。再没有,就报错。

    7、动态库的搜索路径

    dl对动态库的搜索路径如下(按顺序如下)

    a.编译目标代码时指定的动态库搜索路径;(如果要指定程序行时在./lib目录下找库文件libtest.so,命令如下:gcc -o main main.c -L./lib -ltest -Wl,-rpath ./lib) ,其中,-Wl的意思是,后面的选项直接交给ld程序处理,-rpath选项是说更改搜索路径为后面的参数./lib

    b.环境变量LD_LIBRARY_PATH指定的动态库搜索路径;

    c.配置文件/etc/ld.so.conf中指定的动态库搜索路径;(修改完文件后,用ldconfig更新)

    d.默认的动态库搜索路径/lib和/usr/lib;

    8、一些常用的命令(与库有关的)

    (1)、ld 是gcc的链接程序。

    (2)、ldd是查看可执行文件中所依赖的库的程序,比如想查main程序用到了那些动态库,可以直接
    ldd main

    (3)、ldconfig用来更新文件/etc/ld.so.conf的修改生效。

    (4)、nm用来查看.so库中的函数名字,标记是T的就是动态库里面生成的名字。如:nm /lib/libc*.so

  • 相关阅读:
    配置文件管理
    Nacos学习
    dockerCompose学习
    Dockerfile
    vue生命周期
    github使用
    推荐系统
    js笔记17
    js笔记16
    js笔记15
  • 原文地址:https://www.cnblogs.com/stevensfollower/p/4357194.html
Copyright © 2011-2022 走看看