blob: 727a9b819cd493769439b65039cec03c0658177e (
plain)
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
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
|
cmake_minimum_required(VERSION 3.13)
include(CheckFunctionExists)
include(CheckSymbolExists)
project(ucode C)
add_definitions(-Os -Wall -Werror --std=gnu99 -ffunction-sections -fwrapv -D_GNU_SOURCE)
if(CMAKE_C_COMPILER_VERSION VERSION_GREATER 6)
add_definitions(-Wextra -Werror=implicit-function-declaration)
add_definitions(-Wformat -Werror=format-security -Werror=format-nonliteral)
endif()
if(NOT CMAKE_C_FLAGS MATCHES -D_FORTIFY_SOURCE=)
add_definitions(-D_FORTIFY_SOURCE=2)
endif()
add_definitions(-Wmissing-declarations -Wno-error=unused-variable -Wno-unused-parameter)
include_directories(include)
option(COMPILE_SUPPORT "Support compilation from source" ON)
if(NOT COMPILE_SUPPORT)
add_definitions(-DNO_COMPILE)
endif()
find_library(libuci NAMES uci)
find_library(libubox NAMES ubox)
find_library(libubus NAMES ubus)
find_library(libblobmsg_json NAMES blobmsg_json)
find_library(libmbedtls NAMES mbedtls)
find_library(libcrypto NAMES crypto)
find_package(ZLIB)
if(LINUX)
find_library(libnl_tiny NAMES nl-tiny)
if(libnl_tiny AND libubox)
set(DEFAULT_NL_SUPPORT ON)
endif()
endif()
if(libuci AND libubox)
set(DEFAULT_UCI_SUPPORT ON)
endif()
if(libubus AND libblobmsg_json)
set(DEFAULT_UBUS_SUPPORT ON)
endif()
if(libubox)
set(DEFAULT_ULOOP_SUPPORT ON)
endif()
if(ZLIB_FOUND)
set(DEFAULT_ZLIB_SUPPORT ON)
endif()
if(libmbedtls)
set(DEFAULT_CRYPTO_MBEDTLS_SUPPORT ON)
endif()
if(libcrypto)
set(DEFAULT_CRYPTO_OPENSSL_SUPPORT ON)
endif()
option(DEBUG_SUPPORT "Debug plugin support" ON)
option(FS_SUPPORT "Filesystem plugin support" ON)
option(MATH_SUPPORT "Math plugin support" ON)
option(UBUS_SUPPORT "Ubus plugin support" ${DEFAULT_UBUS_SUPPORT})
option(UCI_SUPPORT "UCI plugin support" ${DEFAULT_UCI_SUPPORT})
option(RTNL_SUPPORT "Route Netlink plugin support" ${DEFAULT_NL_SUPPORT})
option(NL80211_SUPPORT "Wireless Netlink plugin support" ${DEFAULT_NL_SUPPORT})
option(RESOLV_SUPPORT "NS resolve plugin support" ON)
option(STRUCT_SUPPORT "Struct plugin support" ON)
option(ULOOP_SUPPORT "Uloop plugin support" ${DEFAULT_ULOOP_SUPPORT})
option(LOG_SUPPORT "Log plugin support" ON)
option(SOCKET_SUPPORT "Socket plugin support" ON)
option(ZLIB_SUPPORT "Zlib plugin support" ${DEFAULT_ZLIB_SUPPORT})
option(CRYPTO_MBEDTLS_SUPPORT "Crypto Mbed-TLS plugin support" ${DEFAULT_CRYPTO_MBEDTLS_SUPPORT})
option(CRYPTO_OPENSSL_SUPPORT "Crypto OpenSSL plugin support" ${DEFAULT_CRYPTO_OPENSSL_SUPPORT})
set(LIB_SEARCH_PATH "${CMAKE_INSTALL_PREFIX}/lib/ucode/*.so:${CMAKE_INSTALL_PREFIX}/share/ucode/*.uc:./*.so:./*.uc" CACHE STRING "Default library search path")
string(REPLACE ":" "\", \"" LIB_SEARCH_DEFINE "${LIB_SEARCH_PATH}")
add_definitions(-DLIB_SEARCH_PATH="${LIB_SEARCH_DEFINE}")
if(APPLE)
set(UCODE_MODULE_LINK_OPTIONS "LINKER:-undefined,dynamic_lookup")
add_definitions(-DBIND_8_COMPAT)
else()
set(CMAKE_SHARED_LIBRARY_LINK_C_FLAGS "-Wl,--gc-sections")
endif()
if(DEBUG)
add_definitions(-DDEBUG -g3 -Og)
else()
add_definitions(-DNDEBUG)
endif()
include(FindPkgConfig)
pkg_check_modules(JSONC REQUIRED json-c)
include_directories(${JSONC_INCLUDE_DIRS})
set(UCODE_SOURCES lexer.c lib.c vm.c chunk.c vallist.c compiler.c source.c types.c program.c platform.c)
add_library(libucode SHARED ${UCODE_SOURCES})
set(SOVERSION 0 CACHE STRING "Override ucode library version")
set_target_properties(libucode PROPERTIES OUTPUT_NAME ucode SOVERSION ${SOVERSION})
target_link_libraries(libucode ${JSONC_LINK_LIBRARIES})
set(CLI_SOURCES main.c)
add_executable(ucode ${CLI_SOURCES})
target_link_libraries(ucode libucode ${JSONC_LINK_LIBRARIES})
check_function_exists(dlopen DLOPEN_FUNCTION_EXISTS)
if(NOT DLOPEN_FUNCTION_EXISTS)
target_link_libraries(libucode dl)
endif()
check_function_exists(fmod FMOD_FUNCTION_EXISTS)
if(NOT FMOD_FUNCTION_EXISTS)
target_link_libraries(libucode m)
endif()
list(APPEND CMAKE_REQUIRED_INCLUDES ${JSONC_INCLUDE_DIRS})
list(APPEND CMAKE_REQUIRED_LIBRARIES ${JSONC_LINK_LIBRARIES})
check_symbol_exists(json_tokener_get_parse_end "json-c/json.h" HAVE_PARSE_END)
if(HAVE_PARSE_END)
add_definitions(-DHAVE_PARSE_END)
endif()
check_symbol_exists(json_object_new_array_ext "json-c/json.h" HAVE_ARRAY_EXT)
if(HAVE_ARRAY_EXT)
add_definitions(-DHAVE_ARRAY_EXT)
endif()
check_symbol_exists(json_object_new_uint64 "json-c/json.h" HAVE_JSON_UINT64)
if(HAVE_JSON_UINT64)
add_definitions(-DHAVE_JSON_UINT64)
endif()
set(LIBRARIES "")
if(DEBUG_SUPPORT)
set(LIBRARIES ${LIBRARIES} debug_lib)
add_library(debug_lib MODULE lib/debug.c)
set_target_properties(debug_lib PROPERTIES OUTPUT_NAME debug PREFIX "")
target_link_options(debug_lib PRIVATE ${UCODE_MODULE_LINK_OPTIONS})
if(libubox)
find_path(uloop_include_dir NAMES libubox/uloop.h)
include_directories(${uloop_include_dir})
target_link_libraries(debug_lib ${libubox} ${libucode})
set_target_properties(debug_lib PROPERTIES COMPILE_DEFINITIONS HAVE_ULOOP)
endif()
endif()
if(FS_SUPPORT)
set(LIBRARIES ${LIBRARIES} fs_lib)
add_library(fs_lib MODULE lib/fs.c)
set_target_properties(fs_lib PROPERTIES OUTPUT_NAME fs PREFIX "")
target_link_options(fs_lib PRIVATE ${UCODE_MODULE_LINK_OPTIONS})
endif()
if(MATH_SUPPORT)
set(LIBRARIES ${LIBRARIES} math_lib)
add_library(math_lib MODULE lib/math.c)
set_target_properties(math_lib PROPERTIES OUTPUT_NAME math PREFIX "")
target_link_options(math_lib PRIVATE ${UCODE_MODULE_LINK_OPTIONS})
check_function_exists(ceil CEIL_FUNCTION_EXISTS)
if(NOT CEIL_FUNCTION_EXISTS)
target_link_libraries(math_lib m)
endif()
endif()
if(UBUS_SUPPORT)
find_path(ubus_include_dir NAMES libubus.h)
include_directories(${ubus_include_dir})
set(LIBRARIES ${LIBRARIES} ubus_lib)
add_library(ubus_lib MODULE lib/ubus.c)
set_target_properties(ubus_lib PROPERTIES OUTPUT_NAME ubus PREFIX "")
target_link_options(ubus_lib PRIVATE ${UCODE_MODULE_LINK_OPTIONS})
target_link_libraries(ubus_lib ${libubus} ${libblobmsg_json})
list(APPEND CMAKE_REQUIRED_LIBRARIES ${libubox})
file(WRITE "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/test.c" "
#include <libubus.h>
int main() { return UBUS_STATUS_NO_MEMORY; }
")
try_compile(HAVE_NEW_UBUS_STATUS_CODES
${CMAKE_BINARY_DIR}
"${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/test.c")
check_symbol_exists(uloop_fd_set_cb "libubox/uloop.h" FD_SET_CB_EXISTS)
if(HAVE_NEW_UBUS_STATUS_CODES)
add_definitions(-DHAVE_NEW_UBUS_STATUS_CODES)
endif()
if(FD_SET_CB_EXISTS)
target_compile_definitions(ubus_lib PUBLIC HAVE_ULOOP_FD_SET_CB)
endif()
endif()
if(UCI_SUPPORT)
find_path(uci_include_dir uci.h)
include_directories(${uci_include_dir})
set(LIBRARIES ${LIBRARIES} uci_lib)
add_library(uci_lib MODULE lib/uci.c)
set_target_properties(uci_lib PROPERTIES OUTPUT_NAME uci PREFIX "")
target_link_options(uci_lib PRIVATE ${UCODE_MODULE_LINK_OPTIONS})
target_link_libraries(uci_lib ${libuci} ${libubox})
endif()
if(RTNL_SUPPORT)
find_path(nl_include_dir NAMES netlink/msg.h PATH_SUFFIXES libnl-tiny)
include_directories(${nl_include_dir})
set(LIBRARIES ${LIBRARIES} rtnl_lib)
add_library(rtnl_lib MODULE lib/rtnl.c)
set_target_properties(rtnl_lib PROPERTIES OUTPUT_NAME rtnl PREFIX "")
target_link_options(rtnl_lib PRIVATE ${UCODE_MODULE_LINK_OPTIONS})
target_link_libraries(rtnl_lib ${libnl_tiny} ${libubox})
endif()
if(NL80211_SUPPORT)
find_path(nl_include_dir NAMES netlink/msg.h PATH_SUFFIXES libnl-tiny)
include_directories(${nl_include_dir})
set(LIBRARIES ${LIBRARIES} nl80211_lib)
add_library(nl80211_lib MODULE lib/nl80211.c)
set_target_properties(nl80211_lib PROPERTIES OUTPUT_NAME nl80211 PREFIX "")
target_link_options(nl80211_lib PRIVATE ${UCODE_MODULE_LINK_OPTIONS})
target_link_libraries(nl80211_lib ${libnl_tiny} ${libubox})
endif()
if(RESOLV_SUPPORT)
set(LIBRARIES ${LIBRARIES} resolv_lib)
add_library(resolv_lib MODULE lib/resolv.c)
set_target_properties(resolv_lib PROPERTIES OUTPUT_NAME resolv PREFIX "")
target_link_options(resolv_lib PRIVATE ${UCODE_MODULE_LINK_OPTIONS})
check_function_exists(res_mkquery RES_MKQUERY_FUNCTION_EXISTS)
check_function_exists(ns_initparse NS_INITARSE_FUNCTION_EXISTS)
check_function_exists(clock_gettime CLOCK_GETTIME_FUNCTION_EXISTS)
if(NOT RES_MKQUERY_FUNCTION_EXISTS OR NOT NS_INITARSE_FUNCTION_EXISTS)
target_link_libraries(resolv_lib resolv)
endif()
if(NOT CLOCK_GETTIME_FUNCTION_EXISTS)
target_link_libraries(resolv_lib rt)
endif()
endif()
if(STRUCT_SUPPORT)
set(LIBRARIES ${LIBRARIES} struct_lib)
add_library(struct_lib MODULE lib/struct.c)
set_target_properties(struct_lib PROPERTIES OUTPUT_NAME struct PREFIX "")
target_link_options(struct_lib PRIVATE ${UCODE_MODULE_LINK_OPTIONS})
check_function_exists(frexp FREXP_FUNCTION_EXISTS)
if(NOT FREXP_FUNCTION_EXISTS)
target_link_libraries(struct_lib m)
endif()
endif()
if(ULOOP_SUPPORT)
find_path(uloop_include_dir NAMES libubox/uloop.h)
include_directories(${uloop_include_dir})
set(LIBRARIES ${LIBRARIES} uloop_lib)
add_library(uloop_lib MODULE lib/uloop.c)
set_target_properties(uloop_lib PROPERTIES OUTPUT_NAME uloop PREFIX "")
target_link_options(uloop_lib PRIVATE ${UCODE_MODULE_LINK_OPTIONS})
list(APPEND CMAKE_REQUIRED_LIBRARIES ${libubox})
check_function_exists(uloop_timeout_remaining64 REMAINING64_FUNCTION_EXISTS)
check_function_exists(uloop_interval_set INTERVAL_FUNCTION_EXISTS)
check_function_exists(uloop_signal_add SIGNAL_FUNCTION_EXISTS)
if(REMAINING64_FUNCTION_EXISTS)
target_compile_definitions(uloop_lib PUBLIC HAVE_ULOOP_TIMEOUT_REMAINING64)
endif()
if(INTERVAL_FUNCTION_EXISTS)
target_compile_definitions(uloop_lib PUBLIC HAVE_ULOOP_INTERVAL)
endif()
if(SIGNAL_FUNCTION_EXISTS)
target_compile_definitions(uloop_lib PUBLIC HAVE_ULOOP_SIGNAL)
endif()
target_link_libraries(uloop_lib ${libubox})
endif()
if(LOG_SUPPORT)
set(LIBRARIES ${LIBRARIES} log_lib)
add_library(log_lib MODULE lib/log.c)
set_target_properties(log_lib PROPERTIES OUTPUT_NAME log PREFIX "")
target_link_options(log_lib PRIVATE ${UCODE_MODULE_LINK_OPTIONS})
if(libubox)
find_path(ulog_include_dir NAMES libubox/ulog.h)
include_directories(${ulog_include_dir})
target_link_libraries(log_lib ${libubox})
set_target_properties(log_lib PROPERTIES COMPILE_DEFINITIONS HAVE_ULOG)
endif()
endif()
if(SOCKET_SUPPORT)
set(LIBRARIES ${LIBRARIES} socket_lib)
add_library(socket_lib MODULE lib/socket.c)
set_target_properties(socket_lib PROPERTIES OUTPUT_NAME socket PREFIX "")
target_link_options(socket_lib PRIVATE ${UCODE_MODULE_LINK_OPTIONS})
endif()
if(ZLIB_SUPPORT)
set(LIBRARIES ${LIBRARIES} zlib_lib)
add_library(zlib_lib MODULE lib/zlib.c)
set_target_properties(zlib_lib PROPERTIES OUTPUT_NAME zlib PREFIX "")
target_link_options(zlib_lib PRIVATE ${UCODE_MODULE_LINK_OPTIONS})
target_link_libraries(zlib_lib ZLIB::ZLIB)
endif()
if(CRYPTO_MBEDTLS_SUPPORT)
set(LIBRARIES ${LIBRARIES} crypto_mbedtls_lib)
add_library(crypto_mbedtls_lib MODULE lib/crypto-mbedtls.c)
set_target_properties(crypto_mbedtls_lib PROPERTIES OUTPUT_NAME crypto_mbedtls PREFIX "")
target_link_options(crypto_mbedtls_lib PRIVATE ${UCODE_MODULE_LINK_OPTIONS} -Wl,-no-as-needed)
target_link_libraries(crypto_mbedtls_lib ${libmbedtls})
endif()
if(CRYPTO_OPENSSL_SUPPORT)
set(LIBRARIES ${LIBRARIES} crypto_openssl_lib)
add_library(crypto_openssl_lib MODULE lib/crypto-openssl.c)
set_target_properties(crypto_openssl_lib PROPERTIES OUTPUT_NAME crypto_openssl PREFIX "")
#target_link_options(crypto_openssl_lib PRIVATE ${UCODE_MODULE_LINK_OPTIONS} -Wl,-no-as-needed)
target_link_libraries(crypto_openssl_lib crypto)
endif()
if(UNIT_TESTING)
enable_testing()
add_definitions(-DUNIT_TESTING)
add_subdirectory(tests)
list(APPEND CMAKE_CTEST_ARGUMENTS "--output-on-failure")
if(CMAKE_C_COMPILER_ID STREQUAL "Clang")
add_executable(ucode-san ${CLI_SOURCES} ${UCODE_SOURCES})
set_property(TARGET ucode-san PROPERTY ENABLE_EXPORTS 1)
target_link_libraries(ucode-san ${JSONC_LINK_LIBRARIES})
target_compile_options(ucode-san PRIVATE -g -fno-omit-frame-pointer -fsanitize=undefined,address,leak -fno-sanitize-recover=all)
target_link_options(ucode-san PRIVATE -fsanitize=undefined,address,leak)
endif()
endif()
install(TARGETS ucode RUNTIME DESTINATION bin)
install(TARGETS libucode LIBRARY DESTINATION lib)
install(TARGETS ${LIBRARIES} LIBRARY DESTINATION lib/ucode)
add_custom_target(utpl ALL COMMAND ${CMAKE_COMMAND} -E create_symlink ucode utpl)
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/utpl DESTINATION bin)
if(COMPILE_SUPPORT)
add_custom_target(ucc ALL COMMAND ${CMAKE_COMMAND} -E create_symlink ucode ucc)
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/ucc DESTINATION bin)
endif()
file(GLOB UCODE_HEADERS "include/ucode/*.h")
install(FILES ${UCODE_HEADERS} DESTINATION include/ucode)
add_subdirectory(examples)
|