summaryrefslogtreecommitdiff
path: root/CMake/DolphinLibraryTools.cmake
blob: bedba9dcbd2156ab01d775ff41152764175ca734 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
# like add_library(new ALIAS old) but avoids add_library cannot create ALIAS target "new" because target "old" is imported but not globally visible. on older cmake
# This can be replaced with a direct alias call once our minimum is cmake 3.18
function(dolphin_alias_library new old)
  string(REPLACE "::" "" library_no_namespace ${old})
  if (NOT TARGET _alias_${library_no_namespace})
    add_library(_alias_${library_no_namespace} INTERFACE)
    target_link_libraries(_alias_${library_no_namespace} INTERFACE ${old})
  endif()
  add_library(${new} ALIAS _alias_${library_no_namespace})
endfunction()

# Makes an imported target if it doesn't exist.  Useful for when find scripts from older versions of cmake don't make the targets you need
function(dolphin_make_imported_target_if_missing target lib)
  if(${lib}_FOUND AND NOT TARGET ${target})
    add_library(_${lib} INTERFACE)
    target_link_libraries(_${lib} INTERFACE "${${lib}_LIBRARIES}")
    target_include_directories(_${lib} INTERFACE "${${lib}_INCLUDE_DIRS}")
    add_library(${target} ALIAS _${lib})
  endif()
endfunction()

function(dolphin_optional_system_library out_use_system library)
  string(TOUPPER ${library} upperlib)
  set(USE_SYSTEM_${upperlib} "" CACHE STRING "Use system ${library} instead of bundled.  ON - Always use system and fail if unavailable, OFF - Always use bundled, AUTO - Use system if available, otherwise use bundled, blank - Delegate to USE_SYSTEM_LIBS.  Default is blank.")
  if("${USE_SYSTEM_${upperlib}}" STREQUAL "")
    if(APPROVED_VENDORED_DEPENDENCIES)
      string(TOLOWER ${library} lowerlib)
      if(lowerlib IN_LIST APPROVED_VENDORED_DEPENDENCIES)
        set(${out_use_system} AUTO PARENT_SCOPE)
      else()
        set(${out_use_system} ON PARENT_SCOPE)
      endif()
    else()
      set(${out_use_system} ${USE_SYSTEM_LIBS} PARENT_SCOPE)
    endif()
  else()
    set(${out_use_system} ${USE_SYSTEM_${upperlib}} PARENT_SCOPE)
  endif()
endfunction()

function(dolphin_add_bundled_library library use_system bundled_path)
  if (${use_system} STREQUAL "AUTO")
    message(STATUS "No system ${library} was found.  Using static ${library} from Externals.")
  else()
    message(STATUS "Using static ${library} from Externals")
  endif()
  if (NOT EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/${bundled_path}/CMakeLists.txt")
    message(FATAL_ERROR "No bundled ${library} was found.  Did you forget to checkout submodules?")
  endif()
  add_subdirectory(${bundled_path} EXCLUDE_FROM_ALL)
endfunction()

function(dolphin_set_library_type library type)
  if(DEFINED ${library}_TYPE AND NOT ${${library}_TYPE} STREQUAL "${type}")
    message(FATAL_ERROR
      "The selection for ${library} changed from '${${library}_TYPE}' to '${type}' after configuration.\n"
      "Please delete the build directory (or at least CMakeCache.txt) and reconfigure."
    )
  endif()

  set(${library}_TYPE "${type}" CACHE INTERNAL "")
endfunction()

function(dolphin_find_optional_system_library library bundled_path)
  dolphin_optional_system_library(use_system ${library})
  string(TOUPPER ${library} upperlib)
  if(use_system)
    # Try a list of versions
    # Will be obsoleted if cmake ever fixes https://gitlab.kitware.com/cmake/cmake/-/issues/26477
    if("DOLPHIN_TRY_VERSIONS" IN_LIST ARGN)
      list(FIND ARGN DOLPHIN_TRY_VERSIONS versions_idx)
      list(REMOVE_AT ARGN ${versions_idx})
      # Extract list of version-like elements from ARGN into version_list
      set(version_list)
      while(TRUE)
        list(LENGTH ARGN len)
        if(len EQUAL versions_idx)
          break()
        endif()
        LIST(GET ARGN ${versions_idx} ver)
        if(ver MATCHES "^[0-9]+(\\.[0-9]+)*$")
          list(APPEND version_list "${ver}")
          list(REMOVE_AT ARGN ${versions_idx})
        else()
          break()
        endif()
      endwhile()
      # Quietly check all the listed versions
      foreach(version IN LISTS version_list)
        find_package(${library} ${version} ${ARGN} QUIET)
        if(${library}_FOUND)
          break()
        endif()
      endforeach()
      # If none were found, find_package one version loudly so the user sees
      if(NOT ${library}_FOUND)
        list(GET version_list 0 first_version)
        find_package(${library} ${first_version} ${ARGN})
      endif()
    else()
      find_package(${library} ${ARGN})
    endif()

    # Yay for cmake packages being inconsistent
    if(DEFINED ${library}_FOUND)
      set(prefix ${library})
    else()
      set(prefix ${upperlib})
    endif()
    if((NOT ${prefix}_FOUND) AND (NOT ${use_system} STREQUAL "AUTO"))
      message(FATAL_ERROR "No system ${library} was found.  Please install it or set USE_SYSTEM_${upperlib} to AUTO or OFF.")
    endif()
  endif()
  if(${prefix}_FOUND)
    dolphin_set_library_type(${library} "System")
    message(STATUS "Using system ${library}")
  else()
    dolphin_set_library_type(${library} "Bundled")
    dolphin_add_bundled_library(${library} ${use_system} ${bundled_path})
  endif()
endfunction()

function(dolphin_find_optional_system_library_pkgconfig library search alias bundled_path)
  dolphin_optional_system_library(use_system ${library})
  string(TOUPPER ${library} upperlib)
  if(use_system)
    pkg_search_module(${library} ${search} ${ARGN} IMPORTED_TARGET)
    if((NOT ${library}_FOUND) AND (NOT ${use_system} STREQUAL "AUTO"))
      message(FATAL_ERROR "No system ${library} was found.  Please install it or set USE_SYSTEM_${upperlib} to AUTO or OFF.")
    endif()
  endif()
  if(${library}_FOUND)
    dolphin_set_library_type(${library} "System")
    message(STATUS "Using system ${library}")
    dolphin_alias_library(${alias} PkgConfig::${library})
  else()
    dolphin_set_library_type(${library} "Bundled")
    dolphin_add_bundled_library(${library} ${use_system} ${bundled_path})
  endif()
endfunction()