gcc不同的静态链接方式导致编译结果不同

different static linking ways of gcc cause different compilation results

我使用的是msgpack-c 1.0.0,当我编译下面的程序时失败了:

#include <msgpack.h>
#include <stdio.h>

int main(void) {

    /* creates buffer and serializer instance. */
    msgpack_sbuffer* buffer = msgpack_sbuffer_new();
    msgpack_packer* pk = msgpack_packer_new(buffer, msgpack_sbuffer_write);

    int j;

    for(j = 0; j<23; j++) {
        /* NB: the buffer needs to be cleared on each iteration */
        msgpack_sbuffer_clear(buffer);

        /* serializes ["Hello", "MessagePack"]. */
        msgpack_pack_array(pk, 3);
        msgpack_pack_str(pk, 5);
        msgpack_pack_str_body(pk, "Hello", 5);
        msgpack_pack_str(pk, 11);
        msgpack_pack_str_body(pk, "MessagePack", 11);
        msgpack_pack_int(pk, j);

        /* deserialize the buffer into msgpack_object instance. */
        /* deserialized object is valid during the msgpack_zone instance alive. */
        msgpack_zone mempool;
        msgpack_zone_init(&mempool, 2048);

        msgpack_object deserialized;
        msgpack_unpack(buffer->data, buffer->size, NULL, &mempool, &deserialized);

        /* print the deserialized object. */
        msgpack_object_print(stdout, deserialized);
        puts("");

        msgpack_zone_destroy(&mempool);
    }

    /* cleaninstrong textg */
    msgpack_sbuffer_free(buffer);
    msgpack_packer_free(pk);
}

输出是:

[biao.zhang@ip-10-18-0-42 ~]$ gcc b.c -Icustom_apps/include/ -L/home/biao.zhang/custom_apps/lib/libmsgpack.a
/tmp/ccZKJsdv.o: In function `main':
b.c:(.text+0x685): undefined reference to `msgpack_zone_init'
b.c:(.text+0x6af): undefined reference to `msgpack_unpack'
b.c:(.text+0x6d8): undefined reference to `msgpack_object_print'
b.c:(.text+0x6ee): undefined reference to `msgpack_zone_destroy'
collect2: error: ld returned 1 exit status

但是当我用不同的方式静态 link 相同的库时,它可以成功编译并且 运行 成功:

[biao.zhang@ip-10-18-0-42 ~]$ gcc b.c -Icustom_apps/include/ -Lcustom_apps/lib -Wl,-Bstatic -lmsgpack -Wl,-Bdynamic
[biao.zhang@ip-10-18-0-42 ~]$ ldd a.out
    linux-vdso.so.1 =>  (0x00007fff892c5000)
    libc.so.6 => /lib64/libc.so.6 (0x00007fef6c221000)
    /lib64/ld-linux-x86-64.so.2 (0x00007fef6c5ef000)

静态linking的两种方式有什么区别吗?有什么建议吗?

gcc

  • -L 选项是提供 库的路径 .

    (你的第一个案例,它实际上并没有 link 与图书馆。因此,未定义的引用)。

  • -l选项是提供库的名字

    (你的第二种情况,其实是links与指定的库)

进一步阅读:联机 gcc 帮助手册 for -l and for -L