]> granicus.if.org Git - libevent/commitdiff
cmake: improve package config file
authoryuangongji <82787816@qq.com>
Thu, 7 Nov 2019 10:26:47 +0000 (18:26 +0800)
committeryuangongji <82787816@qq.com>
Thu, 14 Nov 2019 10:09:31 +0000 (18:09 +0800)
.gitignore
CMakeLists.txt
cmake/AddEventLibrary.cmake
cmake/LibeventConfig.cmake.in
cmake/LibeventConfigBuildTree.cmake.in [deleted file]

index 703cf9576a2f991cd0ecbb3a5b9f3108a65dbcdc..ab7965c96ef40d07d4ec2723103d593629bd85a6 100644 (file)
@@ -134,7 +134,7 @@ CTestTestfile.cmake
 DartConfiguration.tcl
 LibeventConfig.cmake
 LibeventConfigVersion.cmake
-LibeventTargets.cmake
+LibeventTargets*.cmake
 bin/
 cmake_install.cmake
 Uninstall.cmake
index c98b619adfdedce676363f643068fc5d5982cd7e..5b2537d5bd67c22945b4eb3768f2fcc2c4990b2f 100644 (file)
@@ -943,19 +943,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()
 
@@ -1449,18 +1451,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"
@@ -1470,26 +1478,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
@@ -1514,9 +1506,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
index 52dc2be65675bc5d3fef1fe27d5f1059a64342fe..4a6802df14d8551bd3ba092b31187b925f364923 100644 (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)
index 54223360a44349e584548999dbe92514ac5f7b26..5e2a3d8d20381056a3019e28a9cc8735cd15af6f 100644 (file)
 # - 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 the include directories.
-set(LIBEVENT_INCLUDE_DIRS "@EVENT_INSTALL_INCLUDE_DIR@")
+set(CONFIG_FOR_INSTALL_TREE @CONFIG_FOR_INSTALL_TREE@)
 
-# 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)
diff --git a/cmake/LibeventConfigBuildTree.cmake.in b/cmake/LibeventConfigBuildTree.cmake.in
deleted file mode 100644 (file)
index 02edef3..0000000
+++ /dev/null
@@ -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)
-