File: Generate.cmake

package info (click to toggle)
cyclonedds 0.10.5-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 21,372 kB
  • sloc: ansic: 224,361; perl: 1,904; xml: 1,894; yacc: 1,018; sh: 882; python: 106; makefile: 94
file content (172 lines) | stat: -rw-r--r-- 5,582 bytes parent folder | download | duplicates (2)
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
#
# Copyright(c) 2021 to 2022 ZettaScale Technology and others
#
# This program and the accompanying materials are made available under the
# terms of the Eclipse Public License v. 2.0 which is available at
# http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License
# v. 1.0 which is available at
# http://www.eclipse.org/org/documents/edl-v10.php.
#
# SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
#

function(IDLC_GENERATE)
  set(options NO_TYPE_INFO)
  set(one_value_keywords TARGET DEFAULT_EXTENSIBILITY BASE_DIR)
  set(multi_value_keywords FILES FEATURES INCLUDES WARNINGS)
  cmake_parse_arguments(
    IDLC "${options}" "${one_value_keywords}" "${multi_value_keywords}" "" ${ARGN})

  set(gen_args
    ${IDLC_UNPARSED_ARGUMENTS}
    TARGET ${IDLC_TARGET}
    BASE_DIR ${IDLC_BASE_DIR}
    FILES ${IDLC_FILES}
    FEATURES ${IDLC_FEATURES}
    INCLUDES ${IDLC_INCLUDES}
    WARNINGS ${IDLC_WARNINGS}
    DEFAULT_EXTENSIBILITY ${IDLC_DEFAULT_EXTENSIBILITY})
  if(${IDLC_NO_TYPE_INFO})
    list(APPEND gen_args NO_TYPE_INFO)
  endif()
  idlc_generate_generic(${gen_args})
endfunction()

function(IDLC_GENERATE_GENERIC)
  set(options NO_TYPE_INFO)
  set(one_value_keywords TARGET BACKEND DEFAULT_EXTENSIBILITY BASE_DIR)
  set(multi_value_keywords FILES FEATURES INCLUDES WARNINGS SUFFIXES DEPENDS)
  cmake_parse_arguments(
    IDLC "${options}" "${one_value_keywords}" "${multi_value_keywords}" "" ${ARGN})

  # find idlc binary
  if(CMAKE_CROSSCOMPILING OR NOT TARGET CycloneDDS::idlc)
    find_program(_idlc_executable idlc NO_CMAKE_FIND_ROOT_PATH REQUIRED)

    if(_idlc_executable)
      set(_idlc_depends "")
    else()
      message(FATAL_ERROR "Cannot find idlc executable. Please install package 'cyclonedds-tools'.")
    endif()
  else()
    set(_idlc_executable CycloneDDS::idlc)
    set(_idlc_depends CycloneDDS::idlc)
  endif()

  if(NOT IDLC_TARGET AND NOT IDLC_FILES)
    # assume deprecated invocation: TARGET FILE [FILE..]
    list(GET IDLC_UNPARSED_ARGUMENTS 0 IDLC_TARGET)
    list(REMOVE_AT IDLC_UNPARSED_ARGUMENTS 0 IDLC_)
    set(IDLC_FILES ${IDLC_UNPARSED_ARGUMENTS})
    if (IDLC_TARGET AND IDLC_FILES)
      message(WARNING " Deprecated use of idlc_generate. \n"
                      " Consider switching to keyword based invocation.")
    endif()
    # Java based compiler used to be case sensitive
    list(APPEND IDLC_FEATURES "case-sensitive")
  endif()

  if(NOT IDLC_TARGET)
    message(FATAL_ERROR "idlc_generate called without TARGET")
  elseif(NOT IDLC_FILES)
    message(FATAL_ERROR "idlc_generate called without FILES")
  endif()

  # remove duplicate features
  if(IDLC_FEATURES)
    list(REMOVE_DUPLICATES IDLC_FEATURES)
  endif()
  foreach(_feature ${IDLC_FEATURES})
    list(APPEND IDLC_ARGS "-f" ${_feature})
  endforeach()

  # add directories to include search list
  if(IDLC_INCLUDES)
    foreach(_dir ${IDLC_INCLUDES})
      list(APPEND IDLC_INCLUDE_DIRS "-I" ${_dir})
    endforeach()
  endif()

  # generate using which language (defaults to c)?
  if(IDLC_BACKEND)
    string(APPEND _language "-l" ${IDLC_BACKEND})
  endif()

  # set dependencies
  if(IDLC_DEPENDS)
    list(APPEND _depends ${_idlc_depends} ${IDLC_DEPENDS})
  else()
    set(_depends ${_idlc_depends})
  endif()

  if(IDLC_DEFAULT_EXTENSIBILITY)
    set(_default_extensibility ${IDLC_DEFAULT_EXTENSIBILITY})
    list(APPEND IDLC_ARGS "-x" ${_default_extensibility})
  endif()

  if(IDLC_WARNINGS)
    foreach(_warn ${IDLC_WARNINGS})
      list(APPEND IDLC_ARGS "-W${_warn}")
    endforeach()
  endif()

  if(IDLC_NO_TYPE_INFO)
    list(APPEND IDLC_ARGS "-t")
  endif()

  if(IDLC_BASE_DIR)
    file(REAL_PATH ${IDLC_BASE_DIR} _base_dir_abs)
    list(APPEND IDLC_ARGS "-b${_base_dir_abs}")
  endif()

  set(_dir ${CMAKE_CURRENT_BINARY_DIR})
  list(APPEND IDLC_ARGS "-o${_dir}")
  set(_target ${IDLC_TARGET})
  foreach(_file ${IDLC_FILES})
    get_filename_component(_path ${_file} ABSOLUTE)
    list(APPEND _files "${_path}")
  endforeach()

  # set source suffixes (defaults to .c and .h)
  if(NOT IDLC_SUFFIXES)
    set(IDLC_SUFFIXES ".c" ".h")
  endif()
  set(_outputs "")
  foreach(_file ${_files})
    get_filename_component(_name ${_file} NAME_WE)
    get_filename_component(_name_ext ${_file} NAME)

    # Determine middle path for directory reconstruction
    if(IDLC_BASE_DIR)
      file(RELATIVE_PATH _file_path_rel ${_base_dir_abs} ${_file})
      # Hard Fail
      if(_file_path_rel MATCHES "^\\.\\.")
        message(FATAL_ERROR "Cannot use base dir with different file tree from input file (${_base_dir_abs} to ${_file} yields ${_file_path_rel})")
      endif()
      string(REPLACE ${_name_ext} "" _mid_dir_path ${_file_path_rel})
      string(REGEX REPLACE "[\\/]$" "" _mid_dir_path ${_mid_dir_path})
    endif()

    set(_file_outputs "")
    foreach(_suffix ${IDLC_SUFFIXES})
      if(IDLC_BASE_DIR)
        list(APPEND _file_outputs "${_dir}/${_mid_dir_path}/${_name}${_suffix}")
      else()
        list(APPEND _file_outputs "${_dir}/${_name}${_suffix}")
      endif()
    endforeach()

    list(APPEND _outputs ${_file_outputs})
    add_custom_command(
      OUTPUT   ${_file_outputs}
      COMMAND  ${_idlc_executable}
      ARGS     ${_language} ${IDLC_ARGS} ${IDLC_INCLUDE_DIRS} ${_file}
      DEPENDS  ${_files} ${_depends})
  endforeach()

  add_custom_target("${_target}_generate" DEPENDS "${_outputs}")
  add_library(${_target} INTERFACE)
  target_sources(${_target} INTERFACE ${_outputs})
  target_include_directories(${_target} INTERFACE "${_dir}")
  add_dependencies(${_target} "${_target}_generate")
endfunction()