我正在尝试使用CMake将项目编译为静态链接库。在这里,我正在检查BFD
和Iberty
是否可用,如果是,我将修改后的backtrace-symbols.c
编译到OBJECT
库中,并将该对象静态链接到项目中以及它所依赖的BFD
,Iberty
和DL
库。当我尝试在项目中使用生成的静态库时,我在BFD
中使用backtrace-symbols.c
函数时会出现错误,表示它们未定义。
如何确保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()
答案 0 :(得分:1)
正如评论中所指出的,您无法将多个静态库合并为一个。这是因为大多数C ++编译器不支持此功能,因此CMake也不能在不破坏其一半生成器的情况下支持它。
您解决此问题的方法是使用target_link_libraries
构建依赖关系层次结构。在您的情况下,看起来backtrace_symbols
取决于iberty
和bfd
,而simplog
又取决于backtrace-symbols
。您可以像这样建模这些依赖项:
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 )
现在任何链接到simplog
的可执行文件都会自动以正确的顺序提取所有依赖项,包括传递顺序。另一方面,如果您要将库的二进制文件发送给其他开发人员,则不仅要包含.a
的{{1}}文件,还要包含simplog
的文件{ {1}}和backtracesymbols
。如果您只想发送单个文件,则必须使iberty
成为动态库。
确保始终在首次使用它们的层次结构中指定库依赖项!尽管链接器在链接最终可执行文件时实际上只需要它们,但以这种方式指定它们可确保链接器以正确的顺序将它们拉入。 如果不这样做,可能会导致未定义的符号错误,如您所遇到的那样。