aboutsummaryrefslogtreecommitdiffstats
path: root/cmake/InstallDependentSharedObjects.cmake.in
blob: a54e1fa54274d143e9d7b18f7932563c0b312635 (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
141
142
143
144
145
146
147
148
149
150
151
if (MINGW AND @CMAKE_CXX_COMPILER_ID@ MATCHES "Clang")
  set(CMAKE_GET_RUNTIME_DEPENDENCIES_TOOL objdump)
endif()
if (WIN32)
  set(filter_regex PRE_EXCLUDE_REGEXES "api-ms-.*|ext-ms-.*")
elseif (APPLE)
  set(filter_regex PRE_EXCLUDE_REGEXES "libiodbc.*|libpq.*")
endif()

get_filename_component(install_prefix "${CMAKE_INSTALL_PREFIX}" ABSOLUTE)

# Get the dependencies of Qt's plugins
set(qt_plugin_directories "@QT_PLUGIN_DIRECTORIES@")
foreach(plugin IN LISTS qt_plugin_directories)
  file(GLOB plugin_files "${install_prefix}/${plugin}/*@CMAKE_SHARED_LIBRARY_SUFFIX@")
  list(APPEND qt_plugin_files "${plugin_files}")
endforeach()

# Get the qml module dependencies
file(GLOB_RECURSE qml_plugin_files "${install_prefix}/@QT_DEST_QML_PATH@/*/*@CMAKE_SHARED_LIBRARY_SUFFIX@")
list(APPEND qt_plugin_files "${qml_plugin_files}")

set(installed_EXECUTABLES_NOT_PREFIXED "@__QTC_INSTALLED_EXECUTABLES@")
set(installed_LIBRARIES_NOT_PREFIXED "@__QTC_INSTALLED_LIBRARIES@")
set(installed_MODULES_NOT_PREFIXED "@__QTC_INSTALLED_PLUGINS@")

foreach(binary_type EXECUTABLES LIBRARIES MODULES)
  foreach(element IN LISTS installed_${binary_type}_NOT_PREFIXED)
    if (EXISTS "${install_prefix}/${element}")
      list(APPEND installed_${binary_type} "${install_prefix}/${element}")
    endif()
  endforeach()
endforeach()

# Install first the dependencies, and continue to install the dependencies
# of the installed dependencies e.g. libicu for libQt5Core on Linux.

list(LENGTH installed_LIBRARIES installed_libraries_size)
unset(qt_plugins_installed)

while(installed_libraries_size GREATER 0)
  foreach(binary_type EXECUTABLES LIBRARIES MODULES)
    list(LENGTH installed_${binary_type} list_size)
    if (NOT list_size EQUAL 0)
      set(${binary_type}_TO_ANALYZE ${binary_type} "${installed_${binary_type}}")
    else()
      set(${binary_type}_TO_ANALYZE "")
    endif()
  endforeach()

  file(GET_RUNTIME_DEPENDENCIES
    UNRESOLVED_DEPENDENCIES_VAR unresolved_deps
    RESOLVED_DEPENDENCIES_VAR resolved_deps
    CONFLICTING_DEPENDENCIES_PREFIX conflicts
    ${EXECUTABLES_TO_ANALYZE}
    ${LIBRARIES_TO_ANALYZE}
    ${MODULES_TO_ANALYZE}
    DIRECTORIES
      "${install_prefix}/@IDE_BIN_PATH@"
      "${install_prefix}/@IDE_PLUGIN_PATH@"
      "${install_prefix}/@IDE_LIBRARY_PATH@"
      "${install_prefix}/@IDE_LIBRARY_BASE_PATH@/Qt/lib"
    ${filter_regex}
  )

  # Clear for next step
  set(installed_EXECUTABLES "")
  set(installed_LIBRARIES "")
  set(installed_MODULES "")

  if (NOT qt_plugins_installed)
    if (WIN32)
      # Needed by QmlDesigner, QmlProfiler, but they are not referenced directly.
      list(APPEND unresolved_deps libEGL.dll libGLESv2.dll)
    endif()

    set(qt_plugins_installed TRUE)
    set(installed_MODULES "${qt_plugin_files}")
  endif()

  list(REMOVE_DUPLICATES unresolved_deps)
  list(REMOVE_DUPLICATES resolved_deps)

  file(TO_CMAKE_PATH "@CMAKE_PREFIX_PATH@" prefix_path)

  # Add parent link directory paths. Needed for e.g. MinGW choco libstdc++-6.dll
  if (WIN32)
    foreach(path "@CMAKE_CXX_IMPLICIT_LINK_DIRECTORIES@")
      get_filename_component(parent_path "${path}" DIRECTORY)
      list(APPEND prefix_path "${parent_path}")
    endforeach()
  endif()

  # On Linux the Qt libraries might exist in the system, and they are passed
  # as resolved, therefore scan the resolved dependencies too
  if (NOT WIN32 AND NOT APPLE)
    list(APPEND unresolved_deps "${resolved_deps}")
  endif()

  foreach(so IN LISTS unresolved_deps)

    # Skip the installed dependencies
    string(FIND "${so}" "${install_prefix}" found_prefix_path)
    if (NOT found_prefix_path EQUAL -1)
      continue()
    endif()

    # On Linux get the name of the resolved Qt dependency, this would come from ldconfig
    # with the full path on the system
    if (NOT APPLE AND NOT WIN32)
      get_filename_component(so "${so}" NAME)
    endif()

    if (APPLE)
      string(REPLACE "@rpath/" "" so "${so}")
      get_filename_component(so_dir "${so}" DIRECTORY)
    endif()

    message(STATUS "Dependency: ${so}")
    foreach(p IN LISTS prefix_path)
      if (WIN32)
        set(so_src "${p}/bin/${so}")
        set(so_dest "${install_prefix}/@IDE_BIN_PATH@")
      elseif(APPLE)
        set(so_src "${p}/lib/${so}")
        set(so_dest "${install_prefix}/@IDE_LIBRARY_PATH@/${so_dir}")
      else()
        set(so_src "${p}/lib/${so}")
        if (p STREQUAL "@QT_BASE_DIR@")
          set(so_dest "${install_prefix}/@IDE_LIBRARY_BASE_PATH@/Qt/lib")
        else()
          set(so_dest "${install_prefix}/@IDE_LIBRARY_PATH@")
        endif()
      endif()

      message(STATUS "Looking at: ${so_src}")
      if (EXISTS "${so_src}")
        file(INSTALL "${so_src}" DESTINATION "${so_dest}" FOLLOW_SYMLINK_CHAIN)
        if (APPLE)
          get_filename_component(so "${so}" NAME)
        endif()
        list(APPEND installed_LIBRARIES "${so_dest}/${so}")
        break()
      endif()

    endforeach()
  endforeach()

  list(LENGTH installed_LIBRARIES installed_libraries_size)

endwhile()