0

How do I point find_package() to my "custom" directory $SYSROOT/usr/lib/arm-linux-gnueabihf/ so it can find libz.so ?

I have a library in this location:

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

With a header that can be found here:

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

With CMake I try:

cmake_minimum_required(VERSION 3.18)
find_package(ZLIB REQUIRED)

Which results in:

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")

So CMake cannot find ZLIB_LIBRARY (libz.so) but it can parse the version (1.2.11) from the header file.

I set my SYSROOT in CMake like this:

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

But it seems CMake doesn't know about usr/lib/arm-linux-gnueabihf/libz.so.

What I tried

I tried to give HINTS or PATH to find_package like this:

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

or like this:

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

But it results in this error message:

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.

extra info

Here is the contents of my toolchain file that I use (targeting raspberry pi 4) with -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)
sf033
  • 107
  • 10
  • have you print the path and check if env variable `sysroot_dir` is what you expect? [This](https://stackoverflow.com/a/9328525/4123703) would help. – Louis Go Aug 09 '21 at 06:57
  • @LouisGo `sysroot_dir` is a variable I created and is an absolute path to the `sysroot` dir, in my OP example this would be `/home/bla/sysroot`, in reality the path is different but the idea is the same. The CMake variable printer you linked is a helpful snippet though, I did not know that. Thanks! – sf033 Aug 09 '21 at 07:04
  • 1
    In your post I didn't see any lines setting `CMAKE_SYSROOT`. You may update it for clarification. – Louis Go Aug 09 '21 at 07:31
  • @LouisGo Updated post (at the bottom) with my toolchain file. – sf033 Aug 09 '21 at 07:39
  • @LouisGo I got it to work. Your suggestion was on point. My toolchain file did not contain `CMAKE_SYSROOT`. Setting this variable made `find_package()` find my packages. Add it as an answer and I will accept it. – sf033 Aug 09 '21 at 07:57

3 Answers3

2

FWIW, I have used toolchain files like this for cross-compiling:

# 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)

I am not exactly sure, but it could be that those last 2 lines are overriding something:

SET(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
SET(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)

I would try removing those.

Also, I would try to periodically try to delete the entire build folder and start over because CMake caches a lot of things. It could be that something is getting cached (a path to some library NOT in your specific sysroot) that is messing up the configuration process.

bremen_matt
  • 6,902
  • 7
  • 42
  • 90
  • Thanks for your snippet. It helps. It turns out I needed `CMAKE_SYSROOT`. To add to the confusion, CMake caches a lot, so I also needed to invalidate the caches - like you suggested. – sf033 Aug 09 '21 at 07:55
  • I would suggest writing your own answer to the question. It will likely help you and others in the future. – bremen_matt Aug 09 '21 at 08:01
  • I'm waiting on @LouisGo to post the answer as technically he hinted at the absence of `CMAKE_SYSROOT` – sf033 Aug 09 '21 at 08:08
  • I would post it before you forget. Life is busy. You can always mark his answer as the correct one if he posts it – bremen_matt Aug 09 '21 at 08:10
  • In fact CMake doesn't suggest to remove the entire build folder, but I got burnt for that several times. I agree delete the full directory worth a try when you have no clues. – Louis Go Aug 09 '21 at 08:38
1

A handy way to check if your variable is as expected.

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

You should change sysroot's value by set(CMAKE_SYSROOT /your/path) instead of set(sysroot /your/path) which directly set the variable inside cmake.

Reference here

Louis Go
  • 2,213
  • 2
  • 16
  • 29
  • 1
    I knew about `message(STATUS ...)` - I use it all the time. The issue was that I did not know about `CMAKE_SYSROOT`. Thank you for the help! – sf033 Aug 09 '21 at 08:39
0

The issue was that I forgot to add CMAKE_SYSROOT to my toolchain file. Without this, CMake cannot find the libraries in $SYSROOT/usr/lib/arm-linux-gnueabihf.

sf033
  • 107
  • 10