Ah, so if those components are always necessary (that is, A always needs B, and B always needs C), there's no need to use the "components" option. Just zip through them in this way - _LIBRARY (cache var) is a single library, _LIBRARIES (not a cache var) is the list containing the library and all its dependencies. If you use the _LIBRARIES variable, you don't need to even mess around with the imported targets thing, though you can if you really want to.

I've pasted an untested full example (done both ways - so actually 2 examples) using what you've explained in your last email. It's at the bottom of this email, after the quote.

Hope this helps!

Ryan

On 01/07/2010 02:20 PM, Nico Schlömer wrote:
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



# - try to find MyPackage library
#
# Example-FindMyPackage.cmake
#
# This example is for a fairly in-depth library that has four
# internal dependencies as well as an external dependency.
# The dependency tree is described below, in graphviz/dot format, and you
# can remove the #'s from the following lines and run it through graphviz,
# with this command: dot dependencies.dot -O -Tpdf
#
# --- start of dependencies.dot ---
# digraph {
#    BLAS;
#    subgraph cluster_mypackage {
#        label = "Components that are part of MyPackage";
#        libmypackagecore -> libmypackagea;
#        libmypackagea -> libmypackageb;
#        libmypackageb -> libmypackagec;
#        libmypackagec -> BLAS;
#    }
# }
# --- end of dependencies.dot ---
#
# Because our imaginary component "c" requires BLAS and BLAS needs some
# linker flags, MYPACKAGE_..._LINKER_FLAGS joins the usual group of
# _LIBRARY/_LIBRARIES and _INCLUDE_DIR/_INCLUDE_DIRS variables.  If
# you don't use a library like that, you don't need to include the
# lines dealing with that group of variables.
#
# Start of what would be a minimal module documentation blog:
#
# Cache Variables: (probably not for direct use in CMakeLists.txt)
#  MYPACKAGE_LIBRARY
#  MYPACKAGE_INCLUDE_DIR
#  MYPACKAGE_a_LIBRARY
#  MYPACKAGE_a_INCLUDE_DIR
#  MYPACKAGE_b_LIBRARY
#  MYPACKAGE_b_INCLUDE_DIR
#  MYPACKAGE_c_LIBRARY
#  MYPACKAGE_c_INCLUDE_DIR
#
# Non-cache variables you might use in your CMakeLists.txt:
#  MYPACKAGE_FOUND
#  MYPACKAGE_MARK_AS_ADVANCED - whether to mark our vars as advanced even
#    if we don't find this library.
#
#  MYPACKAGE_LIBRARIES
#  MYPACKAGE_INCLUDE_DIRS
#  MYPACKAGE_LINKER_FLAGS
#
#  MYPACKAGE_a_LIBRARIES
#  MYPACKAGE_a_INCLUDE_DIRS
#  MYPACKAGE_a_LINKER_FLAGS
#
#  MYPACKAGE_b_LIBRARIES
#  MYPACKAGE_b_INCLUDE_DIRS
#  MYPACKAGE_b_LINKER_FLAGS
#
#  MYPACKAGE_c_LIBRARIES
#  MYPACKAGE_c_INCLUDE_DIRS
#  MYPACKAGE_c_LINKER_FLAGS
#
# Use this module this way:
#  find_package(MyPackage)
#  include_directories(MYPACKAGE_INCLUDE_DIRS)
#  add_executable(myapp ${SOURCES})
#  target_link_libraries(myapp ${MYPACKAGE_LIBRARIES})
#  set_property(TARGET myapp PROPERTY LINK_FLAGS ${MYPACKAGE_LINKER_FLAGS})
#
# Requires these CMake modules:
#  FindPackageHandleStandardArgs (CMake standard module)
#
# Original Author:
# 2009-2010 Ryan Pavlik <rpav...@iastate.edu> <abir...@ryand.net>
# http://academic.cleardefinition.com
# Iowa State University HCI Graduate Program/VRAC


find_library(MYPACKAGE_LIBRARY
    NAMES mypackagecore
    PATHS "${MYPACKAGE_ROOT}"
    PATH_SUFFIXES lib)

find_path(MYPACKAGE_INCLUDE_DIR
    NAMES mypackage/mypackage.h
    PATHS "${MYPACKAGE_ROOT}"
    PATH_SUFFIXES include)

# Assuming that the components are named libmypackagea, libmypackageb, etc
foreach(lib a b c)
    find_library(MYPACKAGE_${lib}_LIBRARY
        NAMES mypackage${lib}
        PATHS "${MYPACKAGE_ROOT}"
        PATH_SUFFIXES lib)

    find_path(MYPACKAGE_${lib}_INCLUDE_DIR
        NAMES mypackage/${lib}/${lib}.h
        PATHS "${MYPACKAGE_ROOT}"
        PATH_SUFFIXES include)

endforeach()

# see /usr/share/cmake-2.x/Modules/FindBLAS.cmake for the variables this will define
if(NOT BLAS_FOUND)
    find_package(BLAS QUIETLY)
endif()

# handle the QUIETLY and REQUIRED arguments and set xxx_FOUND to TRUE if
# all listed variables are TRUE
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(MyPackage DEFAULT_MSG
    MYPACKAGE_LIBRARY
    MYPACKAGE_INCLUDE_DIR
    MYPACKAGE_a_LIBRARY
    MYPACKAGE_a_INCLUDE_DIR
    MYPACKAGE_b_LIBRARY
    MYPACKAGE_b_INCLUDE_DIR
    MYPACKAGE_c_LIBRARY
    MYPACKAGE_c_INCLUDE_DIR
    BLAS_FOUND
    )

if(MYPACKAGE_FOUND)
    # Set variables containing libraries and their dependencies
# Always use the plural form for the variables defined by other find modules:
    # they might have dependencies too!

    set(MYPACKAGE_c_LIBRARIES ${MYPACKAGE_c_LIBRARY} ${BLAS_LIBRARIES})
set(MYPACKAGE_c_INCLUDE_DIRS ${MYPACKAGE_c_INCLUDE_DIR}) # No include dir for BLAS?
    set(MYPACKAGE_c_LINKER_FLAGS ${BLAS_LINKER_FLAGS})

set(MYPACKAGE_b_LIBRARIES ${MYPACKAGE_b_LIBRARY} ${MYPACKAGE_c_LIBRARIES}) set(MYPACKAGE_b_INCLUDE_DIRS ${MYPACKAGE_b_INCLUDE_DIR} ${MYPACKAGE_c_INCLUDE_DIRS})
    set(MYPACKAGE_b_LINKER_FLAGS ${MYPACKAGE_c_LINKER_FLAGS})

set(MYPACKAGE_a_LIBRARIES ${MYPACKAGE_a_LIBRARY} ${MYPACKAGE_b_LIBRARIES}) set(MYPACKAGE_a_INCLUDE_DIRS ${MYPACKAGE_a_INCLUDE_DIR} ${MYPACKAGE_b_INCLUDE_DIRS})
    set(MYPACKAGE_a_LINKER_FLAGS ${MYPACKAGE_b_LINKER_FLAGS})

    set(MYPACKAGE_LIBRARIES ${MYPACKAGE_LIBRARY} ${MYPACKAGE_a_LIBRARIES})
set(MYPACKAGE_INCLUDE_DIRS ${MYPACKAGE_INCLUDE_DIR} ${MYPACKAGE_a_INCLUDE_DIRS})
    set(MYPACKAGE_LINKER_FLAGS ${MYPACKAGE_a_LINKER_FLAGS})

endif()

if(MYPACKAGE_FOUND OR MYPACKAGE_MARK_AS_ADVANCED)
    foreach(_cachevar
            MYPACKAGE_LIBRARY
            MYPACKAGE_INCLUDE_DIR
            MYPACKAGE_a_LIBRARY
            MYPACKAGE_a_INCLUDE_DIR
            MYPACKAGE_b_LIBRARY
            MYPACKAGE_b_INCLUDE_DIR
            MYPACKAGE_c_LIBRARY
            MYPACKAGE_c_INCLUDE_DIR)

        mark_as_advanced(${_cachevar})
    endforeach()
endif()

# End of Example-FindMyPackage.cmake



-------------------------------------------------------------------




# - try to find MyPackage library
#
# Example-FindMyPackage-UsingImportedTargets.cmake
#
# This module does the same thing as Example-FindMyPackage.cmake
# except that rather than passing along full path names for libraries,
# it creates imported targets.  The end result is roughly the same to
# the end-user.  Please see that other file for the full documentation
# of the example.
#
#
# Start of what would be a minimal module documentation blog:
#
# Cache Variables: (probably not for direct use in CMakeLists.txt)
#  MYPACKAGE_LIBRARY
#  MYPACKAGE_INCLUDE_DIR
#  MYPACKAGE_a_LIBRARY
#  MYPACKAGE_a_INCLUDE_DIR
#  MYPACKAGE_b_LIBRARY
#  MYPACKAGE_b_INCLUDE_DIR
#  MYPACKAGE_c_LIBRARY
#  MYPACKAGE_c_INCLUDE_DIR
#
# Non-cache variables you might use in your CMakeLists.txt:
#  MYPACKAGE_FOUND
#  MYPACKAGE_MARK_AS_ADVANCED - whether to mark our vars as advanced even
#    if we don't find this library.
#
#  MYPACKAGE_LIBRARIES
#  MYPACKAGE_INCLUDE_DIRS
#  MYPACKAGE_LINKER_FLAGS
#
#  MYPACKAGE_a_LIBRARIES
#  MYPACKAGE_a_INCLUDE_DIRS
#  MYPACKAGE_a_LINKER_FLAGS
#
#  MYPACKAGE_b_LIBRARIES
#  MYPACKAGE_b_INCLUDE_DIRS
#  MYPACKAGE_b_LINKER_FLAGS
#
#  MYPACKAGE_c_LIBRARIES
#  MYPACKAGE_c_INCLUDE_DIRS
#  MYPACKAGE_c_LINKER_FLAGS
#
# Use this module this way:
#  find_package(MyPackage)
#  include_directories(MYPACKAGE_INCLUDE_DIRS)
#  add_executable(myapp ${SOURCES})
#  target_link_libraries(myapp ${MYPACKAGE_LIBRARIES})
#  set_property(TARGET myapp PROPERTY LINK_FLAGS ${MYPACKAGE_LINKER_FLAGS})
#
# Requires these CMake modules:
#  FindPackageHandleStandardArgs (CMake standard module)
#
# Original Author:
# 2009-2010 Ryan Pavlik <rpav...@iastate.edu> <abir...@ryand.net>
# http://academic.cleardefinition.com
# Iowa State University HCI Graduate Program/VRAC


find_library(MYPACKAGE_LIBRARY
    NAMES mypackagecore
    PATHS "${MYPACKAGE_ROOT}"
    PATH_SUFFIXES lib)

find_path(MYPACKAGE_INCLUDE_DIR
    NAMES mypackage/mypackage.h
    PATHS "${MYPACKAGE_ROOT}"
    PATH_SUFFIXES include)

# Assuming that the components are named libmypackagea, libmypackageb, etc
foreach(lib a b c)
    find_library(MYPACKAGE_${lib}_LIBRARY
        NAMES mypackage${lib}
        PATHS "${MYPACKAGE_ROOT}"
        PATH_SUFFIXES lib)

    find_path(MYPACKAGE_${lib}_INCLUDE_DIR
        NAMES mypackage/${lib}/${lib}.h
        PATHS "${MYPACKAGE_ROOT}"
        PATH_SUFFIXES include)

endforeach()

# see /usr/share/cmake-2.x/Modules/FindBLAS.cmake for the variables this will define
if(NOT BLAS_FOUND)
    find_package(BLAS QUIETLY)
endif()

# handle the QUIETLY and REQUIRED arguments and set xxx_FOUND to TRUE if
# all listed variables are TRUE
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(MyPackage DEFAULT_MSG
    MYPACKAGE_LIBRARY
    MYPACKAGE_INCLUDE_DIR
    MYPACKAGE_a_LIBRARY
    MYPACKAGE_a_INCLUDE_DIR
    MYPACKAGE_b_LIBRARY
    MYPACKAGE_b_INCLUDE_DIR
    MYPACKAGE_c_LIBRARY
    MYPACKAGE_c_INCLUDE_DIR
    BLAS_FOUND
    )

if(MYPACKAGE_FOUND)
    # Set variables containing libraries and their dependencies
# Always use the plural form for the variables defined by other find modules:
    # they might have dependencies too!

    add_library(mypackage_c IMPORTED)
    set_target_properties(mypackage_c PROPERTIES
        IMPORTED_LOCATION ${MYPACKAGE_c_LIBRARY}
        IMPORTED_LINK_INTERFACE_LIBRARIES  ${BLAS_LIBRARIES})
    set(MYPACKAGE_c_LIBRARIES mypackage_c)
set(MYPACKAGE_c_INCLUDE_DIRS ${MYPACKAGE_c_INCLUDE_DIR}) # No include dir for BLAS?
    set(MYPACKAGE_c_LINKER_FLAGS ${BLAS_LINKER_FLAGS})

    add_library(mypackage_b IMPORTED)
    set_target_properties(mypackage_b PROPERTIES
        IMPORTED_LOCATION ${MYPACKAGE_b_LIBRARY}
        IMPORTED_LINK_INTERFACE_LIBRARIES  ${MYPACKAGE_c_LIBRARIES})
    set(MYPACKAGE_b_LIBRARIES mypackage_b)
set(MYPACKAGE_b_INCLUDE_DIRS ${MYPACKAGE_b_INCLUDE_DIR} ${MYPACKAGE_c_INCLUDE_DIRS})
    set(MYPACKAGE_b_LINKER_FLAGS ${MYPACKAGE_c_LINKER_FLAGS})

    add_library(mypackage_a IMPORTED)
    set_target_properties(mypackage_a PROPERTIES
        IMPORTED_LOCATION ${MYPACKAGE_a_LIBRARY}
        IMPORTED_LINK_INTERFACE_LIBRARIES  ${MYPACKAGE_b_LIBRARIES})
    set(MYPACKAGE_a_LIBRARIES mypackage_a)
set(MYPACKAGE_a_INCLUDE_DIRS ${MYPACKAGE_a_INCLUDE_DIR} ${MYPACKAGE_b_INCLUDE_DIRS})
    set(MYPACKAGE_a_LINKER_FLAGS ${MYPACKAGE_b_LINKER_FLAGS})

    add_library(mypackage_core IMPORTED)
    set_target_properties(mypackage_core PROPERTIES
        IMPORTED_LOCATION ${MYPACKAGE_LIBRARY}
        IMPORTED_LINK_INTERFACE_LIBRARIES ${MYPACKAGE_a_LIBRARIES})
    set(MYPACKAGE_LIBRARIES mypackage_core)
set(MYPACKAGE_INCLUDE_DIRS ${MYPACKAGE_INCLUDE_DIR} ${MYPACKAGE_a_INCLUDE_DIRS})
    set(MYPACKAGE_LINKER_FLAGS ${MYPACKAGE_a_LINKER_FLAGS})

endif()

if(MYPACKAGE_FOUND OR MYPACKAGE_MARK_AS_ADVANCED)
    foreach(_cachevar
            MYPACKAGE_LIBRARY
            MYPACKAGE_INCLUDE_DIR
            MYPACKAGE_a_LIBRARY
            MYPACKAGE_a_INCLUDE_DIR
            MYPACKAGE_b_LIBRARY
            MYPACKAGE_b_INCLUDE_DIR
            MYPACKAGE_c_LIBRARY
            MYPACKAGE_c_INCLUDE_DIR)

        mark_as_advanced(${_cachevar})
    endforeach()
endif()

# End of Example-FindMyPackage-UsingImportedTargets.cmake

--
Ryan Pavlik
HCI Graduate Student
Virtual Reality Applications Center
Iowa State University

rpav...@iastate.edu
http://academic.cleardefinition.com
Internal VRAC/HCI Site: http://tinyurl.com/rpavlik

_______________________________________________
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

Reply via email to