Кросс-компиляция и ссылки на библиотеку в sysroot - что не так? - PullRequest
0 голосов
/ 24 сентября 2019

Я неопытный, но мне стало ясно, что мне не хватает фундаментального понимания в области кросс-компиляции и sysroots.Я надеюсь, что кто-то может предоставить мне тот драгоценный камень информации, который мне нужен для продолжения.

Я скачал предварительно собранный кросс-компилятор / toolchain armhf gcc, и он поставляется с каталогом arm-linux-gnueabihf, который содержитследующие каталоги:

bin/
include/
lib/  - contains libstdc++.a, libgcc_s.so, but does NOT contain `libcrypt.so` or `libcrypt.so.1`, etc.
libc/

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

libc/
     etc/
     lib/  - contains files like libcrypt.so.1 / libcrypt-2.24.so
     sbin/
     usr/
         bin/
         include/
         lib/  - contains files like libc.a, libc.so, libcrypt.a, libcrypt.so, 
         libexec/
         sbin/
         share/
     var/

В любом случае, я не уверен, что это проблема, или еслиЯ должен объединить эти два системных корня в один

Я установил его в контейнере Docker по пути /cross-pi-gcc-9.1.0-1.Я использую cmake для кросс-компиляции, и мой файл toolchain.cmake ссылается на эту цепочку инструментов:

SET(CMAKE_SYSTEM_NAME Linux)
SET(CMAKE_SYSTEM_VERSION 1)
SET(CMAKE_C_COMPILER /cross-pi-gcc-9.1.0-1/bin/arm-linux-gnueabihf-gcc)
SET(CMAKE_CXX_COMPILER /cross-pi-gcc-9.1.0-1/bin/arm-linux-gnueabihf-g++)
SET(CMAKE_FIND_ROOT_PATH /cross-pi-gcc-9.1.0-1/arm-linux-gnueabihf/)
SET(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
SET(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
SET(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)

Этого достаточно для создания большей части кода с помощью кросс-компилятора (включая Boost).

Как часть этого контейнера, я хочу, чтобы WiringPi был установлен в sysroot, чтобы я мог создавать и связываться с ним.

Для этого я создал пользовательский файл CMakeLists.txt, который успешнособирает и устанавливает WiringPi:

cmake_minimum_required(VERSION 3.0)
project(WiringPi)
set(CMAKE_THREAD_PREFER_PTHREAD TRUE)
find_package(Threads REQUIRED)
add_library(wiringPi SHARED ads1115.c <snip a bunch of .c files>)
target_include_directories(wiringPi PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
target_link_libraries(wiringPi PUBLIC ${CMAKE_THREAD_LIBS_INIT} crypt m rt)
install(TARGETS wiringPi DESTINATION lib)
install(FILES ads1115.h <snip a bunch of .h files>
        DESTINATION include)

Это указывает на то, что результирующие libwiringpi.so должны быть связаны с libcrypt, libpthread, libm и librt.И если я запускаю целевой инструмент ldd на libwiringpi.so, он действительно показывает эти библиотеки как зависимости:

$ ldd libwiringPi.so 
    linux-vdso.so.1 (0x7eee6000)
    /usr/lib/arm-linux-gnueabihf/libarmmem-${PLATFORM}.so => /usr/lib/arm-linux-gnueabihf/libarmmem-v7l.so (0x76f0a000)
    libpthread.so.0 => /lib/arm-linux-gnueabihf/libpthread.so.0 (0x76ee0000)
    libcrypt.so.1 => /lib/arm-linux-gnueabihf/libcrypt.so.1 (0x76ea0000)
    libm.so.6 => /lib/arm-linux-gnueabihf/libm.so.6 (0x76e1e000)
    librt.so.1 => /lib/arm-linux-gnueabihf/librt.so.1 (0x76e07000)
    libc.so.6 => /lib/arm-linux-gnueabihf/libc.so.6 (0x76cb9000)
    /lib/ld-linux-armhf.so.3 (0x76f43000)

Проблема, с которой я столкнулся, заключается в том, что у меня есть приложение, которое связывается с wiringpi, используяСтрока cmake выглядит следующим образом:

target_link_libraries(myapp wiringPi)

Когда я строю это на Raspberry Pi с помощью встроенного набора инструментов, мне не нужно явно ссылаться на libcrypt.Но в моей среде Docker / кросс-компилятора я получаю эту ошибку во время ссылки:

/cross-pi-gcc-9.1.0-1/bin/arm-linux-gnueabihf-g++     CMakeFiles/app.dir/main.cpp.o   -o myapp -lpthread -lwiringPi -lrt 
/cross-pi-gcc-9.1.0-1/bin/../lib/gcc/arm-linux-gnueabihf/9.1.0/../../../../arm-linux-gnueabihf/bin/ld: warning: libcrypt.so.1, needed by /cross-pi-gcc-9.1.0-1/bin/../lib/gcc/arm-linux-gnueabihf/9.1.0/../../../../arm-linux-gnueabihf/lib/libwiringPi.so, not found (try using -rpath or -rpath-link)
/cross-pi-gcc-9.1.0-1/bin/../lib/gcc/arm-linux-gnueabihf/9.1.0/../../../../arm-linux-gnueabihf/lib/libwiringPi.so: undefined reference to `crypt@GLIBC_2.4'
collect2: error: ld returned 1 exit status

Обратите внимание, что -lrt и -lpthread, кажется, автоматически включены в список библиотеки ссылок.Но -lcrypt отсутствует.

Если я скопирую / вставлю вывод make VERBOSE=1, соответствующий этой ошибке, и вручную добавлю -lcrypt в конец команды, он успешно связывается и компиляция приложениязавершено.

Я понимаю, что это длинное описание, но в конечном итоге я пытаюсь найти дыру в моих знаниях, которая мешает мне понять, почему мне нужно явно связать libcrypt с этимприложения в этой среде.

Я бы подумал, возможно, неправильно, что, поскольку libwiringpi.so уже связан с libcrypt, его не нужно будет связывать на верхнем уровне.Если это не так, то есть кто-нибудь, кто может помочь мне восстановить мою ментальную модель, пожалуйста?

Примечание: я мог бы просто добавить target_link_libraries(myapp wiringPi crypt), однако я не думаю, что это необходимо (не нужно при сборке изначально)) и я хотел бы узнать немного больше о процессе, а не просто найти обходной путь.

1 Ответ

0 голосов
/ 27 сентября 2019

Отвечая на этот вопрос сам ...

Похоже, что наличие каталога libc в sysroot необычно, и я проверил другие цепочки инструментов, и он всегда был объединен с lib.Так что я закончил тем, что отказался от этого конкретного набора инструментов и собрал свой собственный вместо crosstool-ng.Это полностью исключило проблему.Было бы неплохо понять, как у меня это получилось, но сейчас я должен идти дальше.

Обратите внимание, что у меня был успех только с использованием только CMAKE_SYSROOT - в моем случае нет необходимости указывать CMAKE_FIND_ROOT_PATH и друзья.

...