Статическая линковка в CMake

0

Моя цель состоит в том, чтобы иметь возможность максимально приблизить один исполняемый файл, и поэтому я стараюсь как можно более статически ставить цели. Но теперь у меня есть проблемы с 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

Если у вас есть общие предложения или улучшения, а не просто способ решить эту проблему, я тоже заинтересован в них.

Теги:
cmake

1 ответ

3

У меня были аналогичные проблемы со статической связью. Я бы предложил несколько вещей, чтобы попробовать:

1) Постарайтесь статически связывать шаг за шагом (начинайте со всех динамических и добавляйте одну статическую библиотеку за раз). Таким образом вы можете отлаживать именно библиотеку, которая разбивает вашу сборку.

2) Предоставление полного пути к статической библиотеке, которую вы используете, вместо "-Bstatic -lpthread" вы можете сделать "/usr/lib/..../libpthread.a". Я использовал это для кросс-компиляции, но это также должно помочь в вашем случае.

Используя 1 и 2, вы можете выяснить, какая библиотека разбивает вашу сборку и использует динамическую версию этой библиотеки. В вашем случае это похоже на libpthread, поэтому вы можете попробовать динамическую версию libpthread, но сообщения об ошибках иногда обманывают. Дайте мне знать, если это поможет, или если вы столкнетесь с другими ошибками.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню