[CMake] not found library with package configuration files and changed CMAKE_INSTALL_PREFIX

Alexander Dahl post at lespocky.de
Tue Sep 20 05:26:10 EDT 2011


Hello there, 

after using FindFOO.cmake scripts for our own projects for a long time
I'm trying to migrate this to the "real" CMake approach of package
configuration files. Therefor I read chapter 5.7 of the book »Mastering
CMake« and two HowTos [1] [2] on the web merging all of these in some
files. I have own shared C library "foo" and one C command line tool
"bar" and try to build this on Ubuntu Lucid 10.04 with a self compiled
cmake 2.8.4.

This works fine as long as I don't change CMAKE_INSTALL_PREFIX (with
`make edit_cache` or earlier when calling `cmake
-DCMAKE_INSTALL_PREFIX=/some/path /path/to/src`) and it is /usr/local –
however when changing this to /home/adahl/usr (or any other non standard
path) linking the library fails although the include files are still
found (FOO_DIR is correctly set to /home/adahl/usr/lib/cmake/foo).

I'll show my CMakeList.txt files and the package configuration stuff,
maybe someone could have a look and point me to my errors.

In project "foo" which builds a shared C library:

CMakeLists.txt:

  4 project(foo)
  5
  6 cmake_minimum_required(VERSION 2.8)
  7
  8 set(PACKAGE_MAJOR_VERSION "0")
  9 set(PACKAGE_MINOR_VERSION "1")
 10 set(PACKAGE_BUILD_VERSION "0")
 11 set(PACKAGE_VERSION
"${PACKAGE_MAJOR_VERSION}.${PACKAGE_MINOR_VERSION}.${PACKAGE_BUILD_VERSION}"
   )
 12
 13 add_subdirectory("inc")
 14 add_subdirectory("src")
 15
 16 configure_file(
 17     ${CMAKE_CURRENT_SOURCE_DIR}/foo-config.cmake.in
 18     ${CMAKE_CURRENT_BINARY_DIR}/foo-config.cmake @ONLY
 19 )
 20 configure_file(
 21     ${CMAKE_CURRENT_SOURCE_DIR}/foo-config-version.cmake.in
 22     ${CMAKE_CURRENT_BINARY_DIR}/foo-config-version.cmake @ONLY
 23 )
 24 install(FILES
 25     ${CMAKE_CURRENT_BINARY_DIR}/foo-config.cmake
 26     ${CMAKE_CURRENT_BINARY_DIR}/foo-config-version.cmake
 27     DESTINATION "lib/cmake/${PROJECT_NAME}"
 28 )

foo-config.cmake.in:

  4 get_filename_component(_dir "${CMAKE_CURRENT_LIST_FILE}" PATH)
  5 get_filename_component(_prefix "${_dir}/../../.." ABSOLUTE)
  6 include("${_dir}/@PROJECT_NAME at -targets.cmake")
  7 set(FOO_INCLUDE_DIRS "${_prefix}/include/@PROJECT_NAME@")

foo-config-version.cmake.in:

  4 set(PACKAGE_VERSION "@PACKAGE_VERSION@")
  5
  6 if("${PACKAGE_VERSION}" VERSION_LESS "${PACKAGE_FIND_VERSION}")
  7     set(PACKAGE_VERSION_COMPATIBLE FALSE)
  8 else()
  9     set(PACKAGE_VERSION_COMPATIBLE TRUE)
 10     if ("${PACKAGE_VERSION}" VERSION_EQUAL
"${PACKAGE_FIND_VERSION}")
 11         set(PACKAGE_VERSION_EXACT TRUE)
 12     endif()
 13 endif()

inc/CMakeLists.txt:

  4 install(FILES
  5     foo.h
  6     DESTINATION "include/${PROJECT_NAME}"
  7 )

src/CMakeLists.txt:

  4 set(FOO_SRC
  5     foo.c
  6 )
  7
  8 include_directories(
  9     "${PROJECT_SOURCE_DIR}/inc"
 10 )
 11
 12 add_library(${PROJECT_NAME}-shared SHARED ${FOO_SRC})
 13 set_target_properties(${PROJECT_NAME}-shared PROPERTIES
 14     OUTPUT_NAME ${PROJECT_NAME}
 15     SOVERSION   ${PACKAGE_MAJOR_VERSION}
 16     VERSION     ${PACKAGE_VERSION}
 17 )
 18 install(TARGETS ${PROJECT_NAME}-shared DESTINATION "lib" EXPORT
${PROJECT_NAME}-targets)
 19 install(EXPORT ${PROJECT_NAME}-targets DESTINATION
"lib/cmake/${PROJECT_NAME}")

This allows successful build of the library with all files installed
where they should be, at least binaries and header files. The package
configuration files are installed like this:

% ls -l /home/adahl/usr/lib/cmake/foo
insgesamt 16
-rw-r--r-- 1 adahl adahl  248 2011-09-20 11:09 foo-config.cmake
-rw-r--r-- 1 adahl adahl  334 2011-09-20 11:09 foo-config-version.cmake
-rw-r--r-- 1 adahl adahl  924 2011-09-20 11:09 foo-targets.cmake
-rw-r--r-- 1 adahl adahl 1041 2011-09-20 11:09
foo-targets-noconfig.cmake

Now first I build this library like this:

~/Work/build/libfoo % cmake -DCMAKE_INSTALL_PREFIX=/home/adahl/usr
../../src/libfoo
~/Work/build/libfoo % make
~/Work/build/libfoo % make install

No problem so far, but when building the cli tool »bar« like this:

~/Work/build/bar % cmake -DCMAKE_INSTALL_PREFIX=/home/adahl/usr
../../src/bar
~/Work/build/bar % make

This fails like this:

Linking C executable bar
/usr/bin/ld: cannot find -lfoo
collect2: ld returned 1 exit status

(Note: when not changing CMAKE_INSTALL_PATH this works.)

The cmake files for "bar" look like this:

CMakeLists.txt:

  4 project(m16c-progflash)
  5
  6 cmake_minimum_required(VERSION 2.8)
  7
  8 set(PACKAGE_MAJOR_VERSION "0")
  9 set(PACKAGE_MINOR_VERSION "1")
 10 set(PACKAGE_BUILD_VERSION "0")
 11 set(PACKAGE_VERSION
"${PACKAGE_MAJOR_VERSION}.${PACKAGE_MINOR_VERSION}.${PACKAGE_BUILD_VERSION}"
   )
 12
 16 find_package(FOO 0.1 REQUIRED)
 17
 18 add_subdirectory("src")

src/CMakeLists.txt:

 11 set(BAR_SRC
 12     bar.c
 13 )
 14
 15 include_directories(
 16     ${CMAKE_CURRENT_BINARY_DIR}
 17     ${FOO_INCLUDE_DIRS}
 18 )
 19 add_executable(${PROJECT_NAME} ${BAR_SRC})
 20
 21 target_link_libraries(${PROJECT_NAME} foo)
 22
 23 install(TARGETS ${PROJECT_NAME} DESTINATION bin)

With the former find scripts I would have had FOO_LIBRARIES and used
this in target_link_libraries() instead of "foo" but this variable is
not set anymore. So the includes are found, also in the changed
CMAKE_INSTALL_PREFIX tree, but linking fails. I guess this is some
misunderstanding or error in the package files of libfoo, but I can not
see where.

Any help appreciated. O:-)
Greets
Alex

[1]
http://cmake.org/Wiki/CMake/Tutorials/How_to_create_a_ProjectConfig.cmake_file
[2] http://www.vtk.org/Wiki/CMake/Tutorials/Packaging

-- 
»With the first link, the chain is forged. The first speech censured,
the first thought forbidden, the first freedom denied, chains us all
irrevocably.« (Jean-Luc Picard, quoting Judge Aaron Satie)
*** GnuPG-FP: 02C8 A590 7FE5 CA5F 3601  D1D5 8FBA 7744 CC87 10D0 ***


More information about the CMake mailing list