CMake中的静态链接

时间:2014-03-22 08:33:32

标签: c++ cmake

我的目标是能够尽可能地提供单个可执行文件,因此我的目标是尽可能静态地瞄准。但我现在遇到了libc的一些问题。我在构建项目时遇到了这些错误:

/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../x86_64-linux-gnu/libpthread.a(pthread_create.o): In function `allocate_stack':
/build/buildd/eglibc-2.17/nptl/allocatestack.c:465: undefined reference to `_dl_stack_flags'
/build/buildd/eglibc-2.17/nptl/allocatestack.c:604: undefined reference to `_dl_stack_flags'
/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../x86_64-linux-gnu/libpthread.a(ptw-write.o): In function `__write_nocancel':
/build/buildd/eglibc-2.17/nptl/../sysdeps/unix/syscall-template.S:81: undefined reference to `__syscall_error'
/build/buildd/eglibc-2.17/nptl/../sysdeps/unix/syscall-template.S:81: undefined reference to `__syscall_error'
/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../x86_64-linux-gnu/libpthread.a(ptw-close.o): In function `__close_nocancel':
/build/buildd/eglibc-2.17/nptl/../sysdeps/unix/syscall-template.S:81: undefined reference to `__syscall_error'
/build/buildd/eglibc-2.17/nptl/../sysdeps/unix/syscall-template.S:81: undefined reference to `__syscall_error'
/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../x86_64-linux-gnu/libpthread.a(ptw-accept.o): In function `__accept_nocancel':
/build/buildd/eglibc-2.17/nptl/../sysdeps/unix/syscall-template.S:81: undefined reference to `__syscall_error'
/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../x86_64-linux-gnu/libpthread.a(ptw-accept.o):/build/buildd/eglibc-2.17/nptl/../sysdeps/unix/syscall-template.S:81: more undefined references to `__syscall_error' follow
/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../x86_64-linux-gnu/libpthread.a(nptl-init.o): In function `__pthread_initialize_minimal_internal':
/build/buildd/eglibc-2.17/nptl/nptl-init.c:285: undefined reference to `__libc_setup_tls'
/build/buildd/eglibc-2.17/nptl/nptl-init.c:303: undefined reference to `_dl_cpuclock_offset'
/build/buildd/eglibc-2.17/nptl/nptl-init.c:419: undefined reference to `_dl_pagesize'
/build/buildd/eglibc-2.17/nptl/nptl-init.c:445: undefined reference to `_dl_init_static_tls'
/build/buildd/eglibc-2.17/nptl/nptl-init.c:447: undefined reference to `_dl_wait_lookup_done'
/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../x86_64-linux-gnu/libpthread.a(nptl-init.o): In function `__pthread_get_minstack':
/build/buildd/eglibc-2.17/nptl/nptl-init.c:468: undefined reference to `_dl_pagesize'

搜索了一段时间后,我发现添加--static-libgcc and -static-libstdc++应该修复它,但似乎没有。

我正在Ubuntu上构建它。

这是我的主要CMakeLists.txt:

project(lillebror)
cmake_minimum_required(VERSION 2.8)
cmake_policy(SET CMP0015 NEW)

##########################
# Compiler Flags 
if(APPLE)
    ...snip...
else(UNIX)
    message("Building Lillebror on Linux")
    set(COVERAGEFLAG_CXX "-ftest-coverage -fprofile-arcs")
    set(COVERAGEFLAG_LINK "--coverage")
    set(LINKERFLAGS "-static-libgcc -static-libstdc++")
else()
    ...snip...
ENDIF()

set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -O0 -fno-inline ${COVERAGEFLAG_CXX} -D__GLIBCXX_DEBUG")
set(CMAKE_EXE_LINKER_FLAGS_DEBUG "${CMAKE_EXE_LINKER_FLAGS_DEBUG} ${COVERAGEFLAG_LINK} ${LINKERFLAGS}")

add_definitions(-std=c++11)

##########################
# Packages and libraries

set(CMAKE_FIND_LIBRARY_SUFFIXES ${CMAKE_STATIC_LIBRARY_SUFFIX})

set(Boost_USE_STATIC_LIBS ON)
set(Boost_USE_MULTITHREADED ON)
set(Boost_USE_STATIC_RUNTIME OFF)
find_package(Boost 1.54 COMPONENTS date_time log filesystem thread system unit_test_framework REQUIRED)

find_package(Protobuf REQUIRED)

include_directories(/usr/local/include/botan-1.11/)
set(BOTAN_LIBRARY botan-1.11)

##########################
# Source

add_subdirectory(messages)
include_directories(${ProtoBufIncludePath})
add_subdirectory(core)
include_directories(core)

add_subdirectory(server)

##########################
# Tests

#add_subdirectory(mocks)
#include_directories(mocks)
#include(CTest)
#enable_testing()
#add_subdirectory(test)

这是服务器/ CMakeLists.txt:

aux_source_directory(. SRC_LIST)
add_executable(server ${SRC_LIST})
target_link_libraries(server core ${Boost_LIBRARIES})

服务器的链接输出如下所示:

Linking CXX executable server
cd /home/dutt/workspace/lillebror/build/server && /usr/bin/cmake -E cmake_link_script CMakeFiles/server.dir/link.txt --verbose=1
/usr/bin/c++   -g -O0 -fno-inline -ftest-coverage -fprofile-arcs -D__GLIBCXX_DEBUG     --coverage -static-libgcc -static-libstdc++ 
CMakeFiles/server.dir/main.cpp.o  -o server -rdynamic ../core/libcore.a 
-Wl,-Bstatic -lboost_date_time -lboost_log -lboost_filesystem -lboost_thread -lboost_system -lboost_unit_test_framework 
-lpthread ../messages/libmessages.a -lboost_date_time -lboost_log -lboost_filesystem
-lboost_thread -lboost_system -lboost_unit_test_framework -lpthread -lprotobuf -Wl,-Bdynamic

如果您有一般性的建议或改进,而不仅仅是解决这个问题的方法,我也对这些问题感兴趣。

1 个答案:

答案 0 :(得分:3)

我在静态链接方面遇到了类似的问题。我建议尝试几件事:

1)尝试逐步静态链接(从所有动态开始并一次添加一个静态库)。这样,您就可以完全调试破坏构建的库。

2)提供您正在使用的静态库的完整路径,即代替" -Bstatic -lpthread"你可以做" / usr / lib /..../ libpthread.a"。我正在使用它进行交叉编译,但它也应该对你的情况有帮助。

使用1和2,您可以找出哪个库破坏了您的构建并使用该库的动态版本。在你的情况下,它看起来像是libpthread,所以你可以尝试动态版本的libpthread,但错误消息有时是欺骗性的。如果这有帮助或者您遇到其他错误,请告诉我。