Как заставить CMake найти библиотеку в произвольном месте (кросс-компилировать raspberry pi 4)

avatar
sf033
9 августа 2021 в 06:54
564
3
0

Как указать find_package() на мой "пользовательский" каталог $SYSROOT/usr/lib/arm-linux-gnueabihf/, чтобы он мог найти libz.so ?

У меня есть библиотека по этому адресу:

/home/user/bla/sysroot/usr/lib/arm-linux-gnueabihf/libz.so

С заголовком, который можно найти здесь:

/home/user/bla/sysroot/usr/include/zlib.h

С CMake я пытаюсь:

cmake_minimum_required(VERSION 3.18)
find_package(ZLIB REQUIRED)

Что приводит к:

CMake Error at /home/user/cmake/linux/share/cmake-3.19/Modules/FindPackageHandleStandardArgs.cmake:218 (message):
  Could NOT find ZLIB (missing: ZLIB_LIBRARY) (found version "1.2.11")

Поэтому CMake не может найти ZLIB_LIBRARY (libz.so), но может проанализировать версию (1.2.11) из файла заголовка.

Я установил свой SYSROOT в CMake следующим образом:

SET(CMAKE_FIND_ROOT_PATH "${toolchain_dir}/sysroot/")

Но похоже, что CMake не знает о usr/lib/arm-linux-gnueabihf/libz.so.

Что я пробовал

Я пытался дать ПОДСКАЗКИ или ПУТЬ к find_package следующим образом:

find_package(ZLIB REQUIRED HINTS "${sysroot_dir}/usr/lib/arm-linux-gnueabihf/" NO_DEFAULT_PATH)

или вот так:

find_package(ZLIB REQUIRED PATH "${sysroot_dir}/usr/lib/arm-linux-gnueabihf/" NO_DEFAULT_PATH)

Но это приводит к следующему сообщению об ошибке:

CMake Error at CMakeLists.txt:12 (find_package):
  Could not find a package configuration file provided by "ZLIB" with any of
  the following names:

    ZLIBConfig.cmake
    zlib-config.cmake

  Add the installation prefix of "ZLIB" to CMAKE_PREFIX_PATH or set
  "ZLIB_DIR" to a directory containing one of the above files.  If "ZLIB"
  provides a separate development package or SDK, be sure it has been
  installed.

дополнительная информация

Вот содержимое моего файла цепочки инструментов, который я использую (нацеленный на raspberry pi 4) с -DCMAKE_TOOLCHAIN_FILE=/path/to/toolchain.cmake

# Define our host system
SET(CMAKE_SYSTEM_NAME Linux)
SET(CMAKE_SYSTEM_VERSION 1)

# toolchain
set(toolchain_dir "/home/user/bla")
set(sysroot_dir "${toolchain_dir}/sysroot")

SET(CMAKE_C_COMPILER "${toolchain_dir}/tools/gcc-linaro-7.5.0-2019.12-i686_arm-linux-gnueabihf/bin/arm-linux-gnueabihf-gcc")
SET(CMAKE_CXX_COMPILER "${toolchain_dir}/tools/gcc-linaro-7.5.0-2019.12-i686_arm-linux-gnueabihf/bin/arm-linux-gnueabihf-g++")

# Define the sysroot path for the RaspberryPi distribution
SET(CMAKE_FIND_ROOT_PATH "${toolchain_dir}/sysroot/")
message(STATUS "${CMAKE_FIND_ROOT_PATH}")

# Use our definitions for compiler tools
SET(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)

# Search for libraries and headers in the target directories only
SET(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
SET(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
Источник
Louis Go
9 августа 2021 в 06:57
0

Вы распечатали путь и проверили, соответствует ли переменная env sysroot_dir тому, что вы ожидаете? Это поможет.

sf033
9 августа 2021 в 07:04
0

@LouisGo sysroot_dir — это созданная мной переменная, которая представляет собой абсолютный путь к каталогу sysroot, в моем примере OP это будет /home/bla/sysroot, на самом деле путь другой, но идея та же. Связанный вами принтер переменных CMake является полезным фрагментом, хотя я этого не знал. Спасибо!

Louis Go
9 августа 2021 в 07:31
1

В вашем сообщении я не увидел ни одной строки с параметром CMAKE_SYSROOT. Вы можете обновить его для уточнения.

sf033
9 августа 2021 в 07:39
0

@LouisGo Обновленный пост (внизу) с моим файлом цепочки инструментов.

sf033
9 августа 2021 в 07:57
0

@LouisGo Я заставил это работать. Ваше предложение было в точку. Мой файл набора инструментов не содержал CMAKE_SYSROOT. Установка этой переменной заставила find_package() найти мои пакеты. Добавьте это как ответ, и я приму это.

Ответы (3)

avatar
Louis Go
9 августа 2021 в 08:35
1

Удобный способ проверить, соответствует ли ваша переменная ожидаемому.

message(STATUS "sysroot_dir: ${sysroot_dir}")

Вы должны изменить значение sysroot на set(CMAKE_SYSROOT /your/path) вместо set(sysroot /your/path), которое напрямую устанавливает переменную внутри cmake.

Ссылка здесь

sf033
9 августа 2021 в 08:39
1

Я знал про message(STATUS ...) — постоянно им пользуюсь. Проблема была в том, что я не знал о CMAKE_SYSROOT. Спасибо вам за помощь!

avatar
sf033
9 августа 2021 в 08:12
0

Проблема заключалась в том, что я забыл добавить CMAKE_SYSROOT в свой файл цепочки инструментов. Без этого CMake не может найти библиотеки в $SYSROOT/usr/lib/arm-linux-gnueabihf.

avatar
bremen_matt
9 августа 2021 в 07:46
2

FWIW, я использовал такие файлы набора инструментов для кросс-компиляции:

# cmake -DCMAKE_TOOLCHAIN_FILE=../cmake/arm32.cmake ..

# Define our host system
set(CMAKE_SYSTEM_NAME Linux)
set(CMAKE_SYSTEM_VERSION 1)
set(CMAKE_SYSTEM_PROCESSOR armv61)

# Define the cross compiler locations
set(CMAKE_C_COMPILER arm-linux-gnueabi-gcc)
set(CMAKE_CXX_COMPILER arm-linux-gnueabi-g++)

# Define the sysroot path for the RaspberryPi distribution in our tools folder
set(CMAKE_FIND_ROOT_PATH $ENV{AARCH64_LINUX_TOOLS_DIR}/aarch64-linux-gnu/sysroot)

# Use our definitions for compiler tools
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)

Я не совсем уверен, но может быть, что эти последние 2 строки что-то переопределяют:

SET(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
SET(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)

Я бы попробовал их удалить.

Кроме того, я бы попытался периодически пытаться удалить всю папку сборки и начать заново, потому что CMake кэширует много вещей. Возможно, что-то кэшируется (путь к какой-то библиотеке НЕ в вашем конкретном системном корне), что мешает процессу настройки.

sf033
9 августа 2021 в 07:55
0

Спасибо за ваш фрагмент. Это помогает. Оказывается, мне нужно было CMAKE_SYSROOT. Чтобы добавить путаницы, CMake много кеширует, поэтому мне также нужно было сделать кеши недействительными, как вы предложили.

bremen_matt
9 августа 2021 в 08:01
0

Предлагаю написать свой ответ на вопрос. Вероятно, это поможет вам и другим в будущем.

sf033
9 августа 2021 в 08:08
0

Я жду, когда @LouisGo опубликует ответ, поскольку технически он намекнул на отсутствие CMAKE_SYSROOT

bremen_matt
9 августа 2021 в 08:10
0

Я бы выложил, пока ты не забыл. Жизнь занята. Вы всегда можете отметить его ответ как правильный, если он опубликует его.

Louis Go
9 августа 2021 в 08:38
0

На самом деле CMake не предлагает удалить всю папку сборки, но я несколько раз обжигался за это. Я согласен удалить весь каталог, стоит попробовать, когда у вас нет подсказок.