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

时间:2015-04-30 08:17:31

标签: c gcc linker undefined-reference msgpack

我使用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

但是当我以不同的方式静态链接同一个库时,它可以成功编译并成功运行:

[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)

两种静态链接方式之间是否存在差异?有什么建议吗?

1 个答案:

答案 0 :(得分:1)

gcc

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

    (你的第一种情况,它实际上并不是链接与库。因此,未定义的引用)。

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

    (你的第二个案例,它实际上链接与指定的库)

进一步阅读:在线gcc帮助手册for -lfor -L