summaryrefslogtreecommitdiffhomepage
path: root/CMakeLists.txt
blob: 8e7322cdd9db83d68a823b4f98b830a9f29144c3 (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
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()
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()

OPTION(FS_SUPPORT "Filesystem plugin support" ON)
OPTION(MATH_SUPPORT "Math plugin support" ON)
OPTION(UBUS_SUPPORT "Ubus plugin support" ON)
OPTION(UCI_SUPPORT "UCI plugin support" ON)
OPTION(RTNL_SUPPORT "Route Netlink plugin support" ON)
OPTION(NL80211_SUPPORT "Wireless Netlink plugin support" ON)
OPTION(RESOLV_SUPPORT "NS resolve plugin support" ON)
OPTION(STRUCT_SUPPORT "Struct plugin support" ON)
OPTION(ULOOP_SUPPORT "Uloop plugin support" ON)

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(NOT APPLE)
  SET(CMAKE_SHARED_LIBRARY_LINK_C_FLAGS "-Wl,--gc-sections")
ENDIF()

FIND_LIBRARY(json NAMES json-c json)

IF(DEBUG)
  ADD_DEFINITIONS(-DDEBUG -g3 -O0)
ELSE()
  ADD_DEFINITIONS(-DNDEBUG)
ENDIF()

INCLUDE(FindPkgConfig)
PKG_CHECK_MODULES(JSONC json-c json)
IF(JSONC_FOUND)
  ADD_DEFINITIONS(-DJSONC)
  INCLUDE_DIRECTORIES(${JSONC_INCLUDE_DIRS})
ENDIF()

SET(UCODE_SOURCES lexer.c lib.c vm.c chunk.c vallist.c compiler.c source.c types.c program.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 ${json})

SET(CLI_SOURCES main.c)
ADD_EXECUTABLE(ucode ${CLI_SOURCES})
TARGET_LINK_LIBRARIES(ucode libucode ${json})

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

SET(CMAKE_REQUIRED_LIBRARIES json-c)
CHECK_SYMBOL_EXISTS(json_object_array_shrink "json.h" HAVE_ARRAY_SHRINK)
IF(HAVE_ARRAY_SHRINK)
  ADD_DEFINITIONS(-DHAVE_ARRAY_SHRINK)
ELSE()
  CHECK_SYMBOL_EXISTS(json_object_array_shrink "json-c/json.h" HAVE_ARRAY_SHRINK2)
  IF(HAVE_ARRAY_SHRINK2)
    ADD_DEFINITIONS(-DHAVE_ARRAY_SHRINK)
  ENDIF()
ENDIF()
UNSET(CMAKE_REQUIRED_LIBRARIES)

SET(LIBRARIES "")

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 "")
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 "")
  CHECK_FUNCTION_EXISTS(ceil CEIL_FUNCTION_EXISTS)
  IF (NOT CEIL_FUNCTION_EXISTS)
    TARGET_LINK_LIBRARIES(math_lib m)
  ENDIF()
ENDIF()

IF(UBUS_SUPPORT)
  FIND_LIBRARY(ubus NAMES ubus)
  FIND_LIBRARY(blobmsg_json NAMES blobmsg_json)
  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_LIBRARIES(ubus_lib ${ubus} ${blobmsg_json})
ENDIF()

IF(UCI_SUPPORT)
  FIND_LIBRARY(uci NAMES uci)
  FIND_LIBRARY(ubox NAMES ubox)
  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_LIBRARIES(uci_lib ${uci} ${ubox})
ENDIF()

IF(RTNL_SUPPORT)
  FIND_LIBRARY(nl NAMES nl-tiny)
  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_LIBRARIES(rtnl_lib ${nl})
ENDIF()

IF(NL80211_SUPPORT)
  FIND_LIBRARY(nl NAMES nl-tiny)
  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_LIBRARIES(nl80211_lib ${nl})
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 "")
  CHECK_FUNCTION_EXISTS(res_mkquery RES_MKQUERY_FUNCTION_EXISTS)
  CHECK_FUNCTION_EXISTS(clock_gettime CLOCK_GETTIME_FUNCTION_EXISTS)
  IF (NOT RES_MKQUERY_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 "")
  CHECK_FUNCTION_EXISTS(frexp FREXP_FUNCTION_EXISTS)
  IF (NOT FREXP_FUNCTION_EXISTS)
    TARGET_LINK_LIBRARIES(struct_lib m)
  ENDIF()
ENDIF()

IF(ULOOP_SUPPORT)
  FIND_LIBRARY(ubox NAMES ubox)
  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 "")
  SET(CMAKE_REQUIRED_LIBRARIES ubox)
  CHECK_FUNCTION_EXISTS(uloop_timeout_remaining64 REMAINING64_FUNCTION_EXISTS)
  UNSET(CMAKE_REQUIRED_LIBRARIES)
  IF (REMAINING64_FUNCTION_EXISTS)
    TARGET_COMPILE_DEFINITIONS(uloop_lib PUBLIC HAVE_ULOOP_TIMEOUT_REMAINING64)
  ENDIF()
  TARGET_LINK_LIBRARIES(uloop_lib ${ubox})
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 ${json})
    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)

FILE(GLOB UCODE_HEADERS "include/ucode/*.h")
INSTALL(FILES ${UCODE_HEADERS} DESTINATION include/ucode)

ADD_SUBDIRECTORY(examples)