[CMake] install export : ignore imported_link_interface_libraries and imported_link_dependents_libraries

Michael Hertling mhertling at online.de
Mon Nov 7 21:27:24 EST 2011


On 11/02/2011 04:19 PM, Jaonary Rabarisoa wrote:
> Hi all,
> 
> I'm using the command install(EXPORT ) to create a configuration file for
> my project. This works great but by default
> cmake fills the IMPORTED_LINK_INTERFACE_LIBRARIES and
> IMPORTED_LINK_DEPENDENTS_LIBRARIES. I'd like cmake
> to ignore these properties because it introduces a hard link to my build
> machine. For example, it output a hard to boost libraries, which
> are in fact use in may project.
> So is there a way to tell cmake to ignore these properties while exporting
> a target ?
> 
> Best regards,
> 
> Jaonary

You might empty the LINK_INTERFACE_LIBRARIES target property:

CMAKE_MINIMUM_REQUIRED(VERSION 2.8 FATAL_ERROR)
PROJECT(LINKLIBS CXX)
SET(CMAKE_VERBOSE_MAKEFILE ON)
FIND_PACKAGE(Boost COMPONENTS date_time)
FILE(WRITE ${CMAKE_BINARY_DIR}/f.cxx "void f(void){}\n")
ADD_LIBRARY(f SHARED f.cxx)
TARGET_LINK_LIBRARIES(f ${Boost_LIBRARIES})
SET_TARGET_PROPERTIES(f PROPERTIES LINK_INTERFACE_LIBRARIES "")
INSTALL(TARGETS f EXPORT f DESTINATION lib)
INSTALL(EXPORT f DESTINATION share)

This installs an export file f-noconfig.cmake containing

SET_TARGET_PROPERTIES(f PROPERTIES
  IMPORTED_LOCATION_NOCONFIG "${_IMPORT_PREFIX}/lib/libf.so"
  IMPORTED_SONAME_NOCONFIG "libf.so"
  )

without any IMPORTED_LINK_{INTERFACE,DEPENDENT}_LIBRARIES properties.
Note that Boost won't be transitively respected anymore for targets
linked against f, neither in your project nor in others importing
the export file.

This approach works for shared libraries only. If you need to do the
same for a static library, you might use a trick with reimportation:

CMAKE_MINIMUM_REQUIRED(VERSION 2.8 FATAL_ERROR)
PROJECT(LINKLIBS CXX)
SET(CMAKE_VERBOSE_MAKEFILE ON)
FIND_PACKAGE(Boost COMPONENTS date_time)
FILE(WRITE ${CMAKE_BINARY_DIR}/f.cxx "void f(void){}\n")
ADD_LIBRARY(f STATIC f.cxx)
EXPORT(TARGETS f FILE reimportedf.cmake NAMESPACE reimported)
INCLUDE(${CMAKE_BINARY_DIR}/reimportedf.cmake)
SET_TARGET_PROPERTIES(reimportedf PROPERTIES
    IMPORTED_LINK_INTERFACE_LIBRARIES "${Boost_LIBRARIES}")
INSTALL(TARGETS f EXPORT f DESTINATION lib)
INSTALL(EXPORT f DESTINATION share)
FILE(WRITE ${CMAKE_BINARY_DIR}/main.cxx "int main(void){return 0;}\n")
ADD_EXECUTABLE(main main.cxx)
TARGET_LINK_LIBRARIES(main reimportedf)

The target "f" is the static library which has a dependency on Boost
you don't want to appear in the export file; thus, you mustn't link f
against Boost. In order to have that dependency resolved for binaries
linking against f within your project, f is effectively duplicated as
a (re)imported target "reimportedf" with the necessary dependency set
in its IMPORTED_LINK_INTERFACE_LIBRARIES property, and it is that re-
importedf library your project's binaries need to be linked against.
You can see this with the "main" target linking against libf.a and
Boost, whereas the installed f-noconfig.cmake export file doesn't
contain any references to Boost anymore. Possibly, the same could
be done to address the above-mentioned issue with the transitive
inner-project dependency on Boost with shared libraries.

Just an additional remark: The files installed by INSTALL(EXPORT ...)
describe the installed targets' dependencies on the system where the
installation has taken place; using these files on another system
within a different environment is usually a rather bad idea.

'hope that helps.

Regards,

Michael


More information about the CMake mailing list