zoukankan      html  css  js  c++  java
  • 库文件的使用

    背景:

    初学者经常搞不清楚,一个main.cpp文件,调用了某库(可能静态也可动态)中的函数,如何将它跑起来。

    编译:

    g++ -c main.cpp
    main.cpp:3:26: fatal error: leveldb/db.h: No such file or directory
     #include "leveldb/db.h"
                              ^
    compilation terminated.
    缺少头文件,加上再编译(编译只与头文件有关,不需要关注库):
    g++ -c main.cpp -I/home/ww/2.src/leveldb/include
    
    OK,生成main.o
     
    链接:
    • 先考虑链接静态库的情况(同时存在动态和静态库的情况下,默认使用静态库)。
    g++ -o main main.o -L/home/ww/2.src/leveldb/out-static -lleveldb -lpthread

    OK,执行正常。

    • 如果是动态库的链接,链接方法是一样:
    g++ -o main main.o -L/home/ww/2.src/leveldb/out-shared -lleveldb -lpthread
    

    但这个可执行文件是跑不了的:

    ldd main
            linux-vdso.so.1 (0x00007fffd58f2000)
            libleveldb.so.1 => not found
            libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007fbb4a509000)
            libstdc++.so.6 => /usr/lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007fbb4a1fe000)
            libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007fbb49efd000)
            libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007fbb49ce7000)
            libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fbb4993c000)
            /lib64/ld-linux-x86-64.so.2 (0x00007fbb4a726000)
    
    ./main
    ./main: error while loading shared libraries: libleveldb.so.1: cannot open shared object file: No such file or directory
    
    因为动态库不仅在编译(具体来看是链接)时要被搜索,在二进制文件加载和执行时也要搜索。上面的例子仅指定了链接时的搜索。
     
    看下文档对于动态库的说明:
    linux程序跑时,program loader会自动被加载并跑起来(即上面加红的/lib64/ld-linux-x86-64.so.2 (0x00007ff40629d000) )。它作用是找到当前程序依赖的各个库文件,并加载它们。

    loader找到动态库文件有几种方法:

    1. ldconfig
    这是最正式的方法,正式发布都应该使用这种方法。
    默认的loader搜索动态库的路径在 /etc/ld.so.conf定义。
    如:
    ww@iZj6c1oc6sq0uze89upki0Z:/etc/ld.so.conf.d$ cat *
    /usr/lib/x86_64-linux-gnu/libfakeroot
    # libc default configuration
    /usr/local/lib
    # Multiarch support
    /lib/x86_64-linux-gnu
    /usr/lib/x86_64-linux-gnu
    

    因此,需要将动态库放到对应的地点,并对应修改或增加.conf文件。

    之后,需要调用ldconfig。它的作用是建立起加载所需要的符号缓存。这里不做示例。

    1. prelaod
    这种方式适用于需要部分替换已有库文件中的一些方法。当然也能作为加载路径使用。具体使用是使用LD_PRELOAD环境变量:
    LD_PRELOAD=/home/ww/2.src/leveldb/out-shared/libleveldb.so ./main
    Open db OK
    1. LD_LIBRARY_PATH
    export LD_LIBRARY_PATH=/home/ww/2.src/leveldb/out-shared:${LD_LIBRARY_PATH}
    
    ldd main
            linux-vdso.so.1 (0x00007ffe239f5000)
            libleveldb.so.1 => /home/ww/2.src/leveldb/out-shared/libleveldb.so.1 (0x00007ff405fe6000)
            libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007ff405dc9000)
            libstdc++.so.6 => /usr/lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007ff405abe000)
            libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007ff4057bd000)
            libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007ff4055a7000)
            libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007ff4051fc000)
            /lib64/ld-linux-x86-64.so.2 (0x00007ff40629d000)
    调试时用此方法比较方便,正式场合也可用。但它有一些潜在的问题:
    - 由于安全原因,在使用setuid的情况下不会生效。具体见参考文献。
     
    1. 直接使用loader指定路径调用
    /lib64/ld-linux-x86-64.so.2 --library-path /home/ww/2.src/leveldb/out-shared ./main
    Open db OK
    调试使用。

    参考:

    【1】http://tldp.org/HOWTO/Program-Library-HOWTO/shared-libraries.html

    【2】http://xahlee.info/UnixResource_dir/_/ldpath.html

     
     
     
     
     
  • 相关阅读:
    最好用的html复制插件——Clipboard.js
    最好用的轮播插件——Swiper.js
    媒体查询
    函数防抖和节流
    JQ增删改查localStorage实现搜索历史功能
    vscode如何设置html模板
    js中innerHTML、outerHTML、innerText、outerText的区别
    JS实现一个简单的网页钟表
    Sql Server 2014完全卸载
    照片尺寸大小怎样换算?
  • 原文地址:https://www.cnblogs.com/qqmomery/p/6291583.html
Copyright © 2011-2022 走看看