forked from CESNET/netopeer2
-
Notifications
You must be signed in to change notification settings - Fork 0
/
CMakeLists.txt
317 lines (276 loc) · 12 KB
/
CMakeLists.txt
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
cmake_minimum_required(VERSION 2.8.12)
project(netopeer2 C)
set(NETOPEER2_DESC "NETCONF tools suite including a server and command-line client")
# include custom Modules
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/CMakeModules/")
include(GNUInstallDirs)
include(CheckFunctionExists)
include(CheckIncludeFile)
include(UseCompat)
include(SourceFormat)
if(POLICY CMP0075)
cmake_policy(SET CMP0075 NEW)
endif()
# check the supported platform
if(NOT UNIX)
message(FATAL_ERROR "Only *nix like systems are supported.")
endif()
# set default build type if not specified by user and normalize it
if(NOT CMAKE_BUILD_TYPE)
set(CMAKE_BUILD_TYPE Debug)
endif()
string(TOUPPER "${CMAKE_BUILD_TYPE}" BUILD_TYPE_UPPER)
if("${BUILD_TYPE_UPPER}" STREQUAL "RELEASE")
set(CMAKE_BUILD_TYPE "Release" CACHE STRING "Build Type" FORCE)
elseif("${BUILD_TYPE_UPPER}" STREQUAL "DEBUG")
set(CMAKE_BUILD_TYPE "Debug" CACHE STRING "Build Type" FORCE)
elseif("${BUILD_TYPE_UPPER}" STREQUAL "RELWITHDEBINFO")
set(CMAKE_BUILD_TYPE "RelWithDebInfo" CACHE STRING "Build Type" FORCE)
elseif("${BUILD_TYPE_UPPER}" STREQUAL "RELWITHDEBUG")
set(CMAKE_BUILD_TYPE "RelWithDebug" CACHE STRING "Build Type" FORCE)
endif()
# compilation flags
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wextra -std=gnu99")
set(CMAKE_C_FLAGS_RELEASE "-DNDEBUG -O2")
set(CMAKE_C_FLAGS_DEBUG "-g -O0")
# Version of the project
# Generic version of not only the library. Major version is reserved for really big changes of the project,
# minor version changes with added functionality (new tool, functionality of the tool or library, ...) and
# micro version is changed with a set of small changes or bugfixes anywhere in the project.
set(NP2SRV_VERSION 2.0.0)
# libyang required SO version
set(LIBYANG_DEP_SOVERSION_MAJOR 2)
# build options
if(("${BUILD_TYPE_UPPER}" STREQUAL "DEBUG") OR ("${BUILD_TYPE_UPPER}" STREQUAL "RELWITHDEBINFO"))
option(ENABLE_TESTS "Build tests" ON)
option(ENABLE_VALGRIND_TESTS "Build tests with valgrind" ON)
else()
option(ENABLE_TESTS "Build tests" OFF)
option(ENABLE_VALGRIND_TESTS "Build tests with valgrind" OFF)
endif()
option(BUILD_CLI "Build and install neotpeer2-cli" ON)
option(ENABLE_URL "Enable URL capability" ON)
set(THREAD_COUNT 5 CACHE STRING "Number of threads accepting new sessions and handling requests")
set(NACM_RECOVERY_UID 0 CACHE STRING "NACM recovery session UID that has unrestricted access")
set(POLL_IO_TIMEOUT 10 CACHE STRING "Timeout in milliseconds of polling sessions for new data. It is also used for synchronization of low level IO such as sending a reply while a notification is being sent")
set(YANG_MODULE_DIR "${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_DATADIR}/yang/modules/netopeer2" CACHE STRING "Directory where to copy the YANG modules to")
# script options
option(INSTALL_MODULES "Install required modules into sysrepo" ON)
option(GENERATE_HOSTKEY "Generate a new RSA host key in the keystore named \"genkey\"" ON)
option(MERGE_LISTEN_CONFIG "Merge default server configuration for listening on all IPv4 interfaces" ON)
set(MODULES_PERMS 600 CACHE STRING "File access permissions set for all the server modules")
if(NOT MODULES_OWNER)
execute_process(COMMAND id -un RESULT_VARIABLE RET
OUTPUT_VARIABLE MODULES_OWNER OUTPUT_STRIP_TRAILING_WHITESPACE
ERROR_VARIABLE ERROR_STR OUTPUT_STRIP_TRAILING_WHITESPACE)
if(RET)
message(WARNING "Learning server module user failed (${ERROR_STR}), the current user will be used.")
endif()
endif()
set(MODULES_OWNER "${MODULES_OWNER}" CACHE STRING "System user that will become the owner of server modules, empty means the current user")
if(NOT MODULES_GROUP AND MODULES_OWNER)
execute_process(COMMAND id -gn ${MODULES_OWNER} RESULT_VARIABLE RET
OUTPUT_VARIABLE MODULES_GROUP OUTPUT_STRIP_TRAILING_WHITESPACE
ERROR_VARIABLE ERROR_STR OUTPUT_STRIP_TRAILING_WHITESPACE)
if(RET)
message(WARNING "Learning server module group failed (${ERROR_STR}), the current user group will be used.")
endif()
endif()
set(MODULES_GROUP "${MODULES_GROUP}" CACHE STRING "System group that the server modules will belong to, empty means the current user group")
# set prefix for the PID file
if(NOT PIDFILE_PREFIX)
set(PIDFILE_PREFIX "/var/run")
endif()
set(NP2SRV_SSH_AUTHORIZED_KEYS_PATTERN "%s/.ssh/authorized_keys" CACHE STRING "printf-like pattern for determining path to users' SSH authorized_keys file. Must contain exactly one '%s'.")
set(NP2SRV_SSH_AUTHORIZED_KEYS_ARG_IS_USERNAME 0 CACHE STRING "If true, replace '%s' by username. If not set, replace '%s' by home directory. By default, unset.")
if(NOT NP2SRV_SSH_AUTHORIZED_KEYS_PATTERN MATCHES "^[^%]*%s[^%]*$")
message(FATAL_ERROR "Wrong format string given for NP2SRV_SSH_AUTHORIZED_KEYS_PATTERN: exactly one '%s' expected.")
endif()
# check that lnc2 supports np2srv thread count
find_package(PkgConfig)
if(PKG_CONFIG_FOUND)
execute_process(COMMAND ${PKG_CONFIG_EXECUTABLE} "--variable=LNC2_MAX_THREAD_COUNT" "libnetconf2" OUTPUT_VARIABLE LNC2_THREAD_COUNT)
if(LNC2_THREAD_COUNT)
string(STRIP ${LNC2_THREAD_COUNT} LNC2_THREAD_COUNT)
if(LNC2_THREAD_COUNT LESS THREAD_COUNT)
message(FATAL_ERROR "libnetconf2 was compiled with support up to ${LNC2_THREAD_COUNT} threads, server is configured with ${THREAD_COUNT}.")
else()
message(STATUS "libnetconf2 was compiled with support of up to ${LNC2_THREAD_COUNT} threads")
endif()
else()
message(STATUS "Unable to learn libnetconf2 thread support, check skipped")
endif()
else()
message(STATUS "pkg-config not found, so it was not possible to check if libnetconf2 supports ${THREAD_COUNT} threads")
endif()
# put all binaries into one directory (even from subprojects)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR})
# dependencies - OpenSSL (required by later libnetconf2 checks and not really the server itself)
find_package(OpenSSL)
if(OPENSSL_FOUND)
list(APPEND CMAKE_REQUIRED_INCLUDES ${OPENSSL_INCLUDE_DIRS})
list(APPEND CMAKE_REQUIRED_LIBRARIES ${OPENSSL_LIBRARIES})
endif()
# dependencies - libssh (also required by libnetconf2 checks)
find_package(LibSSH 0.7.1)
if(LIBSSH_FOUND)
list(APPEND CMAKE_REQUIRED_INCLUDES ${LIBSSH_INCLUDE_DIRS})
list(APPEND CMAKE_REQUIRED_LIBRARIES ${LIBSSH_LIBRARIES})
endif()
# dependencies - libnetconf2 (now, because we need to configure outselves based on it)
find_package(LibNETCONF2 REQUIRED)
include_directories(${LIBNETCONF2_INCLUDE_DIRS})
list(APPEND CMAKE_REQUIRED_INCLUDES ${LIBNETCONF2_INCLUDE_DIRS})
list(APPEND CMAKE_REQUIRED_LIBRARIES ${LIBNETCONF2_LIBRARIES})
# source files
set(SERVER_SRC
src/common.c
src/netconf.c
src/netconf_monitoring.c
src/netconf_acm.c
src/netconf_nmda.c
src/netconf_subscribed_notifications.c
src/subscribed_notifications.c
src/yang_push.c
src/log.c
src/err_netconf.c)
# source files to be covered by the 'format' target
set(FORMAT_SRC
compat/*.c
compat/*.h*
src/*.c
src/*.h
cli/*.c
cli/*.h
tests/*.c
tests/*.h)
# at least some remote transport is enabled
if(LIBNETCONF2_ENABLED_SSH OR LIBNETCONF2_ENABLED_TLS)
list(APPEND SERVER_SRC src/netconf_server.c)
endif()
# SSH is enabled
if(LIBNETCONF2_ENABLED_SSH)
list(APPEND SERVER_SRC src/netconf_server_ssh.c)
endif()
# TLS is enabled
if(LIBNETCONF2_ENABLED_TLS)
list(APPEND SERVER_SRC src/netconf_server_tls.c)
endif()
# link compat
use_compat()
# netopeer2-server
add_library(serverobj OBJECT ${SERVER_SRC})
add_executable(netopeer2-server $<TARGET_OBJECTS:serverobj> src/main.c ${compatsrc})
# dependencies - librt (not required on OSX or QNX)
find_library(LIBRT rt)
if(LIBRT)
target_link_libraries(netopeer2-server ${LIBRT})
endif()
# dependencies - libnetconf2 (was already found)
target_link_libraries(netopeer2-server ${LIBNETCONF2_LIBRARIES})
# dependencies - libssh (was already found, if exists)
if(LIBSSH_FOUND AND LIBNETCONF2_ENABLED_SSH)
target_link_libraries(netopeer2-server ${LIBSSH_LIBRARIES})
include_directories(${LIBSSH_INCLUDE_DIRS})
endif()
# dependencies - libcurl
if(ENABLE_URL)
find_package(CURL)
if(CURL_FOUND)
include_directories(${CURL_INCLUDE_DIRS})
target_link_libraries(netopeer2-server ${CURL_LIBRARIES})
set(NP2SRV_URL_CAPAB 1)
else()
message(STATUS "libcurl not found, url capability will not be supported")
unset(NP2SRV_URL_CAPAB)
endif()
endif()
# dependencies - pthread
set(CMAKE_THREAD_PREFER_PTHREAD TRUE)
find_package(Threads REQUIRED)
target_link_libraries(netopeer2-server ${CMAKE_THREAD_LIBS_INIT})
list(APPEND CMAKE_REQUIRED_FLAGS ${CMAKE_THREAD_LIBS_INIT})
# dependencies - libyang
find_package(LibYANG ${LIBYANG_DEP_SOVERSION_MAJOR} REQUIRED)
target_link_libraries(netopeer2-server ${LIBYANG_LIBRARIES})
include_directories(${LIBYANG_INCLUDE_DIRS})
list(APPEND CMAKE_REQUIRED_INCLUDES ${LIBYANG_INCLUDE_DIRS})
list(APPEND CMAKE_REQUIRED_LIBRARIES ${LIBYANG_LIBRARIES})
# dependencies - sysrepo
find_package(Sysrepo REQUIRED)
target_link_libraries(netopeer2-server ${SYSREPO_LIBRARIES})
include_directories(${SYSREPO_INCLUDE_DIRS})
list(APPEND CMAKE_REQUIRED_INCLUDES ${SYSREPO_INCLUDE_DIRS})
list(APPEND CMAKE_REQUIRED_LIBRARIES ${SYSREPO_LIBRARIES})
# generate files
configure_file("${PROJECT_SOURCE_DIR}/src/config.h.in" "${PROJECT_BINARY_DIR}/config.h" ESCAPE_QUOTES @ONLY)
include_directories(${PROJECT_BINARY_DIR})
if ("${BUILD_TYPE_UPPER}" STREQUAL "DEBUG")
# enable before adding tests to let them detect that format checking is available - one of the tests is format checking
source_format_enable()
endif()
# source files to be covered by the 'format' target and a test with 'format-check' target
source_format(${FORMAT_SRC})
# tests
if(ENABLE_TESTS)
find_package(CMocka 1.0.0)
if(CMOCKA_FOUND)
enable_testing()
add_subdirectory(tests)
else()
message(STATUS "Disabling tests because of missing CMocka.")
set(ENABLE_TESTS NO)
endif()
endif()
# set script dir
set(SCRIPT_DIR "${PROJECT_SOURCE_DIR}/scripts/")
# install the module files
install(DIRECTORY "${PROJECT_SOURCE_DIR}/modules/" DESTINATION ${YANG_MODULE_DIR})
# install the binary, required modules, and default configuration
install(TARGETS netopeer2-server DESTINATION ${CMAKE_INSTALL_BINDIR})
if(INSTALL_MODULES)
install(CODE "
message(STATUS \"Installing missing sysrepo modules...\")
set(ENV{NP2_MODULE_DIR} \"${YANG_MODULE_DIR}\")
set(ENV{NP2_MODULE_PERMS} \"${MODULES_PERMS}\")
set(ENV{NP2_MODULE_OWNER} \"${MODULES_OWNER}\")
set(ENV{NP2_MODULE_GROUP} \"${MODULES_GROUP}\")
execute_process(COMMAND \"${SCRIPT_DIR}/setup.sh\" RESULT_VARIABLE SETUP_RES)
if(NOT SETUP_RES EQUAL \"0\")
message(FATAL_ERROR \" scripts/setup.sh failed: \${SETUP_RES}\")
endif()
")
else()
message(WARNING "Server will refuse to start if the modules are not installed!")
endif()
if(GENERATE_HOSTKEY)
install(CODE "
message(STATUS \"Generating a new RSA host key \\\"genkey\\\" if not already added...\")
execute_process(COMMAND ${SCRIPT_DIR}/merge_hostkey.sh RESULT_VARIABLE MERGE_HOSTKEY_RES)
if(NOT MERGE_HOSTKEY_RES EQUAL \"0\")
message(FATAL_ERROR \" scripts/merge_hostkey.sh failed: \${MERGE_HOSTKEY_RES}\")
endif()
")
endif()
if(MERGE_LISTEN_CONFIG)
install(CODE "
message(STATUS \"Merging default server listen configuration if there is none...\")
execute_process(COMMAND ${SCRIPT_DIR}/merge_config.sh RESULT_VARIABLE MERGE_CONFIG_RES)
if(NOT MERGE_CONFIG_RES EQUAL \"0\")
message(FATAL_ERROR \" scripts/merge_config.sh failed: \${MERGE_CONFIG_RES}\")
endif()
")
endif()
# cli
if(BUILD_CLI)
add_subdirectory(cli)
endif()
# clean cmake cache
add_custom_target(cleancache
COMMAND make clean
COMMAND find . -iname '*cmake*' -not -name CMakeLists.txt -exec rm -rf {} +
COMMAND rm -rf Makefile Doxyfile
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
)
# uninstall
add_custom_target(uninstall "${CMAKE_COMMAND}" -P "${CMAKE_MODULE_PATH}/uninstall.cmake")