# ### Macro: find_library_extended # # Finds libraries with finer control over search paths # for compilers with multiple configuration types. # macro(find_library_extended prefix) include(CMakeParseArguments REQUIRED) # cmake_parse_arguments(prefix options singleValueArgs multiValueArgs ${ARGN}) cmake_parse_arguments(${prefix} "" "" "NAMES;NAMES_DEBUG;NAMES_RELEASE;PATHS_DEBUG;PATHS_RELEASE;PATHS" ${ARGN} ) # Reloading to ensure build always passes and picks up changes # This is more expensive but proves useful for fragmented libraries like WebRTC unset(${prefix}_LIBRARY_DEBUG CACHE) find_library(${prefix}_LIBRARY_DEBUG NAMES ${${prefix}_NAMES_DEBUG} ${${prefix}_NAMES} PATHS ${${prefix}_PATHS_DEBUG} ${${prefix}_PATHS} ) #if(NOT ${prefix}_PATHS_RELEASE) # list(APPEND ${prefix}_PATHS_RELEASE ${${prefix}_PATHS}) #endif() unset(${prefix}_LIBRARY_RELEASE CACHE) find_library(${prefix}_LIBRARY_RELEASE NAMES ${${prefix}_NAMES_RELEASE} ${${prefix}_NAMES} PATHS ${${prefix}_PATHS_RELEASE} ${${prefix}_PATHS} ) include(${CMAKE_ROOT}/Modules/SelectLibraryConfigurations.cmake) select_library_configurations(${prefix}) # print_module_variables(${prefix}) # message("*** Find library for ${prefix}") # message("Debug Library: ${${prefix}_LIBRARY_DEBUG}") # message("Release Library: ${${prefix}_LIBRARY_RELEASE}") # message("Library: ${${prefix}_LIBRARY}") # message("Debug Paths: ${${prefix}_PATHS_RELEASE}") # message("Release Paths: ${${prefix}_PATHS_DEBUG}") # message("Paths: ${${prefix}_PATHS}") # message("Debug Names: ${${prefix}_NAMES_RELEASE}") # message("Release Names: ${${prefix}_NAMES_DEBUG}") # message("Names: ${${prefix}_NAMES}") endmacro(find_library_extended) # ### Macro: set_component_alias # # Sets the current module component alias variables. # macro(set_component_alias module component) set(ALIAS ${module}_${component}) set(ALIAS_FOUND ${ALIAS}_FOUND) set(ALIAS_LIBRARIES ${ALIAS}_LIBRARIES) set(ALIAS_LIBRARY_RELEASE ${ALIAS}_LIBRARY_RELEASE) set(ALIAS_LIBRARY_DEBUG ${ALIAS}_LIBRARY_DEBUG) set(ALIAS_INCLUDE_DIRS ${ALIAS}_INCLUDE_DIRS) set(ALIAS_LIBRARY_DIRS ${ALIAS}_LIBRARY_DIRS) set(ALIAS_DEFINITIONS ${ALIAS}_CFLAGS_OTHER) set(ALIAS_VERSION ${ALIAS}_VERSION) string(TOUPPER ${ALIAS} ALIAS_UPPER) endmacro() # ### Macro: set_module_found # # Marks the given module as found if all required components are present. # macro(set_module_found module) set(${module}_FOUND FALSE) # Compile the list of required vars set(_${module}_REQUIRED_VARS ${module}_LIBRARIES) # ${module}_INCLUDE_DIRS foreach (component ${${module}_FIND_COMPONENTS}) # NOTE: Not including XXX_INCLUDE_DIRS as required var since it may be empty list(APPEND _${module}_REQUIRED_VARS ${module}_${component}_LIBRARIES) # ${module}_${component}_INCLUDE_DIRS if (NOT ${module}_${component}_FOUND) if (${module}_FIND_REQUIRED) message(FATAL_ERROR "Required ${module} component ${component} missing. Please recompile ${module} with ${component} enabled.") endif() else() messageV(" - Required ${module} component ${component} found.") endif() endforeach() # Cache the vars. set(${module}_INCLUDE_DIRS ${${module}_INCLUDE_DIRS} CACHE STRING "The ${module} include directories." FORCE) set(${module}_LIBRARY_DIRS ${${module}_LIBRARY_DIRS} CACHE STRING "The ${module} library directories." FORCE) set(${module}_LIBRARIES ${${module}_LIBRARIES} CACHE STRING "The ${module} libraries." FORCE) set(${module}_FOUND ${${module}_FOUND} CACHE BOOLEAN "The ${module} found status." FORCE) # Ensure required variables have been set, or fail in error. # NOTE: Disabling find_package_handle_standard_args check since it's always # returning false even when variables are set. Maybe an internal CMake issue? # if (${module}_FIND_REQUIRED) # # # Give a nice error message if some of the required vars are missing. # include(FindPackageHandleStandardArgs) # find_package_handle_standard_args(${module} DEFAULT_MSG ${_${module}_REQUIRED_VARS}) # endif() # Set the module as found. if (${module}_LIBRARIES) set(${module}_FOUND TRUE) else() message(WARNING "Failed to locate ${module}. Please specify paths manually.") endif() mark_as_advanced(${module}_INCLUDE_DIRS ${module}_LIBRARY_DIRS ${module}_LIBRARIES ${module}_DEFINITIONS ${module}_FOUND) endmacro() # ### Macro: set_component_found # # Marks the given component as found if both *_LIBRARIES AND *_INCLUDE_DIRS are present. # macro(set_component_found module component) set_component_alias(${module} ${component}) messageV("${ALIAS_LIBRARIES}=${${ALIAS_LIBRARIES}}") messageV("${ALIAS_INCLUDE_DIRS}=${${ALIAS_INCLUDE_DIRS}}") messageV("${ALIAS_LIBRARY_DIRS}=${${ALIAS_LIBRARY_DIRS}}") #if (${module}_${component}_LIBRARIES AND ${module}_${component}_INCLUDE_DIRS) if (${ALIAS_LIBRARIES}) # AND ${ALIAS_INCLUDE_DIRS} (XXX_INCLUDE_DIRS may be empty) messageV(" - ${module} ${component} found.") set(${ALIAS_FOUND} TRUE) # set(${ALIAS_FOUND} TRUE PARENT_SCOPE) # Add component vars to the parent module lists append_unique_list(${module}_INCLUDE_DIRS ${ALIAS_INCLUDE_DIRS}) append_unique_list(${module}_LIBRARY_DIRS ${ALIAS_LIBRARY_DIRS}) append_unique_list(${module}_LIBRARIES ${ALIAS_LIBRARIES}) append_unique_list(${module}_DEFINITIONS ${ALIAS_DEFINITIONS}) # set(${module}_INCLUDE_DIRS ${${module}_INCLUDE_DIRS} PARENT_SCOPE) # set(${module}_LIBRARY_DIRS ${${module}_LIBRARY_DIRS} PARENT_SCOPE) # set(${module}_LIBRARIES ${${module}_LIBRARIES} PARENT_SCOPE) # set(${module}_DEFINITIONS ${${module}_DEFINITIONS} PARENT_SCOPE) # messageV("Find Component Paths=${module}:${component}:${library}:${header}") # messageV("${ALIAS_INCLUDE_DIRS}=${${ALIAS_INCLUDE_DIRS}}") # messageV("${ALIAS_LIBRARY_RELEASE}=${${ALIAS_LIBRARY_RELEASE}}") # messageV("${ALIAS_LIBRARY_DEBUG}=${${ALIAS_LIBRARY_DEBUG}}") # messageV("${ALIAS_LIBRARIES}=${${ALIAS_LIBRARIES}}") # messageV("${module}_INCLUDE_DIRS=${${module}_INCLUDE_DIRS}") # messageV("${module}_LIBRARIES=${${module}_LIBRARIES}") # Only mark as advanced when found mark_as_advanced(${ALIAS_INCLUDE_DIRS} ${ALIAS_LIBRARY_DIRS}) else() # NOTE: an error message will be displayed in set_module_found # if the module is REQUIRED messageV(" - ${module} ${component} not found.") endif() set(HAVE_${ALIAS} ${${ALIAS_FOUND}}) set(HAVE_${ALIAS_UPPER} ${${ALIAS_FOUND}}) get_directory_property(hasParent PARENT_DIRECTORY) if(hasParent) set(HAVE_${ALIAS} ${${ALIAS_FOUND}} PARENT_SCOPE) set(HAVE_${ALIAS_UPPER} ${${ALIAS_FOUND}} PARENT_SCOPE) endif() mark_as_advanced(${ALIAS_FOUND} ${ALIAS_LIBRARY_DEBUG} ${ALIAS_LIBRARY_RELEASE} ${ALIAS_LIBRARIES} ${ALIAS_DEFINITIONS} ${ALIAS_VERSION}) endmacro() # ### Macro: set_module_notfound # # Marks the given component as not found, and resets the cache for find_path and find_library results. # macro(set_module_notfound module) #messageV(" - Setting ${module} not found.") set(${module}_FOUND FALSE) #set(${module}_FOUND FALSE PARENT_SCOPE) if (CMAKE_CONFIGURATION_TYPES OR CMAKE_BUILD_TYPE) set(${module}_LIBRARY_RELEASE "") set(${module}_LIBRARY_DEBUG "") set(${module}_LIBRARIES "") #set(${module}_LIBRARY_RELEASE "" PARENT_SCOPE) #set(${module}_LIBRARY_DEBUG "" PARENT_SCOPE) #set(${module}_LIBRARIES "" PARENT_SCOPE) else() set(${module}_LIBRARIES ${ALIAS_LIBRARIES}-NOTFOUND) #set(${module}_LIBRARIES ${ALIAS_LIBRARIES}-NOTFOUND PARENT_SCOPE) endif() endmacro() # ### Macro: set_component_notfound # # Marks the given component as not found, and resets the cache for find_path and find_library results. # macro(set_component_notfound module component) set_component_alias(${module} ${component}) #messageV(" - Setting ${module} ${component} not found.") set(${ALIAS_FOUND} FALSE) #set(${ALIAS_FOUND} FALSE PARENT_SCOPE) set(${ALIAS_INCLUDE_DIRS} ${ALIAS_INCLUDE_DIRS}-NOTFOUND) if (${module}_MULTI_CONFIGURATION AND (CMAKE_CONFIGURATION_TYPES OR CMAKE_BUILD_TYPE)) set(${ALIAS_LIBRARY_RELEASE} ${ALIAS_LIBRARY_RELEASE}-NOTFOUND) set(${ALIAS_LIBRARY_DEBUG} ${ALIAS_LIBRARY_DEBUG}-NOTFOUND) set(${ALIAS_LIBRARIES} "") #${module}_${component}_LIBRARIES-NOTFOUND) #set(${ALIAS_LIBRARY_RELEASE} ${ALIAS_LIBRARY_RELEASE}-NOTFOUND PARENT_SCOPE) #set(${ALIAS_LIBRARY_DEBUG} ${ALIAS_LIBRARY_DEBUG}-NOTFOUND PARENT_SCOPE) #set(${ALIAS_LIBRARIES} "") #${module}_${component}_LIBRARIES-NOTFOUND PARENT_SCOPE) else() set(${ALIAS_LIBRARIES} ${ALIAS_LIBRARIES}-NOTFOUND) #set(${ALIAS_LIBRARIES} ${ALIAS_LIBRARIES}-NOTFOUND PARENT_SCOPE) endif() endmacro() # ### Macro: find_component_paths # # Finds the given component library and include paths. # macro(find_component_paths module component library header) messageV("Find Component Paths=${module}:${component}:${library}:${header}") messageV("INCLUDE_DIR: ${${module}_INCLUDE_DIR} HINTS: ${${module}_INCLUDE_HINTS}") #unset(${ALIAS_LIBRARY} CACHE) #unset(${ALIAS_LIBRARIES} CACHE) #unset(${ALIAS_LIBRARY_RELEASE} CACHE) #unset(${ALIAS_LIBRARY_DEBUG} CACHE) # Reset alias namespace (force recheck) #set_component_alias(${module} ${component}) #set_component_notfound(${module} ${component}) find_path(${ALIAS_INCLUDE_DIRS} ${header} HINTS ${${module}_INCLUDE_HINTS} PATHS ${${module}_INCLUDE_DIR} PATH_SUFFIXES ${${module}_INCLUDE_SUFFIXES} # try find from root module include suffixes ) # Create a Debug and a Release list for multi configuration builds. # NOTE: _CONFIGURATION_TYPES must be set to use this. if (${module}_MULTI_CONFIGURATION AND (CMAKE_CONFIGURATION_TYPES OR CMAKE_BUILD_TYPE)) find_library(${ALIAS_LIBRARY_RELEASE} NAMES ${library} HINTS ${${module}_LIBRARY_HINTS} PATHS ${${ALIAS_LIBRARY_DIRS}} ${${module}_LIBRARY_DIR} PATH_SUFFIXES ${${module}_LIBRARY_SUFFIXES} ) find_library(${ALIAS_LIBRARY_DEBUG} NAMES ${library}d HINTS ${${module}_LIBRARY_HINTS} PATHS ${${ALIAS_LIBRARY_DIRS}} ${${module}_LIBRARY_DIR} PATH_SUFFIXES ${${module}_LIBRARY_SUFFIXES} ) if (${ALIAS_LIBRARY_RELEASE}) list(APPEND ${ALIAS_LIBRARIES} optimized ${${ALIAS_LIBRARY_RELEASE}}) endif() if (${ALIAS_LIBRARY_DEBUG}) list(APPEND ${ALIAS_LIBRARIES} debug ${${ALIAS_LIBRARY_DEBUG}}) endif() #include(${CMAKE_ROOT}/Modules/SelectLibraryConfigurations.cmake) #select_library_configurations(${ALIAS}) # message(STATUS "ALIAS_INCLUDE_DIRS: ${${ALIAS_INCLUDE_DIRS}}") # message(STATUS "ALIAS_LIBRARY_DEBUG: ${${ALIAS_LIBRARY_DEBUG}}") # message(STATUS "ALIAS_LIBRARY_RELEASE: ${${ALIAS_LIBRARY_RELEASE}}") # message(STATUS "ALIAS_LIBRARIES: ${ALIAS_LIBRARIES}: ${${ALIAS_LIBRARIES}}") # message(STATUS "ALIAS_LIBRARY: ${${ALIAS_LIBRARY}}") # message(STATUS "ALIAS_LIBRARY_DIRS: ${${ALIAS_LIBRARY_DIRS}}") # message(STATUS "LIBRARY_HINTS: ${${module}_LIBRARY_DIR}") # message(STATUS "INCLUDE_DIR: ${${module}_INCLUDE_DIR}") # message(STATUS "LIBRARY_SUFFIXES: ${${module}_LIBRARY_SUFFIXES}") else() find_library(${ALIAS_LIBRARIES} NAMES ${library} ${library}d HINTS ${${module}_LIBRARY_HINTS} PATHS ${${ALIAS_LIBRARY_DIRS}} ${${module}_LIBRARY_DIR} PATH_SUFFIXES ${${module}_LIBRARY_SUFFIXES} ) endif() # print_module_variables(${module}) set_component_found(${module} ${component}) endmacro() # ### Macro: find_component # # Checks for the given component by invoking pkg-config and then looking up the # libraries and include directories. # macro(find_component module component pkgconfig library header) messageV("Find Component=${module}:${component}:${pkgconfig}:${library}:${header}") # Reset component alias values (force recheck) set_component_alias(${module} ${component}) find_component_paths(${module} ${component} ${library} ${header}) if(NOT ${ALIAS_FOUND}) messageV(" - ${module} ${component} not found, searching with pkg-config...") # Use pkg-config to obtain directories for the find_path() and find_library() calls. find_package(PkgConfig QUIET) if (PKG_CONFIG_FOUND) pkg_search_module(${ALIAS} ${pkgconfig} QUIET) messageV("Find Component PkgConfig=${ALIAS}:${${ALIAS}_FOUND}:${${ALIAS}_LIBRARIES}:${${ALIAS}_INCLUDE_DIRS}:${${ALIAS}_LIBRARY_DIRS}:${${ALIAS}_LIBDIR}:${${ALIAS}_INCLUDEDIR}") endif() else() messageV(" - ${module} ${component} found without pkg-config.") endif() # messageV("${ALIAS_FOUND}=${${ALIAS_FOUND}}") # messageV("${ALIAS_LIBRARIES}=${${ALIAS_LIBRARIES}}") # messageV("${ALIAS_INCLUDE_DIRS}=${${ALIAS_INCLUDE_DIRS}}") if(${ALIAS_FOUND}) set_component_found(${module} ${component}) endif() endmacro()