[CMake] intercomponent link dependencies?

Ryan Pavlik rpavlik at iastate.edu
Thu Jan 7 14:43:32 EST 2010


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

-------------- next part --------------
A non-text attachment was scrubbed...
Name: FindGPM.cmake
Type: text/x-cmake
Size: 1075 bytes
Desc: not available
URL: <http://www.cmake.org/pipermail/cmake/attachments/20100107/a19a0b59/attachment.bin>


More information about the CMake mailing list