cmake: improve package config file

(cherry picked from commit dc4be869d5009f38e0ef02ff07dd799f9c2fef2f)
This commit is contained in:
yuangongji 2019-11-07 18:26:47 +08:00 committed by Azat Khuzhin
parent 976f7d34ff
commit 1c047618ba
5 changed files with 265 additions and 81 deletions

2
.gitignore vendored
View File

@ -131,7 +131,7 @@ CTestTestfile.cmake
DartConfiguration.tcl
LibeventConfig.cmake
LibeventConfigVersion.cmake
LibeventTargets.cmake
LibeventTargets*.cmake
bin/
cmake_install.cmake
Uninstall.cmake

View File

@ -939,19 +939,21 @@ configure_file(
include(AddEventLibrary)
add_event_library(event_core SOURCES ${SRC_CORE})
add_event_library(event_extra
LIBRARIES event_core_shared
INNER_LIBRARIES event_core
SOURCES ${SRC_EXTRA})
if (NOT EVENT__DISABLE_OPENSSL)
add_event_library(event_openssl
LIBRARIES event_core_shared ${OPENSSL_LIBRARIES}
INNER_LIBRARIES event_core
OUTER_INCLUDES ${OPENSSL_INCLUDE_DIR}
LIBRARIES ${OPENSSL_LIBRARIES}
SOURCES ${SRC_OPENSSL})
endif()
if (CMAKE_USE_PTHREADS_INIT)
set(SRC_PTHREADS evthread_pthread.c)
add_event_library(event_pthreads
LIBRARIES event_core_shared
INNER_LIBRARIES event_core
SOURCES ${SRC_PTHREADS})
endif()
@ -1439,18 +1441,24 @@ endif()
# Installation preparation.
#
if(WIN32 AND NOT CYGWIN)
set(DEF_INSTALL_CMAKE_DIR cmake)
else()
set(DEF_INSTALL_CMAKE_DIR lib/cmake/libevent)
endif()
set(EVENT_INSTALL_CMAKE_DIR
"${CMAKE_INSTALL_PREFIX}/${DEF_INSTALL_CMAKE_DIR}"
CACHE PATH "Installation directory for CMake files")
"${CMAKE_INSTALL_PREFIX}/lib/cmake/libevent")
export(PACKAGE libevent)
function(gen_package_config forinstall)
if(${forinstall})
set(CONFIG_FOR_INSTALL_TREE 1)
set(dir "${PROJECT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}")
else()
set(CONFIG_FOR_INSTALL_TREE 0)
set(dir "${PROJECT_BINARY_DIR}")
endif()
configure_file(${PROJECT_SOURCE_DIR}/cmake/LibeventConfig.cmake.in
"${dir}/LibeventConfig.cmake"
@ONLY)
endfunction()
# Generate the config file for the build-tree.
set(EVENT__INCLUDE_DIRS
"${PROJECT_SOURCE_DIR}/include"
@ -1460,26 +1468,10 @@ set(LIBEVENT_INCLUDE_DIRS
${EVENT__INCLUDE_DIRS}
CACHE PATH "Libevent include directories")
configure_file(${PROJECT_SOURCE_DIR}/cmake/LibeventConfigBuildTree.cmake.in
${PROJECT_BINARY_DIR}/LibeventConfig.cmake
@ONLY)
gen_package_config(0)
# Generate the config file for the installation tree.
# Calculate the relative directory from the Cmake dir.
file(RELATIVE_PATH
REL_INCLUDE_DIR
"${EVENT_INSTALL_CMAKE_DIR}"
"${CMAKE_INSTALL_PREFIX}/include")
# Note the LIBEVENT_CMAKE_DIR is defined in LibeventConfig.cmake.in,
# we escape it here so it's evaluated when it is included instead
# so that the include dirs are given relative to where the
# config file is located.
set(EVENT_INSTALL_INCLUDE_DIR "\${LIBEVENT_CMAKE_DIR}/${REL_INCLUDE_DIR}")
configure_file(${PROJECT_SOURCE_DIR}/cmake/LibeventConfig.cmake.in
${PROJECT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/LibeventConfig.cmake
@ONLY)
gen_package_config(1)
# Generate version info for both build-tree and install-tree.
configure_file(${PROJECT_SOURCE_DIR}/cmake/LibeventConfigVersion.cmake.in
@ -1504,9 +1496,19 @@ install(FILES
COMPONENT dev)
# Install exports for the install-tree.
install(EXPORT LibeventTargets
DESTINATION "${DEF_INSTALL_CMAKE_DIR}"
macro(install_export type)
install(EXPORT LibeventTargets-${type}
NAMESPACE ${PROJECT_NAME}::
DESTINATION "${EVENT_INSTALL_CMAKE_DIR}"
COMPONENT dev)
endmacro()
if (${EVENT_LIBRARY_STATIC})
install_export(static)
endif()
if (${EVENT_LIBRARY_SHARED})
install_export(shared)
endif()
# Install the scripts.
install(PROGRAMS

View File

@ -35,6 +35,45 @@ macro(generate_pkgconfig LIB_NAME)
)
endmacro()
# LIB_NAME maybe event_core, event_extra, event_openssl, event_pthreads or event.
# Targets whose LIB_NAME is not 'event' should be exported and installed.
macro(export_install_target TYPE LIB_NAME OUTER_INCLUDES)
if("${LIB_NAME}" STREQUAL "event")
install(TARGETS "${LIB_NAME}_${TYPE}"
LIBRARY DESTINATION "lib" COMPONENT lib
ARCHIVE DESTINATION "lib" COMPONENT lib
RUNTIME DESTINATION "lib" COMPONENT lib
COMPONENT dev
)
else()
string(REPLACE "event_" "" PURE_NAME ${LIB_NAME})
string(TOUPPER ${TYPE} UPPER_TYPE)
list(APPEND LIBEVENT_${UPPER_TYPE}_LIBRARIES "${PURE_NAME}")
set(OUTER_INCS)
if (NOT "${OUTER_INCLUDES}" STREQUAL "NONE")
set(OUTER_INCS ${OUTER_INCLUDES})
endif()
target_include_directories("${LIB_NAME}_${TYPE}"
PUBLIC "$<INSTALL_INTERFACE:include>"
"$<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/include>"
"$<BUILD_INTERFACE:${PROJECT_BINARY_DIR}/include>"
${OUTER_INCS}
)
set_target_properties("${LIB_NAME}_${TYPE}" PROPERTIES EXPORT_NAME ${PURE_NAME})
export(TARGETS "${LIB_NAME}_${TYPE}"
NAMESPACE ${PROJECT_NAME}::
FILE "${PROJECT_BINARY_DIR}/LibeventTargets-${TYPE}.cmake"
APPEND
)
install(TARGETS "${LIB_NAME}_${TYPE}"
EXPORT LibeventTargets-${TYPE}
LIBRARY DESTINATION "lib" COMPONENT lib
ARCHIVE DESTINATION "lib" COMPONENT lib
RUNTIME DESTINATION "lib" COMPONENT lib
COMPONENT dev
)
endif()
endmacro()
# Global variables that it uses:
# - EVENT_ABI_LIBVERSION
@ -55,11 +94,13 @@ macro(add_event_library LIB_NAME)
cmake_parse_arguments(LIB
"" # Options
"VERSION" # One val
"SOURCES;LIBRARIES" # Multi val
"SOURCES;LIBRARIES;INNER_LIBRARIES;OUTER_INCLUDES" # Multi val
${ARGN}
)
set(ADD_EVENT_LIBRARY_TARGETS)
if ("${LIB_OUTER_INCLUDES}" STREQUAL "")
set(LIB_OUTER_INCLUDES NONE)
endif()
set(ADD_EVENT_LIBRARY_INTERFACE)
if (${EVENT_LIBRARY_STATIC})
@ -68,18 +109,30 @@ macro(add_event_library LIB_NAME)
OUTPUT_NAME "${LIB_NAME}"
CLEAN_DIRECT_OUTPUT 1)
list(APPEND LIBEVENT_STATIC_LIBRARIES "${LIB_NAME}_static")
list(APPEND ADD_EVENT_LIBRARY_TARGETS "${LIB_NAME}_static")
if(LIB_INNER_LIBRARIES)
set(INNER_LIBRARIES "${LIB_INNER_LIBRARIES}_static")
endif()
target_link_libraries("${LIB_NAME}_static"
${CMAKE_THREAD_LIBS_INIT}
${LIB_PLATFORM}
${INNER_LIBRARIES}
${LIB_LIBRARIES})
export_install_target(static "${LIB_NAME}" "${LIB_OUTER_INCLUDES}")
set(ADD_EVENT_LIBRARY_INTERFACE "${LIB_NAME}_static")
endif()
if (${EVENT_LIBRARY_SHARED})
add_library("${LIB_NAME}_shared" SHARED ${LIB_SOURCES})
if(LIB_INNER_LIBRARIES)
set(INNER_LIBRARIES "${LIB_INNER_LIBRARIES}_shared")
endif()
target_link_libraries("${LIB_NAME}_shared"
${CMAKE_THREAD_LIBS_INIT}
${LIB_PLATFORM}
${INNER_LIBRARIES}
${LIB_LIBRARIES})
if (EVENT_SHARED_FLAGS)
@ -120,29 +173,16 @@ macro(add_event_library LIB_NAME)
WORKING_DIRECTORY "lib")
endif()
list(APPEND LIBEVENT_SHARED_LIBRARIES "${LIB_NAME}_shared")
list(APPEND ADD_EVENT_LIBRARY_TARGETS "${LIB_NAME}_shared")
export_install_target(shared "${LIB_NAME}" "${LIB_OUTER_INCLUDES}")
set(ADD_EVENT_LIBRARY_INTERFACE "${LIB_NAME}_shared")
endif()
export(TARGETS ${ADD_EVENT_LIBRARY_TARGETS}
FILE "${PROJECT_BINARY_DIR}/LibeventTargets.cmake"
APPEND
)
install(TARGETS ${ADD_EVENT_LIBRARY_TARGETS}
EXPORT LibeventTargets
LIBRARY DESTINATION "lib" COMPONENT lib
ARCHIVE DESTINATION "lib" COMPONENT lib
RUNTIME DESTINATION "lib" COMPONENT lib
COMPONENT dev
)
if (NOT WIN32 AND ${EVENT_LIBRARY_SHARED})
install(FILES
"$<TARGET_FILE_DIR:${LIB_NAME}_shared>/${LIB_LINK_NAME}"
DESTINATION "lib"
COMPONENT lib)
if (NOT WIN32)
install(FILES
"$<TARGET_FILE_DIR:${LIB_NAME}_shared>/${LIB_LINK_NAME}"
DESTINATION "lib"
COMPONENT lib)
endif()
endif()
add_library(${LIB_NAME} INTERFACE)

View File

@ -1,18 +1,177 @@
# - Config file for the Libevent package
# It defines the following variables
# LIBEVENT_INCLUDE_DIRS - include directories
# LIBEVENT_FOUND - true if libevent and all required components found on the system
# LIBEVENT_xxx_FOUND - true if component xxx(see available components) found on the system
# LIBEVENT_VERSION - libevent version in format Major.Minor.Patch
# LIBEVENT_INCLUDE_DIRS - directories where libevent header is located.
# LIBEVENT_INCLUDE_DIR - same as DIRS
# LIBEVENT_LIBRARIES - libevent library to link against.
# LIBEVENT_LIBRARY - same as LIBRARIES
#
# These variables are deprecated, don't use them.
# LIBEVENT_STATIC_LIBRARIES - libraries to link against (archive/static)
# LIBEVENT_SHARED_LIBRARIES - libraries to link against (shared)
#
# When you try to locate the libevent libraries, you should specify which components you want to use.
# The following table lists all available components. If none is given, all imported targets will used.
# core - the core functons of libevent
# extra - extra functions, contains http, dns and rpc
# pthreads - multiple threads for libevent, not exists on Windows
# openssl - openssl support for libevent
#
# By default, the shared libraries of libevent will be found. To find the static ones instead,
# you must set the LIBEVENT_STATIC_LINK variable to TRUE before calling find_package(Libevent ...).
# If no component provided, all components will be used.
# example:
# set(LIBEVENT_STATIC_LINK TRUE)
# find_package(Libevent 2.2 REQUIRED COMPONENTS core)
# include_directories(${LIBEVENT_INCLUDE_DIRS}) # Can be omitted
# target_link_libraries(myapp ${LIBEVENT_LIBRARIES})
# or target_link_libraries(myapp libevent::core)
#
# find_package() can handle dependencies automatically. For example, given the 'openssl' component,
# all dependencies (libevent_core, libssl, libcrypto and openssl include directories) will be found.
# Get the path of the current file.
get_filename_component(LIBEVENT_CMAKE_DIR "${CMAKE_CURRENT_LIST_FILE}" PATH)
set(CONFIG_FOR_INSTALL_TREE @CONFIG_FOR_INSTALL_TREE@)
# Set the include directories.
set(LIBEVENT_INCLUDE_DIRS "@EVENT_INSTALL_INCLUDE_DIR@")
# Include the project Targets file, this contains definitions for IMPORTED targets.
include(${LIBEVENT_CMAKE_DIR}/LibeventTargets.cmake)
set(LIBEVENT_VERSION @EVENT_PACKAGE_VERSION@)
# IMPORTED targets from LibeventTargets.cmake
set(LIBEVENT_STATIC_LIBRARIES "@LIBEVENT_STATIC_LIBRARIES@")
set(LIBEVENT_SHARED_LIBRARIES "@LIBEVENT_SHARED_LIBRARIES@")
if(LIBEVENT_STATIC_LINK)
set(_LIB_TYPE static)
set(CMAKE_FIND_LIBRARY_SUFFIXES ${CMAKE_STATIC_LIBRARY_SUFFIX})
set(_AVAILABLE_LIBS ${LIBEVENT_STATIC_LIBRARIES})
else()
set(_LIB_TYPE shared)
set(CMAKE_FIND_LIBRARY_SUFFIXES ${CMAKE_SHARED_LIBRARY_SUFFIX})
set(_AVAILABLE_LIBS ${LIBEVENT_SHARED_LIBRARIES})
endif()
# Get the path of the current file.
get_filename_component(LIBEVENT_CMAKE_DIR "${CMAKE_CURRENT_LIST_FILE}" PATH)
get_filename_component(_INSTALL_PREFIX "${LIBEVENT_CMAKE_DIR}/../../.." ABSOLUTE)
macro(message_if_needed _flag _msg)
if (NOT ${CMAKE_FIND_PACKAGE_NAME}_FIND_QUIETLY)
message(${_flag} "${_msg}")
endif()
endmacro()
macro(no_component_msg _comp)
if(${CMAKE_FIND_PACKAGE_NAME}_FIND_REQUIRED_${_comp})
set(pthreadlib)
if(NOT WIN32)
set(pthreadlib ", pthreads")
endif()
message(FATAL_ERROR "Your libevent library does not contain a ${_comp} component!\n"
"The valid components are core, extra${pthreadlib} and openssl.")
else()
message_if_needed(WARNING "Your libevent library does not contain a ${_comp} component!")
endif()
endmacro()
set(_EVENT_COMPONENTS)
if(${CMAKE_FIND_PACKAGE_NAME}_FIND_COMPONENTS)
list(REMOVE_DUPLICATES ${CMAKE_FIND_PACKAGE_NAME}_FIND_COMPONENTS)
foreach(_comp ${${CMAKE_FIND_PACKAGE_NAME}_FIND_COMPONENTS})
list(FIND _AVAILABLE_LIBS ${_comp} _INDEX)
if(_INDEX GREATER -1)
list(APPEND _EVENT_COMPONENTS ${_comp})
else()
no_component_msg(${_comp})
endif()
endforeach()
else()
set(_EVENT_COMPONENTS ${_AVAILABLE_LIBS})
endif()
set(_POSSIBLE_PKG_NAMES)
list(APPEND _POSSIBLE_PKG_NAMES ${CMAKE_FIND_PACKAGE_NAME} LIBEVENT Libevent libevent)
list(REMOVE_DUPLICATES _POSSIBLE_PKG_NAMES)
macro(set_case_insensitive_found _comp)
foreach(name ${_POSSIBLE_PKG_NAMES})
if("${_comp}" STREQUAL "")
set(${name}_FOUND TRUE)
set(${name}_NOTFOUND FALSE)
else()
set(${name}_${_comp}_FOUND TRUE)
set(${name}_${_comp}_NOTFOUND FALSE)
endif()
endforeach()
endmacro()
if(CONFIG_FOR_INSTALL_TREE)
## Config for install tree ----------------------------------------
# Find includes
unset(_event_h CACHE)
find_path(_event_h
NAMES event2/event.h
PATHS "${_INSTALL_PREFIX}/include"
NO_DEFAULT_PATH)
if(_event_h)
set(LIBEVENT_INCLUDE_DIRS "${_event_h}")
message_if_needed(STATUS "Found libevent include directory: ${_event_h}")
else()
message_if_needed(WARNING "Your libevent library does not contain header files!")
endif()
# Find libraries
macro(find_event_lib _comp)
unset(_event_lib CACHE)
find_library(_event_lib
NAMES "event_${_comp}"
PATHS "${_INSTALL_PREFIX}/lib"
NO_DEFAULT_PATH)
if(_event_lib)
list(APPEND LIBEVENT_LIBRARIES "libevent::${_comp}")
set_case_insensitive_found(${_comp})
message_if_needed(STATUS "Found libevent component: ${_event_lib}")
else()
no_component_msg(${_comp})
endif()
endmacro()
foreach(comp ${_EVENT_COMPONENTS})
find_event_lib(${comp})
endforeach()
else()
## Config for build tree ----------------------------------------
set(LIBEVENT_INCLUDE_DIRS "@EVENT__INCLUDE_DIRS@")
foreach(_comp ${_EVENT_COMPONENTS})
list(APPEND LIBEVENT_LIBRARIES "libevent::${_comp}")
set_case_insensitive_found(${_comp})
endforeach()
endif()
set(LIBEVENT_INCLUDE_DIR ${LIBEVENT_INCLUDE_DIRS})
if(LIBEVENT_LIBRARIES)
set(LIBEVENT_LIBRARY ${LIBEVENT_LIBRARIES})
if(CONFIG_FOR_INSTALL_TREE)
message_if_needed(STATUS "Found libevent ${LIBEVENT_VERSION} in ${_INSTALL_PREFIX}")
else()
message_if_needed(STATUS "Found libevent ${LIBEVENT_VERSION} in ${LIBEVENT_CMAKE_DIR}")
endif()
# Avoid including targets more than one times
if(NOT TARGET event_core_${_LIB_TYPE})
# Include the project Targets file, this contains definitions for IMPORTED targets.
include(${LIBEVENT_CMAKE_DIR}/LibeventTargets-${_LIB_TYPE}.cmake)
endif()
else()
if(${CMAKE_FIND_PACKAGE_NAME}_FIND_REQUIRED)
message(FATAL_ERROR "Can not find any libraries for libevent.")
else()
message_if_needed(WARNING "Can not find any libraries for libevent.")
endif()
endif()
unset(_LIB_TYPE)
unset(_AVAILABLE_LIBS)
unset(_EVENT_COMPONENTS)
unset(_POSSIBLE_PKG_NAMES)
unset(_INSTALL_PREFIX)

View File

@ -1,17 +0,0 @@
# - Config file for the Libevent package
# It defines the following variables
# LIBEVENT_INCLUDE_DIRS - include directories for FooBar
# LIBEVENT_LIBRARIES - libraries to link against
# Get the path of the current file.
get_filename_component(LIBEVENT_CMAKE_DIR "${CMAKE_CURRENT_LIST_FILE}" PATH)
# Set the include directories.
set(LIBEVENT_INCLUDE_DIRS "@EVENT__INCLUDE_DIRS@")
# Include the project Targets file, this contains definitions for IMPORTED targets.
include(${LIBEVENT_CMAKE_DIR}/LibeventTargets.cmake)
# IMPORTED targets from LibeventTargets.cmake
set(LIBEVENT_LIBRARIES event event_core event_extra)