[vtkusers] Correctly exporting dependency on VTK in CMake ProjectConfig

Timo Oster timo.oster at ovgu.de
Wed Jan 25 08:47:36 EST 2017


Hi vtkusers,

I am developing a small C++ library that is dependent on some components
of VTK. I am using CMake to build my library, and I am providing a
ProjectConfig.cmake file to make it easier to use my library with CMake.
My ProjectConfig file is structured according to the example at
https://cmake.org/Wiki/CMake/Tutorials/How_to_create_a_ProjectConfig.cmake_file.
This means when installing, I am creating a ProjectTargets.cmake file
that contains my library plus all the libraries that my lib depends on.
I should also mention that I am on Linux and am using VTK 7.1 and CMake 3.4.

My problem is that this file does not contain the path of the vtk
libraries I depend on, only their names. When I build my project, this
is not a problem, as it knows the VTK link directory (via
find_package(VTK)). However, when I use my lib in another CMake project,
the VTK library path is not available any more (The other project does
not and should not need to find VTK itself). This leads to lots of
library not found errors when linking.

Here is how my CMake Project is structured:

Main CMakeLists.txt (almost 1:1 copy&paste from the Wiki example):
------------------------------------------------------------------------
[...]
add_subdirectory(src)

export(TARGETS my_lib
    FILE "${PROJECT_BINARY_DIR}/MyProjectTargets.cmake")

# export(PACKAGE MyProject)

file(RELATIVE_PATH REL_INCLUDE_DIR
    "${INSTALL_CMAKE_DIR}" "${INSTALL_INCLUDE_DIR}")

set(CONF_INCLUDE_DIRS "${PROJECT_SOURCE_DIR}" "${PROJECT_BINARY_DIR}")
configure_file(MyProjectConfig.cmake.in
    "${PROJECT_BINARY_DIR}/MyProjectConfig.cmake" @ONLY)

set(CONF_INCLUDE_DIRS "\${MYPROJECT_CMAKE_DIR}/${REL_INCLUDE_DIR}")
configure_file(MyProjectConfig.cmake.in

"${PROJECT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/MyProjectConfig.cmake" @ONLY)

configure_file(MyProjectConfigVersion.cmake.in
    "${PROJECT_BINARY_DIR}/MyProjectConfigVersion.cmake" @ONLY)

install(FILES
   	"${PROJECT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/MyProjectConfig.cmake"
    "${PROJECT_BINARY_DIR}/MyProjectConfigVersion.cmake"
    DESTINATION "${INSTALL_CMAKE_DIR}" COMPONENT dev)

install(EXPORT MyProjectTargets
    DESTINATION "${INSTALL_CMAKE_DIR}" COMPONENT dev)
------------------------------------------------------------------------

src/CMakeLists.txt:
------------------------------------------------------------------------
set(SOURCES ...)

set(HEADERS ...)

add_library(my_lib ${SOURCES} ${HEADERS})

...

find_package(VTK REQUIRED COMPONENTS vtkParallelMPI vtkIOParallelXML
NO_MODULE)
if(VTK_FOUND)
    include(${VTK_USE_FILE})
    target_link_libraries(my_lib ${VTK_LIBRARIES})
endif()

...

install(TARGETS my_lib
    EXPORT MyProjectTargets
    LIBRARY DESTINATION "${INSTALL_LIB_DIR}" COMPONENT lib
    ARCHIVE DESTINATION "${INSTALL_LIB_DIR}" COMPONENT lib
    PUBLIC_HEADER DESTINATION "${INSTALL_INCLUDE_DIR}/my_lib" COMPONENT dev)
------------------------------------------------------------------------

This works fine and I can use find_package(MyProject) in some other
CMake project to use my lib. The generated
MyProjectTargets-release.cmake file contains a statement to set up the
dependencies of my lib looking like this:
------------------------------------------------------------------------
# Import target "my_lib" for configuration "Release"
set_property(TARGET my_lib APPEND PROPERTY IMPORTED_CONFIGURATIONS RELEASE)
set_target_properties(my_lib PROPERTIES
  IMPORTED_LINK_INTERFACE_LIBRARIES_RELEASE
"/some/path/lib64/libmpi.so;/some/path/lib64/libmpigc4.so;/usr/lib64/libdl.so;/some/path/intel64/libirc.so;/usr/lib64/libpthread.so;/usr/lib64/librt.so;[...];vtkParallelMPI;vtkCommonCore;vtksys;vtkCommonDataModel;vtkCommonMath;
vtkCommonMisc;vtkCommonSystem;vtkCommonTransforms;vtkParallelCore;
vtkIOLegacy;vtkCommonExecutionModel;vtkIOCore;vtkzlib;vtkIOParallelXML;
vtkIOXML;vtkIOXMLParser;vtkexpat"
  IMPORTED_LOCATION_RELEASE "/some/path/MyProject/lib/my_lib.so"
  IMPORTED_SONAME_RELEASE "my_lib.so"
  )
------------------------------------------------------------------------
As you can see, all the dependent libraries listed are given with their
full path, except for the vtk ones. Since they are installed in a
non-standard location, the linker will not find them unless explicitly
told where to look. There is however no reference to the path they
reside in anywhere in that file.

Where is the error? Does the VTKConfig.cmake file that is used when
find_package(VTK) is called export its targets incorrectly? Did I forget
to export something in my CMake script (it worked without that for all
my other dependencies)? Do I have to add the VTK lib path to some
environment variable so the linker finds it (I tried both LIBRARY_PATH
and LD_LIBRARY_PATH to no effect)?

I hope this question is not too complex, but I guess if anybody knows
how to do ProjectConfig right it's the VTK developers.

Best,

Timo
-- 
Timo Oster

Visual Computing Group / Lab. of Fluid Dynamics and Technical Flows
University of Magdeburg
Universitätsplatz 2
D-39106 Magdeburg

Phone: (+49-391) 67-12647 / (+49-391) 67-51349
Offices: Building 29 - Room 234 / Building 14 - Room 108

PGP Fingerprint: 4F25 89EE A9FD C5FE FEE5 D086 C625 B58C 2411 932F


More information about the vtkusers mailing list