[英]Problems compiling to a static library with CMake
I'm trying to compile a project into a statically linked library with CMake. 我正在尝试使用CMake将项目编译为静态链接库。 Here I'm checking if BFD
and Iberty
are availabe, and if they are I compile a modified backtrace-symbols.c
into an OBJECT
Library, and statically link that object into the project along with the BFD
, Iberty
, and DL
libraries it depends on. 在这里,我正在检查BFD
和Iberty
是否Iberty
,是否将它们修改后的backtrace-symbols.c
Iberty
编译到OBJECT
库中,并将该对象与BFD
, Iberty
和DL
库一起静态链接到项目中上。 When I try to use the resultant static library in a project, I get errors on BFD
functions that are used in backtrace-symbols.c
saying they are undefined. 当我尝试在项目中使用生成的静态库时,在backtrace-symbols.c
中使用的BFD
函数出现错误,提示它们未定义。
How can I ensure that BFD
, Iberty
, and DL
are also statically linked into this library so that the user won't have to worry about linking against them in their project? 如何确保BFD
, Iberty
和DL
也静态链接到该库中,以便用户不必担心在他们的项目中与它们链接?
cmake_minimum_required(VERSION 2.8)
project(simplog)
configure_file (
"SimpLogConfig.h.in"
"SimpLogConfig.h"
@ONLY
)
set( CMAKE_C_COMPILER "clang" )
find_library( BFD_LIBRARY bfd )
find_library( IBERTY_LIBRARY iberty )
find_path(
IBERTY_HEADER_PATH libiberty.h
PATHS
/usr/include/libiberty
/usr/local/include/libiberty.h
)
include_directories(
${IBERTY_HEADER_PATH}
${PROJECT_BINARY_DIR}
)
set( PACKAGE "SimpLog" )
set( PACKAGE_VERSION "0.0.1" )
if( BFD_LIBRARY AND IBERTY_LIBRARY )
option( BETTER_BACKTRACE "" ON )
add_library( backtrace-symbols OBJECT backtrace-symbols.c )
add_library( simplog STATIC simplog.c $<TARGET_OBJECTS:backtrace-symbols> )
target_link_libraries( simplog ${BFD_LIBRARY} ${IBERTY_LIBRARY} ${CMAKE_DL_LIBS} )
else()
option( BETTER_BACKTRACE "" OFF )
add_library( simplog STATIC simplog.c )
endif()
As pointed out in the comments, you cannot merge multiple static libraries into one. 如注释中所指出的,您不能将多个静态库合并为一个。 This is because most C++ compilers do not support this feature, so CMake also cannot support it without breaking half of its generators. 这是因为大多数C ++编译器不支持此功能,因此CMake在不破坏其一半生成器的情况下也无法支持该功能。
The way you solve this instead is by building dependency hierarchies using target_link_libraries
. 相反,解决此问题的方法是使用target_link_libraries
构建依赖关系层次结构。 In your case, it looks like backtrace_symbols
depends on iberty
and bfd
, while simplog
in turn depends on backtrace-symbols
. 在您的情况下, backtrace_symbols
取决于iberty
和bfd
,而simplog
则取决于backtrace-symbols
。 You can model those dependencies like this: 您可以像这样对那些依赖进行建模:
add_library( backtrace-symbols backtrace-symbols.c )
target_link_libraries( backtracesymbols ${IBERTY_LIBRARY} ${BFD_LIBRARY} )
add_library( simplog STATIC simplog.c )
target_link_libraries( simplog backtracesymbols )
Now any executable that links to simplog
will automatically pull in all dependencies in the correct order, including transitive ones. 现在,链接到simplog
任何可执行文件simplog
将以正确的顺序自动提取所有依赖项,包括传递性依赖项。 On the other hand, if you want to ship binaries of your library to other developers, you need to include not only the .a
file for simplog
, but also the ones for backtracesymbols
, iberty
and bfd
. 另一方面,如果要将库的二进制文件运送给其他开发人员,则不仅需要包括.a
文件用于simplog
,还需要包括用于backtracesymbols
, iberty
和bfd
。 If you want to ship only a single file, you have to make simplog
a dynamic library instead. 如果只想发送一个文件,则必须使simplog
成为动态库。
Ensure that you always specify library dependencies at the level in the hierarchy where they are first used! 确保始终在首次使用它们的层次结构中指定库依赖项! Even though the linker will only actually need them when linking the final executable, specifying them in this way ensures that the linker pulls them in in the right order. 即使链接器仅在链接最终的可执行文件时才真正需要它们,以这种方式指定它们也可以确保链接器以正确的顺序将它们拉出。 Failing to do so can lead to undefined symbol errors like those you experienced. 否则,可能会导致未定义的符号错误,如您遇到的错误。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.