macros_public.cmake 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565
  1. # --------------- Generate NodeIDs header ---------------------
  2. #
  3. # Generates header file from .csv which contains defines for every
  4. # node id to be used instead of numeric node ids.
  5. #
  6. # The resulting files will be put into OUTPUT_DIR with the names:
  7. # - NAME.h
  8. #
  9. #
  10. # The following arguments are accepted:
  11. # Options:
  12. #
  13. # Arguments taking one value:
  14. #
  15. # NAME Full name of the generated files, e.g. di_nodeids
  16. # TARGET_SUFFIX Suffix for the resulting target. e.g. ids-di
  17. # [TARGET_PREFIX] Optional prefix for the resulting target. Default `open62541-generator`
  18. # ID_PREFIX Prefix for the generated node ID defines, e.g. NS_DI
  19. # [OUTPUT_DIR] Optional target directory for the generated files. Default is '${PROJECT_BINARY_DIR}/src_generated'
  20. # FILE_CSV Path to the .csv file containing the node ids, e.g. 'OpcUaDiModel.csv'
  21. #
  22. function(ua_generate_nodeid_header)
  23. set(options )
  24. set(oneValueArgs NAME ID_PREFIX OUTPUT_DIR FILE_CSV TARGET_SUFFIX TARGET_PREFIX)
  25. set(multiValueArgs )
  26. cmake_parse_arguments(UA_GEN_ID "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN} )
  27. if(NOT UA_GEN_ID_TARGET_SUFFIX OR "${UA_GEN_ID_TARGET_SUFFIX}" STREQUAL "")
  28. message(FATAL_ERROR "ua_generate_nodeid_header function requires a value for the TARGET_SUFFIX argument")
  29. endif()
  30. # Set default value for output dir
  31. if(NOT UA_GEN_ID_OUTPUT_DIR OR "${UA_GEN_ID_OUTPUT_DIR}" STREQUAL "")
  32. set(UA_GEN_ID_OUTPUT_DIR ${PROJECT_BINARY_DIR}/src_generated/open62541)
  33. endif()
  34. # Set default target prefix
  35. if(NOT UA_GEN_ID_TARGET_PREFIX OR "${UA_GEN_ID_TARGET_PREFIX}" STREQUAL "")
  36. set(UA_GEN_ID_TARGET_PREFIX "open62541-generator")
  37. endif()
  38. # Replace dash with underscore to make valid c literal
  39. string(REPLACE "-" "_" UA_GEN_ID_NAME ${UA_GEN_ID_NAME})
  40. add_custom_target(${UA_GEN_ID_TARGET_PREFIX}-${UA_GEN_ID_TARGET_SUFFIX} DEPENDS
  41. ${UA_GEN_ID_OUTPUT_DIR}/${UA_GEN_ID_NAME}.h
  42. )
  43. # Make sure that the output directory exists
  44. if(NOT EXISTS ${UA_GEN_ID_OUTPUT_DIR})
  45. file(MAKE_DIRECTORY ${UA_GEN_ID_OUTPUT_DIR})
  46. endif()
  47. # Header containing defines for all NodeIds
  48. add_custom_command(OUTPUT ${UA_GEN_ID_OUTPUT_DIR}/${UA_GEN_ID_NAME}.h
  49. PRE_BUILD
  50. COMMAND ${PYTHON_EXECUTABLE} ${open62541_TOOLS_DIR}/generate_nodeid_header.py
  51. ${UA_GEN_ID_FILE_CSV} ${UA_GEN_ID_OUTPUT_DIR}/${UA_GEN_ID_NAME} ${UA_GEN_ID_ID_PREFIX}
  52. DEPENDS ${open62541_TOOLS_DIR}/generate_nodeid_header.py
  53. ${UA_GEN_ID_FILE_CSV})
  54. endfunction()
  55. # --------------- Generate Datatypes ---------------------
  56. #
  57. # Generates Datatype definition based on the .csv and .bsd files of a nodeset.
  58. # The result of the generation will be C Code which can be compiled with the rest of the stack.
  59. # Some nodesets come with custom datatypes. These datatype structures first need to be
  60. # generated so that the nodeset can use these types.
  61. #
  62. # The resulting files will be put into OUTPUT_DIR with the names:
  63. # - NAME_generated.c
  64. # - NAME_generated.h
  65. # - NAME_generated_encoding_binary.h
  66. # - NAME_generated_handling.h
  67. #
  68. # The cmake resulting cmake target will be named like this:
  69. # open62541-generator-${TARGET_SUFFIX}
  70. #
  71. # The following arguments are accepted:
  72. # Options:
  73. #
  74. # [BUILTIN] Optional argument. If given, then builtin types will be generated.
  75. # [INTERNAL] Optional argument. If given, then the given types file is seen as internal file (e.g. does not require a .csv)
  76. #
  77. # Arguments taking one value:
  78. #
  79. # NAME Full name of the generated files, e.g. ua_types_di
  80. # TARGET_SUFFIX Suffix for the resulting target. e.g. types-di
  81. # [TARGET_PREFIX] Optional prefix for the resulting target. Default `open62541-generator`
  82. # NAMESPACE_IDX Namespace index of the nodeset, when it is loaded into the server. This index
  83. # is used for the node ids withing the types array and is currently not determined automatically.
  84. # Make sure that it matches the namespace index in the server.
  85. # [OUTPUT_DIR] Optional target directory for the generated files. Default is '${PROJECT_BINARY_DIR}/src_generated'
  86. # FILE_CSV Path to the .csv file containing the node ids, e.g. 'OpcUaDiModel.csv'
  87. #
  88. # Arguments taking multiple values:
  89. #
  90. # FILES_BSD Path to the .bsd file containing the type definitions, e.g. 'Opc.Ua.Di.Types.bsd'. Multiple files can be
  91. # passed which will all combined to one resulting code.
  92. # IMPORT_BSD Combination of types array and path to the .bsd file containing additional type definitions referenced by
  93. # the FILES_BSD files. The value is separated with a hash sign, i.e.
  94. # 'UA_TYPES#${PROJECT_SOURCE_DIR}/deps/ua-nodeset/Schema/Opc.Ua.Types.bsd'
  95. # Multiple files can be passed which will all be imported.
  96. # [FILES_SELECTED] Optional path to a simple text file which contains a list of types which should be included in the generation.
  97. # The file should contain one type per line. Multiple files can be passed to this argument.
  98. #
  99. #
  100. function(ua_generate_datatypes)
  101. set(options BUILTIN INTERNAL)
  102. set(oneValueArgs NAME TARGET_SUFFIX TARGET_PREFIX NAMESPACE_IDX OUTPUT_DIR FILE_CSV)
  103. set(multiValueArgs FILES_BSD IMPORT_BSD FILES_SELECTED)
  104. cmake_parse_arguments(UA_GEN_DT "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN} )
  105. if(NOT DEFINED open62541_TOOLS_DIR)
  106. message(FATAL_ERROR "open62541_TOOLS_DIR must point to the open62541 tools directory")
  107. endif()
  108. # ------ Argument checking -----
  109. if(NOT DEFINED UA_GEN_DT_NAMESPACE_IDX AND NOT "${UA_GEN_DT_NAMESPACE_IDX}" STREQUAL "0")
  110. message(FATAL_ERROR "ua_generate_datatype function requires a value for the NAMESPACE_IDX argument")
  111. endif()
  112. if(NOT UA_GEN_DT_NAME OR "${UA_GEN_DT_NAME}" STREQUAL "")
  113. message(FATAL_ERROR "ua_generate_datatype function requires a value for the NAME argument")
  114. endif()
  115. if(NOT UA_GEN_DT_TARGET_SUFFIX OR "${UA_GEN_DT_TARGET_SUFFIX}" STREQUAL "")
  116. message(FATAL_ERROR "ua_generate_datatype function requires a value for the TARGET_SUFFIX argument")
  117. endif()
  118. if(NOT UA_GEN_DT_FILE_CSV OR "${UA_GEN_DT_FILE_CSV}" STREQUAL "")
  119. message(FATAL_ERROR "ua_generate_datatype function requires a value for the FILE_CSV argument")
  120. endif()
  121. if(NOT UA_GEN_DT_FILES_BSD OR "${UA_GEN_DT_FILES_BSD}" STREQUAL "")
  122. message(FATAL_ERROR "ua_generate_datatype function requires a value for the FILES_BSD argument")
  123. endif()
  124. # Set default value for output dir
  125. if(NOT UA_GEN_DT_OUTPUT_DIR OR "${UA_GEN_DT_OUTPUT_DIR}" STREQUAL "")
  126. set(UA_GEN_DT_OUTPUT_DIR ${PROJECT_BINARY_DIR}/src_generated/open62541)
  127. endif()
  128. # Set default target prefix
  129. if(NOT UA_GEN_DT_TARGET_PREFIX OR "${UA_GEN_DT_TARGET_PREFIX}" STREQUAL "")
  130. set(UA_GEN_DT_TARGET_PREFIX "open62541-generator")
  131. endif()
  132. # ------ Add custom command and target -----
  133. set(UA_GEN_DT_NO_BUILTIN "--no-builtin")
  134. if (UA_GEN_DT_BUILTIN)
  135. set(UA_GEN_DT_NO_BUILTIN "")
  136. endif()
  137. set(UA_GEN_DT_INTERNAL_ARG "")
  138. if (UA_GEN_DT_INTERNAL)
  139. set(UA_GEN_DT_INTERNAL_ARG "--internal")
  140. endif()
  141. set(SELECTED_TYPES_TMP "")
  142. foreach(f ${UA_GEN_DT_FILES_SELECTED})
  143. set(SELECTED_TYPES_TMP ${SELECTED_TYPES_TMP} "--selected-types=${f}")
  144. endforeach()
  145. set(BSD_FILES_TMP "")
  146. foreach(f ${UA_GEN_DT_FILES_BSD})
  147. set(BSD_FILES_TMP ${BSD_FILES_TMP} "--type-bsd=${f}")
  148. endforeach()
  149. set(IMPORT_BSD_TMP "")
  150. foreach(f ${UA_GEN_DT_IMPORT_BSD})
  151. set(IMPORT_BSD_TMP ${IMPORT_BSD_TMP} "--import=${f}")
  152. endforeach()
  153. # Make sure that the output directory exists
  154. if(NOT EXISTS ${UA_GEN_DT_OUTPUT_DIR})
  155. file(MAKE_DIRECTORY ${UA_GEN_DT_OUTPUT_DIR})
  156. endif()
  157. # Replace dash with underscore to make valid c literal
  158. string(REPLACE "-" "_" UA_GEN_DT_NAME ${UA_GEN_DT_NAME})
  159. add_custom_command(OUTPUT ${UA_GEN_DT_OUTPUT_DIR}/${UA_GEN_DT_NAME}_generated.c
  160. ${UA_GEN_DT_OUTPUT_DIR}/${UA_GEN_DT_NAME}_generated.h
  161. ${UA_GEN_DT_OUTPUT_DIR}/${UA_GEN_DT_NAME}_generated_handling.h
  162. ${UA_GEN_DT_OUTPUT_DIR}/${UA_GEN_DT_NAME}_generated_encoding_binary.h
  163. PRE_BUILD
  164. COMMAND ${PYTHON_EXECUTABLE} ${open62541_TOOLS_DIR}/generate_datatypes.py
  165. --namespace=${UA_GEN_DT_NAMESPACE_IDX}
  166. ${SELECTED_TYPES_TMP}
  167. ${BSD_FILES_TMP}
  168. ${IMPORT_BSD_TMP}
  169. --type-csv=${UA_GEN_DT_FILE_CSV}
  170. ${UA_GEN_DT_NO_BUILTIN}
  171. ${UA_GEN_DT_INTERNAL_ARG}
  172. ${UA_GEN_DT_OUTPUT_DIR}/${UA_GEN_DT_NAME}
  173. DEPENDS ${open62541_TOOLS_DIR}/generate_datatypes.py
  174. ${UA_GEN_DT_FILES_BSD}
  175. ${UA_GEN_DT_FILE_CSV}
  176. ${UA_GEN_DT_FILES_SELECTED})
  177. add_custom_target(${UA_GEN_DT_TARGET_PREFIX}-${UA_GEN_DT_TARGET_SUFFIX} DEPENDS
  178. ${UA_GEN_DT_OUTPUT_DIR}/${UA_GEN_DT_NAME}_generated.c
  179. ${UA_GEN_DT_OUTPUT_DIR}/${UA_GEN_DT_NAME}_generated.h
  180. ${UA_GEN_DT_OUTPUT_DIR}/${UA_GEN_DT_NAME}_generated_handling.h
  181. ${UA_GEN_DT_OUTPUT_DIR}/${UA_GEN_DT_NAME}_generated_encoding_binary.h
  182. )
  183. string(TOUPPER "${UA_GEN_DT_NAME}" GEN_NAME_UPPER)
  184. set(UA_${GEN_NAME_UPPER}_SOURCES "${UA_GEN_DT_OUTPUT_DIR}/${UA_GEN_DT_NAME}_generated.c" CACHE INTERNAL "${UA_GEN_DT_NAME} source files")
  185. set(UA_${GEN_NAME_UPPER}_HEADERS "${UA_GEN_DT_OUTPUT_DIR}/${UA_GEN_DT_NAME}_generated.h;${UA_GEN_DT_OUTPUT_DIR}/${UA_GEN_DT_NAME}_generated_handling.h;${UA_GEN_DT_OUTPUT_DIR}/${UA_GEN_DT_NAME}_generated_encoding_binary.h"
  186. CACHE INTERNAL "${UA_GEN_DT_NAME} header files")
  187. if(UA_COMPILE_AS_CXX)
  188. set_source_files_properties(${UA_GEN_DT_OUTPUT_DIR}/${UA_GEN_DT_NAME}_generated.c PROPERTIES LANGUAGE CXX)
  189. endif()
  190. endfunction()
  191. # --------------- Generate Nodeset ---------------------
  192. #
  193. # Generates C code for the given NodeSet2.xml file.
  194. # This C code can be used to initialize the server.
  195. #
  196. # The resulting files will be put into OUTPUT_DIR with the names:
  197. # - ua_namespace_NAME.c
  198. # - ua_namespace_NAME.h
  199. #
  200. # The resulting cmake target will be named like this:
  201. # open62541-generator-ns-${NAME}
  202. #
  203. # The following arguments are accepted:
  204. # Options:
  205. #
  206. # [INTERNAL] Optional argument. If given, then the generated node set code will use internal headers.
  207. #
  208. # Arguments taking one value:
  209. #
  210. # NAME Name of the nodeset, e.g. 'di'
  211. # [TYPES_ARRAY] Optional name of the types array containing the custom datatypes of this node set.
  212. # [OUTPUT_DIR] Optional target directory for the generated files. Default is '${PROJECT_BINARY_DIR}/src_generated'
  213. # [IGNORE] Optional file containing a list of node ids which should be ignored. The file should have one id per line.
  214. # [TARGET_PREFIX] Optional prefix for the resulting target. Default `open62541-generator`
  215. # [BLACKLIST] Blacklist file passed as --blacklist to the nodeset compiler. All the given nodes will be removed from the generated
  216. # nodeset, including all the references to and from that node. The format is a node id per line.
  217. # Supported formats: "i=123" (for NS0), "ns=2;s=asdf" (matches NS2 in that specific file), or recommended
  218. # "ns=http://opcfoundation.org/UA/DI/;i=123" namespace index independent node id
  219. #
  220. # Arguments taking multiple values:
  221. #
  222. # FILE Path to the NodeSet2.xml file. Multiple values can be passed. These nodesets will be combined into one output.
  223. # [DEPENDS_TYPES] Optional list of types array which match with the DEPENDS_NS node sets. e.g. 'UA_TYPES;UA_TYPES_DI'
  224. # [DEPENDS_NS] Optional list of NodeSet2.xml files which are a dependency of this node set.
  225. # [DEPENDS_TARGET] Optional list of CMake targets this nodeset depends on.
  226. #
  227. #
  228. function(ua_generate_nodeset)
  229. set(options INTERNAL )
  230. set(oneValueArgs NAME TYPES_ARRAY OUTPUT_DIR IGNORE TARGET_PREFIX BLACKLIST)
  231. set(multiValueArgs FILE DEPENDS_TYPES DEPENDS_NS DEPENDS_TARGET)
  232. cmake_parse_arguments(UA_GEN_NS "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN} )
  233. if(NOT DEFINED open62541_TOOLS_DIR)
  234. message(FATAL_ERROR "open62541_TOOLS_DIR must point to the open62541 tools directory")
  235. endif()
  236. # ------ Argument checking -----
  237. if(NOT UA_GEN_NS_NAME OR "${UA_GEN_NS_NAME}" STREQUAL "")
  238. message(FATAL_ERROR "ua_generate_nodeset function requires a value for the NAME argument")
  239. endif()
  240. if(NOT UA_GEN_NS_FILE OR "${UA_GEN_NS_FILE}" STREQUAL "")
  241. message(FATAL_ERROR "ua_generate_nodeset function requires a value for the FILE argument")
  242. endif()
  243. # Set default value for output dir
  244. if(NOT UA_GEN_NS_OUTPUT_DIR OR "${UA_GEN_NS_OUTPUT_DIR}" STREQUAL "")
  245. set(UA_GEN_NS_OUTPUT_DIR ${PROJECT_BINARY_DIR}/src_generated/open62541)
  246. endif()
  247. # Set default target prefix
  248. if(NOT UA_GEN_NS_TARGET_PREFIX OR "${UA_GEN_NS_TARGET_PREFIX}" STREQUAL "")
  249. set(UA_GEN_NS_TARGET_PREFIX "open62541-generator")
  250. endif()
  251. # Set blacklist file
  252. set(GEN_BLACKLIST "")
  253. set(GEN_BLACKLIST_DEPENDS "")
  254. if(UA_GEN_NS_BLACKLIST)
  255. set(GEN_BLACKLIST "--blacklist=${UA_GEN_NS_BLACKLIST}")
  256. set(GEN_BLACKLIST_DEPENDS "${UA_GEN_NS_BLACKLIST}")
  257. endif()
  258. # ------ Add custom command and target -----
  259. set(GEN_INTERNAL_HEADERS "")
  260. if (UA_GEN_NS_INTERNAL)
  261. set(GEN_INTERNAL_HEADERS "--internal-headers")
  262. endif()
  263. set(GEN_NS0 "")
  264. set(TARGET_SUFFIX "ns-${UA_GEN_NS_NAME}")
  265. set(FILE_SUFFIX "_${UA_GEN_NS_NAME}_generated")
  266. string(REPLACE "-" "_" FILE_SUFFIX ${FILE_SUFFIX})
  267. if ("${UA_GEN_NS_NAME}" STREQUAL "ns0")
  268. set(TARGET_SUFFIX "namespace")
  269. set(FILE_SUFFIX "0_generated")
  270. endif()
  271. set(GEN_IGNORE "")
  272. if (UA_GEN_NS_IGNORE)
  273. set(GEN_IGNORE "--ignore=${UA_GEN_NS_IGNORE}")
  274. endif()
  275. set(TYPES_ARRAY_LIST "")
  276. foreach(f ${UA_GEN_NS_DEPENDS_TYPES})
  277. # Replace dash with underscore to make valid c literal
  278. string(REPLACE "-" "_" TYPE_ARRAY ${f})
  279. set(TYPES_ARRAY_LIST ${TYPES_ARRAY_LIST} "--types-array=${TYPE_ARRAY}")
  280. endforeach()
  281. if(UA_GEN_NS_TYPES_ARRAY)
  282. # Replace dash with underscore to make valid c literal
  283. string(REPLACE "-" "_" TYPE_ARRAY ${UA_GEN_NS_TYPES_ARRAY})
  284. set(TYPES_ARRAY_LIST ${TYPES_ARRAY_LIST} "--types-array=${TYPE_ARRAY}")
  285. endif()
  286. set(DEPENDS_FILE_LIST "")
  287. foreach(f ${UA_GEN_NS_DEPENDS_NS})
  288. set(DEPENDS_FILE_LIST ${DEPENDS_FILE_LIST} "--existing=${f}")
  289. endforeach()
  290. set(FILE_LIST "")
  291. foreach(f ${UA_GEN_NS_FILE})
  292. set(FILE_LIST ${FILE_LIST} "--xml=${f}")
  293. endforeach()
  294. # Make sure that the output directory exists
  295. if(NOT EXISTS ${UA_GEN_NS_OUTPUT_DIR})
  296. file(MAKE_DIRECTORY ${UA_GEN_NS_OUTPUT_DIR})
  297. endif()
  298. add_custom_command(OUTPUT ${UA_GEN_NS_OUTPUT_DIR}/namespace${FILE_SUFFIX}.c
  299. ${UA_GEN_NS_OUTPUT_DIR}/namespace${FILE_SUFFIX}.h
  300. PRE_BUILD
  301. COMMAND ${PYTHON_EXECUTABLE} ${open62541_TOOLS_DIR}/nodeset_compiler/nodeset_compiler.py
  302. ${GEN_INTERNAL_HEADERS}
  303. ${GEN_NS0}
  304. ${GEN_BIN_SIZE}
  305. ${GEN_IGNORE}
  306. ${GEN_BLACKLIST}
  307. ${TYPES_ARRAY_LIST}
  308. ${DEPENDS_FILE_LIST}
  309. ${FILE_LIST}
  310. ${UA_GEN_NS_OUTPUT_DIR}/namespace${FILE_SUFFIX}
  311. DEPENDS
  312. ${open62541_TOOLS_DIR}/nodeset_compiler/nodeset_compiler.py
  313. ${open62541_TOOLS_DIR}/nodeset_compiler/nodes.py
  314. ${open62541_TOOLS_DIR}/nodeset_compiler/nodeset.py
  315. ${open62541_TOOLS_DIR}/nodeset_compiler/datatypes.py
  316. ${open62541_TOOLS_DIR}/nodeset_compiler/backend_open62541.py
  317. ${open62541_TOOLS_DIR}/nodeset_compiler/backend_open62541_nodes.py
  318. ${open62541_TOOLS_DIR}/nodeset_compiler/backend_open62541_datatypes.py
  319. ${UA_GEN_NS_FILE}
  320. ${UA_GEN_NS_DEPENDS_NS}
  321. ${GEN_BLACKLIST_DEPENDS}
  322. )
  323. add_custom_target(${UA_GEN_NS_TARGET_PREFIX}-${TARGET_SUFFIX}
  324. DEPENDS
  325. ${UA_GEN_NS_OUTPUT_DIR}/namespace${FILE_SUFFIX}.c
  326. ${UA_GEN_NS_OUTPUT_DIR}/namespace${FILE_SUFFIX}.h)
  327. if (UA_GEN_NS_DEPENDS_TARGET)
  328. add_dependencies(${UA_GEN_NS_TARGET_PREFIX}-${TARGET_SUFFIX} ${UA_GEN_NS_DEPENDS_TARGET})
  329. endif()
  330. if(UA_COMPILE_AS_CXX)
  331. set_source_files_properties(${UA_GEN_NS_OUTPUT_DIR}/namespace${FILE_SUFFIX}.c PROPERTIES LANGUAGE CXX)
  332. endif()
  333. string(REPLACE "-" "_" UA_GEN_NS_NAME ${UA_GEN_NS_NAME})
  334. string(TOUPPER "${UA_GEN_NS_NAME}" GEN_NAME_UPPER)
  335. set_property(GLOBAL PROPERTY "UA_GEN_NS_DEPENDS_FILE_${UA_GEN_NS_NAME}" ${UA_GEN_NS_DEPENDS_NS} ${UA_GEN_NS_FILE})
  336. set_property(GLOBAL PROPERTY "UA_GEN_NS_DEPENDS_TYPES_${UA_GEN_NS_NAME}" ${UA_GEN_NS_DEPENDS_TYPES} ${UA_GEN_NS_TYPES_ARRAY})
  337. set(UA_NODESET_${GEN_NAME_UPPER}_SOURCES "${UA_GEN_NS_OUTPUT_DIR}/namespace${FILE_SUFFIX}.c" CACHE INTERNAL "UA_NODESET_${GEN_NAME_UPPER} source files")
  338. set(UA_NODESET_${GEN_NAME_UPPER}_HEADERS "${UA_GEN_NS_OUTPUT_DIR}/namespace${FILE_SUFFIX}.h" CACHE INTERNAL "UA_NODESET_${GEN_NAME_UPPER} header files")
  339. set(UA_NODESET_${GEN_NAME_UPPER}_TARGET "${UA_GEN_NS_TARGET_PREFIX}-${TARGET_SUFFIX}" CACHE INTERNAL "UA_NODESET_${GEN_NAME_UPPER} target")
  340. endfunction()
  341. # --------------- Generate Nodeset and Datatypes ---------------------
  342. #
  343. # Generates C code for the given NodeSet2.xml and Datatype file.
  344. # This C code can be used to initialize the server.
  345. #
  346. # This is a combination of the ua_generate_datatypes, ua_generate_nodeset, and
  347. # ua_generate_nodeid_header macros.
  348. # This function can also be used to just create a nodeset without datatypes by
  349. # omitting the CSV, BSD, and NAMESPACE_IDX parameter.
  350. # If only one of the previous parameters is given, all of them are required.
  351. #
  352. # It is possible to define dependencies of nodesets by using the DEPENDS argument.
  353. # E.g. the PLCOpen nodeset depends on the 'di' nodeset. Thus it is enough to just
  354. # pass 'DEPENDS di' to the function. The 'di' nodeset then first needs to be generated
  355. # with this function or with the ua_generate_nodeset function.
  356. #
  357. # The resulting cmake target will be named like this:
  358. # open62541-generator-ns-${NAME}
  359. #
  360. # The following arguments are accepted:
  361. #
  362. # Options:
  363. #
  364. # INTERNAL Include internal headers. Required if custom datatypes are added.
  365. #
  366. # Arguments taking one value:
  367. #
  368. # NAME Short name of the nodeset. E.g. 'di'
  369. # FILE_NS Path to the NodeSet2.xml file. Multiple values can be passed. These nodesets will be combined into one output.
  370. #
  371. # [FILE_CSV] Optional path to the .csv file containing the node ids, e.g. 'OpcUaDiModel.csv'
  372. # [FILE_BSD] Optional path to the .bsd file containing the type definitions, e.g. 'Opc.Ua.Di.Types.bsd'. Multiple files can be
  373. # passed which will all combined to one resulting code.
  374. # [NAMESPACE_IDX] Optional namespace index of the nodeset, when it is loaded into the server. This parameter is mandatory if FILE_CSV
  375. # or FILE_BSD is set. See ua_generate_datatypes function.
  376. # [BLACKLIST] Blacklist file passed as --blacklist to the nodeset compiler. All the given nodes will be removed from the generated
  377. # nodeset, including all the references to and from that node. The format is a node id per line.
  378. # Supported formats: "i=123" (for NS0), "ns=2;s=asdf" (matches NS2 in that specific file), or recommended
  379. # "ns=http://opcfoundation.org/UA/DI/;i=123" namespace index independent node id
  380. # [TARGET_PREFIX] Optional prefix for the resulting targets. Default `open62541-generator`
  381. #
  382. # Arguments taking multiple values:
  383. # [DEPENDS] Optional list of nodeset names on which this nodeset depends. These names must match any name from a previous
  384. # call to this funtion. E.g. 'di' if you are generating the 'plcopen' nodeset
  385. #
  386. #
  387. function(ua_generate_nodeset_and_datatypes)
  388. set(options INTERNAL)
  389. set(oneValueArgs NAME FILE_NS FILE_CSV FILE_BSD NAMESPACE_IDX OUTPUT_DIR TARGET_PREFIX BLACKLIST)
  390. set(multiValueArgs DEPENDS)
  391. cmake_parse_arguments(UA_GEN "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN} )
  392. if(NOT DEFINED open62541_TOOLS_DIR)
  393. message(FATAL_ERROR "open62541_TOOLS_DIR must point to the open62541 tools directory")
  394. endif()
  395. if(NOT DEFINED open62541_NODESET_DIR)
  396. message(FATAL_ERROR "open62541_NODESET_DIR must point to the open62541/deps/ua-nodeset directory")
  397. endif()
  398. # ------ Argument checking -----
  399. if(NOT UA_GEN_NAME OR "${UA_GEN_NAME}" STREQUAL "")
  400. message(FATAL_ERROR "ua_generate_nodeset_and_datatypes function requires a value for the NAME argument")
  401. endif()
  402. string(TOUPPER "${UA_GEN_NAME}" GEN_NAME_UPPER)
  403. if(NOT UA_GEN_FILE_NS OR "${UA_GEN_FILE_NS}" STREQUAL "")
  404. message(FATAL_ERROR "ua_generate_nodeset_and_datatypes function requires a value for the FILE_NS argument")
  405. endif()
  406. if((NOT UA_GEN_FILE_CSV OR "${UA_GEN_FILE_CSV}" STREQUAL "") AND
  407. (NOT "${UA_GEN_FILE_BSD}" STREQUAL "" OR
  408. NOT "${UA_GEN_NAMESPACE_IDX}" STREQUAL ""))
  409. message(FATAL_ERROR "ua_generate_nodeset_and_datatypes function requires FILE_CSV argument if any of FILE_BSD or NAMESPACE_IDX are set")
  410. endif()
  411. if((NOT UA_GEN_FILE_BSD OR "${UA_GEN_FILE_BSD}" STREQUAL "") AND
  412. (NOT "${UA_GEN_FILE_CSV}" STREQUAL "" OR
  413. NOT "${UA_GEN_NAMESPACE_IDX}" STREQUAL ""))
  414. message(FATAL_ERROR "ua_generate_nodeset_and_datatypes function requires FILE_BSD argument if any of FILE_CSV or NAMESPACE_IDX are set")
  415. endif()
  416. if(NOT UA_GEN_NAMESPACE_IDX OR "${UA_GEN_NAMESPACE_IDX}" STREQUAL "" AND
  417. (NOT "${UA_GEN_FILE_CSV}" STREQUAL "" OR
  418. NOT "${UA_GEN_FILE_BSD}" STREQUAL ""))
  419. message(FATAL_ERROR "ua_generate_nodeset_and_datatypes function requires NAMESPACE_IDX argument if any of FILE_CSV or FILE_BSD are set")
  420. endif()
  421. # Set default value for output dir
  422. if(NOT UA_GEN_OUTPUT_DIR OR "${UA_GEN_OUTPUT_DIR}" STREQUAL "")
  423. set(UA_GEN_OUTPUT_DIR ${PROJECT_BINARY_DIR}/src_generated/open62541)
  424. endif()
  425. # Set default target prefix
  426. if(NOT UA_GEN_TARGET_PREFIX OR "${UA_GEN_TARGET_PREFIX}" STREQUAL "")
  427. set(UA_GEN_TARGET_PREFIX "open62541-generator")
  428. endif()
  429. set(NODESET_DEPENDS_TARGET "")
  430. set(NODESET_TYPES_ARRAY "UA_TYPES")
  431. if(NOT "${UA_GEN_FILE_BSD}" STREQUAL "")
  432. # Generate Datatypes for nodeset
  433. ua_generate_datatypes(
  434. NAME "types_${UA_GEN_NAME}"
  435. TARGET_PREFIX "${UA_GEN_TARGET_PREFIX}"
  436. TARGET_SUFFIX "types-${UA_GEN_NAME}"
  437. NAMESPACE_IDX ${UA_GEN_NAMESPACE_IDX}
  438. FILE_CSV "${UA_GEN_FILE_CSV}"
  439. FILES_BSD "${UA_GEN_FILE_BSD}"
  440. OUTPUT_DIR "${UA_GEN_OUTPUT_DIR}"
  441. )
  442. set(NODESET_DEPENDS_TARGET "${UA_GEN_TARGET_PREFIX}-types-${UA_GEN_NAME}")
  443. set(NODESET_TYPES_ARRAY "UA_TYPES_${GEN_NAME_UPPER}")
  444. ua_generate_nodeid_header(
  445. NAME "${UA_GEN_NAME}_nodeids"
  446. ID_PREFIX "${GEN_NAME_UPPER}"
  447. FILE_CSV "${UA_GEN_FILE_CSV}"
  448. OUTPUT_DIR "${UA_GEN_OUTPUT_DIR}"
  449. TARGET_PREFIX "${UA_GEN_TARGET_PREFIX}"
  450. TARGET_SUFFIX "ids-${UA_GEN_NAME}"
  451. )
  452. set(NODESET_DEPENDS_TARGET ${NODESET_DEPENDS_TARGET} "${UA_GEN_TARGET_PREFIX}-ids-${UA_GEN_NAME}")
  453. endif()
  454. # Create a list of nodesets on which this nodeset depends on
  455. if (NOT UA_GEN_DEPENDS OR "${UA_GEN_DEPENDS}" STREQUAL "" )
  456. if(NOT UA_FILE_NS0)
  457. set(NODESET_DEPENDS "${open62541_NODESET_DIR}/Schema/Opc.Ua.NodeSet2.xml")
  458. else()
  459. set(NODESET_DEPENDS "${UA_FILE_NS0}")
  460. endif()
  461. set(TYPES_DEPENDS "UA_TYPES")
  462. else()
  463. foreach(f ${UA_GEN_DEPENDS})
  464. if(EXISTS ${f})
  465. set(NODESET_DEPENDS ${NODESET_DEPENDS} "${f}")
  466. else()
  467. string(REPLACE "-" "_" DEPENDS_NAME "${f}")
  468. get_property(DEPENDS_FILE GLOBAL PROPERTY "UA_GEN_NS_DEPENDS_FILE_${DEPENDS_NAME}")
  469. if(NOT DEPENDS_FILE OR "${DEPENDS_FILE}" STREQUAL "")
  470. message(FATAL_ERROR "Nodeset dependency ${f} needs to be generated before ${UA_GEN_NAME}")
  471. endif()
  472. set(NODESET_DEPENDS ${NODESET_DEPENDS} "${DEPENDS_FILE}")
  473. get_property(DEPENDS_TYPES GLOBAL PROPERTY "UA_GEN_NS_DEPENDS_TYPES_${DEPENDS_NAME}")
  474. set(TYPES_DEPENDS ${TYPES_DEPENDS} "${DEPENDS_TYPES}")
  475. set(NODESET_DEPENDS_TARGET ${NODESET_DEPENDS_TARGET} "${UA_GEN_TARGET_PREFIX}-ns-${f}")
  476. endif()
  477. endforeach()
  478. endif()
  479. set(NODESET_INTERNAL "")
  480. if (${UA_GEN_INTERNAL})
  481. set(NODESET_INTERNAL "INTERNAL")
  482. endif()
  483. ua_generate_nodeset(
  484. NAME "${UA_GEN_NAME}"
  485. FILE "${UA_GEN_FILE_NS}"
  486. TYPES_ARRAY "${NODESET_TYPES_ARRAY}"
  487. BLACKLIST "${UA_GEN_BLACKLIST}"
  488. ${NODESET_INTERNAL}
  489. DEPENDS_TYPES ${TYPES_DEPENDS}
  490. DEPENDS_NS ${NODESET_DEPENDS}
  491. DEPENDS_TARGET ${NODESET_DEPENDS_TARGET}
  492. OUTPUT_DIR "${UA_GEN_OUTPUT_DIR}"
  493. TARGET_PREFIX "${UA_GEN_TARGET_PREFIX}"
  494. )
  495. endfunction()