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