简体   繁体   中英

Static linking in CMake

My goal is to be able to deliver, as close as possible, a single executable and hence I'm aiming for aiming as much as possible statically. But I've now run into some issues with libc. I get these errors when building my project:

/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'

After search for a while I found that adding --static-libgcc and -static-libstdc++ should fix it, but it seems not.

I'm building this on Ubuntu.

Here's my main 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)

And here's the server/CMakeLists.txt:

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

The linking output for server looks like this:

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

If you have general suggestions or improvements and not just a way to solve this problem I'm interested in those as well.

I've had similar problems with static linking. I would suggest several things to try:

1) Attempt to statically link step by step (start with all dynamic and add one static library at a time). This way you can debug exactly the library that breaks your build.

2) Providing full path to the static library that you are using ie instead of "-Bstatic -lpthread" you can do "/usr/lib/..../libpthread.a". I was using this for cross compilation, but it should help in your case as well.

Using 1 and 2, you can figure out what library breaks your build and use the dynamic version of that library. In your case it looks like it is libpthread, so you can try the dynamic version of libpthread, but the error messages are sometimes deceiving. Let me know if this helps or if you run into other errors.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM