diff --git a/Makefile b/Makefile index f6555909e..82f423741 100644 --- a/Makefile +++ b/Makefile @@ -8,6 +8,7 @@ clean: ninja-build -C build clean run: + SPA_PLUGIN_DIR=build/spa/plugins \ PIPEWIRE_MODULE_DIR=build \ PIPEWIRE_CONFIG_FILE=build/pipewire/daemon/pipewire.conf \ build/pipewire/daemon/pipewire diff --git a/config.h.meson b/config.h.meson index 08b7d55a3..0d5add753 100644 --- a/config.h.meson +++ b/config.h.meson @@ -360,12 +360,15 @@ /* Define to the version of this package. */ #mesondefine PACKAGE_VERSION -/* directory where plugins are located */ +/* directory where modules are located */ #mesondefine MODULEDIR /* directory where config files are located */ #mesondefine PIPEWIRE_CONFIG_DIR +/* directory where plugins are located */ +#mesondefine PLUGINDIR + /* Define to necessary symbol if this constant uses a non-standard name on your system. */ #mesondefine PTHREAD_CREATE_JOINABLE diff --git a/meson.build b/meson.build index 5b991b212..8fc4bb353 100644 --- a/meson.build +++ b/meson.build @@ -53,9 +53,10 @@ cdata.set('PACKAGE_STRING', '"PipeWire @0@"'.format(pipewire_version)) cdata.set('PACKAGE_TARNAME', '"pipewire"') cdata.set('PACKAGE_URL', '"http://pipewire.org"') cdata.set('PACKAGE_VERSION', '"@0@"'.format(pipewire_version)) -cdata.set('MODULEDIR', '"@0@/@1@/pipewire-@2@"'.format(pipewire_libdir,apiversion)) +cdata.set('MODULEDIR', '"@0@/pipewire-@1@"'.format(pipewire_libdir,apiversion)) cdata.set('PIPEWIRE_CONFIG_DIR', '"@0@/pipewire"'.format(pipewire_sysconfdir)) cdata.set('VERSION', '"@0@"'.format(pipewire_version)) +cdata.set('PLUGINDIR', '"@0@/spa"'.format(pipewire_libdir)) # FIXME: --with-memory-alignment],[8,N,malloc,pagesize (default is 32)]) option cdata.set('MEMORY_ALIGNMENT_MALLOC', 1) diff --git a/pipewire/client/pipewire.c b/pipewire/client/pipewire.c index 6fe699fcc..8f33b26cd 100644 --- a/pipewire/client/pipewire.c +++ b/pipewire/client/pipewire.c @@ -17,6 +17,10 @@ * Boston, MA 02110-1301, USA. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include #include #include @@ -37,21 +41,29 @@ static struct support_info { } support_info; static bool -open_support(const char *lib, +open_support(const char *path, + const char *lib, struct support_info *info) { - if ((info->hnd = dlopen(lib, RTLD_NOW)) == NULL) { - fprintf(stderr, "can't load %s: %s\n", lib, dlerror()); - return false; + char *filename; + + asprintf(&filename, "%s/%s.so", path, lib); + + if ((info->hnd = dlopen(filename, RTLD_NOW)) == NULL) { + fprintf(stderr, "can't load %s: %s\n", filename, dlerror()); + goto open_failed; } if ((info->enum_func = dlsym(info->hnd, SPA_HANDLE_FACTORY_ENUM_FUNC_NAME)) == NULL) { fprintf(stderr, "can't find enum function\n"); goto no_symbol; } + free(filename); return true; no_symbol: dlclose(info->hnd); + open_failed: + free(filename); return false; } @@ -182,7 +194,10 @@ void pw_init(int *argc, char **argv[]) if ((str = getenv("PIPEWIRE_DEBUG"))) configure_debug(str); - if (open_support("build/spa/plugins/support/libspa-support.so", &support_info)) + if ((str = getenv("SPA_PLUGIN_DIR")) == NULL) + str = PLUGINDIR; + + if (open_support(str, "support/libspa-support", &support_info)) configure_support(&support_info); } diff --git a/pipewire/modules/meson.build b/pipewire/modules/meson.build index 420949e75..05104a850 100644 --- a/pipewire/modules/meson.build +++ b/pipewire/modules/meson.build @@ -1,4 +1,3 @@ -#subdir('gst') subdir('spa') pipewire_module_c_args = [ diff --git a/pipewire/modules/module-mixer.c b/pipewire/modules/module-mixer.c index 6a6d0246d..716d04916 100644 --- a/pipewire/modules/module-mixer.c +++ b/pipewire/modules/module-mixer.c @@ -27,7 +27,7 @@ #include "pipewire/server/core.h" #include "pipewire/server/module.h" -#define AUDIOMIXER_LIB "build/spa/plugins/audiomixer/libspa-audiomixer.so" +#define AUDIOMIXER_LIB "audiomixer/libspa-audiomixer" struct impl { struct pw_core *core; @@ -43,10 +43,17 @@ static const struct spa_handle_factory *find_factory(struct impl *impl) uint32_t index; const struct spa_handle_factory *factory = NULL; int res; + char *filename; + const char *dir; - if ((impl->hnd = dlopen(AUDIOMIXER_LIB, RTLD_NOW)) == NULL) { + if ((dir = getenv("SPA_PLUIGIN_DIR")) == NULL) + dir = PLUGINDIR; + + asprintf(&filename, "%s/%s.so", dir, AUDIOMIXER_LIB); + + if ((impl->hnd = dlopen(filename, RTLD_NOW)) == NULL) { pw_log_error("can't load %s: %s", AUDIOMIXER_LIB, dlerror()); - return NULL; + goto open_failed; } if ((enum_func = dlsym(impl->hnd, SPA_HANDLE_FACTORY_ENUM_FUNC_NAME)) == NULL) { pw_log_error("can't find enum function"); @@ -62,12 +69,15 @@ static const struct spa_handle_factory *find_factory(struct impl *impl) if (strcmp(factory->name, "audiomixer") == 0) break; } + free(filename); return factory; enum_failed: no_symbol: dlclose(impl->hnd); impl->hnd = NULL; + open_failed: + free(filename); return NULL; } diff --git a/pipewire/modules/spa/module.c b/pipewire/modules/spa/module.c index ff636a7ac..6bb2fd56c 100644 --- a/pipewire/modules/spa/module.c +++ b/pipewire/modules/spa/module.c @@ -18,6 +18,10 @@ * Boston, MA 02110-1301, USA. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include #include @@ -73,6 +77,7 @@ setup_video_node(struct pw_core *core, struct spa_node *spa_node, struct pw_prop bool pipewire__module_init(struct pw_module *module, const char *args) { + const char *dir; struct pw_properties *video_props = NULL, *audio_props = NULL; if (args != NULL) { @@ -118,17 +123,17 @@ bool pipewire__module_init(struct pw_module *module, const char *args) free(argv); pw_free_strv(tmp_argv); } + if ((dir = getenv("SPA_PLUGIN_DIR")) == NULL) + dir = PLUGINDIR; + + pw_spa_monitor_load(module->core, dir, "alsa/libspa-alsa", "alsa-monitor", "alsa"); + + pw_spa_monitor_load(module->core, dir, "v4l2/libspa-v4l2", "v4l2-monitor", "v4l2"); - pw_spa_monitor_load(module->core, - "build/spa/plugins/alsa/libspa-alsa.so", "alsa-monitor", "alsa"); - pw_spa_monitor_load(module->core, - "build/spa/plugins/v4l2/libspa-v4l2.so", "v4l2-monitor", "v4l2"); audio_props = pw_properties_new("media.class", "Audio/Source", NULL); - pw_spa_node_load(module->core, - "build/spa/plugins/audiotestsrc/libspa-audiotestsrc.so", + pw_spa_node_load(module->core, dir, "audiotestsrc/libspa-audiotestsrc", "audiotestsrc", "audiotestsrc", audio_props, NULL); - pw_spa_node_load(module->core, - "build/spa/plugins/videotestsrc/libspa-videotestsrc.so", + pw_spa_node_load(module->core, dir, "videotestsrc/libspa-videotestsrc", "videotestsrc", "videotestsrc", video_props, setup_video_node); return true; diff --git a/pipewire/modules/spa/spa-monitor.c b/pipewire/modules/spa/spa-monitor.c index 84c4bf8e4..a285206af 100644 --- a/pipewire/modules/spa/spa-monitor.c +++ b/pipewire/modules/spa/spa-monitor.c @@ -200,6 +200,7 @@ static const struct spa_monitor_callbacks callbacks = { }; struct pw_spa_monitor *pw_spa_monitor_load(struct pw_core *core, + const char *dir, const char *lib, const char *factory_name, const char *system_name) { @@ -212,10 +213,13 @@ struct pw_spa_monitor *pw_spa_monitor_load(struct pw_core *core, uint32_t index; spa_handle_factory_enum_func_t enum_func; const struct spa_handle_factory *factory; + char *filename; - if ((hnd = dlopen(lib, RTLD_NOW)) == NULL) { - pw_log_error("can't load %s: %s", lib, dlerror()); - return NULL; + asprintf(&filename, "%s/%s.so", dir, lib); + + if ((hnd = dlopen(filename, RTLD_NOW)) == NULL) { + pw_log_error("can't load %s: %s", filename, dlerror()); + goto open_failed; } if ((enum_func = dlsym(hnd, SPA_HANDLE_FACTORY_ENUM_FUNC_NAME)) == NULL) { pw_log_error("can't find enum function"); @@ -250,7 +254,7 @@ struct pw_spa_monitor *pw_spa_monitor_load(struct pw_core *core, this = &impl->this; pw_signal_init(&this->destroy_signal); this->monitor = iface; - this->lib = strdup(lib); + this->lib = filename; this->factory_name = strdup(factory_name); this->system_name = strdup(system_name); this->handle = handle; @@ -281,6 +285,8 @@ struct pw_spa_monitor *pw_spa_monitor_load(struct pw_core *core, enum_failed: no_symbol: dlclose(hnd); + open_failed: + free(filename); return NULL; } diff --git a/pipewire/modules/spa/spa-monitor.h b/pipewire/modules/spa/spa-monitor.h index 76b48cb2f..80f07dd09 100644 --- a/pipewire/modules/spa/spa-monitor.h +++ b/pipewire/modules/spa/spa-monitor.h @@ -40,6 +40,7 @@ struct pw_spa_monitor { struct pw_spa_monitor * pw_spa_monitor_load(struct pw_core *core, + const char *dir, const char *lib, const char *factory_name, const char *system_name); void diff --git a/pipewire/modules/spa/spa-node.c b/pipewire/modules/spa/spa-node.c index 16b553dd3..f1b647180 100644 --- a/pipewire/modules/spa/spa-node.c +++ b/pipewire/modules/spa/spa-node.c @@ -33,6 +33,7 @@ struct impl { }; struct pw_spa_node *pw_spa_node_load(struct pw_core *core, + const char *dir, const char *lib, const char *factory_name, const char *name, @@ -49,10 +50,13 @@ struct pw_spa_node *pw_spa_node_load(struct pw_core *core, spa_handle_factory_enum_func_t enum_func; const struct spa_handle_factory *factory; void *iface; + char *filename; - if ((hnd = dlopen(lib, RTLD_NOW)) == NULL) { - pw_log_error("can't load %s: %s", lib, dlerror()); - return NULL; + asprintf(&filename, "%s/%s.so", dir, lib); + + if ((hnd = dlopen(filename, RTLD_NOW)) == NULL) { + pw_log_error("can't load %s: %s", filename, dlerror()); + goto open_failed; } if ((enum_func = dlsym(hnd, SPA_HANDLE_FACTORY_ENUM_FUNC_NAME)) == NULL) { pw_log_error("can't find enum function"); @@ -98,7 +102,7 @@ struct pw_spa_node *pw_spa_node_load(struct pw_core *core, } this->node = pw_node_new(core, NULL, name, false, spa_node, spa_clock, properties); - this->lib = strdup(lib); + this->lib = filename; this->factory_name = strdup(factory_name); this->handle = handle; @@ -111,6 +115,8 @@ struct pw_spa_node *pw_spa_node_load(struct pw_core *core, enum_failed: no_symbol: dlclose(hnd); + open_failed: + free(filename); return NULL; } diff --git a/pipewire/modules/spa/spa-node.h b/pipewire/modules/spa/spa-node.h index 9464e62a9..c03bbd9c7 100644 --- a/pipewire/modules/spa/spa-node.h +++ b/pipewire/modules/spa/spa-node.h @@ -41,6 +41,7 @@ typedef int (*setup_node_t) (struct pw_core *core, struct pw_spa_node * pw_spa_node_load(struct pw_core *core, + const char *dir, const char *lib, const char *factory_name, const char *name, diff --git a/spa/plugins/alsa/meson.build b/spa/plugins/alsa/meson.build index 9544839cf..b6b38c059 100644 --- a/spa/plugins/alsa/meson.build +++ b/spa/plugins/alsa/meson.build @@ -10,4 +10,4 @@ spa_alsa = shared_library('spa-alsa', dependencies : [ alsa_dep, libudev_dep ], link_with : spalib, install : true, - install_dir : '@0@/spa'.format(get_option('libdir'))) + install_dir : '@0@/spa/alsa'.format(get_option('libdir'))) diff --git a/spa/plugins/audiomixer/meson.build b/spa/plugins/audiomixer/meson.build index 2f081dcb3..41474fa01 100644 --- a/spa/plugins/audiomixer/meson.build +++ b/spa/plugins/audiomixer/meson.build @@ -5,4 +5,4 @@ audiomixerlib = shared_library('spa-audiomixer', include_directories : [spa_inc, spa_libinc], link_with : spalib, install : true, - install_dir : '@0@/spa'.format(get_option('libdir'))) + install_dir : '@0@/spa/audiomixer/'.format(get_option('libdir'))) diff --git a/spa/plugins/audiotestsrc/meson.build b/spa/plugins/audiotestsrc/meson.build index 681bcaef6..9886b0cb8 100644 --- a/spa/plugins/audiotestsrc/meson.build +++ b/spa/plugins/audiotestsrc/meson.build @@ -6,4 +6,4 @@ audiotestsrclib = shared_library('spa-audiotestsrc', dependencies : libm, link_with : spalib, install : true, - install_dir : '@0@/spa'.format(get_option('libdir'))) + install_dir : '@0@/spa/audiotestsrc'.format(get_option('libdir'))) diff --git a/spa/plugins/ffmpeg/meson.build b/spa/plugins/ffmpeg/meson.build index 7dee7b0c6..deacdf03d 100644 --- a/spa/plugins/ffmpeg/meson.build +++ b/spa/plugins/ffmpeg/meson.build @@ -8,4 +8,4 @@ ffmpeglib = shared_library('spa-ffmpeg', dependencies : [ avcodec_dep, avformat_dep ], link_with : spalib, install : true, - install_dir : '@0@/spa'.format(get_option('libdir'))) + install_dir : '@0@/spa/ffmpeg'.format(get_option('libdir'))) diff --git a/spa/plugins/support/meson.build b/spa/plugins/support/meson.build index 7a2d7734b..a04b8d68a 100644 --- a/spa/plugins/support/meson.build +++ b/spa/plugins/support/meson.build @@ -8,4 +8,4 @@ spa_support_lib = shared_library('spa-support', include_directories : [ spa_inc, spa_libinc], dependencies : threads_dep, install : true, - install_dir : '@0@/spa'.format(get_option('libdir'))) + install_dir : '@0@/spa/support'.format(get_option('libdir'))) diff --git a/spa/plugins/test/meson.build b/spa/plugins/test/meson.build index 31cef6b15..0f1fc2b22 100644 --- a/spa/plugins/test/meson.build +++ b/spa/plugins/test/meson.build @@ -6,4 +6,4 @@ testlib = shared_library('spa-test', dependencies : threads_dep, link_with : spalib, install : true, - install_dir : '@0@/spa'.format(get_option('libdir'))) + install_dir : '@0@/spa/test'.format(get_option('libdir'))) diff --git a/spa/plugins/v4l2/meson.build b/spa/plugins/v4l2/meson.build index d4d236f90..1d82379cb 100644 --- a/spa/plugins/v4l2/meson.build +++ b/spa/plugins/v4l2/meson.build @@ -8,4 +8,4 @@ v4l2lib = shared_library('spa-v4l2', dependencies : [ v4l2_dep, libudev_dep ], link_with : spalib, install : true, - install_dir : '@0@/spa'.format(get_option('libdir'))) + install_dir : '@0@/spa/v4l2'.format(get_option('libdir'))) diff --git a/spa/plugins/videotestsrc/meson.build b/spa/plugins/videotestsrc/meson.build index 53d9febc4..1db13b449 100644 --- a/spa/plugins/videotestsrc/meson.build +++ b/spa/plugins/videotestsrc/meson.build @@ -6,4 +6,4 @@ videotestsrclib = shared_library('spa-videotestsrc', dependencies : threads_dep, link_with : spalib, install : true, - install_dir : '@0@/spa'.format(get_option('libdir'))) + install_dir : '@0@/spa/videotestsrc'.format(get_option('libdir'))) diff --git a/spa/plugins/volume/meson.build b/spa/plugins/volume/meson.build index 860e2e66c..f21d94ab6 100644 --- a/spa/plugins/volume/meson.build +++ b/spa/plugins/volume/meson.build @@ -5,4 +5,4 @@ volumelib = shared_library('spa-volume', include_directories : [spa_inc, spa_libinc], link_with : spalib, install : true, - install_dir : '@0@/spa'.format(get_option('libdir'))) + install_dir : '@0@/spa/volume'.format(get_option('libdir')))