1include(helpers) 2 3include(CheckSymbolExists) 4 5# The threading library is not needed for igraph itself, but might be needed 6# for tests 7include(FindThreads) 8 9macro(find_dependencies) 10 # Declare the list of dependencies that _may_ be vendored and those that may not 11 set(VENDORABLE_DEPENDENCIES BLAS CXSparse GLPK LAPACK ARPACK GMP) 12 set(NONVENDORABLE_DEPENDENCIES GLPK OpenMP) 13 14 # Declare configuration options for dependencies 15 tristate(IGRAPH_USE_INTERNAL_GMP "Compile igraph with internal Mini-GMP" AUTO) 16 tristate(IGRAPH_USE_INTERNAL_ARPACK "Compile igraph with internal ARPACK" AUTO) 17 tristate(IGRAPH_USE_INTERNAL_BLAS "Compile igraph with internal BLAS" AUTO) 18 tristate(IGRAPH_USE_INTERNAL_CXSPARSE "Compile igraph with internal CXSparse" AUTO) 19 tristate(IGRAPH_USE_INTERNAL_GLPK "Compile igraph with internal GLPK" AUTO) 20 tristate(IGRAPH_USE_INTERNAL_LAPACK "Compile igraph with internal LAPACK" AUTO) 21 22 # Declare dependencies 23 set(REQUIRED_DEPENDENCIES "") 24 set(OPTIONAL_DEPENDENCIES FLEX BISON OpenMP) 25 set(VENDORED_DEPENDENCIES "") 26 27 # Extend dependencies depending on whether we will be using the vendored 28 # copies or not 29 foreach(DEPENDENCY ${VENDORABLE_DEPENDENCIES}) 30 string(TOUPPER "${DEPENDENCY}" LIBNAME_UPPER) 31 32 if(IGRAPH_USE_INTERNAL_${LIBNAME_UPPER} STREQUAL "AUTO") 33 find_package(${DEPENDENCY}) 34 if(${LIBNAME_UPPER}_FOUND) 35 set(IGRAPH_USE_INTERNAL_${LIBNAME_UPPER} OFF) 36 else() 37 set(IGRAPH_USE_INTERNAL_${LIBNAME_UPPER} ON) 38 endif() 39 endif() 40 41 if(IGRAPH_USE_INTERNAL_${LIBNAME_UPPER}) 42 list(APPEND VENDORED_DEPENDENCIES ${DEPENDENCY}) 43 else() 44 list(APPEND REQUIRED_DEPENDENCIES ${DEPENDENCY}) 45 endif() 46 endforeach() 47 48 # For nonvendorable dependencies, figure out whether we should attempt to 49 # link to them based on the value of the IGRAPH_..._SUPPORT option 50 foreach(DEPENDENCY ${NONVENDORABLE_DEPENDENCIES}) 51 string(TOUPPER "${DEPENDENCY}" LIBNAME_UPPER) 52 53 if(IGRAPH_${LIBNAME_UPPER}_SUPPORT STREQUAL "AUTO") 54 find_package(${DEPENDENCY}) 55 if(${LIBNAME_UPPER}_FOUND) 56 set(IGRAPH_${LIBNAME_UPPER}_SUPPORT ON) 57 else() 58 set(IGRAPH_${LIBNAME_UPPER}_SUPPORT OFF) 59 endif() 60 endif() 61 endforeach() 62 63 # GraphML support is treated separately because the library name is different 64 if(IGRAPH_GRAPHML_SUPPORT STREQUAL "AUTO") 65 find_package(LibXml2) 66 if(LibXml2_FOUND) 67 set(IGRAPH_GRAPHML_SUPPORT ON) 68 else() 69 set(IGRAPH_GRAPHML_SUPPORT OFF) 70 endif() 71 endif() 72 73 if(NOT IGRAPH_GLPK_SUPPORT) 74 if(IGRAPH_USE_INTERNAL_GLPK) 75 list(REMOVE_ITEM VENDORED_DEPENDENCIES GLPK) 76 else() 77 list(REMOVE_ITEM REQUIRED_DEPENDENCIES GLPK) 78 endif() 79 endif() 80 81 if(IGRAPH_GRAPHML_SUPPORT) 82 list(APPEND REQUIRED_DEPENDENCIES LibXml2) 83 endif() 84 85 # Find dependencies 86 foreach(DEPENDENCY ${REQUIRED_DEPENDENCIES} ${OPTIONAL_DEPENDENCIES}) 87 list(FIND REQUIRED_DEPENDENCIES "${DEPENDENCY}" INDEX) 88 set(NEED_THIS_DEPENDENCY NO) 89 90 if(INDEX GREATER_EQUAL 0) 91 # This is a required dependency, search for it unconditionally. Do 92 # not use REQUIRED; we will report errors in a single batch at the end 93 # of the configuration process 94 set(NEED_THIS_DEPENDENCY YES) 95 else() 96 # This is an optional dependency, search for it only if the user did not 97 # turn it off explicitly 98 string(TOUPPER "${DEPENDENCY}" LIBNAME_UPPER) 99 if(NOT DEFINED IGRAPH_${LIBNAME_UPPER}_SUPPORT) 100 set(NEED_THIS_DEPENDENCY YES) 101 elseif(IGRAPH_${LIBNAME_UPPER}_SUPPORT) 102 set(NEED_THIS_DEPENDENCY YES) 103 endif() 104 endif() 105 106 if(NEED_THIS_DEPENDENCY AND NOT DEFINED ${DEPENDENCY}_FOUND) 107 find_package(${DEPENDENCY}) 108 endif() 109 endforeach() 110 111 # Override libraries of vendored dependencies even if they were somehow 112 # detected above 113 foreach(DEPENDENCY ${VENDORED_DEPENDENCIES}) 114 string(TOUPPER "${DEPENDENCY}" LIBNAME_UPPER) 115 string(TOLOWER "${DEPENDENCY}" LIBNAME_LOWER) 116 if(IGRAPH_USE_INTERNAL_${LIBNAME_UPPER}) 117 set(${LIBNAME_UPPER}_LIBRARIES "") 118 set(${LIBNAME_UPPER}_FOUND 1) 119 set(${LIBNAME_UPPER}_IS_VENDORED 1) 120 set(INTERNAL_${LIBNAME_UPPER} 1) 121 endif() 122 endforeach() 123 124 # Export some aliases that will be used in config.h 125 set(HAVE_GLPK ${GLPK_FOUND}) 126 set(HAVE_GMP ${GMP_FOUND}) 127 set(HAVE_LIBXML ${LIBXML2_FOUND}) 128 129 # Check whether we need to link to the math library 130 if(NOT DEFINED CACHE{NEED_LINKING_AGAINST_LIBM}) 131 set(CMAKE_REQUIRED_QUIET_SAVE ${CMAKE_REQUIRED_QUIET}) 132 set(CMAKE_REQUIRED_QUIET ON) 133 check_symbol_exists(sinh "math.h" SINH_FUNCTION_EXISTS) 134 if(NOT SINH_FUNCTION_EXISTS) 135 unset(SINH_FUNCTION_EXISTS CACHE) 136 set(CMAKE_REQUIRED_LIBRARIES_SAVE ${CMAKE_REQUIRED_LIBRARIES}) 137 list(APPEND CMAKE_REQUIRED_LIBRARIES m) 138 check_symbol_exists(sinh "math.h" SINH_FUNCTION_EXISTS) 139 if(SINH_FUNCTION_EXISTS) 140 set(NEED_LINKING_AGAINST_LIBM True CACHE BOOL "" FORCE) 141 else() 142 message(FATAL_ERROR "Failed to figure out how to link to the math library on this platform") 143 endif() 144 set(CMAKE_REQUIRED_LIBRARIES ${CMAKE_REQUIRED_LIBRARIES_SAVE}) 145 endif() 146 unset(SINH_FUNCTION_EXISTS CACHE) 147 set(CMAKE_REQUIRED_QUIET ${CMAKE_REQUIRED_QUIET_SAVE}) 148 endif() 149 150 if(NEED_LINKING_AGAINST_LIBM) 151 find_library(MATH_LIBRARY m) 152 endif() 153 154 mark_as_advanced(MATH_LIBRARY) 155 mark_as_advanced(NEED_LINKING_AGAINST_LIBM) 156endmacro() 157