1# Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
2# file Copyright.txt or https://cmake.org/licensing for details.
3
4#[=======================================================================[.rst:
5CMakeExpandImportedTargets
6--------------------------
7
8.. deprecated:: 3.4
9
10  Do not use.
11
12This module was once needed to expand imported targets to the underlying
13libraries they reference on disk for use with the :command:`try_compile`
14and :command:`try_run` commands.  These commands now support imported
15libraries in their ``LINK_LIBRARIES`` options (since CMake 2.8.11
16for :command:`try_compile` and since CMake 3.2 for :command:`try_run`).
17
18This module does not support the policy :policy:`CMP0022` ``NEW``
19behavior or use of the :prop_tgt:`INTERFACE_LINK_LIBRARIES` property
20because :manual:`generator expressions <cmake-generator-expressions(7)>`
21cannot be evaluated during configuration.
22
23::
24
25 CMAKE_EXPAND_IMPORTED_TARGETS(<var> LIBRARIES lib1 lib2...libN
26                               [CONFIGURATION <config>])
27
28CMAKE_EXPAND_IMPORTED_TARGETS() takes a list of libraries and replaces
29all imported targets contained in this list with their actual file
30paths of the referenced libraries on disk, including the libraries
31from their link interfaces.  If a CONFIGURATION is given, it uses the
32respective configuration of the imported targets if it exists.  If no
33CONFIGURATION is given, it uses the first configuration from
34${CMAKE_CONFIGURATION_TYPES} if set, otherwise ${CMAKE_BUILD_TYPE}.
35
36::
37
38    cmake_expand_imported_targets(expandedLibs
39      LIBRARIES ${CMAKE_REQUIRED_LIBRARIES}
40      CONFIGURATION "${CMAKE_TRY_COMPILE_CONFIGURATION}" )
41#]=======================================================================]
42
43function(CMAKE_EXPAND_IMPORTED_TARGETS _RESULT )
44
45  set(options )
46  set(oneValueArgs CONFIGURATION )
47  set(multiValueArgs LIBRARIES )
48
49  cmake_parse_arguments(CEIT "${options}" "${oneValueArgs}" "${multiValueArgs}"  ${ARGN})
50
51  if(CEIT_UNPARSED_ARGUMENTS)
52    message(FATAL_ERROR "Unknown keywords given to CMAKE_EXPAND_IMPORTED_TARGETS(): \"${CEIT_UNPARSED_ARGUMENTS}\"")
53  endif()
54
55  if(NOT CEIT_CONFIGURATION)
56    # Would be better to test GENERATOR_IS_MULTI_CONFIG global property,
57    # but the documented behavior specifically says we check
58    # CMAKE_CONFIGURATION_TYPES and fall back to CMAKE_BUILD_TYPE if no
59    # config types are defined.
60    if(CMAKE_CONFIGURATION_TYPES)
61      list(GET CMAKE_CONFIGURATION_TYPES 0 CEIT_CONFIGURATION)
62    else()
63      set(CEIT_CONFIGURATION ${CMAKE_BUILD_TYPE})
64    endif()
65  endif()
66
67  # handle imported library targets
68
69  set(_CCSR_REQ_LIBS ${CEIT_LIBRARIES})
70
71  set(_CHECK_FOR_IMPORTED_TARGETS TRUE)
72  set(_CCSR_LOOP_COUNTER 0)
73  while(_CHECK_FOR_IMPORTED_TARGETS)
74    math(EXPR _CCSR_LOOP_COUNTER "${_CCSR_LOOP_COUNTER} + 1 ")
75    set(_CCSR_NEW_REQ_LIBS )
76    set(_CHECK_FOR_IMPORTED_TARGETS FALSE)
77    foreach(_CURRENT_LIB ${_CCSR_REQ_LIBS})
78      if(TARGET "${_CURRENT_LIB}")
79        get_target_property(_importedConfigs "${_CURRENT_LIB}" IMPORTED_CONFIGURATIONS)
80      else()
81        set(_importedConfigs "")
82      endif()
83      if (_importedConfigs)
84        # message(STATUS "Detected imported target ${_CURRENT_LIB}")
85        # Ok, so this is an imported target.
86        # First we get the imported configurations.
87        # Then we get the location of the actual library on disk of the first configuration.
88        # then we'll get its link interface libraries property,
89        # iterate through it and replace all imported targets we find there
90        # with there actual location.
91
92        # guard against infinite loop: abort after 100 iterations ( 100 is arbitrary chosen)
93        if ("${_CCSR_LOOP_COUNTER}" LESS 100)
94          set(_CHECK_FOR_IMPORTED_TARGETS TRUE)
95#       else ()
96#          message(STATUS "********* aborting loop, counter : ${_CCSR_LOOP_COUNTER}")
97        endif ()
98
99        # if one of the imported configurations equals ${CMAKE_TRY_COMPILE_CONFIGURATION},
100        # use it, otherwise simply use the first one:
101        list(FIND _importedConfigs "${CEIT_CONFIGURATION}" _configIndexToUse)
102        if("${_configIndexToUse}" EQUAL -1)
103          set(_configIndexToUse 0)
104        endif()
105        list(GET _importedConfigs ${_configIndexToUse} _importedConfigToUse)
106
107        get_target_property(_importedLocation "${_CURRENT_LIB}" IMPORTED_LOCATION_${_importedConfigToUse})
108        get_target_property(_linkInterfaceLibs "${_CURRENT_LIB}" IMPORTED_LINK_INTERFACE_LIBRARIES_${_importedConfigToUse} )
109
110        list(APPEND _CCSR_NEW_REQ_LIBS  "${_importedLocation}")
111#       message(STATUS "Appending lib ${_CURRENT_LIB} as ${_importedLocation}")
112        if(_linkInterfaceLibs)
113          foreach(_currentLinkInterfaceLib ${_linkInterfaceLibs})
114#           message(STATUS "Appending link interface lib ${_currentLinkInterfaceLib}")
115            if(_currentLinkInterfaceLib)
116              list(APPEND _CCSR_NEW_REQ_LIBS "${_currentLinkInterfaceLib}" )
117            endif()
118          endforeach()
119        endif()
120      else()
121        # "Normal" libraries are just used as they are.
122        list(APPEND _CCSR_NEW_REQ_LIBS "${_CURRENT_LIB}" )
123#       message(STATUS "Appending lib directly: ${_CURRENT_LIB}")
124      endif()
125    endforeach()
126    set(_CCSR_REQ_LIBS ${_CCSR_NEW_REQ_LIBS} )
127  endwhile()
128
129  # Finally we iterate once more over all libraries. This loop only removes
130  # all remaining imported target names (there shouldn't be any left anyway).
131  set(_CCSR_NEW_REQ_LIBS )
132  foreach(_CURRENT_LIB ${_CCSR_REQ_LIBS})
133    if(TARGET "${_CURRENT_LIB}")
134      get_target_property(_importedConfigs "${_CURRENT_LIB}" IMPORTED_CONFIGURATIONS)
135    else()
136      set(_importedConfigs "")
137    endif()
138    if (NOT _importedConfigs)
139      list(APPEND _CCSR_NEW_REQ_LIBS "${_CURRENT_LIB}" )
140#     message(STATUS "final: appending ${_CURRENT_LIB}")
141#   else ()
142#   message(STATUS "final: skipping ${_CURRENT_LIB}")
143    endif ()
144  endforeach()
145# message(STATUS "setting -${_RESULT}- to -${_CCSR_NEW_REQ_LIBS}-")
146  set(${_RESULT} "${_CCSR_NEW_REQ_LIBS}" PARENT_SCOPE)
147
148endfunction()
149