Skip to content

Commit f3e28c2

Browse files
authored
Merge pull request #505 from sartura/static_build
add static compile support
2 parents cc51054 + d8e2729 commit f3e28c2

25 files changed

+606
-312
lines changed

CMakeLists.txt

Lines changed: 69 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,6 @@ configure_file(${PROJECT_SOURCE_DIR}/src/common.h.in ${PROJECT_BINARY_DIR}/src/c
7676

7777
set(EXTENSIONS_PLUGINS_DIR_MACRO "${PLUGINS_DIR}/extensions")
7878
set(USER_TYPES_PLUGINS_DIR_MACRO "${PLUGINS_DIR}/user_types")
79-
configure_file(${PROJECT_SOURCE_DIR}/src/plugin_config.h.in ${PROJECT_BINARY_DIR}/src/plugin_config.h)
8079

8180
# include custom Modules
8281
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/CMakeModules/")
@@ -174,6 +173,10 @@ else ()
174173
configure_file(${PROJECT_SOURCE_DIR}/packages/local-rpm.sh.in ${PROJECT_BINARY_DIR}/build-packages/local-rpm.sh @ONLY)
175174
endif()
176175

176+
# by default build shared library
177+
# static build requires static libpcre library
178+
option(ENABLE_STATIC "Build static (.a) library" OFF)
179+
177180
# check the supported platform
178181
if(NOT UNIX)
179182
message(FATAL_ERROR "Only *nix like systems are supported.")
@@ -229,24 +232,40 @@ set(headers
229232
src/xml.h
230233
src/dict.h)
231234

232-
set(CMAKE_POSITION_INDEPENDENT_CODE TRUE)
233-
add_library(yangobj OBJECT ${libsrc})
234-
add_library(yang SHARED $<TARGET_OBJECTS:yangobj>)
235+
# create static libyang library
236+
if(ENABLE_STATIC)
237+
add_definitions(-DSTATIC)
238+
set(CMAKE_EXE_LINKER_FLAGS -static)
239+
set(CMAKE_FIND_LIBRARY_SUFFIXES .a)
240+
set(CMAKE_EXE_LINK_DYNAMIC_C_FLAGS) # remove -Wl,-Bdynamic
241+
set(CMAKE_EXE_LINK_DYNAMIC_CXX_FLAGS)
242+
add_library(yang STATIC ${libsrc})
243+
else()
244+
set(CMAKE_POSITION_INDEPENDENT_CODE TRUE)
245+
add_library(yangobj OBJECT ${libsrc})
246+
add_library(yang SHARED $<TARGET_OBJECTS:yangobj>)
247+
248+
#link dl
249+
target_link_libraries(yang ${CMAKE_DL_LIBS})
250+
endif(ENABLE_STATIC)
251+
235252
set_target_properties(yang PROPERTIES VERSION ${LIBYANG_VERSION} SOVERSION ${LIBYANG_SOVERSION})
236253
set_target_properties(yang PROPERTIES COMPILE_FLAGS "-fvisibility=hidden")
237254

238255
# link math
239256
target_link_libraries(yang m)
240257

241-
#link dl
242-
target_link_libraries(yang ${CMAKE_DL_LIBS})
243-
244258
# find pthreads
245259
set(CMAKE_THREAD_PREFER_PTHREAD TRUE)
246260
find_package(Threads REQUIRED)
247-
target_link_libraries(yang ${CMAKE_THREAD_LIBS_INIT})
261+
if(ENABLE_STATIC)
262+
target_link_libraries(yang -Wl,--whole-archive ${CMAKE_THREAD_LIBS_INIT} -Wl,--no-whole-archive)
263+
else()
264+
target_link_libraries(yang ${CMAKE_THREAD_LIBS_INIT})
265+
endif(ENABLE_STATIC)
248266

249267
# find PCRE library
268+
unset(PCRE_LIBRARY CACHE)
250269
find_package(PCRE REQUIRED)
251270
include_directories(${PCRE_INCLUDE_DIRS})
252271
target_link_libraries(yang ${PCRE_LIBRARIES})
@@ -288,10 +307,50 @@ add_custom_target(cclean
288307
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})
289308

290309
# YANG extensions plugins
291-
add_subdirectory(src/extensions)
310+
set(EXTENSIONS_LIST "nacm" "metadata" "yangdata")
311+
# if the tests are enabled, build libyang_ext_test
312+
if(ENABLE_BUILD_TESTS)
313+
find_package(CMocka 1.0.0)
314+
if(CMOCKA_FOUND AND CMAKE_BUILD_TYPE MATCHES debug)
315+
list(APPEND EXTENSIONS_LIST "libyang_ext_test")
316+
endif(CMOCKA_FOUND AND CMAKE_BUILD_TYPE MATCHES debug)
317+
endif(ENABLE_BUILD_TESTS)
318+
319+
if(ENABLE_STATIC)
320+
set(EXTENSIONS_LIST_SIZE " 0 ")
321+
set(ITEM 0)
322+
foreach(EXTENSION ${EXTENSIONS_LIST})
323+
add_library(${EXTENSION} STATIC "src/extensions/${EXTENSION}.c")
324+
target_link_libraries(yang ${EXTENSION})
325+
set(EXTENSIONS_LIST_SIZE "${EXTENSIONS_LIST_SIZE} + lyext_size(${EXTENSION})")
326+
set(EXTERN_EXTENSIONS_LIST "${EXTERN_EXTENSIONS_LIST}extern struct lyext_plugin_list ${EXTENSION}[];\n")
327+
set(MEMCPY_EXTENSIONS_LIST "${MEMCPY_EXTENSIONS_LIST} lyext_add(plugin, count, ${EXTENSION});\n")
328+
set(STATIC_LOADED_PLUGINS "${STATIC_LOADED_PLUGINS} \"${EXTENSION}\",")
329+
MATH(EXPR ITEM "${ITEM}+1")
330+
endforeach()
331+
else()
332+
add_subdirectory(src/extensions)
333+
endif(ENABLE_STATIC)
292334

293335
# YANG user types plugins
294-
add_subdirectory(src/user_types)
336+
set(USER_TYPE_LIST "user_date_and_time" "user_ipv4")
337+
if(ENABLE_STATIC)
338+
set(USER_TYPE_LIST_SIZE " 0 ")
339+
foreach(USER_TYPE ${USER_TYPE_LIST})
340+
add_library(${USER_TYPE} STATIC "src/user_types/${USER_TYPE}.c")
341+
target_link_libraries(yang ${USER_TYPE})
342+
set(USER_TYPE_LIST_SIZE "${USER_TYPE_LIST_SIZE} + lytype_size(${USER_TYPE})")
343+
set(EXTERN_USER_TYPE_LIST "${EXTERN_USER_TYPE_LIST}extern struct lytype_plugin_list ${USER_TYPE}[];\n")
344+
set(MEMCPY_USER_TYPE_LIST "${MEMCPY_USER_TYPE_LIST} lytype_add(plugin, count, ${USER_TYPE});\n")
345+
set(STATIC_LOADED_PLUGINS "${STATIC_LOADED_PLUGINS} \"${USER_TYPE}\",")
346+
MATH(EXPR ITEM "${ITEM}+1")
347+
endforeach()
348+
set(STATIC_LOADED_PLUGINS_COUNT "${ITEM}")
349+
else()
350+
add_subdirectory(src/user_types)
351+
endif(ENABLE_STATIC)
352+
353+
configure_file(${PROJECT_SOURCE_DIR}/src/plugin_config.h.in ${PROJECT_BINARY_DIR}/src/plugin_config.h)
295354

296355
# yanglint
297356
add_executable(yanglint ${lintsrc})
@@ -312,7 +371,6 @@ if(ENABLE_VALGRIND_TESTS)
312371
endif()
313372

314373
if(ENABLE_BUILD_TESTS)
315-
find_package(CMocka 1.0.0)
316374
if(CMOCKA_FOUND)
317375
enable_testing()
318376
add_subdirectory(tests)
@@ -325,7 +383,3 @@ endif(ENABLE_BUILD_TESTS)
325383
if(GEN_LANGUAGE_BINDINGS AND GEN_CPP_BINDINGS)
326384
add_subdirectory(swig)
327385
endif()
328-
329-
if(GEN_LANGUAGE_BINDINGS AND GEN_JAVASCRIPT_BINDINGS)
330-
include(swig/javascript/CMakeLists.txt)
331-
endif()

src/extensions/CMakeLists.txt

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,6 @@ macro(EXTENSION_PLUGIN PLUGIN_NAME SRCS)
55
install(TARGETS ${PLUGIN_NAME} DESTINATION ${EXTENSIONS_PLUGINS_DIR_MACRO})
66
endmacro(EXTENSION_PLUGIN)
77

8-
EXTENSION_PLUGIN(nacm "nacm.c")
9-
EXTENSION_PLUGIN(metadata "metadata.c")
10-
EXTENSION_PLUGIN(yangdata "yang-data.c")
11-
12-
# special plugin for test_extensions - only built, but not installed
13-
add_library(libyang_ext_test SHARED ext_test.c)
14-
set_target_properties(libyang_ext_test PROPERTIES PREFIX "")
15-
target_link_libraries(libyang_ext_test yang)
8+
foreach(EXTENSION ${EXTENSIONS_LIST})
9+
EXTENSION_PLUGIN(${EXTENSION} "${EXTENSION}.c")
10+
endforeach()
File renamed without changes.
File renamed without changes.

src/plugin_config.h.in

Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,4 +26,102 @@
2626
# define LY_PLUGIN_SUFFIX_LEN 6
2727
#endif
2828

29+
#ifdef STATIC
30+
@EXTERN_EXTENSIONS_LIST@
31+
@EXTERN_USER_TYPE_LIST@
32+
33+
int lytype_size(struct lytype_plugin_list plugin[]) {
34+
struct lytype_plugin_list *tmp;
35+
int i = 0;
36+
while (1) {
37+
tmp = &plugin[i];
38+
if (!tmp) break;
39+
if (!tmp->module && !tmp->revision && !tmp->name && !tmp->store_clb && !tmp->free_clb) break;
40+
i++;
41+
}
42+
43+
return i;
44+
}
45+
46+
void lytype_add(struct lytype_plugin_list *type_plugins, uint16_t *type_plugins_count, struct lytype_plugin_list plugin[]) {
47+
struct lytype_plugin_list *tmp;
48+
int i = 0;
49+
while (1) {
50+
tmp = &plugin[i];
51+
if (!tmp) break;
52+
if (!tmp->module && !tmp->revision && !tmp->name && !tmp->store_clb && !tmp->free_clb) break;
53+
i++;
54+
memcpy(&type_plugins[*type_plugins_count], tmp, sizeof *tmp);
55+
(*type_plugins_count)++;
56+
}
57+
58+
return;
59+
}
60+
61+
62+
int lyext_size(struct lyext_plugin_list plugin[]) {
63+
struct lyext_plugin_list *tmp;
64+
int i = 0;
65+
while (1) {
66+
tmp = &plugin[i];
67+
if (!tmp) break;
68+
if (!tmp->module && !tmp->revision && !tmp->name && !tmp->plugin) break;
69+
i++;
70+
}
71+
72+
return i;
73+
}
74+
75+
void lyext_add(struct lyext_plugin_list *ext_plugins, uint16_t *ext_plugins_count, struct lyext_plugin_list plugin[]) {
76+
struct lyext_plugin_list *tmp;
77+
int i = 0;
78+
while (1) {
79+
tmp = &plugin[i];
80+
if (!tmp) break;
81+
if (!tmp->module && !tmp->revision && !tmp->name && !tmp->plugin) break;
82+
i++;
83+
memcpy(&ext_plugins[*ext_plugins_count], tmp, sizeof *tmp);
84+
(*ext_plugins_count)++;
85+
}
86+
87+
return;
88+
}
89+
90+
struct lyext_plugin_list *static_load_lyext_plugins(uint16_t *count)
91+
{
92+
struct lyext_plugin_list *plugin;
93+
uint16_t size = @EXTENSIONS_LIST_SIZE@;
94+
95+
plugin = malloc(size * (sizeof *plugin));
96+
if (!plugin) {
97+
LOGMEM(NULL);
98+
return NULL;
99+
}
100+
101+
*count = 0;
102+
@MEMCPY_EXTENSIONS_LIST@
103+
return plugin;
104+
}
105+
106+
struct lytype_plugin_list *static_load_lytype_plugins(uint16_t *count)
107+
{
108+
struct lytype_plugin_list *plugin;
109+
uint16_t size = @USER_TYPE_LIST_SIZE@;
110+
111+
plugin = malloc(size * (sizeof *plugin));
112+
if (!plugin) {
113+
LOGMEM(NULL);
114+
return NULL;
115+
}
116+
117+
*count = 0;
118+
@MEMCPY_USER_TYPE_LIST@
119+
return plugin;
120+
}
121+
122+
uint16_t static_loaded_plugins_count = @STATIC_LOADED_PLUGINS_COUNT@;
123+
char *static_loaded_plugins[] = {@STATIC_LOADED_PLUGINS@};
124+
125+
#endif /* STATIC */
126+
29127
#endif /* LY_PLUGIN_CONFIG_H_ */

src/plugins.c

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,34 @@ ly_clean_plugins(void)
6161
unsigned int u;
6262
int ret = EXIT_SUCCESS;
6363

64+
#ifdef STATIC
65+
/* lock the extension plugins list */
66+
pthread_mutex_lock(&plugins_lock);
67+
68+
if(ext_plugins) {
69+
free(ext_plugins);
70+
ext_plugins = NULL;
71+
ext_plugins_count = 0;
72+
}
73+
74+
if(type_plugins) {
75+
free(type_plugins);
76+
type_plugins = NULL;
77+
type_plugins_count = 0;
78+
}
79+
80+
for (u = 0; u < loaded_plugins_count; ++u) {
81+
free(loaded_plugins[u]);
82+
}
83+
free(loaded_plugins);
84+
loaded_plugins = NULL;
85+
loaded_plugins_count = 0;
86+
87+
/* unlock the global structures */
88+
pthread_mutex_unlock(&plugins_lock);
89+
return ret;
90+
#endif /* STATIC */
91+
6492
/* lock the extension plugins list */
6593
pthread_mutex_lock(&plugins_lock);
6694

@@ -114,6 +142,10 @@ lytype_load_plugin(void *dlhandler, const char *file_name)
114142
uint32_t u, v;
115143
char *str;
116144

145+
#ifdef STATIC
146+
return 0;
147+
#endif /* STATIC */
148+
117149
/* get the plugin data */
118150
plugin = dlsym(dlhandler, file_name);
119151
str = dlerror();
@@ -160,6 +192,10 @@ lyext_load_plugin(void *dlhandler, const char *file_name)
160192
uint32_t u, v;
161193
char *str;
162194

195+
#ifdef STATIC
196+
return 0;
197+
#endif /* STATIC */
198+
163199
/* get the plugin data */
164200
plugin = dlsym(dlhandler, file_name);
165201
str = dlerror();
@@ -242,6 +278,10 @@ ly_load_plugins_dir(DIR *dir, const char *dir_path, int ext_or_type)
242278
void *dlhandler;
243279
int ret;
244280

281+
#ifdef STATIC
282+
return;
283+
#endif /* STATIC */
284+
245285
while ((file = readdir(dir))) {
246286
/* required format of the filename is *LY_PLUGIN_SUFFIX */
247287
len = strlen(file->d_name);
@@ -312,6 +352,23 @@ ly_load_plugins(void)
312352
DIR* dir;
313353
const char *pluginsdir;
314354

355+
#ifdef STATIC
356+
/* lock the extension plugins list */
357+
pthread_mutex_lock(&plugins_lock);
358+
359+
ext_plugins = static_load_lyext_plugins(&ext_plugins_count);
360+
type_plugins = static_load_lytype_plugins(&type_plugins_count);
361+
362+
int u;
363+
for (u = 0; u < static_loaded_plugins_count; u++) {
364+
ly_add_loaded_plugin(strdup(static_loaded_plugins[u]));
365+
}
366+
367+
/* unlock the global structures */
368+
pthread_mutex_unlock(&plugins_lock);
369+
return;
370+
#endif /* STATIC */
371+
315372
/* lock the extension plugins list */
316373
pthread_mutex_lock(&plugins_lock);
317374

src/user_types/CMakeLists.txt

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,4 +5,6 @@ macro(USER_TYPE_PLUGIN PLUGIN_NAME SRCS)
55
install(TARGETS ${PLUGIN_NAME} DESTINATION ${USER_TYPES_PLUGINS_DIR_MACRO})
66
endmacro(USER_TYPE_PLUGIN)
77

8-
USER_TYPE_PLUGIN(user_date_and_time "user_date_and_time.c")
8+
foreach(USER_TYPE ${USER_TYPE_LIST})
9+
USER_TYPE_PLUGIN(${USER_TYPE} "${USER_TYPE}.c")
10+
endforeach()

src/user_types/user_ipv4.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
#include <string.h>
1717
#include <arpa/inet.h>
1818

19-
#include <libyang/user_types.h>
19+
#include "../user_types.h"
2020

2121
static int
2222
ipv4_store_clb(const char *type_name, const char *value_str, lyd_val *value, char **err_msg)

0 commit comments

Comments
 (0)