# Copyright 2019-2020 CERN and copyright holders of ALICE O2.
# See https://alice-o2.web.cern.ch/copyright for details of the copyright holders.
# All rights not expressly granted are reserved.
#
# This software is distributed under the terms of the GNU General Public
# License v3 (GPL Version 3), copied verbatim in the file "COPYING".
#
# In applying this license CERN does not waive the privileges and immunities
# granted to it by virtue of its status as an Intergovernmental Organization
# or submit itself to any jurisdiction.
include_guard()
include(O2NameTarget)
#
# o2_add_library(baseTargetName SOURCES c1.cxx c2.cxx .....) defines a new
# target of type "library" composed of the given sources. It also defines an
# alias named O2::baseTargetName. The generated library will be called
# libO2[baseTargetName].(dylib|so|.a) (for exact naming see the o2_name_target
# function).
#
# The library will be static or shared depending on the BUILD_SHARED_LIBS option
# (which is normally ON for O2 project)
#
# Parameters:
#
# * SOURCES (required) : the list of source files to compile into this library
#
# * PUBLIC_LINK_LIBRARIES (needed in most cases) : the list of targets this
# library depends on (e.g. ROOT::Hist, O2::CommonConstants). It is mandatory
# to use the fully qualified target name (i.e. including the namespace part)
# even for internal (O2) targets.
#
# * PUBLIC_INCLUDE_DIRECTORIES (not needed in most cases) : the list of include
# directories where to find the include files needed to compile this library
# and that will be needed as well by the consumers of that library. By default
# the include subdirectory of the current source directory is taken into
# account, which should cover most of the use cases. Use this parameter only
# for special cases then. Note that if you do specify this parameter it
# replaces the default, it does not add to them.
#
# * PRIVATE_LINK_LIBRARIES (not needed in most cases) : the list of targets this
# library needs at compile time (i.e. those dependencies won't be propagated
# to the targets depending on this one). It is mandatory to use the fully
# qualified target name (i.e. including the namespace part) even for internal
# (O2) targets.
#
# * PRIVATE_INCLUDE_DIRECTORIES (not needed in most cases) : the list of include
# directories where to find the include files needed to compile this library,
# but that will _not_ be needed by its consumers. But default we add the
# ${CMAKE_CURRENT_BINARY_DIR} here to cover use case of generated headers
# (e.g. by protobuf). Note that if you do specify this parameter it replaces
# the default, it does not add to them.
#
function(o2_add_library baseTargetName)
cmake_parse_arguments(
PARSE_ARGV
1
A
""
"TARGETVARNAME"
"SOURCES;PUBLIC_INCLUDE_DIRECTORIES;PUBLIC_LINK_LIBRARIES;PRIVATE_INCLUDE_DIRECTORIES;PRIVATE_LINK_LIBRARIES"
)
if(A_UNPARSED_ARGUMENTS)
message(
FATAL_ERROR "Unexpected unparsed arguments: ${A_UNPARSED_ARGUMENTS}")
endif()
o2_name_target(${baseTargetName} NAME targetName)
set(target ${targetName})
# define the target and its O2:: alias
add_library(${target} ${A_SOURCES})
add_library(O2::${baseTargetName} ALIAS ${target})
# set the export name so that packages using O2 can reference the target as
# O2::${baseTargetName} as well (assuming the export is installed with
# namespace O2::)
set_property(TARGET ${target} PROPERTY EXPORT_NAME ${baseTargetName})
# output name of the lib will be libO2[baseTargetName].(so|dylib|a)
set_property(TARGET ${target} PROPERTY OUTPUT_NAME O2${baseTargetName})
if(A_TARGETVARNAME)
set(${A_TARGETVARNAME} ${target} PARENT_SCOPE)
endif()
# Start by adding the public dependencies to other targets
if(A_PUBLIC_LINK_LIBRARIES)
foreach(L IN LISTS A_PUBLIC_LINK_LIBRARIES)
string(FIND ${L} "::" NS)
if(${NS} EQUAL -1)
message(FATAL_ERROR "Trying to use a non-namespaced target ${L}")
endif()
target_link_libraries(${target} PUBLIC ${L})
endforeach()
endif()
# Then add the private dependencies to other targets
if(A_PRIVATE_LINK_LIBRARIES)
foreach(L IN LISTS A_PRIVATE_LINK_LIBRARIES)
string(FIND ${L} "::" NS)
if(${NS} EQUAL -1)
message(FATAL_ERROR "Trying to use a non-namespaced target ${L}")
endif()
target_link_libraries(${target} PRIVATE ${L})
endforeach()
endif()
# set the public include directories if available
if(A_PUBLIC_INCLUDE_DIRECTORIES)
foreach(d IN LISTS A_PUBLIC_INCLUDE_DIRECTORIES)
get_filename_component(adir ${d} ABSOLUTE)
if(NOT IS_DIRECTORY ${adir})
message(
FATAL_ERROR "Trying to append non existing include directory ${d}")
endif()
target_include_directories(${target} PUBLIC $)
endforeach()
else()
# use sane default (if it exists)
if(IS_DIRECTORY ${CMAKE_CURRENT_LIST_DIR}/include)
target_include_directories(
${target}
PUBLIC $)
endif()
endif()
# set the private include directories if available
if(A_PRIVATE_INCLUDE_DIRECTORIES)
foreach(d IN LISTS A_PRIVATE_INCLUDE_DIRECTORIES)
get_filename_component(adir ${d} ABSOLUTE)
if(NOT IS_DIRECTORY ${adir})
message(
FATAL_ERROR "Trying to append non existing include directory ${d}")
endif()
target_include_directories(${target} PRIVATE $)
endforeach()
else()
# use sane(?) default
target_include_directories(
${target}
PRIVATE $)
get_filename_component(adir ${CMAKE_CURRENT_LIST_DIR}/src ABSOLUTE)
if(EXISTS ${adir})
target_include_directories(
${target}
PRIVATE $)
endif()
endif()
if(EXISTS ${CMAKE_CURRENT_LIST_DIR}/include/${baseTargetName})
# The INCLUDES DESTINATION adds ${CMAKE_INSTALL_INCLUDEDIR} to the
# INTERFACE_INCLUDE_DIRECTORIES property
#
# The EXPORT must come first in the list of parameters
#
install(TARGETS ${target}
EXPORT O2Targets
INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR})
# install all the includes found in
# ${CMAKE_CURRENT_LIST_DIR}/include/${baseTargetName} as those are public
# headers
install(DIRECTORY ${CMAKE_CURRENT_LIST_DIR}/include/${baseTargetName}
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
else()
# The EXPORT must come first in the list of parameters
#
install(TARGETS ${target}
EXPORT O2Targets
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR})
endif()
endfunction()