1 cmake_minimum_required(VERSION 3.13) 2 3 project(ucode C) 4 5 add_library(uc_defines INTERFACE) 6 7 include(CheckFunctionExists) 8 include(CheckSymbolExists) 9 include(CheckCSourceCompiles) 10 include(GNUInstallDirs) 11 12 option(BUILD_OPTIMIZE_SIZE "Optimize for size" ON) 13 if(BUILD_OPTIMIZE_SIZE) 14 add_compile_options( 15 -Os 16 ) 17 endif() 18 19 set(CMAKE_C_STANDARD 99) 20 set(CMAKE_C_STANDARD_REQUIRED ON) 21 set(CMAKE_C_EXTENSIONS ON) 22 23 add_compile_definitions( _GNU_SOURCE ) 24 add_compile_options( 25 -Wall 26 -Werror 27 -Wmissing-declarations 28 ) 29 30 if(CMAKE_C_COMPILER_VERSION VERSION_GREATER 6) 31 add_compile_options( 32 -Wextra 33 -Wformat 34 -Werror=implicit-function-declaration 35 -Werror=format-security 36 -Werror=format-nonliteral 37 ) 38 endif() 39 40 add_compile_options( 41 -Wno-unused-parameter 42 -Wno-error=unused-variable 43 ) 44 45 # signed overflow semantics are defined AND expected 46 add_compile_options(-fwrapv) 47 48 option(BUILD_FUNCTION_SECTIONS "Compile with -ffunction-sections" ON) 49 if(BUILD_FUNCTION_SECTIONS) 50 add_compile_options(-ffunction-sections) 51 endif() 52 53 check_c_source_compiles(" 54 int main() { 55 #ifndef _FORTIFY_SOURCE 56 #error No fortification 57 #endif 58 return 0; 59 } 60 " DEFAULT_FORTIFY_SOURCE) 61 62 if(NOT DEFAULT_FORTIFY_SOURCE) 63 add_compile_definitions( FORTIFY_SOURCE=2 ) 64 endif() 65 66 include_directories(include) 67 68 option(COMPILE_SUPPORT "Support compilation from source" ON) 69 if(NOT COMPILE_SUPPORT) 70 target_compile_definitions(uc_defines INTERFACE NO_COMPILE) 71 endif() 72 73 find_library(libuci NAMES uci) 74 find_library(libubox NAMES ubox) 75 find_library(libubus NAMES ubus) 76 find_library(libblobmsg_json NAMES blobmsg_json) 77 find_package(ZLIB) 78 find_library(libmd NAMES libmd.a md) 79 80 if(LINUX) 81 find_library(libnl_tiny NAMES nl-tiny) 82 83 if(libnl_tiny AND libubox) 84 set(DEFAULT_NL_SUPPORT ON) 85 endif() 86 endif() 87 88 if(libuci AND libubox) 89 set(DEFAULT_UCI_SUPPORT ON) 90 endif() 91 92 if(libubus AND libblobmsg_json) 93 set(DEFAULT_UBUS_SUPPORT ON) 94 endif() 95 96 if(libubox) 97 set(DEFAULT_ULOOP_SUPPORT ON) 98 endif() 99 100 if(ZLIB_FOUND) 101 set(DEFAULT_ZLIB_SUPPORT ON) 102 endif() 103 104 if(libmd) 105 set(DEFAULT_DIGEST_SUPPORT ON) 106 endif() 107 108 option(DEBUG_SUPPORT "Debug plugin support" ON) 109 option(FS_SUPPORT "Filesystem plugin support" ON) 110 option(IO_SUPPORT "IO plugin support" ON) 111 option(MATH_SUPPORT "Math plugin support" ON) 112 option(UBUS_SUPPORT "Ubus plugin support" ${DEFAULT_UBUS_SUPPORT}) 113 option(UCI_SUPPORT "UCI plugin support" ${DEFAULT_UCI_SUPPORT}) 114 option(RTNL_SUPPORT "Route Netlink plugin support" ${DEFAULT_NL_SUPPORT}) 115 option(NL80211_SUPPORT "Wireless Netlink plugin support" ${DEFAULT_NL_SUPPORT}) 116 option(RESOLV_SUPPORT "NS resolve plugin support" ON) 117 option(STRUCT_SUPPORT "Struct plugin support" ON) 118 option(ULOOP_SUPPORT "Uloop plugin support" ${DEFAULT_ULOOP_SUPPORT}) 119 option(LOG_SUPPORT "Log plugin support" ON) 120 option(SOCKET_SUPPORT "Socket plugin support" ON) 121 option(ZLIB_SUPPORT "Zlib plugin support" ${DEFAULT_ZLIB_SUPPORT}) 122 option(DIGEST_SUPPORT "Digest plugin support" ${DEFAULT_DIGEST_SUPPORT}) 123 option(DIGEST_SUPPORT_EXTENDED "Enable additional hash algorithms" ${DEFAULT_DIGEST_SUPPORT}) 124 125 set(LIB_SEARCH_PATH "${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}/ucode/*.so:${CMAKE_INSTALL_PREFIX}/share/ucode/*.uc:./*.so:./*.uc" CACHE STRING "Default library search path") 126 string(REPLACE ":" "\", \"" LIB_SEARCH_DEFINE "${LIB_SEARCH_PATH}") 127 target_compile_definitions(uc_defines INTERFACE LIB_SEARCH_PATH="${LIB_SEARCH_DEFINE}") 128 129 if(APPLE) 130 set(UCODE_MODULE_LINK_OPTIONS "LINKER:-undefined,dynamic_lookup") 131 # TODO: localize target(s) and switch to target_compile_definitions() 132 add_compile_definitions( BIND_8_COMPAT ) 133 endif() 134 135 if(APPLE) 136 set(DEFAULT_LINK_GC_SECTIONS OFF) 137 else() 138 set(DEFAULT_LINK_GC_SECTIONS ON) 139 endif() 140 option(LINK_GC_SECTIONS "Link with --gc-sections" ${DEFAULT_LINK_GC_SECTIONS}) 141 if(LINK_GC_SECTIONS) 142 if(UNIT_TESTING) 143 message(WARNING "Unit testing **MAY** conflict with --gc-sections") 144 else() 145 add_link_options("LINKER:--gc-sections") 146 endif() 147 endif() 148 149 if(DEBUG) 150 add_compile_definitions( DEBUG ) 151 add_compile_options( 152 -Og 153 -g3 154 ) 155 else() 156 add_compile_definitions( NDEBUG ) 157 endif() 158 159 include(FindPkgConfig) 160 pkg_check_modules(JSONC REQUIRED json-c) 161 include_directories(${JSONC_INCLUDE_DIRS}) 162 163 set(UCODE_SOURCES lexer.c lib.c vm.c chunk.c vallist.c compiler.c source.c types.c program.c platform.c) 164 add_library(libucode SHARED ${UCODE_SOURCES}) 165 set(SOVERSION 0 CACHE STRING "Override ucode library version") 166 set_target_properties(libucode PROPERTIES OUTPUT_NAME ucode SOVERSION ${SOVERSION}) 167 target_link_libraries(libucode uc_defines ${JSONC_LINK_LIBRARIES}) 168 169 set(CLI_SOURCES main.c) 170 add_executable(ucode ${CLI_SOURCES}) 171 target_link_libraries(ucode uc_defines libucode) 172 173 # Ensure rpath is used on macOS 174 set(CMAKE_MACOSX_RPATH ON) 175 176 # Automatically include linked library paths in rpath 177 set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE) 178 179 if(APPLE) 180 set_target_properties(libucode PROPERTIES 181 INSTALL_NAME_DIR "@rpath" 182 ) 183 set_target_properties(ucode PROPERTIES 184 INSTALL_RPATH "@loader_path/../${CMAKE_INSTALL_LIBDIR}" 185 ) 186 endif() 187 188 if(APPLE AND CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT) 189 execute_process( 190 COMMAND brew --prefix 191 OUTPUT_VARIABLE HOMEBREW_PREFIX 192 OUTPUT_STRIP_TRAILING_WHITESPACE 193 ERROR_QUIET 194 ) 195 196 if(HOMEBREW_PREFIX AND EXISTS "${HOMEBREW_PREFIX}") 197 message(STATUS "Using Homebrew prefix: ${HOMEBREW_PREFIX}") 198 set(CMAKE_INSTALL_PREFIX "${HOMEBREW_PREFIX}" CACHE PATH "Install path" FORCE) 199 endif() 200 endif() 201 202 check_function_exists(dlopen DLOPEN_FUNCTION_EXISTS) 203 if(NOT DLOPEN_FUNCTION_EXISTS) 204 target_link_libraries(libucode dl) 205 endif() 206 207 check_function_exists(fmod FMOD_FUNCTION_EXISTS) 208 if(NOT FMOD_FUNCTION_EXISTS) 209 target_link_libraries(libucode m) 210 endif() 211 212 list(APPEND CMAKE_REQUIRED_INCLUDES ${JSONC_INCLUDE_DIRS}) 213 list(APPEND CMAKE_REQUIRED_LIBRARIES ${JSONC_LINK_LIBRARIES}) 214 check_symbol_exists(json_tokener_get_parse_end "json-c/json.h" HAVE_PARSE_END) 215 if(HAVE_PARSE_END) 216 target_compile_definitions(uc_defines INTERFACE HAVE_PARSE_END) 217 endif() 218 check_symbol_exists(json_object_new_array_ext "json-c/json.h" HAVE_ARRAY_EXT) 219 if(HAVE_ARRAY_EXT) 220 target_compile_definitions(uc_defines INTERFACE HAVE_ARRAY_EXT) 221 endif() 222 check_symbol_exists(json_object_new_uint64 "json-c/json.h" HAVE_JSON_UINT64) 223 if(HAVE_JSON_UINT64) 224 target_compile_definitions(uc_defines INTERFACE HAVE_JSON_UINT64) 225 endif() 226 227 set(LIBRARIES "") 228 229 if(DEBUG_SUPPORT) 230 set(LIBRARIES ${LIBRARIES} debug_lib) 231 add_library(debug_lib MODULE lib/debug.c) 232 set_target_properties(debug_lib PROPERTIES OUTPUT_NAME debug PREFIX "") 233 target_link_options(debug_lib PRIVATE ${UCODE_MODULE_LINK_OPTIONS}) 234 if(libubox) 235 find_path(uloop_include_dir NAMES libubox/uloop.h) 236 include_directories(${uloop_include_dir}) 237 target_link_libraries(debug_lib ${libubox} ${libucode}) 238 target_compile_definitions(debug_lib PRIVATE HAVE_ULOOP) 239 endif() 240 endif() 241 242 if(FS_SUPPORT) 243 set(LIBRARIES ${LIBRARIES} fs_lib) 244 add_library(fs_lib MODULE lib/fs.c) 245 set_target_properties(fs_lib PROPERTIES OUTPUT_NAME fs PREFIX "") 246 target_link_options(fs_lib PRIVATE ${UCODE_MODULE_LINK_OPTIONS}) 247 endif() 248 249 if(IO_SUPPORT) 250 set(LIBRARIES ${LIBRARIES} io_lib) 251 add_library(io_lib MODULE lib/io.c) 252 set_target_properties(io_lib PROPERTIES OUTPUT_NAME io PREFIX "") 253 target_link_options(io_lib PRIVATE ${UCODE_MODULE_LINK_OPTIONS}) 254 endif() 255 256 if(MATH_SUPPORT) 257 set(LIBRARIES ${LIBRARIES} math_lib) 258 add_library(math_lib MODULE lib/math.c) 259 set_target_properties(math_lib PROPERTIES OUTPUT_NAME math PREFIX "") 260 target_link_options(math_lib PRIVATE ${UCODE_MODULE_LINK_OPTIONS}) 261 check_function_exists(ceil CEIL_FUNCTION_EXISTS) 262 if(NOT CEIL_FUNCTION_EXISTS) 263 target_link_libraries(math_lib m) 264 endif() 265 endif() 266 267 if(UBUS_SUPPORT) 268 find_path(ubus_include_dir NAMES libubus.h) 269 include_directories(${ubus_include_dir}) 270 set(LIBRARIES ${LIBRARIES} ubus_lib) 271 add_library(ubus_lib MODULE lib/ubus.c) 272 set_target_properties(ubus_lib PROPERTIES OUTPUT_NAME ubus PREFIX "") 273 target_link_options(ubus_lib PRIVATE ${UCODE_MODULE_LINK_OPTIONS}) 274 target_link_libraries(ubus_lib ${libubus} ${libblobmsg_json}) 275 list(APPEND CMAKE_REQUIRED_LIBRARIES ${libubox} ${libubus}) 276 file(WRITE "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/test.c" " 277 #include <libubus.h> 278 int main() { return UBUS_STATUS_NO_MEMORY; } 279 ") 280 try_compile(HAVE_NEW_UBUS_STATUS_CODES 281 ${CMAKE_BINARY_DIR} 282 "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/test.c") 283 check_function_exists(ubus_flush_requests HAVE_UBUS_FLUSH_REQUESTS) 284 check_function_exists(uloop_timeout_remaining64 REMAINING64_FUNCTION_EXISTS) 285 check_function_exists(ubus_channel_connect HAVE_CHANNEL_SUPPORT) 286 file(WRITE "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/test2.c" " 287 #include <libubus.h> 288 int main() { struct ubus_subscriber sub = { .new_obj_cb = NULL }; return 0; } 289 ") 290 try_compile(HAVE_UBUS_NEW_OBJ_CB 291 ${CMAKE_BINARY_DIR} 292 "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/test2.c") 293 if(REMAINING64_FUNCTION_EXISTS) 294 target_compile_definitions(ubus_lib PRIVATE HAVE_ULOOP_TIMEOUT_REMAINING64) 295 endif() 296 if(HAVE_CHANNEL_SUPPORT) 297 target_compile_definitions(ubus_lib PRIVATE HAVE_UBUS_CHANNEL_SUPPORT) 298 endif() 299 if(HAVE_NEW_UBUS_STATUS_CODES) 300 target_compile_definitions(ubus_lib PRIVATE HAVE_NEW_UBUS_STATUS_CODES) 301 endif() 302 if(HAVE_UBUS_FLUSH_REQUESTS) 303 target_compile_definitions(ubus_lib PRIVATE HAVE_UBUS_FLUSH_REQUESTS) 304 endif() 305 if (HAVE_UBUS_NEW_OBJ_CB) 306 target_compile_definitions(ubus_lib PRIVATE HAVE_UBUS_NEW_OBJ_CB) 307 endif() 308 endif() 309 310 if(UCI_SUPPORT) 311 find_path(uci_include_dir uci.h) 312 include_directories(${uci_include_dir}) 313 set(LIBRARIES ${LIBRARIES} uci_lib) 314 add_library(uci_lib MODULE lib/uci.c) 315 list(APPEND CMAKE_REQUIRED_LIBRARIES ${libubox} ${libuci}) 316 check_function_exists(uci_set_conf2dir HAVE_UCI_CONF2DIR) 317 if (HAVE_UCI_CONF2DIR) 318 target_compile_definitions(uci_lib PRIVATE HAVE_UCI_CONF2DIR) 319 endif() 320 set_target_properties(uci_lib PROPERTIES OUTPUT_NAME uci PREFIX "") 321 target_link_options(uci_lib PRIVATE ${UCODE_MODULE_LINK_OPTIONS}) 322 target_link_libraries(uci_lib ${libuci} ${libubox}) 323 endif() 324 325 if(RTNL_SUPPORT) 326 find_path(nl_include_dir NAMES netlink/msg.h PATH_SUFFIXES libnl-tiny) 327 include_directories(${nl_include_dir}) 328 set(LIBRARIES ${LIBRARIES} rtnl_lib) 329 add_library(rtnl_lib MODULE lib/rtnl.c) 330 set_target_properties(rtnl_lib PROPERTIES OUTPUT_NAME rtnl PREFIX "") 331 target_link_options(rtnl_lib PRIVATE ${UCODE_MODULE_LINK_OPTIONS}) 332 target_link_libraries(rtnl_lib ${libnl_tiny} ${libubox}) 333 endif() 334 335 if(NL80211_SUPPORT) 336 find_path(nl_include_dir NAMES netlink/msg.h PATH_SUFFIXES libnl-tiny) 337 include_directories(${nl_include_dir}) 338 set(LIBRARIES ${LIBRARIES} nl80211_lib) 339 add_library(nl80211_lib MODULE lib/nl80211.c) 340 set_target_properties(nl80211_lib PROPERTIES OUTPUT_NAME nl80211 PREFIX "") 341 target_link_options(nl80211_lib PRIVATE ${UCODE_MODULE_LINK_OPTIONS}) 342 target_link_libraries(nl80211_lib ${libnl_tiny} ${libubox}) 343 endif() 344 345 if(RESOLV_SUPPORT) 346 set(LIBRARIES ${LIBRARIES} resolv_lib) 347 add_library(resolv_lib MODULE lib/resolv.c) 348 set_target_properties(resolv_lib PROPERTIES OUTPUT_NAME resolv PREFIX "") 349 target_link_options(resolv_lib PRIVATE ${UCODE_MODULE_LINK_OPTIONS}) 350 check_function_exists(res_mkquery RES_MKQUERY_FUNCTION_EXISTS) 351 check_function_exists(ns_initparse NS_INITARSE_FUNCTION_EXISTS) 352 check_function_exists(clock_gettime CLOCK_GETTIME_FUNCTION_EXISTS) 353 if(NOT RES_MKQUERY_FUNCTION_EXISTS OR NOT NS_INITARSE_FUNCTION_EXISTS) 354 target_link_libraries(resolv_lib resolv) 355 endif() 356 if(NOT CLOCK_GETTIME_FUNCTION_EXISTS) 357 target_link_libraries(resolv_lib rt) 358 endif() 359 endif() 360 361 if(STRUCT_SUPPORT) 362 set(LIBRARIES ${LIBRARIES} struct_lib) 363 add_library(struct_lib MODULE lib/struct.c) 364 set_target_properties(struct_lib PROPERTIES OUTPUT_NAME struct PREFIX "") 365 target_link_options(struct_lib PRIVATE ${UCODE_MODULE_LINK_OPTIONS}) 366 check_function_exists(frexp FREXP_FUNCTION_EXISTS) 367 if(NOT FREXP_FUNCTION_EXISTS) 368 target_link_libraries(struct_lib m) 369 endif() 370 endif() 371 372 if(ULOOP_SUPPORT) 373 find_path(uloop_include_dir NAMES libubox/uloop.h) 374 include_directories(${uloop_include_dir}) 375 set(LIBRARIES ${LIBRARIES} uloop_lib) 376 add_library(uloop_lib MODULE lib/uloop.c) 377 set_target_properties(uloop_lib PROPERTIES OUTPUT_NAME uloop PREFIX "") 378 target_link_options(uloop_lib PRIVATE ${UCODE_MODULE_LINK_OPTIONS}) 379 list(APPEND CMAKE_REQUIRED_LIBRARIES ${libubox}) 380 check_function_exists(uloop_timeout_remaining64 REMAINING64_FUNCTION_EXISTS) 381 check_function_exists(uloop_interval_set INTERVAL_FUNCTION_EXISTS) 382 check_function_exists(uloop_signal_add SIGNAL_FUNCTION_EXISTS) 383 if(REMAINING64_FUNCTION_EXISTS) 384 target_compile_definitions(uloop_lib PRIVATE HAVE_ULOOP_TIMEOUT_REMAINING64) 385 endif() 386 if(INTERVAL_FUNCTION_EXISTS) 387 target_compile_definitions(uloop_lib PRIVATE HAVE_ULOOP_INTERVAL) 388 endif() 389 if(SIGNAL_FUNCTION_EXISTS) 390 target_compile_definitions(uloop_lib PRIVATE HAVE_ULOOP_SIGNAL) 391 endif() 392 target_link_libraries(uloop_lib ${libubox}) 393 endif() 394 395 if(LOG_SUPPORT) 396 set(LIBRARIES ${LIBRARIES} log_lib) 397 add_library(log_lib MODULE lib/log.c) 398 set_target_properties(log_lib PROPERTIES OUTPUT_NAME log PREFIX "") 399 target_link_options(log_lib PRIVATE ${UCODE_MODULE_LINK_OPTIONS}) 400 if(libubox) 401 find_path(ulog_include_dir NAMES libubox/ulog.h) 402 include_directories(${ulog_include_dir}) 403 target_link_libraries(log_lib ${libubox}) 404 target_compile_definitions(log_lib PRIVATE HAVE_ULOG) 405 endif() 406 endif() 407 408 if(SOCKET_SUPPORT) 409 set(LIBRARIES ${LIBRARIES} socket_lib) 410 add_library(socket_lib MODULE lib/socket.c) 411 set_target_properties(socket_lib PROPERTIES OUTPUT_NAME socket PREFIX "") 412 target_link_options(socket_lib PRIVATE ${UCODE_MODULE_LINK_OPTIONS}) 413 endif() 414 415 if(ZLIB_SUPPORT) 416 set(LIBRARIES ${LIBRARIES} zlib_lib) 417 add_library(zlib_lib MODULE lib/zlib.c) 418 set_target_properties(zlib_lib PROPERTIES OUTPUT_NAME zlib PREFIX "") 419 target_link_options(zlib_lib PRIVATE ${UCODE_MODULE_LINK_OPTIONS}) 420 target_link_libraries(zlib_lib ZLIB::ZLIB) 421 if(ZLIB_CHUNK_SIZE) 422 target_compile_definitions(zlib_lib PRIVATE UC_ZLIB_CHUNK=${ZLIB_CHUNK_SIZE}) 423 endif() 424 endif() 425 426 if(DIGEST_SUPPORT) 427 pkg_check_modules(LIBMD REQUIRED libmd) 428 include_directories(${LIBMD_INCLUDE_DIRS}) 429 set(LIBRARIES ${LIBRARIES} digest_lib) 430 add_library(digest_lib MODULE lib/digest.c) 431 set_target_properties(digest_lib PROPERTIES OUTPUT_NAME digest PREFIX "") 432 if(DIGEST_SUPPORT_EXTENDED) 433 target_compile_definitions(digest_lib PRIVATE HAVE_DIGEST_EXTENDED) 434 endif() 435 target_link_options(digest_lib PRIVATE ${UCODE_MODULE_LINK_OPTIONS}) 436 target_link_libraries(digest_lib ${libmd}) 437 endif() 438 439 if(UNIT_TESTING) 440 enable_testing() 441 add_compile_definitions( UNIT_TESTING ) 442 add_subdirectory(tests) 443 list(APPEND CMAKE_CTEST_ARGUMENTS "--output-on-failure") 444 445 if(CMAKE_C_COMPILER_ID STREQUAL "Clang") 446 add_executable(ucode-san ${CLI_SOURCES} ${UCODE_SOURCES}) 447 set_property(TARGET ucode-san PROPERTY ENABLE_EXPORTS 1) 448 target_link_libraries(ucode-san uc_defines ${JSONC_LINK_LIBRARIES}) 449 target_compile_options(ucode-san PRIVATE -g -fno-omit-frame-pointer -fsanitize=undefined,address,leak -fno-sanitize-recover=all) 450 target_link_options(ucode-san PRIVATE -fsanitize=undefined,address,leak) 451 endif() 452 endif() 453 454 install(TARGETS ucode RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}) 455 install(TARGETS libucode LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}) 456 install(TARGETS ${LIBRARIES} LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}/ucode) 457 458 add_custom_target(utpl ALL COMMAND ${CMAKE_COMMAND} -E create_symlink ucode utpl) 459 install(FILES ${CMAKE_CURRENT_BINARY_DIR}/utpl DESTINATION ${CMAKE_INSTALL_BINDIR}) 460 461 if(COMPILE_SUPPORT) 462 add_custom_target(ucc ALL COMMAND ${CMAKE_COMMAND} -E create_symlink ucode ucc) 463 install(FILES ${CMAKE_CURRENT_BINARY_DIR}/ucc DESTINATION ${CMAKE_INSTALL_BINDIR}) 464 endif() 465 466 file(GLOB UCODE_HEADERS "include/ucode/*.h") 467 install(FILES ${UCODE_HEADERS} DESTINATION include/ucode) 468 469 add_subdirectory(examples)
This page was automatically generated by LXR 0.3.1. • OpenWrt