[cmake-developers] Building with Qt for the Raspberry Pi with CMake

Stephen Kelly steveire at gmail.com
Fri Apr 12 11:51:01 EDT 2013


Stephen Kelly wrote:

> However, the Raspberry Pi has libz.so in some funny locations:
> 
> stephen at hal:~/rpi/rasp-pi-rootfs$ find -name "*libz*"
> ./lib/arm-linux-gnueabihf/libz.so.1
> ./lib/arm-linux-gnueabihf/libz.so.1.2.7
> ./usr/lib/arm-linux-gnueabihf/libz.so
> ./usr/lib/arm-linux-gnueabihf/libz.a

This doesn't affect only Qt, but could affect any CMake user trying to use a 
library which depends on zlib on the Raspberry Pi.

 find_package(ZLIB REQUIRED)
 include_directories(${ZLIB_INCLUDE_DIRS})

 if (NOT USE_FOO)
   add_library(foo SHARED foo.cpp)
   target_link_libraries(foo LINK_PRIVATE ${ZLIB_LIBRARIES})

   export(TARGETS foo NAMESPACE FOO:: FILE fooTarget.cmake)

 else()
   set(CMAKE_INCLUDE_CURRENT_DIR ON)

   include("${CMAKE_CURRENT_BINARY_DIR}/fooTarget.cmake")

   set_property(TARGET FOO::foo APPEND PROPERTY 
IMPORTED_LINK_DEPENDENT_LIBRARIES_NOCONFIG "${ZLIB_LIBRARIES}")

 #   set(CMAKE_CXX_LINK_FLAGS "${CMAKE_CXX_LINK_FLAGS} -Wl,-rpath-link,
${CMAKE_FIND_ROOT_PATH}/lib/arm-linux-gnueabihf")

   add_executable(bar foo_user.cpp)
   target_link_libraries(bar FOO::foo)
 endif()

If execute that once with -DUSE_FOO=0 (and then make) and again with -
DUSE_FOO=1, the second make fails with 

 $ make
 makeobj[0]: Entering directory `/home/stephen/dev/src/playground/cmake/rpi'
 Linking CXX executable bar
 /home/stephen/rpi/gcc-4.7-linaro-rpi-gnueabihf/bin/../lib/gcc/arm-linux-
gnueabihf/4.7.2/../../../../arm-linux-gnueabihf/bin/ld: warning: libz.so.1, 
needed by libfoo.so, not found (try using -rpath or -rpath-link)
 CMakeFiles/bar.dir/empty.cpp.o: In function `main':
 empty.cpp:(.text+0x28): undefined reference to `compress2'
 collect2: error: ld returned 1 exit status
 make[2]: *** [bar] Error 1
 make[1]: *** [CMakeFiles/bar.dir/all] Error 2
 make: *** [all] Error 2
 makeobj[0]: Leaving directory `/home/stephen/dev/src/playground/cmake/rpi'


I can 'fix' that by uncommenting the line which adds a manual -rpath-link 
entry to the link flags. I don't think that's a very good fix though. 
Another workaround would be to also find and add the path to /lib/arm-linux-
gnueabihf/libz.so.1, in addition to the /usr/lib/arm-linux-gnueabihf/libz.so 
already found by FindZLIB.cmake and put that in the 
IMPORTED_LINK_DEPENDENT_LIBRARIES too. That's basically what I described in 
my initial mail.

I tried adding the needed directory to 
IMPORTED_LINK_DEPENDENT_LIBRARIES_NOCONFIG, but that didn't add to the 
rpath-link entries either:

  set_property(TARGET FOO::foo APPEND PROPERTY 
    IMPORTED_LINK_DEPENDENT_LIBRARIES_NOCONFIG 
      "${ZLIB_LIBRARIES}" 
      "/lib/arm-linux-gnueabihf"
 )

Do you think it should? At least that would be easier from a point of view 
of using the information from the Qt mkspec files, which lists the 
directories required to be in rpath-link already.

I also notice that IMPORTED_LINK_DEPENDENT_LIBRARIES_* entries are only 
populated on export for targets, not for 'raw' targets. So 

 target_link_libraries(foo LINK_PRIVATE /lib/libz.so)

will not add /lib/libz.so to the IMPORTED_LINK_DEPENDENT_LIBRARIES_* on 
export. Should it be allowed? It is possible to have a config file which 
includes the target file, and then sets the property as a workaround, which 
is similar to what I would be doing by populating it in the Qt config files.

If that shouldn't be allowed, do we need to design a better way to define 
the rpath-link entries that need to be used when using a target foo? It 
seems that some improvement in cmake would be beneficial here, and we just 
need to decide on what the change to cmake should look like.

Thanks,

Steve.





More information about the cmake-developers mailing list