File: IgnImportTarget.cmake

package info (click to toggle)
ignition-cmake 2.11.0-1
  • links: PTS, VCS
  • area: main
  • in suites: bookworm
  • size: 3,132 kB
  • sloc: xml: 35,671; python: 3,768; javascript: 2,308; sh: 172; ansic: 109; cpp: 64; makefile: 7
file content (182 lines) | stat: -rw-r--r-- 7,398 bytes parent folder | download | duplicates (3)
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
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
#===============================================================================
# Copyright (C) 2017 Open Source Robotics Foundation
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
########################################
# ign_import_target(<package> [INTERFACE]
#     [TARGET_NAME <target_name>]
#     [LIB_VAR <library_variable>]
#     [INCLUDE_VAR <header_directory_variable>]
#     [CFLAGS_VAR <cflags_varaible>])
#
# This macro will create an imported target based on the variables pertaining
# to <package>, such as <package>_LIBRARIES, <package>_INCLUDE_DIRS, and
# <package>_CFLAGS. Optionally, you can provide TARGET_NAME followed by a
# string, which will then be used as the name of the imported target. If
# TARGET_NAME is not provided, the name of the imported target will default to
# <package>::<package>.
#
# INTERFACE: Optional. Use INTERFACE when the target does not actually provide
#            a library that needs to be linked against (e.g. it is a header-only
#            library, or the target is just used to specify compiler flags).
#
# TARGET_NAME: Optional. Explicitly specify the desired imported target name.
#              Default is <package>::<package>.
#
# LIB_VAR: Optional. Explicitly specify the name of the library variable for
#          this package. Default is <package>_LIBRARIES.
#
# INCLUDE_VAR: Optional. Explicitly specify the name of the include directory
#              variable for this package. Default is <package>_INCLUDE_DIRS.
#
# CFLAGS_VAR: Optional. Explicitly specify the name of the cflags variable for
#             this package. Default is <package>_CFLAGS.
#
macro(ign_import_target package)

  #------------------------------------
  # Define the expected arguments
  set(options "INTERFACE")
  set(oneValueArgs "TARGET_NAME" "LIB_VAR" "INCLUDE_VAR" "CFLAGS_VAR")
  set(multiValueArgs) # We are not using multiValueArgs yet

  #------------------------------------
  # Parse the arguments
  _ign_cmake_parse_arguments(ign_import_target "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})

  #------------------------------------
  # Check if a target name has been provided, otherwise use
  # ${package}::{$package} as the target name.
  if(ign_import_target_TARGET_NAME)
    set(target_name ${ign_import_target_TARGET_NAME})
  else()
    set(target_name ${package}::${package})
  endif()

  if(NOT TARGET ${target_name})

    #------------------------------------
    # Use default versions of these build variables if custom versions were not
    # provided.
    if(NOT ign_import_target_LIB_VAR)
      set(ign_import_target_LIB_VAR ${package}_LIBRARIES)
    endif()

    if(NOT ign_import_target_INCLUDE_VAR)
      set(ign_import_target_INCLUDE_VAR ${package}_INCLUDE_DIRS)
    endif()

    if(NOT ign_import_target_CFLAGS_VAR)
      set(ign_import_target_CFLAGS_VAR ${package}_CFLAGS)
    endif()

    #------------------------------------
    # Link against this "imported" target by saying
    # target_link_libraries(mytarget package::package), instead of linking
    # against the variable package_LIBRARIES with the old-fashioned
    # target_link_libraries(mytarget ${package_LIBRARIES}
    if(NOT ign_import_target_INTERFACE)
      add_library(${target_name} UNKNOWN IMPORTED)
    else()
      add_library(${target_name} INTERFACE IMPORTED)
    endif()

    # Do not bother with the IMPORTED_LOCATION or IMPORTED_IMPLIB variables if it
    # is an INTERFACE target.
    if(NOT ign_import_target_INTERFACE)

      if(${ign_import_target_LIB_VAR})
        _ign_sort_libraries(${target_name} ${${ign_import_target_LIB_VAR}})
      endif()

    endif()

    if(${ign_import_target_LIB_VAR})
      set_target_properties(${target_name} PROPERTIES
        INTERFACE_LINK_LIBRARIES "${${ign_import_target_LIB_VAR}}")
    endif()

    if(${ign_import_target_INCLUDE_VAR})
      # TODO: In a later version of cmake, it should be possible to replace this
      # with
      #
      # target_include_directories(${target_name} INTERFACE ${${ign_import_target_INCLUDE_VAR}})
      #
      # But this will not be possible until we are using whichever version of cmake
      # the PR https://gitlab.kitware.com/cmake/cmake/merge_requests/1264
      # is available for.
      set_property(
        TARGET ${target_name}
        PROPERTY INTERFACE_INCLUDE_DIRECTORIES
          ${${ign_import_target_INCLUDE_VAR}})
    endif()

    if(${ign_import_target_CFLAGS_VAR})
      # TODO: See note above. We should eventually be able to replace this with
      # target_compile_options(${target_name} INTERFACE ${${ign_import_target_CFLAGS_VAR}})
      set_property(
        TARGET ${target_name}
        PROPERTY INTERFACE_COMPILE_OPTIONS
          ${${ign_import_target_CFLAGS_VAR}})
    endif()

    # What about linker flags? Is there no target property for that?

  endif()

endmacro()

# This is an awkward hack to give the package both an IMPORTED_LOCATION and
# a set of INTERFACE_LIBRARIES in the event that PkgConfig returns multiple
# libraries for this package. It seems that IMPORTED_LOCATION cannot support
# specifying multiple libraries, so if we have multiple libraries, we need to
# pass them into INTERFACE_LINK_LIBRARIES. However, if IMPORTED_LOCATION is
# missing from the target, the dependencies do not get configured correctly by
# the generator expressions, and the build system will try to link to a nonsense
# garbage file.
#
# TODO: Figure out if there is a better way to fill in the various library
# properties of an imported target.
function(_ign_sort_libraries target_name first_lib)

  if(MSVC)
    # Note: For MSVC, we only care about the "import library" which is the
    # library ending in *.lib. The linker only needs to be told where the
    # *.lib library is. The dynamic library (*.dll) only needs to be visible
    # to the program at run-time, not at compile or link time. Furthermore,
    # find_library on Windows only looks for *.lib files, so we expect that
    # results of the form package_LIBRARIES will contain *.lib files when
    # running on Windows. IMPORTED_IMPLIB is the target property that
    # indicates the "import library" of an "imported target", so that is
    # the property that will fill in first and foremost.
    #
    # TODO: How does MinGW handle libraries?
    set_target_properties(${target_name} PROPERTIES
      IMPORTED_IMPLIB "${first_lib}")
  endif()
  set_target_properties(${target_name} PROPERTIES
    IMPORTED_LOCATION "${first_lib}")

  foreach(extra_lib ${ARGN})
    set_target_properties(${target_name} PROPERTIES
      INTERFACE_LINK_LIBRARIES "${extra_lib}")
  endforeach()

  get_target_property(ill ${target_name} INTERFACE_LINK_LIBRARIES)
  set_target_properties(${target_name}
    PROPERTIES IMPORTED_LINK_INTERFACE_LIBRARIES ${ill})
  set_target_properties(${target_name}
    PROPERTIES IMPORTED_LINK_DEPENDENT_LIBRARIES ${ill})

endfunction()