Project

General

Profile

Adding Product Dependencies

The CET build system uses cmake and other tools to enable use of product dependencies.

In general, you will rarely need to add or remove a dependency.
Most often, you will just be changing the version of a dependent product.

1. To change the version of a dependent product:

  • edit <your package>/ups/product_deps
  • you may also wish to edit the miniumum required version in <your package>/CMakeLists.txt
  • find_ups_product( <product-name> <minimum-required-version-in-ups-format> )
  • the ups version format is vx_y_z, for instance, root v5_34_01

2. Identifying product versions

  • To list all available versions of a product:
     ups list -aK+ <product-name> 
     e.g., ups list -aK+ cetlib
    
  • To list a single version of a product:
     ups list -aK+ <product-name> <product-version> 
     e.g., ups list -aK+ cetlib v1_03_12
    
  • Note that the qualifiers are colon separated. They may be listed in any order. In other words, "e2:debug" is exactly the same as "debug:e2".
  • Ups lists colon separated qualifiers in alphabetical order, but we typically list them in order of importance.

3. Adding a product definition

The product is defined in <your package>/ups/product_deps
You will also need a find_ups_product( ) line in <your package>/CMakeLists.txt
Depending on how the product is used, you will also need to make other changes in the relevant CMakeLists.txt files.

Because root and boost are complex products, they have their own find_ups_root() and find_ups_boost() macros.

If you are building a brand new product_deps file, go directly to Defining products in the CET build environment

3.1 editing product_deps

  • see Defining products in the CET build environment
  • add a line for the new product in the product version block
     <ups-product-name> <ups-product-version>
     e.g., cetlib v1_03_12
    
  • add a column in the qualifier block
    qualifier art        <ups-product>               gcc    notes
    e2:debug  e2:debug   <ups-debug-qualifier-list>  -nq-
    e2:prof   e2:prof    <ups-prof-qualifier-list.   -nq-   The notes field is optional.
    
  • Note that a particular product qualifier may not be the same as other product qualifiers.
  • Art has its own dependencies. We DO NOT list these dependencies. These additional dependencies will be pulled in directly by art, ensuring that you have a consistent build set.
  • We do, however, list gcc explicitly. This should be the only exception.
  • We use tabs to keep the columns aligned.
  • See, for instance, the artdaq product_deps file:
    parent artdaq   v0_02_01
    defaultqual     e2
    #
    product    version    optional
    gcc        v4_7_1
    art        v1_01_01
    mvapich2   v1_7_0        
    
    # cetbuildtools is required when building artdaq, but NEVER when using artdaq
    only_for_build  cetbuildtools  v2_01_05
    
    # -nq- here means there is no qualifier
    # a - here means the dependent product is not required by the parent and will not be setup
    qualifier       art        mvapich2   gcc   notes
    e2:debug        e2:debug    -nq-      -nq-   -std=c++11
    e2:opt          e2:opt      -nq-      -nq-   -std=c++11
    e2:prof         e2:prof     -nq-      -nq-   -std=c++11
    e2:nompi:debug  e2:debug    -         -nq-   -std=c++11
    e2:nompi:opt    e2:opt      -         -nq-   -std=c++11
    e2:nompi:prof   e2:prof     -         -nq-   -std=c++11
    

3.2 editing the top level CMakeLists.txt file

  • The top level CMakeLists.txt file defines the environment for your cmake build. It uses a number of macros to help define the CET build environment.
  • Before cmake can use a product, it must be declared to cmake. We do this with the find_ups_product() macro. This macro will set several useful variables and add the header directory to the cmake include path. Because library names are varied, this macro will NOT define libraries. This may change in the future.
    find_ups_product( <ups-product-name> <ups-product-version> )
    
  • You must declare all products that you will be using to cmake.
  • Remember that the version used in the call to find_ups_product() is a minimum required version.
  • Here is that block from artdaq:
    find_ups_product( art v1_00_12 )
    find_ups_product( cetbuildtools v2_00_00 )
    find_ups_product( cpp0x v1_03_00 )
    find_ups_product( cetlib v1_03_00 )
    find_ups_product( fhiclcpp v2_16_00 )
    find_ups_product( messagefacility v1_10_00 )
    find_ups_root( v5_30_02 )
    find_ups_boost( v1_47_0 filesystem
                            program_options
                            regex
                            system
                            thread
                            unit_test_framework
     )
    
  • If a product has headers in a non-standard directory, you must add that information. This example is from artdaq.
    include_directories ( $ENV{LIBSIGCPP_INC}/sigc++-2.0 )
    include_directories ( $ENV{LIBSIGCPP_LIB}/sigc++-2.0/include )
    
  • Finally, you need to tell cmake to find and define all libraries that will be needed when linking. Here is the list of libraries used by artdaq.
    find_library( ART_FRAMEWORK_ART NAMES art_Framework_Art PATHS $ENV{ART_LIB} )
    find_library( ART_FRAMEWORK_CORE NAMES art_Framework_Core PATHS $ENV{ART_LIB} )
    find_library( ART_FRAMEWORK_PRINCIPAL NAMES art_Framework_Principal PATHS $ENV{ART_LIB} )
    find_library( ART_FRAMEWORK_SERVICES_REGISTRY NAMES art_Framework_Services_Registry PATHS $ENV{ART_LIB} )
    find_library( ART_PERSISTENCY_COMMON NAMES art_Persistency_Common PATHS $ENV{ART_LIB} )
    find_library( ART_PERSISTENCY_COMMON_DICT NAMES art_Persistency_Common_dict PATHS $ENV{ART_LIB} )
    find_library( ART_PERSISTENCY_PROVENANCE NAMES art_Persistency_Provenance PATHS $ENV{ART_LIB} )
    find_library( ART_UTILITIES NAMES art_Utilities PATHS $ENV{ART_LIB} )
    find_library( CETLIB NAMES cetlib PATHS $ENV{CETLIB_LIB} )
    find_library( CPPUNIT NAMES cppunit   PATHS $ENV{CPPUNIT_LIB}   NO_DEFAULT_PATH )
    find_library( FHICLCPP NAMES fhiclcpp PATHS $ENV{FHICLCPP_LIB} )
    find_library( MF_EXTENSIONS NAMES MF_ExtModules PATHS $ENV{MESSAGEFACILITY_LIB} )
    find_library( MF_MESSAGELOGGER NAMES MF_MessageLogger PATHS $ENV{MESSAGEFACILITY_LIB} )
    find_library( MF_MESSAGESERVICE NAMES MF_MessageService PATHS $ENV{MESSAGEFACILITY_LIB} )
    find_library( MF_UTILITIES NAMES MF_Utilities PATHS $ENV{MESSAGEFACILITY_LIB} )
    find_library( SIGC    NAMES sigc-2.0  PATHS $ENV{LIBSIGCPP_LIB} NO_DEFAULT_PATH )
    
  • Notice the use of $ENV to translate environmental variables. This is the only way that cmake will recognize environmental variables.
  • Notice that you must use a separate find_library() call for each library.
  • If you are using art v1_02_00 or later and cetbuildtools v2_03_00 or later, find_ups_product() will look for a cmake config file. In the case of art and other CET packages, the cmake config file will contain the necessary find_library() calls.

3.3 editing other CMakeLists.txt files

  • The library names are defined in the top level CMakeLists.txt file because they may be used in several places.
  • To link with a library, you need to add it to the link list for the library or executable you are building.
  • Use the target_link_libraries() macro
    target_link_libraries( <target-name> <library-list> )
    
  • This example will define, link, and install a library named libmyLib.so. See https://cdcvs.fnal.gov/redmine/projects/artdaq/repository/entry/artdaq/DAQdata/CMakeLists.txt?rev= for a working example.
    add_library( myLib SHARED file1.cc file2.cc fileN.cc )
    target_link_libraries(myLib
      ${ART_PERSISTENCY_COMMON}
      ${ART_UTILITIES}
      ${FHICLCPP}
      ${CETLIB}
      )
    install(TARGETS myLib DESTINATION ${flavorqual_dir}/lib )
    
  • This example will define, link, and install an executable named "builder".
      add_executable( builder builder.cc )
      target_link_libraries(builder
        ${ART_FRAMEWORK_ART}
        artdaq_DAQrate
        artdaq_DAQdata
        ${FHICLCPP}
        ${CETLIB}
        ${Boost_PROGRAM_OPTIONS_LIBRARY}
        ${MPI_LIBRARIES}
        )
      install(TARGETS builder DESTINATION ${flavorqual_dir}/bin)
    
  • Notice that if you are linking a library from within the package, you just use the bare library name (e.g., "artdaq_DAQrate").

4. Cmake documentation