From 0d591fe5a11d733a98e4204d6b384b25a7331e6c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ekl=C3=B6f?= Date: Mon, 14 Jan 2019 20:57:03 +0100 Subject: [PATCH] allow plugins to be compiled into the f00bar main binary --- CMakeLists.txt | 15 +++++ decorations/CMakeLists.txt | 12 +++- decorations/background.c | 13 ++++- decorations/stack.c | 13 ++++- decorations/underline.c | 13 ++++- modules/CMakeLists.txt | 60 +++++++++++--------- modules/alsa.c | 13 ++++- modules/backlight.c | 13 ++++- modules/battery.c | 13 ++++- modules/clock.c | 13 ++++- modules/i3.c | 13 ++++- modules/label.c | 13 ++++- modules/mpd.c | 13 ++++- modules/network.c | 13 ++++- modules/removables.c | 13 ++++- modules/xkb.c | 13 ++++- modules/xwindow.c | 13 ++++- particles/CMakeLists.txt | 16 +++++- particles/empty.c | 13 ++++- particles/list.c | 13 ++++- particles/map.c | 13 ++++- particles/progress-bar.c | 13 ++++- particles/ramp.c | 13 ++++- particles/string.c | 13 ++++- plugin.c | 109 ++++++++++++++++++++++++++++++++++++- 25 files changed, 400 insertions(+), 72 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index b567e37..80183ab 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,6 +1,9 @@ cmake_minimum_required(VERSION 3.13) project(f00bar C) +set(CORE_PLUGINS_AS_SHARED_LIBRARIES 0 CACHE BOOL + "Compiles modules, particles and decorations as shared libraries, which are loaded on-demand") + set(CMAKE_C_STANDARD_REQUIRED ON) set(CMAKE_C_EXTENSIONS OFF) set(CMAKE_C_STANDARD 11) @@ -10,6 +13,11 @@ set_property(DIRECTORY . APPEND PROPERTY COMPILE_DEFINITIONS _GNU_SOURCE ) +if (CORE_PLUGINS_AS_SHARED_LIBRARIES) + set_property(DIRECTORY . APPEND PROPERTY COMPILE_DEFINITIONS + CORE_PLUGINS_AS_SHARED_LIBRARIES) +endif () + set(CMAKE_C_FLAGS "-Wall -Werror ${CMAKE_C_FLAGS}") find_package(Threads REQUIRED) @@ -72,3 +80,10 @@ install(TARGETS f00bar DESTINATION bin) add_subdirectory(modules) add_subdirectory(particles) add_subdirectory(decorations) + +if (NOT CORE_PLUGINS_AS_SHARED_LIBRARIES) + target_link_libraries(f00bar background stack underline) + target_link_libraries(f00bar dynlist empty list map progress-bar ramp string) + target_link_libraries(f00bar alsa backlight battery clock i3 label mpd network + removables xkb xwindow) +endif () diff --git a/decorations/CMakeLists.txt b/decorations/CMakeLists.txt index 90affdc..3201768 100644 --- a/decorations/CMakeLists.txt +++ b/decorations/CMakeLists.txt @@ -8,9 +8,17 @@ set(CMAKE_SHARED_MODULE_PREFIX decoration_) set(decorations background stack underline) +if (CORE_PLUGINS_AS_SHARED_LIBRARIES) + set(lib_type MODULE) +else() + set(lib_type STATIC) +endif () + foreach (deco ${decorations}) - add_library(${deco} MODULE ${deco}.c) + add_library(${deco} ${lib_type} ${deco}.c) target_link_libraries(${deco} decoration-sdk) endforeach () -install(TARGETS ${decorations} DESTINATION lib/f00bar) +if (CORE_PLUGINS_AS_SHARED_LIBRARIES) + install(TARGETS ${decorations} DESTINATION lib/f00bar) +endif () diff --git a/decorations/background.c b/decorations/background.c index 0a0c218..bfc62a0 100644 --- a/decorations/background.c +++ b/decorations/background.c @@ -41,14 +41,14 @@ background_new(struct rgba color) } struct deco * -from_conf(const struct yml_node *node) +background_from_conf(const struct yml_node *node) { const struct yml_node *color = yml_get_value(node, "color"); return background_new(conf_to_color(color)); } bool -verify_conf(keychain_t *chain, const struct yml_node *node) +background_verify_conf(keychain_t *chain, const struct yml_node *node) { static const struct attr_info attrs[] = { {"color", true, &conf_verify_color}, @@ -57,3 +57,12 @@ verify_conf(keychain_t *chain, const struct yml_node *node) return conf_verify_dict(chain, node, attrs); } + +#if defined(CORE_PLUGINS_AS_SHARED_LIBRARIES) + +bool verify_conf(keychain_t *chain, const struct yml_node *node) + __attribute__((weak, alias("background_verify_conf"))); +struct deco *from_conf(const struct yml_node *node) + __attribute__((weak, alias("background_from_conf"))); + +#endif diff --git a/decorations/stack.c b/decorations/stack.c index 38d3a74..aab7ca8 100644 --- a/decorations/stack.c +++ b/decorations/stack.c @@ -48,7 +48,7 @@ stack_new(struct deco *decos[], size_t count) return deco; } struct deco * -from_conf(const struct yml_node *node) +stack_from_conf(const struct yml_node *node) { size_t count = yml_list_length(node); @@ -66,7 +66,7 @@ from_conf(const struct yml_node *node) } bool -verify_conf(keychain_t *chain, const struct yml_node *node) +stack_verify_conf(keychain_t *chain, const struct yml_node *node) { if (!yml_is_list(node)) { LOG_ERR("%s: must be a list of decorations", conf_err_prefix(chain, node)); @@ -83,3 +83,12 @@ verify_conf(keychain_t *chain, const struct yml_node *node) return true; } + +#if defined(CORE_PLUGINS_AS_SHARED_LIBRARIES) + +bool verify_conf(keychain_t *chain, const struct yml_node *node) + __attribute__((weak, alias("stack_verify_conf"))); +struct deco *from_conf(const struct yml_node *node) + __attribute__((weak, alias("stack_from_conf"))); + +#endif diff --git a/decorations/underline.c b/decorations/underline.c index 838f9a0..453970a 100644 --- a/decorations/underline.c +++ b/decorations/underline.c @@ -43,7 +43,7 @@ underline_new(int size, struct rgba color) } struct deco * -from_conf(const struct yml_node *node) +underline_from_conf(const struct yml_node *node) { const struct yml_node *size = yml_get_value(node, "size"); const struct yml_node *color = yml_get_value(node, "color"); @@ -51,7 +51,7 @@ from_conf(const struct yml_node *node) } bool -verify_conf(keychain_t *chain, const struct yml_node *node) +underline_verify_conf(keychain_t *chain, const struct yml_node *node) { static const struct attr_info attrs[] = { {"size", true, &conf_verify_int}, @@ -61,3 +61,12 @@ verify_conf(keychain_t *chain, const struct yml_node *node) return conf_verify_dict(chain, node, attrs); } + +#if defined(CORE_PLUGINS_AS_SHARED_LIBRARIES) + +bool verify_conf(keychain_t *chain, const struct yml_node *node) + __attribute__((weak, alias("underline_verify_conf"))); +struct deco *from_conf(const struct yml_node *node) + __attribute__((weak, alias("underline_from_conf"))); + +#endif diff --git a/modules/CMakeLists.txt b/modules/CMakeLists.txt index 5fa03c1..ec86964 100644 --- a/modules/CMakeLists.txt +++ b/modules/CMakeLists.txt @@ -5,72 +5,80 @@ target_compile_options(module-sdk INTERFACE ${CAIRO_CFLAGS_OTHER}) target_include_directories(module-sdk INTERFACE ${CAIRO_INCLUDE_DIRS}) target_link_libraries(module-sdk INTERFACE ${CMAKE_THREAD_LIBS_INIT}) -set(CMAKE_SHARED_MODULE_PREFIX module_) +if (CORE_PLUGINS_AS_SHARED_LIBRARIES) + set(lib_type MODULE) +else () + set(lib_type STATIC) +endif () + +set(CMAKE_SHARED_${lib_type}_PREFIX module_) pkg_check_modules(ALSA REQUIRED alsa) -add_library(alsa MODULE alsa.c) +add_library(alsa ${lib_type} alsa.c) target_compile_options(alsa PRIVATE ${ALSA_CFLAGS_OTHER}) target_include_directories(alsa PRIVATE ${ALSA_INCLUDE_DIRS}) target_link_libraries(alsa module-sdk ${ALSA_LIBRARIES}) pkg_check_modules(UDEV REQUIRED libudev) -add_library(backlight MODULE backlight.c) +add_library(backlight ${lib_type} backlight.c) target_compile_options(backlight PRIVATE ${UDEV_CFLAGS_OTHER}) target_include_directories(backlight PRIVATE ${UDEV_INCLUDE_DIRS}) target_link_libraries(backlight module-sdk ${UDEV_LIBRARIES}) -add_library(battery MODULE battery.c) +add_library(battery ${lib_type} battery.c) target_compile_options(battery PRIVATE ${UDEV_CFLAGS_OTHER}) target_include_directories(battery PRIVATE ${UDEV_INCLUDE_DIRS}) target_link_libraries(battery module-sdk ${UDEV_LIBRARIES}) -add_library(clock MODULE clock.c) +add_library(clock ${lib_type} clock.c) target_link_libraries(clock module-sdk) pkg_check_modules(JSON REQUIRED json-c) -add_library(i3 MODULE i3.c) +add_library(i3 ${lib_type} i3.c) target_compile_options(i3 PRIVATE ${JSON_CFLAGS_OTHER}) target_include_directories(i3 PRIVATE ${JSON_INCLUDE_DIRS}) target_link_libraries(i3 module-sdk dynlist ${JSON_LIBRARIES}) -add_library(label MODULE label.c) +add_library(label ${lib_type} label.c) target_link_libraries(label module-sdk) pkg_check_modules(MPD REQUIRED libmpdclient) -add_library(mpd MODULE mpd.c) +add_library(mpd ${lib_type} mpd.c) target_compile_options(mpd PRIVATE ${MPD_CFLAGS_OTHER}) target_include_directories(mpd PRIVATE ${MPD_INCLUDE_DIRS}) target_link_libraries(mpd module-sdk ${MPD_LIBRARIES}) -add_library(network MODULE network.c) +add_library(network ${lib_type} network.c) target_link_libraries(network module-sdk) -add_library(removables MODULE removables.c) +add_library(removables ${lib_type} removables.c) target_compile_options(removables PRIVATE ${UDEV_CFLAGS_OTHER}) target_include_directories(removables PRIVATE ${UDEV_INCLUDE_DIRS}) target_link_libraries(removables module-sdk dynlist ${UDEV_LIBRARIES}) pkg_check_modules(XCB_XKB REQUIRED xcb-xkb) -add_library(xkb MODULE xkb.c) +add_library(xkb ${lib_type} xkb.c) target_compile_options(xkb PRIVATE ${XCB_XKB_CFLAGS_OTHER}) target_include_directories(xkb PRIVATE ${XCB_XKB_INCLUDE_DIRS}) target_link_libraries(xkb module-sdk ${XCB_XKB_LIBRARIES}) -add_library(xwindow MODULE xwindow.c) +add_library(xwindow ${lib_type} xwindow.c) target_link_libraries(xwindow module-sdk) -install( - TARGETS - alsa - backlight - battery - clock - i3 - label - mpd - network - removables - xkb - xwindow +if (CORE_PLUGINS_AS_SHARED_LIBRARIES) + install( + TARGETS + alsa + backlight + battery + clock + i3 + label + mpd + network + removables + xkb + xwindow - DESTINATION lib/f00bar) + DESTINATION lib/f00bar) +endif () diff --git a/modules/alsa.c b/modules/alsa.c index be6d876..9e3de2e 100644 --- a/modules/alsa.c +++ b/modules/alsa.c @@ -268,7 +268,7 @@ alsa_new(const char *card, const char *mixer, struct particle *label) } struct module * -from_conf(const struct yml_node *node, struct conf_inherit inherited) +alsa_from_conf(const struct yml_node *node, struct conf_inherit inherited) { const struct yml_node *card = yml_get_value(node, "card"); const struct yml_node *mixer = yml_get_value(node, "mixer"); @@ -281,7 +281,7 @@ from_conf(const struct yml_node *node, struct conf_inherit inherited) } bool -verify_conf(keychain_t *chain, const struct yml_node *node) +alsa_verify_conf(keychain_t *chain, const struct yml_node *node) { static const struct attr_info attrs[] = { {"card", true, &conf_verify_string}, @@ -293,3 +293,12 @@ verify_conf(keychain_t *chain, const struct yml_node *node) return conf_verify_dict(chain, node, attrs); } + +#if defined(CORE_PLUGINS_AS_SHARED_LIBRARIES) + +bool verify_conf(keychain_t *chain, const struct yml_node *node) + __attribute__((weak, alias("alsa_verify_conf"))); +struct deco *from_conf(const struct yml_node *node, struct conf_inherit inherited) + __attribute__((weak, alias("alsa_from_conf"))); + +#endif diff --git a/modules/backlight.c b/modules/backlight.c index dee1cc0..3a4ea1e 100644 --- a/modules/backlight.c +++ b/modules/backlight.c @@ -220,7 +220,7 @@ backlight_new(const char *device, struct particle *label) } struct module * -from_conf(const struct yml_node *node, struct conf_inherit inherited) +backlight_from_conf(const struct yml_node *node, struct conf_inherit inherited) { const struct yml_node *name = yml_get_value(node, "name"); const struct yml_node *c = yml_get_value(node, "content"); @@ -230,7 +230,7 @@ from_conf(const struct yml_node *node, struct conf_inherit inherited) } bool -verify_conf(keychain_t *chain, const struct yml_node *node) +backlight_verify_conf(keychain_t *chain, const struct yml_node *node) { static const struct attr_info attrs[] = { {"name", true, &conf_verify_string}, @@ -241,3 +241,12 @@ verify_conf(keychain_t *chain, const struct yml_node *node) return conf_verify_dict(chain, node, attrs); } + +#if defined(CORE_PLUGINS_AS_SHARED_LIBRARIES) + +bool verify_conf(keychain_t *chain, const struct yml_node *node) + __attribute__((weak, alias("backlight_verify_conf"))); +struct deco *from_conf(const struct yml_node *node, struct conf_inherit inherited) + __attribute__((weak, alias("backlight_from_conf"))); + +#endif diff --git a/modules/battery.c b/modules/battery.c index 2fef9d1..0802520 100644 --- a/modules/battery.c +++ b/modules/battery.c @@ -350,7 +350,7 @@ battery_new(const char *battery, struct particle *label, int poll_interval_secs) } struct module * -from_conf(const struct yml_node *node, struct conf_inherit inherited) +battery_from_conf(const struct yml_node *node, struct conf_inherit inherited) { const struct yml_node *c = yml_get_value(node, "content"); const struct yml_node *name = yml_get_value(node, "name"); @@ -363,7 +363,7 @@ from_conf(const struct yml_node *node, struct conf_inherit inherited) } bool -verify_conf(keychain_t *chain, const struct yml_node *node) +battery_verify_conf(keychain_t *chain, const struct yml_node *node) { static const struct attr_info attrs[] = { {"name", true, &conf_verify_string}, @@ -375,3 +375,12 @@ verify_conf(keychain_t *chain, const struct yml_node *node) return conf_verify_dict(chain, node, attrs); } + +#if defined(CORE_PLUGINS_AS_SHARED_LIBRARIES) + +bool verify_conf(keychain_t *chain, const struct yml_node *node) + __attribute__((weak, alias("battery_verify_conf"))); +struct deco *from_conf(const struct yml_node *node, struct conf_inherit inherited) + __attribute__((weak, alias("battery_from_conf"))); + +#endif diff --git a/modules/clock.c b/modules/clock.c index e982907..2a9fbb4 100644 --- a/modules/clock.c +++ b/modules/clock.c @@ -95,7 +95,7 @@ clock_new(struct particle *label, const char *date_format, const char *time_form } struct module * -from_conf(const struct yml_node *node, struct conf_inherit inherited) +clock_from_conf(const struct yml_node *node, struct conf_inherit inherited) { const struct yml_node *c = yml_get_value(node, "content"); const struct yml_node *date_format = yml_get_value(node, "date-format"); @@ -108,7 +108,7 @@ from_conf(const struct yml_node *node, struct conf_inherit inherited) } bool -verify_conf(keychain_t *chain, const struct yml_node *node) +clock_verify_conf(keychain_t *chain, const struct yml_node *node) { static const struct attr_info attrs[] = { {"date-format", false, &conf_verify_string}, @@ -120,3 +120,12 @@ verify_conf(keychain_t *chain, const struct yml_node *node) return conf_verify_dict(chain, node, attrs); } + +#if defined(CORE_PLUGINS_AS_SHARED_LIBRARIES) + +bool verify_conf(keychain_t *chain, const struct yml_node *node) + __attribute__((weak, alias("clock_verify_conf"))); +struct deco *from_conf(const struct yml_node *node, struct conf_inherit inherited) + __attribute__((weak, alias("clock_from_conf"))); + +#endif diff --git a/modules/i3.c b/modules/i3.c index e079429..ec1d607 100644 --- a/modules/i3.c +++ b/modules/i3.c @@ -641,7 +641,7 @@ i3_new(struct i3_workspaces workspaces[], size_t workspace_count, } struct module * -from_conf(const struct yml_node *node, struct conf_inherit inherited) +i3_from_conf(const struct yml_node *node, struct conf_inherit inherited) { const struct yml_node *c = yml_get_value(node, "content"); const struct yml_node *spacing = yml_get_value(node, "spacing"); @@ -698,7 +698,7 @@ verify_content(keychain_t *chain, const struct yml_node *node) } bool -verify_conf(keychain_t *chain, const struct yml_node *node) +i3_verify_conf(keychain_t *chain, const struct yml_node *node) { static const struct attr_info attrs[] = { {"spacing", false, &conf_verify_int}, @@ -711,3 +711,12 @@ verify_conf(keychain_t *chain, const struct yml_node *node) return conf_verify_dict(chain, node, attrs); } + +#if defined(CORE_PLUGINS_AS_SHARED_LIBRARIES) + +bool verify_conf(keychain_t *chain, const struct yml_node *node) + __attribute__((weak, alias("i3_verify_conf"))); +struct deco *from_conf(const struct yml_node *node, struct conf_inherit inherited) + __attribute__((weak, alias("i3_from_conf"))); + +#endif diff --git a/modules/label.c b/modules/label.c index 73d10f5..758e384 100644 --- a/modules/label.c +++ b/modules/label.c @@ -48,14 +48,14 @@ label_new(struct particle *label) } struct module * -from_conf(const struct yml_node *node, struct conf_inherit inherited) +label_from_conf(const struct yml_node *node, struct conf_inherit inherited) { const struct yml_node *c = yml_get_value(node, "content"); return label_new(conf_to_particle(c, inherited)); } bool -verify_conf(keychain_t *chain, const struct yml_node *node) +label_verify_conf(keychain_t *chain, const struct yml_node *node) { static const struct attr_info attrs[] = { {"content", true, &conf_verify_particle}, @@ -65,3 +65,12 @@ verify_conf(keychain_t *chain, const struct yml_node *node) return conf_verify_dict(chain, node, attrs); } + +#if defined(CORE_PLUGINS_AS_SHARED_LIBRARIES) + +bool verify_conf(keychain_t *chain, const struct yml_node *node) + __attribute__((weak, alias("label_verify_conf"))); +struct deco *from_conf(const struct yml_node *node, struct conf_inherit inherited) + __attribute__((weak, alias("label_from_conf"))); + +#endif diff --git a/modules/mpd.c b/modules/mpd.c index b4e31b4..ee38fa0 100644 --- a/modules/mpd.c +++ b/modules/mpd.c @@ -477,7 +477,7 @@ mpd_new(const char *host, uint16_t port, struct particle *label) } struct module * -from_conf(const struct yml_node *node, struct conf_inherit inherited) +mpd_from_conf(const struct yml_node *node, struct conf_inherit inherited) { const struct yml_node *host = yml_get_value(node, "host"); const struct yml_node *port = yml_get_value(node, "port"); @@ -490,7 +490,7 @@ from_conf(const struct yml_node *node, struct conf_inherit inherited) } bool -verify_conf(keychain_t *chain, const struct yml_node *node) +mpd_verify_conf(keychain_t *chain, const struct yml_node *node) { static const struct attr_info attrs[] = { {"host", true, &conf_verify_string}, @@ -502,3 +502,12 @@ verify_conf(keychain_t *chain, const struct yml_node *node) return conf_verify_dict(chain, node, attrs); } + +#if defined(CORE_PLUGINS_AS_SHARED_LIBRARIES) + +bool verify_conf(keychain_t *chain, const struct yml_node *node) + __attribute__((weak, alias("mpd_verify_conf"))); +struct deco *from_conf(const struct yml_node *node, struct conf_inherit inherited) + __attribute__((weak, alias("mpd_from_conf"))); + +#endif diff --git a/modules/network.c b/modules/network.c index 09c0cf4..2f9a74e 100644 --- a/modules/network.c +++ b/modules/network.c @@ -532,7 +532,7 @@ network_new(const char *iface, struct particle *label) } struct module * -from_conf(const struct yml_node *node, struct conf_inherit inherited) +network_from_conf(const struct yml_node *node, struct conf_inherit inherited) { const struct yml_node *name = yml_get_value(node, "name"); const struct yml_node *content = yml_get_value(node, "content"); @@ -542,7 +542,7 @@ from_conf(const struct yml_node *node, struct conf_inherit inherited) } bool -verify_conf(keychain_t *chain, const struct yml_node *node) +network_verify_conf(keychain_t *chain, const struct yml_node *node) { static const struct attr_info attrs[] = { {"name", true, &conf_verify_string}, @@ -553,3 +553,12 @@ verify_conf(keychain_t *chain, const struct yml_node *node) return conf_verify_dict(chain, node, attrs); } + +#if defined(CORE_PLUGINS_AS_SHARED_LIBRARIES) + +bool verify_conf(keychain_t *chain, const struct yml_node *node) + __attribute__((weak, alias("network_verify_conf"))); +struct deco *from_conf(const struct yml_node *node, struct conf_inherit inherited) + __attribute__((weak, alias("network_from_conf"))); + +#endif diff --git a/modules/removables.c b/modules/removables.c index 1b24a6c..92d186b 100644 --- a/modules/removables.c +++ b/modules/removables.c @@ -559,7 +559,7 @@ removables_new(struct particle *label, int left_spacing, int right_spacing) } struct module * -from_conf(const struct yml_node *node, struct conf_inherit inherited) +removables_from_conf(const struct yml_node *node, struct conf_inherit inherited) { const struct yml_node *content = yml_get_value(node, "content"); const struct yml_node *spacing = yml_get_value(node, "spacing"); @@ -575,7 +575,7 @@ from_conf(const struct yml_node *node, struct conf_inherit inherited) } bool -verify_conf(keychain_t *chain, const struct yml_node *node) +removables_verify_conf(keychain_t *chain, const struct yml_node *node) { static const struct attr_info attrs[] = { {"spacing", false, &conf_verify_int}, @@ -588,3 +588,12 @@ verify_conf(keychain_t *chain, const struct yml_node *node) return conf_verify_dict(chain, node, attrs); } + +#if defined(CORE_PLUGINS_AS_SHARED_LIBRARIES) + +bool verify_conf(keychain_t *chain, const struct yml_node *node) + __attribute__((weak, alias("removables_verify_conf"))); +struct deco *from_conf(const struct yml_node *node, struct conf_inherit inherited) + __attribute__((weak, alias("removables_from_conf"))); + +#endif diff --git a/modules/xkb.c b/modules/xkb.c index 8f9ad83..b2856c2 100644 --- a/modules/xkb.c +++ b/modules/xkb.c @@ -469,14 +469,14 @@ xkb_new(struct particle *label) } struct module * -from_conf(const struct yml_node *node, struct conf_inherit inherited) +xkb_from_conf(const struct yml_node *node, struct conf_inherit inherited) { const struct yml_node *c = yml_get_value(node, "content"); return xkb_new(conf_to_particle(c, inherited)); } bool -verify_conf(keychain_t *chain, const struct yml_node *node) +xkb_verify_conf(keychain_t *chain, const struct yml_node *node) { static const struct attr_info attrs[] = { {"content", true, &conf_verify_particle}, @@ -486,3 +486,12 @@ verify_conf(keychain_t *chain, const struct yml_node *node) return conf_verify_dict(chain, node, attrs); } + +#if defined(CORE_PLUGINS_AS_SHARED_LIBRARIES) + +bool verify_conf(keychain_t *chain, const struct yml_node *node) + __attribute__((weak, alias("xkb_verify_conf"))); +struct deco *from_conf(const struct yml_node *node, struct conf_inherit inherited) + __attribute__((weak, alias("xkb_from_conf"))); + +#endif diff --git a/modules/xwindow.c b/modules/xwindow.c index 67e36d5..13b2c46 100644 --- a/modules/xwindow.c +++ b/modules/xwindow.c @@ -313,14 +313,14 @@ xwindow_new(struct particle *label) } struct module * -from_conf(const struct yml_node *node, struct conf_inherit inherited) +xwindow_from_conf(const struct yml_node *node, struct conf_inherit inherited) { const struct yml_node *c = yml_get_value(node, "content"); return xwindow_new(conf_to_particle(c, inherited)); } bool -verify_conf(keychain_t *chain, const struct yml_node *node) +xwindow_verify_conf(keychain_t *chain, const struct yml_node *node) { static const struct attr_info attrs[] = { {"content", true, &conf_verify_particle}, @@ -330,3 +330,12 @@ verify_conf(keychain_t *chain, const struct yml_node *node) return conf_verify_dict(chain, node, attrs); } + +#if defined(CORE_PLUGINS_AS_SHARED_LIBRARIES) + +bool verify_conf(keychain_t *chain, const struct yml_node *node) + __attribute__((weak, alias("xwindow_verify_conf"))); +struct deco *from_conf(const struct yml_node *node, struct conf_inherit inherited) + __attribute__((weak, alias("xwindow_from_conf"))); + +#endif diff --git a/particles/CMakeLists.txt b/particles/CMakeLists.txt index 8aae4da..6289b9d 100644 --- a/particles/CMakeLists.txt +++ b/particles/CMakeLists.txt @@ -4,8 +4,16 @@ add_library(particle-sdk INTERFACE) target_compile_options(particle-sdk INTERFACE ${CAIRO_CFLAGS_OTHER}) target_include_directories(particle-sdk INTERFACE ${CAIRO_INCLUDE_DIRS}) +if (CORE_PLUGINS_AS_SHARED_LIBRARIES) + set(lib_type MODULE) + set(dynlist_lib_type SHARED) +else () + set(lib_type STATIC) + set(dynlist_lib_type STATIC) +endif () + # Only an exposable, not a particle. Used by a couple of modules -add_library(dynlist SHARED dynlist.c dynlist.h) +add_library(dynlist ${dynlist_lib_type} dynlist.c dynlist.h) target_link_libraries(dynlist PRIVATE particle-sdk) set(CMAKE_SHARED_MODULE_PREFIX particle_) @@ -13,10 +21,12 @@ set(CMAKE_SHARED_MODULE_PREFIX particle_) set(particles empty list map progress-bar ramp string) foreach (particle ${particles}) - add_library(${particle} MODULE ${particle}.c) + add_library(${particle} ${lib_type} ${particle}.c) target_link_libraries(${particle} particle-sdk) endforeach () target_link_libraries(string ${CAIRO_LIBRARIES}) -install(TARGETS ${particles} dynlist DESTINATION lib/f00bar) +if (CORE_PLUGINS_AS_SHARED_LIBRARIES) + install(TARGETS ${particles} dynlist DESTINATION lib/f00bar) +endif () diff --git a/particles/empty.c b/particles/empty.c index d8b4df4..55c34c6 100644 --- a/particles/empty.c +++ b/particles/empty.c @@ -40,13 +40,13 @@ empty_new(struct particle *common) } struct particle * -from_conf(const struct yml_node *node, struct particle *common) +empty_from_conf(const struct yml_node *node, struct particle *common) { return empty_new(common); } bool -verify_conf(keychain_t *chain, const struct yml_node *node) +empty_verify_conf(keychain_t *chain, const struct yml_node *node) { static const struct attr_info attrs[] = { PARTICLE_COMMON_ATTRS, @@ -54,3 +54,12 @@ verify_conf(keychain_t *chain, const struct yml_node *node) return conf_verify_dict(chain, node, attrs); } + +#if defined(CORE_PLUGINS_AS_SHARED_LIBRARIES) + +bool verify_conf(keychain_t *chain, const struct yml_node *node) + __attribute__((weak, alias("empty_verify_conf"))); +struct deco *from_conf(const struct yml_node *node, struct particle *common) + __attribute__((weak, alias("empty_from_conf"))); + +#endif diff --git a/particles/list.c b/particles/list.c index 43f3874..deb18f0 100644 --- a/particles/list.c +++ b/particles/list.c @@ -164,7 +164,7 @@ particle_list_new(struct particle *common, } struct particle * -from_conf(const struct yml_node *node, struct particle *common) +list_from_conf(const struct yml_node *node, struct particle *common) { const struct yml_node *items = yml_get_value(node, "items"); const struct yml_node *spacing = yml_get_value(node, "spacing"); @@ -192,7 +192,7 @@ from_conf(const struct yml_node *node, struct particle *common) } bool -verify_conf(keychain_t *chain, const struct yml_node *node) +list_verify_conf(keychain_t *chain, const struct yml_node *node) { static const struct attr_info attrs[] = { {"items", true, &conf_verify_particle_list_items}, @@ -204,3 +204,12 @@ verify_conf(keychain_t *chain, const struct yml_node *node) return conf_verify_dict(chain, node, attrs); } + +#if defined(CORE_PLUGINS_AS_SHARED_LIBRARIES) + +bool verify_conf(keychain_t *chain, const struct yml_node *node) + __attribute__((weak, alias("list_verify_conf"))); +struct deco *from_conf(const struct yml_node *node, struct particle *common) + __attribute__((weak, alias("list_from_conf"))); + +#endif diff --git a/particles/map.c b/particles/map.c index 99625d0..27325eb 100644 --- a/particles/map.c +++ b/particles/map.c @@ -197,7 +197,7 @@ verify_map_values(keychain_t *chain, const struct yml_node *node) } struct particle * -from_conf(const struct yml_node *node, struct particle *common) +map_from_conf(const struct yml_node *node, struct particle *common) { const struct yml_node *tag = yml_get_value(node, "tag"); const struct yml_node *values = yml_get_value(node, "values"); @@ -228,7 +228,7 @@ from_conf(const struct yml_node *node, struct particle *common) } bool -verify_conf(keychain_t *chain, const struct yml_node *node) +map_verify_conf(keychain_t *chain, const struct yml_node *node) { static const struct attr_info attrs[] = { {"tag", true, &conf_verify_string}, @@ -239,3 +239,12 @@ verify_conf(keychain_t *chain, const struct yml_node *node) return conf_verify_dict(chain, node, attrs); } + +#if defined(CORE_PLUGINS_AS_SHARED_LIBRARIES) + +bool verify_conf(keychain_t *chain, const struct yml_node *node) + __attribute__((weak, alias("map_verify_conf"))); +struct deco *from_conf(const struct yml_node *node, struct particle *common) + __attribute__((weak, alias("map_from_conf"))); + +#endif diff --git a/particles/progress-bar.c b/particles/progress-bar.c index 130bc76..f6f6d23 100644 --- a/particles/progress-bar.c +++ b/particles/progress-bar.c @@ -229,7 +229,7 @@ progress_bar_new(struct particle *common, const char *tag, int width, } struct particle * -from_conf(const struct yml_node *node, struct particle *common) +progress_bar_from_conf(const struct yml_node *node, struct particle *common) { const struct yml_node *tag = yml_get_value(node, "tag"); const struct yml_node *length = yml_get_value(node, "length"); @@ -256,7 +256,7 @@ from_conf(const struct yml_node *node, struct particle *common) } bool -verify_conf(keychain_t *chain, const struct yml_node *node) +progress_bar_verify_conf(keychain_t *chain, const struct yml_node *node) { static const struct attr_info attrs[] = { {"tag", true, &conf_verify_string}, @@ -272,3 +272,12 @@ verify_conf(keychain_t *chain, const struct yml_node *node) return conf_verify_dict(chain, node, attrs); } + +#if defined(CORE_PLUGINS_AS_SHARED_LIBRARIES) + +bool verify_conf(keychain_t *chain, const struct yml_node *node) + __attribute__((weak, alias("progress_bar_verify_conf"))); +struct deco *from_conf(const struct yml_node *node, struct particle *common) + __attribute__((weak, alias("progress_bar_from_conf"))); + +#endif diff --git a/particles/ramp.c b/particles/ramp.c index 0ef91b8..987ff64 100644 --- a/particles/ramp.c +++ b/particles/ramp.c @@ -154,7 +154,7 @@ ramp_new(struct particle *common, const char *tag, } struct particle * -from_conf(const struct yml_node *node, struct particle *common) +ramp_from_conf(const struct yml_node *node, struct particle *common) { const struct yml_node *tag = yml_get_value(node, "tag"); const struct yml_node *items = yml_get_value(node, "items"); @@ -175,7 +175,7 @@ from_conf(const struct yml_node *node, struct particle *common) } bool -verify_conf(keychain_t *chain, const struct yml_node *node) +ramp_verify_conf(keychain_t *chain, const struct yml_node *node) { static const struct attr_info attrs[] = { {"tag", true, &conf_verify_string}, @@ -185,3 +185,12 @@ verify_conf(keychain_t *chain, const struct yml_node *node) return conf_verify_dict(chain, node, attrs); } + +#if defined(CORE_PLUGINS_AS_SHARED_LIBRARIES) + +bool verify_conf(keychain_t *chain, const struct yml_node *node) + __attribute__((weak, alias("ramp_verify_conf"))); +struct deco *from_conf(const struct yml_node *node, struct particle *common) + __attribute__((weak, alias("ramp_from_conf"))); + +#endif diff --git a/particles/string.c b/particles/string.c index 7b66c86..6588105 100644 --- a/particles/string.c +++ b/particles/string.c @@ -135,7 +135,7 @@ string_new(struct particle *common, const char *text, size_t max_len) } struct particle * -from_conf(const struct yml_node *node, struct particle *common) +string_from_conf(const struct yml_node *node, struct particle *common) { const struct yml_node *text = yml_get_value(node, "text"); const struct yml_node *max = yml_get_value(node, "max"); @@ -147,7 +147,7 @@ from_conf(const struct yml_node *node, struct particle *common) } bool -verify_conf(keychain_t *chain, const struct yml_node *node) +string_verify_conf(keychain_t *chain, const struct yml_node *node) { static const struct attr_info attrs[] = { {"text", true, &conf_verify_string}, @@ -157,3 +157,12 @@ verify_conf(keychain_t *chain, const struct yml_node *node) return conf_verify_dict(chain, node, attrs); } + +#if defined(CORE_PLUGINS_AS_SHARED_LIBRARIES) + +bool verify_conf(keychain_t *chain, const struct yml_node *node) + __attribute__((weak, alias("string_verify_conf"))); +struct deco *from_conf(const struct yml_node *node, struct particle *common) + __attribute__((weak, alias("string_from_conf"))); + +#endif diff --git a/plugin.c b/plugin.c index b43a12f..c680408 100644 --- a/plugin.c +++ b/plugin.c @@ -9,6 +9,54 @@ #include "config.h" #include "tllist.h" +#if !defined(CORE_PLUGINS_AS_SHARED_LIBRARIES) + +#define EXTERN_MODULE(plug_name) \ + extern bool plug_name##_verify_conf( \ + keychain_t *chain, const struct yml_node *node); \ + extern struct module *plug_name##_from_conf( \ + const struct yml_node *node, struct conf_inherit inherited); + +#define EXTERN_PARTICLE(plug_name) \ + extern bool plug_name##_verify_conf( \ + keychain_t *chain, const struct yml_node *node); \ + extern struct particle *plug_name##_from_conf( \ + const struct yml_node *node, struct particle *common); + +#define EXTERN_DECORATION(plug_name) \ + extern bool plug_name##_verify_conf( \ + keychain_t *chain, const struct yml_node *node); \ + extern struct deco *plug_name##_from_conf(const struct yml_node *node); + +EXTERN_MODULE(alsa); +EXTERN_MODULE(backlight); +EXTERN_MODULE(battery); +EXTERN_MODULE(clock); +EXTERN_MODULE(i3); +EXTERN_MODULE(label); +EXTERN_MODULE(mpd); +EXTERN_MODULE(network); +EXTERN_MODULE(removables); +EXTERN_MODULE(xkb); +EXTERN_MODULE(xwindow); + +EXTERN_PARTICLE(empty); +EXTERN_PARTICLE(list); +EXTERN_PARTICLE(map); +EXTERN_PARTICLE(progress_bar); +EXTERN_PARTICLE(ramp); +EXTERN_PARTICLE(string); + +EXTERN_DECORATION(background); +EXTERN_DECORATION(stack); +EXTERN_DECORATION(underline); + +#undef EXTERN_DECORATION +#undef EXTERN_PARTICLE +#undef EXTERN_MODULE + +#endif + static tll(struct plugin) plugins = tll_init(); static const char * @@ -23,11 +71,70 @@ type2str(enum plugin_type type) return NULL; } +static void __attribute__((constructor)) +init(void) +{ +#if !defined(CORE_PLUGINS_AS_SHARED_LIBRARIES) + +#define REGISTER_CORE_PLUGIN(plug_name, func_prefix, plug_type) \ + do { \ + tll_push_back( \ + plugins, \ + ((struct plugin){ \ + .name = strdup(#plug_name), \ + .type = (plug_type), \ + .lib = NULL, \ + .dummy = { \ + .sym1 = &func_prefix##_verify_conf, \ + .sym2 = &func_prefix##_from_conf, \ + } \ + })); \ + } while (0) + +#define REGISTER_CORE_MODULE(plug_name, func_prefix) \ + REGISTER_CORE_PLUGIN(plug_name, func_prefix, PLUGIN_MODULE) +#define REGISTER_CORE_PARTICLE(plug_name, func_prefix) \ + REGISTER_CORE_PLUGIN(plug_name, func_prefix, PLUGIN_PARTICLE) +#define REGISTER_CORE_DECORATION(plug_name, func_prefix) \ + REGISTER_CORE_PLUGIN(plug_name, func_prefix, PLUGIN_DECORATION) + + REGISTER_CORE_MODULE(alsa, alsa); + REGISTER_CORE_MODULE(backlight, backlight); + REGISTER_CORE_MODULE(battery, battery); + REGISTER_CORE_MODULE(clock, clock); + REGISTER_CORE_MODULE(i3, i3); + REGISTER_CORE_MODULE(label, label); + REGISTER_CORE_MODULE(mpd, mpd); + REGISTER_CORE_MODULE(network, network); + REGISTER_CORE_MODULE(removables, removables); + REGISTER_CORE_MODULE(xkb, xkb); + REGISTER_CORE_MODULE(xwindow, xwindow); + + REGISTER_CORE_PARTICLE(empty, empty); + REGISTER_CORE_PARTICLE(list, list); + REGISTER_CORE_PARTICLE(map, map); + REGISTER_CORE_PARTICLE(progress-bar, progress_bar); + REGISTER_CORE_PARTICLE(ramp, ramp); + REGISTER_CORE_PARTICLE(string, string); + + REGISTER_CORE_DECORATION(background, background); + REGISTER_CORE_DECORATION(stack, stack); + REGISTER_CORE_DECORATION(underline, underline); + +#undef REGISTER_CORE_DECORATION +#undef REGISTER_CORE_PARTICLE +#undef REGISTER_CORE_PLUGIN + +#endif /* !CORE_PLUGINS_AS_SHARED_LIBRARIES */ +} + static void free_plugin(struct plugin plug) { dlerror(); - dlclose(plug.lib); + + if (plug.lib != NULL) + dlclose(plug.lib); const char *dl_error = dlerror(); if (dl_error != NULL)