[CMake] intercomponent link dependencies?

Nico Schlömer nico.schloemer at gmail.com
Thu Jan 7 15:20:39 EST 2010


Hi Ryan,

thanks very much for your answer.

For clarification, the package I would like to link against has (say)
three components A, B, C, where A at link time needs symbols of B
needs symbols of C needs symbols of some external libs.

I would like to make sure that the user can say

   FIND_PACKAGE( mypackage COMPONENTS A )

and then find in some variable *all* the dependencies that are
required for linking, e.g.,
MYPACKAGE_A_LIBRARY="a;b;c;/usr/local/lib/libblas.a".
Right now (and which I'm not happy with), if a user would like to link
against liba.a, he or she has to know that libb.a, libc.a, and
/usr/local/lib/libblas.a have to be pulled in as well, and do so
manually.

If on the other hand I have the same dependency situation with
libraries that I *built*, the TARGET_LINK_LIBRARIES mechanism works
very well. If I understand correctly, this cannot be applied to
components in a FINDmypackage.cmake

Cheers,
Nico






On Thu, Jan 7, 2010 at 8:43 PM, Ryan Pavlik <rpavlik at iastate.edu> wrote:
> Hello,
>
> My apologies in advance if I'm completely mis-reading your question and if
> this answer seems way off base: just addressing what seemed like the most
> likely issue from the info you provided.  (This link below [1] might help
> you get better results out of mailing lists.)
>
> A script called by find_package(whatever) only normally sets variables in
> CMake - it doesn't include or link any targets against any libraries.  (You
> might have several targets in one CMake project, each that link against
> different libraries)  So, in addition to the find_package(Mypackage), in
> your CMakeLists.txt, you'll also want to do, for example:
>
> include_directories(${MYPACKAGE_INCLUDE_DIRS})
> add_executable(myapp ${MYAPP_SOURCES})
> target_link_libraries(myapp ${MYPACKAGE_FOOCOMP_LIBRARY}
> ${MYPACKAGE_BARCOMP_LIBRARY})
>
> Note that according to the readme.txt in the modules directory of cmake (and
> what seems to be convention), you'll note that your find module variables
> should probably be named as above  ( PACKAGEUPPER_COMPONENTUPPER_LIBRARY ).
>  Additionally, once you've run find_package_handle_standard_args,
> if(PACKAGEUPPER_FOUND), you will probably want to do the following - this
> example assumes you have some main library for the package that's always
> needed to link against that package, and some additional optional libraries
> specified as components (openscenegraph is an example of one of these types
> of packages)
>
> set(PACKAGEUPPER_LIBRARIES ${PACKAGEUPPER_LIBRARY})
> foreach(COMPONENT ${list_of_requested_and_found_components})
>    list(APPEND PACKAGEUPPER_LIBRARIES ${PACKAGEUPPER_COMPONENT_LIBRARY})
> endforeach()
>
>
> I've attached a rather simple example of this kind of script - you'd of
> course have your component search loop and the additional foreach loop
> explained above added to this basic structure.  (and if you're doing it by
> creating imported targets, you'll obviously use that code instead of the
> direct file path code)
>
> Hope this helps!
>
> Ryan
>
>
> [1] http://catb.org/~esr/faqs/smart-questions.html
>
> On 01/07/2010 09:19 AM, Nico Schlömer wrote:
>>
>> Hi Michael,
>>
>> I added to the FindMypackage.cmake in the FOREACH(COMPONENT) loop the
>> following snipped
>>
>>       ADD_LIBRARY(${COMPONENT} STATIC IMPORTED)
>>       SET_TARGET_PROPERTIES( ${COMPONENT} PROPERTIES
>>                              IMPORTED_LOCATION
>> "${${UPPERCOMPONENT}_LIBRARY}"
>>                              LINK_INTERFACE_LIBRARIES
>> "${${COMPONENT}_LINK_INTERFACE_LIBRARIES}"
>>                            )
>>
>> where "${${UPPERCOMPONENT}_LIBRARY}" is the path of the respective
>> library in the filesystem, and
>> "${${COMPONENT}_LINK_INTERFACE_LIBRARIES}" a semicolon-separated list
>> of dependencies of ${COMPONENT} (being either another component, or
>> something of the form /path/to/libfancy.a). CMake does create all the
>> Makefiles -- good -- but the dependency information doesn't sit in
>> there (?).
>> I expected that I can go like
>>
>> FIND_PACKAGE( Mypackage COMPONENTS foocomp barcomp )
>>
>> and that all the necessary stuff would be included automatically. --
>> Well, now that I think about it this is probably a pipe dream. What
>> would I further have to include?
>>
>> Cheers,
>> Nico
>>
>>
>>
>> On Thu, Jan 7, 2010 at 12:47 PM, Michael Wild<themiwi at gmail.com>  wrote:
>>
>>>
>>> Hi Nico
>>>
>>> In that case you need to do this:
>>>
>>> add_library(${COMPONENT} IMPORTED)
>>> set_target_properties(${COMPONENT} PROPERTIES
>>>  IMPORTED_LOCATION "${${COMPONENT}_LIBRARY}"
>>>  LINK_INTERFACE_LIBRARIES "${${COMPONENT}_LINK_INTERFACE_LIBRARIES}"
>>>  )
>>>
>>> where each of the components X has a variable X_LIBRARY containing its
>>> path on the system (e.g. determined by find_library(X_LIBRARY ...)) and a
>>> variable X_LINK_INTERFACE_LIBRARIES which you have to set outside the
>>> foreach loop.
>>>
>>> HTH
>>>
>>> Michael
>>>
>>> On 7. Jan, 2010, at 11:51 , Nico Schlömer wrote:
>>>
>>>
>>>>
>>>> Hi Michael,
>>>>
>>>> thanks for the explanations.
>>>>
>>>> I'm indeed about to write a FindModule.cmake for a library which I did
>>>> *not* write, but to certain components of which I'd like to link
>>>> against using CMake (in a clean fashion).
>>>> I'm FOREACHing through the components of the library, and upon trying to
>>>> set
>>>>
>>>>  ADD_LIBRARY( ${COMPONENT} )
>>>>
>>>> cmake complains about
>>>>
>>>>  add_library cannot create target "A" because another target with the
>>>>  same name already exists.  The existing target is a static library
>>>> created
>>>>  in source directory "/path/to/A".  See
>>>>  documentation for policy CMP0002 for more details.
>>>>
>>>> Okay, so it exists already? Fine. Let's then
>>>>
>>>>  SET_TARGET_PROPERTIES( ${COMPONENT} PROPERTIES
>>>> LINK_INTERFACE_LIBRARIES "B;C;" )
>>>>
>>>> -- but again, cmake complains that
>>>>
>>>>  set_target_properties Can not find target to add properties to: A
>>>>
>>>> TARGET_LINK_LIBRARIES doesn't work anyway as I'm not *building the
>>>> libraries (cmake says).
>>>>
>>>> Hmmm...
>>>> Nico
>>>>
>>>>
>>>>
>>>> On Thu, Jan 7, 2010 at 11:08 AM, Michael Wild<themiwi at gmail.com>  wrote:
>>>>
>>>>>
>>>>> One quick question: Are these libraries created by you? In that case
>>>>> you shouldn't write a FindMymodule.cmake, but a MymoduleConfig.cmake (see
>>>>> the documentation of find_package).
>>>>>
>>>>> Anyhow, to define the transitive link dependencies you can either use
>>>>> target_link_libraries(A LINK_INTERFACE_LIBRARIES B C) if your CMake is new
>>>>> enough, or you can use set_target_properties(A PROPERTIES
>>>>> LINK_INTERFACE_LIBRARIES "B;C"). Both solutions require that you use
>>>>> add_library(X IMPORTED) (where X = A, B and C) and set their
>>>>> IMPORTED_LOCATION property to the location on the file system. All of this
>>>>> is full automatic if you write a MymoduleConfig.cmake, because then you can
>>>>> use
>>>>>
>>>>> install_targets(A B C EXPORT MymoduleExports
>>>>>  ARCHIVE DESTINATION lib
>>>>>  LIBRARY DESTINATION lib
>>>>>  RUNTIME DESTINATION bin
>>>>>  PUBLIC_HEADER DESTINATION include
>>>>>  )
>>>>>
>>>>> install(EXPORT MymoduleExports
>>>>>  NAMESPACE Mymodule_
>>>>>  DESTINATION share/mymodule/cmake
>>>>>  )
>>>>>
>>>>> which will install a file
>>>>> ${CMAKE_INSTALL_PREFIX}/share/mymodule/cmake/MymoduleExports.cmake
>>>>> containing all the IMPORT stuff and which you can INCLUDE in your
>>>>> MymoduleConfig.cmake.
>>>>>
>>>>>
>>>>> I hope I could help a bit, otherwise tell us which case it is and I'll
>>>>> be able to help more.
>>>>>
>>>>> Michael
>>>>>
>>>>>
>>>>>
>>>
>>>
>>
>> _______________________________________________
>> Powered by www.kitware.com
>>
>> Visit other Kitware open-source projects at
>> http://www.kitware.com/opensource/opensource.html
>>
>> Please keep messages on-topic and check the CMake FAQ at:
>> http://www.cmake.org/Wiki/CMake_FAQ
>>
>> Follow this link to subscribe/unsubscribe:
>> http://www.cmake.org/mailman/listinfo/cmake
>>
>
> --
> Ryan Pavlik
> HCI Graduate Student
> Virtual Reality Applications Center
> Iowa State University
>
> rpavlik at iastate.edu
> http://academic.cleardefinition.com
> Internal VRAC/HCI Site: http://tinyurl.com/rpavlik
>
>


More information about the CMake mailing list