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()
|