# (C) Copyright 2020- UCAR. # # Find the GPTL: General Purpose Timing Library (https://jmrosinski.github.io/GPTL/) # # This find module sets the following variables and targets: # # Variables: # GPTL_FOUND - True if GPTL was found # GPTL_VERSION_STRING - Version of installed GPTL # GPTL_BIN_DIR - GPTL binary directory # GPTL_HAS_PKG_CONFIG - GPTL was found with installed `gptl.pc` and pkg-config. This indicates full support # for compiler and linker flags as exported by GPTL. # Targets: # GPTL::GPTL - Imported interface target to pass to target_link_libraries() # # NOTE: This find modules uses `pkg-config` to locate GPTL and glean the appropriate flags, directories, # and link dependency ordering. For this to work, both a `pkg-config` executable and a `gptl.pc` # config file need to be found. # * To find the `pkg-config` executable, ensure it is on your PATH. # * For non-standard locations the official CMake FindPkgConfig uses Cmake variable `PKG_CONFIG_EXECUTABLE` # or environment variable `PKG_CONFIG`. See: https://cmake.org/cmake/help/latest/module/FindPkgConfig.html # * To find `gptl.pc` ensure it is on the (colon-separated) directories listed in standard pkg-config # environment variable `PKG_CONFIG_PATH`. # * See: https://linux.die.net/man/1/pkg-config # * A working GPTL pkg-config install can be confirmed on the command line, e.g., # ``` # $ pkg-config --modversion gptl # 8.0.2 # ``` # To set a non-standard location for GPTL, ensure the correct `gptl.pc` pkg config file is found first # on the environment's `PKG_CONFIG_PATH`. This can be checked with the pkg-config executable, e.g., # ``` # $ pkg-config --variable=prefix gptl # /usr/local # ``` # Only when pkg-config is not supported or available, GPTL will be searched by the standard CMake search procedures. # Set environment or CMake variable GPTL_ROOT to control this search. The GPTL_ROOT variable will have no effect # if GPTL_HAS_PKG_CONFIG=True. # find_package(PkgConfig QUIET) if(PKG_CONFIG_FOUND) message(DEBUG "[FindGPTL] Using PKG_CONFIG_EXECUTABLE:${PKG_CONFIG_EXECUTABLE}") endif() #Helper: #check_pkg_config(ret_var pcname pcflags...) # Check if pcname is known to pkg-config # Returns: # Boolean: true if ${pcname}.pc file is found by pkg-config). # Args: # ret_var: return variable name. # pcname: pkg-config name to look for (.pc file) function(check_pkg_config ret_var pcname) if(NOT PKG_CONFIG_FOUND OR NOT EXISTS ${PKG_CONFIG_EXECUTABLE}) set(${ret_var} False PARENT_SCOPE) else() execute_process(COMMAND ${PKG_CONFIG_EXECUTABLE} --exists ${pcname} RESULT_VARIABLE _found) if(_found EQUAL 0) set(${ret_var} True PARENT_SCOPE) else() set(${ret_var} False PARENT_SCOPE) endif() endif() endfunction() #Helper: #get_pkg_config(ret_var pcname pcflags...) # Get the output of pkg-config # Args: # ret_var: return variable name # pcname: pkg-config name to look for (.pc file) # pcflags: pkg-config flags to pass function(get_pkg_config ret_var pcname pcflags) execute_process(COMMAND ${PKG_CONFIG_EXECUTABLE} ${ARGN} ${pcname} ${pcflags} OUTPUT_VARIABLE _out RESULT_VARIABLE _ret OUTPUT_STRIP_TRAILING_WHITESPACE) if(_ret EQUAL 0) separate_arguments(_out) set(${ret_var} ${_out} PARENT_SCOPE) else() set(${ret_var} "" PARENT_SCOPE) endif() endfunction() check_pkg_config(GPTL_HAS_PKG_CONFIG gptl) if(GPTL_HAS_PKG_CONFIG) #Use pkg-config to find the prefix, flags, directories, executables, and libraries get_pkg_config(GPTL_VERSION_STRING gptl --modversion) get_pkg_config(GPTL_PREFIX gptl --variable=prefix) get_pkg_config(GPTL_INCLUDE_DIR gptl --cflags-only-I) if(GPTL_INCLUDE_DIR) string(REGEX REPLACE "-I([^ ]+)" "\\1" GPTL_INCLUDE_DIR ${GPTL_INCLUDE_DIR}) #Remove -I endif() if(NOT EXISTS ${GPTL_INCLUDE_DIR}) find_path(GPTL_INCLUDE_DIR NAMES gptl.h PATH_SUFFIXES include include/gptl PATHS ${GPTL_PREFIX} NO_DEFAULT_PATH) endif() find_path(GPTL_MODULE_DIR NAMES gptl.mod PATH_SUFFIXES include include/gptl module module/gptl PATHS ${GPTL_PREFIX} NO_DEFAULT_PATH) get_pkg_config(GPTL_COMPILE_OPTIONS gptl --cflags-only-other) get_pkg_config(GPTL_LINK_LIBRARIES gptl --libs-only-l) get_pkg_config(GPTL_LINK_DIRECTORIES gptl --libs-only-L) if(GPTL_LINK_DIRECTORIES) string(REGEX REPLACE "-L([^ ]+)" "\\1" GPTL_LINK_DIRECTORIES ${GPTL_LINK_DIRECTORIES}) #Remove -L endif() get_pkg_config(GPTL_LINK_OPTIONS gptl --libs-only-other) find_library(GPTL_LIBRARY NAMES gptl PATH_SUFFIXES lib lib64 PATHS ${GPTL_PREFIX} NO_DEFAULT_PATH) find_path(GPTL_BIN_DIR NAMES gptl_avail gran_overhead print_mpistatus_size PATH_SUFFIXES bin PATHS ${GPTL_PREFIX} NO_DEFAULT_PATH) else() #Attempt to find GPTL without pkg-config as last resort. if(NOT EXISTS ${PKG_CONFIG_EXECUTABLE}) message(WARNING "\ FindGPTL: The `pkg-config` executable was not found. Ensure it is on your path or set \ environment variable PKG_CONFIG to your pkg-config executable. \ Attempting to find GPTL without pkg-config support may cause some required compiler and linker options to be unset.") else() message(WARNING "\ FindGPTL: The `pkg-config` executable was found at: ${PKG_CONFIG_EXECUTABLE}. However no `gptl.pc` file was found on \ PKG_CONFIG_PATH='$ENV{PKG_CONFIG_PATH}'. \ Attempting to find GPTL without pkg-config support may cause some required compiler and linker options to be unset.") endif() find_path(GPTL_INCLUDE_DIR NAMES gptl.h PATH_SUFFIXES include include/gptl) find_path(GPTL_MODULE_DIR NAMES gptl.mod PATH_SUFFIXES include include/gptl module module/gptl) find_library(GPTL_LIBRARY NAMES gptl PATH_SUFFIXES lib lib64) find_path(GPTL_BIN_DIR NAMES gptl_avail gran_overhead print_mpistatus_size PATH_SUFFIXES bin) endif() #Hide non-documented cache variables reserved for internal/advanced usage mark_as_advanced( GPTL_INCLUDE_DIR GPTL_MODULE_DIR GPTL_LIBRARY ) #Debugging output message(DEBUG "[FindGPTL] GPTL_FOUND: ${GPTL_FOUND}") message(DEBUG "[FindGPTL] GPTL_VERSION_STRING: ${GPTL_VERSION_STRING}") message(DEBUG "[FindGPTL] GPTL_HAS_PKG_CONFIG: ${GPTL_HAS_PKG_CONFIG}") message(DEBUG "[FindGPTL] GPTL_PREFIX: ${GPTL_PREFIX}") message(DEBUG "[FindGPTL] GPTL_BIN_DIR: ${GPTL_BIN_DIR}") message(DEBUG "[FindGPTL] GPTL_INCLUDE_DIR: ${GPTL_INCLUDE_DIR}") message(DEBUG "[FindGPTL] GPTL_MODULE_DIR: ${GPTL_MODULE_DIR}") message(DEBUG "[FindGPTL] GPTL_LIBRARY: ${GPTL_LIBRARY}") message(DEBUG "[FindGPTL] GPTL_LINK_LIBRARIES: ${GPTL_LINK_LIBRARIES}") message(DEBUG "[FindGPTL] GPTL_LINK_DIRECTORIES: ${GPTL_LINK_DIRECTORIES}") message(DEBUG "[FindGPTL] GPTL_LINK_OPTIONS: ${GPTL_LINK_OPTIONS}") #Check package has been found correctly include(FindPackageHandleStandardArgs) find_package_handle_standard_args( GPTL REQUIRED_VARS GPTL_LIBRARY GPTL_INCLUDE_DIR GPTL_MODULE_DIR GPTL_BIN_DIR VERSION_VAR GPTL_VERSION_STRING ) #Create GPTL::GPTL imported interface target if(GPTL_FOUND AND NOT TARGET GPTL::GPTL) add_library(GPTL::GPTL INTERFACE IMPORTED) set_property(TARGET GPTL::GPTL PROPERTY INTERFACE_INCLUDE_DIRECTORIES ${GPTL_INCLUDE_DIR}) if(GPTL_MODULE_DIR) set_property(TARGET GPTL::GPTL APPEND PROPERTY INTERFACE_INCLUDE_DIRECTORIES ${GPTL_MODULE_DIR}) endif() if(GPTL_COMPILE_OPTIONS) set_property(TARGET GPTL::GPTL PROPERTY INTERFACE_COMPILE_OPTIONS ${GPTL_COMPILE_OPTIONS}) endif() if(GPTL_LINK_DIRECTORIES) set_property(TARGET GPTL::GPTL PROPERTY INTERFACE_LINK_DIRECTORIES ${GPTL_LINK_DIRECTORIES}) endif() if(GPTL_LINK_OPTIONS) set_property(TARGET GPTL::GPTL PROPERTY INTERFACE_LINK_OPTIONS ${GPTL_LINK_OPTIONS}) endif() if(GPTL_LINK_LIBRARIES) set_property(TARGET GPTL::GPTL PROPERTY INTERFACE_LINK_LIBRARIES ${GPTL_LINK_LIBRARIES}) else() set_property(TARGET GPTL::GPTL PROPERTY INTERFACE_LINK_LIBRARIES ${GPTL_LIBRARY}) get_filename_component(_lib_dir ${GPTL_LIBRARY} DIRECTORY) set_property(TARGET GPTL::GPTL APPEND PROPERTY INTERFACE_LINK_DIRECTORIES ${_lib_dir}) unset(_lib_dir) endif() endif()