[英]Static linking third party libraries together with my C++ wrapper code
I am working on a little project to understand the chain of compiler and linker better.我正在做一个小项目,以更好地了解编译器链和 linker。
Suppose that i have the libraries libfoo.a
and libbar.a
.假设我有库
libfoo.a
和libbar.a
。 I want to create a library libmy.a
, that acts like a wrapper or top level API to both libraries.我想创建一个库
libmy.a
,它就像两个库的包装器或顶级 API 。 The target is, that only libmy.a
should be required to build an executable, that uses my defined wrapper functions.目标是,只需要
libmy.a
来构建一个使用我定义的包装函数的可执行文件。 I created a cmake project and set up the library我创建了一个 cmake 项目并设置了库
cmake_minimum_required(VERSION 3.14)
project(Wrapper)
set(CMAKE_CXX_STANDARD 11)
add_library(my STATIC ${SOME_SRC_FILES})
#set up the lib/inc paths and libs to link
target_include_directories(my PUBLIC /path/to/Foo/inc/ /path/to/Bar/inc/)
target_link_directories(my PUBLIC /path/to/Foo/lib/ /path/to/Bar/lib)
target_link_libraries(my PUBLIC foo bar)
That works fine and there is no problem in compilation.这工作正常,编译没有问题。 However, if I try to reference the object from an external project, it tells me, that I have undefined references to the functions in
libfoo.a
and libbar.a
.但是,如果我尝试从外部项目引用 object,它会告诉我,我对
libfoo.a
和libbar.a
中的函数有未定义的引用。 As far as I understand the problem, the linker only creates a declaration in the libmy.a, without including its definition from the external library.据我了解这个问题,linker 只在 libmy.a 中创建一个声明,而不包括它从外部库中的定义。 I checked this by opening
libmy.a
with the nm libmy.a
command, where the used functions of the external libraries are declared, but undefined.我通过使用
nm libmy.a
命令打开libmy.a
来检查这一点,其中声明了外部库的使用函数,但未定义。
I came across one solution that used ar
to combine multiple library files.我遇到了一种使用
ar
组合多个库文件的解决方案。 However I would like to avoid such methods, because if it is not a single library, but a bunch of, say 10 libraries, it is not suitable to search each library for a definition and copy it into libmy.a
.但是我想避免这种方法,因为如果它不是一个库,而是一堆,比如 10 个库,不适合在每个库中搜索定义并将其复制到
libmy.a
中。 Just throwing all libraries together isn't a solution either, because the file will get too big.将所有库放在一起也不是解决方案,因为文件会变得太大。
Is it importand to note, that one of these library packages is CUDA?重要的是要注意,这些库包之一是 CUDA?
I am sure there is a solution, but I was not able to find one.我确信有一个解决方案,但我找不到一个。 Any help would be appreciated
任何帮助,将不胜感激
The target is, that only
libmy.a
should be required to build an executable目标是,构建可执行文件只需要
libmy.a
This is already an unconventional goal for static libraries.对于 static 库来说,这已经是一个非常规的目标。
Static libraries normally only contain the object code built from the source code for that library . Static 库通常只包含从该库的源代码构建的 object 代码。 Users of that library must also link to the libraries that your library requires, because the definitions have not been copied in to your library when it was built.
该库的用户还必须链接到您的库所需的库,因为在构建库时定义尚未复制到您的库中。
Tools like ar
can be used to combine multiple static libraries together, since they are just archives of object code.像
ar
这样的工具可用于将多个 static 库组合在一起,因为它们只是 object 代码的存档。 The tool can not predict which object code the end-user will use though, so it will bundle entire libraries.该工具无法预测最终用户将使用哪个 object 代码,因此它将捆绑整个库。 Otherwise, the end user may be looking for a definition that you left out and then need to link in a 2nd copy of the dependency lib anyways.
否则,最终用户可能正在寻找您遗漏的定义,然后无论如何都需要链接到依赖库的第二个副本。
If you want to provide a library that has everything the end-user needs, cut down to what your wrapper actually uses, you can build a shared library.如果您想提供一个包含最终用户需要的所有内容的库,减少到您的包装器实际使用的内容,您可以构建一个共享库。 Shared libraries are considered executable, so the compiler knows that any unreferenced object code is not going to be used, and it will not be included in the shared library.
共享库被认为是可执行的,因此编译器知道任何未引用的 object 代码都不会被使用,也不会包含在共享库中。
You can force the entire static libraries to be included in shared libraries though.您可以强制将整个 static 库包含在共享库中。
On GCC you can use the linker argument: --whole-archive
to ensure that all of the object code from the following libraries is included.在 GCC 上,您可以使用 linker 参数:--whole
--whole-archive
以确保包含以下库中的所有 object 代码。
On MSVC, you can use the /WHOLEARCHIVE:<library file name>
argument to do the same.在 MSVC 上,您可以使用
/WHOLEARCHIVE:<library file name>
参数来执行相同的操作。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.