首页 > 解决方案 > -static -lxyz 和 -l:libxyz.a 之间的区别

问题描述

对不起,我的英语很糟糕。我正在使用可视化代码,我的项目是 c++,-L./libs/curl/lib 仅包含 libcurl.a,即静态库当我使用此链接选项构建项目时,一切正常:

LDFLAGS = -static -L./libs/curl/lib -lcurl -lssl -lcrypto -lsqlite3 -lpthread -ldl -lz

但是当我使用这个链接选项时:

LDFLAGS = -L./libs/curl/lib -l:libcurl.a -l:libssl.a -l:libcrypto.a -l:libsqlite3.a -l:libpthread.a -l:libdl.a -l:libz.a

我收到了这个错误:

/usr/lib/gcc/x86_64-linux-gnu/7/../../../x86_64-linux-gnu/libpthread.a(pthread_create.o): In function `allocate_stack':
/build/glibc-2ORdQG/glibc-2.27/nptl/allocatestack.c:526: undefined reference to `_dl_stack_flags'
/build/glibc-2ORdQG/glibc-2.27/nptl/allocatestack.c:652: undefined reference to `_dl_stack_flags'
/usr/lib/gcc/x86_64-linux-gnu/7/../../../x86_64-linux-gnu/libpthread.a(elision-lock.o): In function `do_set_elision_enable':
/build/glibc-2ORdQG/glibc-2.27/nptl/../sysdeps/unix/sysv/linux/x86/elision-conf.c:67: undefined reference to `_dl_x86_cpu_features'
/usr/lib/gcc/x86_64-linux-gnu/7/../../../x86_64-linux-gnu/libpthread.a(nptl-init.o): In function `__pthread_initialize_minimal_internal':
/build/glibc-2ORdQG/glibc-2.27/nptl/nptl-init.c:294: undefined reference to `_dl_cpuclock_offset'
/build/glibc-2ORdQG/glibc-2.27/nptl/nptl-init.c:429: undefined reference to `_dl_pagesize'
/build/glibc-2ORdQG/glibc-2.27/nptl/nptl-init.c:438: undefined reference to `_dl_pagesize'
/build/glibc-2ORdQG/glibc-2.27/nptl/nptl-init.c:454: undefined reference to `_dl_init_static_tls'
/build/glibc-2ORdQG/glibc-2.27/nptl/nptl-init.c:456: undefined reference to `_dl_wait_lookup_done'
/usr/lib/gcc/x86_64-linux-gnu/7/../../../x86_64-linux-gnu/libpthread.a(nptl-init.o): In function `__pthread_get_minstack':
/build/glibc-2ORdQG/glibc-2.27/nptl/nptl-init.c:475: undefined reference to `_dl_pagesize'
/usr/lib/gcc/x86_64-linux-gnu/7/../../../x86_64-linux-gnu/libdl.a(dlopen.o): In function `dlopen':
(.text+0x5): undefined reference to `__dlopen'
/usr/lib/gcc/x86_64-linux-gnu/7/../../../x86_64-linux-gnu/libdl.a(dlclose.o): In function `dlclose':
(.text+0x1): undefined reference to `__dlclose'
/usr/lib/gcc/x86_64-linux-gnu/7/../../../x86_64-linux-gnu/libdl.a(dlsym.o): In function `dlsym':
(.text+0x5): undefined reference to `__dlsym'
/usr/lib/gcc/x86_64-linux-gnu/7/../../../x86_64-linux-gnu/libdl.a(dlerror.o): In function `dlerror':
(.text+0x1): undefined reference to `__dlerror'
/usr/lib/gcc/x86_64-linux-gnu/7/../../../x86_64-linux-gnu/libdl.a(dladdr.o): In function `dladdr':
(.text+0x1): undefined reference to `__dladdr'

所以我的问题是:

  1. -static -lxyz 和 -l:libxyz.a 链接选项有什么区别?
  2. -static 是否具有添加其他库的隐式链接?

标签: c++linux

解决方案


默认情况下 gcc 或 g++ 将链接到一些标准库。这些库的列表取决于体系结构,但您可以找到 libc libgcc 和其他一些库。要查看用于链接的库列表,您可以添加-v选项。您将看到传递给 collect2 的库列表。由于您正在为 x86_64 进行编译,因此列表可能是(libc、libgcc 和 libgcc_s)。

当您使用静态选项时,您强制链接器使用所有库的静态版本,您使用 -l 选项提供的库和默认库。

在第二种情况下,您为链接器提供库的静态版本,但对于其他库,它将采用共享版本。If both static and shared libraries are found, the linker gives preference to linking with the shared library unless the -static option is used.来自https://gcc.gnu.org/onlinedocs/gcc/Link-Options.html#Link-Options

最后一件事。如果您使用静态选项,crt 文件也会有所不同。-v您也可以通过选项查看它。

如果您想准确控制应该使用哪个库,可以选择nostdlib。使用此选项时,编译器在链接时不要使用标准的系统启动文件或库。没有启动文件,只有您指定的库被传递给链接器,并且指定系统库链接的选项(例如 -static-libgcc 或 -shared-libgcc)被忽略。


推荐阅读