From e03c111e4e631817e82c5172396859968a736b2d Mon Sep 17 00:00:00 2001 From: Daniel Stone Date: Thu, 24 Nov 2016 20:45:45 +0000 Subject: [PATCH] tests: Don't rely on build directory layout Rather than having a hardcoded dependency on the build-directory layout, use an explicit module-map environment variable, which rewrites requests for modules and helper/libexec binaries to specific paths. Pekka: This will help with migration to Meson where setting up the paths according to autotools would be painful and unnecessary. Emre: This should also help setting up the test suite after a cross-compile. Pekka: A caveat here is that this patch makes it slightly easier to load external backends by abusing the module map. External backends are specifically not supported in libweston. Signed-off-by: Daniel Stone v2: Fixed ivi_layout-test-plugin.c:wet_module_init(). Do not change the lookup name of ivi-layout.ivi. Improved documentation of weston_module_path_from_env() and made it cope with map strings that a) do not end with a semicolon, and b) have multiple consecutive semicolons. Let WESTON_MODULE_MAP be printed into the test log so that it is easier to run tests manually. Reviewed-by: Daniel Stone Reviewed-by: Emre Ucan Suggested by Emil: Use a variable for strlen(name). Signed-off-by: Pekka Paalanen Reviewed-by: Emil Velikov --- compositor/main.c | 26 ++++++++++---- compositor/text-backend.c | 6 +--- compositor/weston-screenshooter.c | 8 ++--- compositor/weston.h | 3 ++ desktop-shell/shell.c | 9 ++--- libweston/compositor.c | 58 ++++++++++++++++++++++++++++--- libweston/compositor.h | 3 ++ tests/ivi_layout-test-plugin.c | 16 ++++----- tests/weston-tests-env | 17 +++++++++ 9 files changed, 109 insertions(+), 37 deletions(-) diff --git a/compositor/main.c b/compositor/main.c index 86e3782f..a801be87 100644 --- a/compositor/main.c +++ b/compositor/main.c @@ -652,7 +652,6 @@ weston_create_listening_socket(struct wl_display *display, const char *socket_na WL_EXPORT void * wet_load_module_entrypoint(const char *name, const char *entrypoint) { - const char *builddir = getenv("WESTON_BUILD_DIR"); char path[PATH_MAX]; void *module, *init; size_t len; @@ -661,10 +660,8 @@ wet_load_module_entrypoint(const char *name, const char *entrypoint) return NULL; if (name[0] != '/') { - if (builddir) - len = snprintf(path, sizeof path, "%s/.libs/%s", builddir, - name); - else + len = weston_module_path_from_env(name, path, sizeof path); + if (len == 0) len = snprintf(path, sizeof path, "%s/%s", MODULEDIR, name); } else { @@ -701,7 +698,6 @@ wet_load_module_entrypoint(const char *name, const char *entrypoint) return init; } - WL_EXPORT int wet_load_module(struct weston_compositor *compositor, const char *name, int *argc, char *argv[]) @@ -732,6 +728,24 @@ wet_load_shell(struct weston_compositor *compositor, return 0; } +WL_EXPORT char * +wet_get_binary_path(const char *name) +{ + char path[PATH_MAX]; + size_t len; + + len = weston_module_path_from_env(name, path, sizeof path); + if (len > 0) + return strdup(path); + + len = snprintf(path, sizeof path, "%s/%s", + weston_config_get_libexec_dir(), name); + if (len >= sizeof path) + return NULL; + + return strdup(path); +} + static int load_modules(struct weston_compositor *ec, const char *modules, int *argc, char *argv[], int32_t *xwayland) diff --git a/compositor/text-backend.c b/compositor/text-backend.c index 4d8c085b..54242427 100644 --- a/compositor/text-backend.c +++ b/compositor/text-backend.c @@ -1047,14 +1047,10 @@ text_backend_configuration(struct text_backend *text_backend) struct weston_config *config = wet_get_config(text_backend->compositor); struct weston_config_section *section; char *client; - int ret; section = weston_config_get_section(config, "input-method", NULL, NULL); - ret = asprintf(&client, "%s/weston-keyboard", - weston_config_get_libexec_dir()); - if (ret < 0) - client = NULL; + client = wet_get_binary_path("weston-keyboard"); weston_config_section_get_string(section, "path", &text_backend->input_method.path, client); diff --git a/compositor/weston-screenshooter.c b/compositor/weston-screenshooter.c index 70afed4a..0994cb4f 100644 --- a/compositor/weston-screenshooter.c +++ b/compositor/weston-screenshooter.c @@ -117,12 +117,10 @@ screenshooter_binding(struct weston_keyboard *keyboard, { struct screenshooter *shooter = data; char *screenshooter_exe; - int ret; - ret = asprintf(&screenshooter_exe, "%s/%s", - weston_config_get_libexec_dir(), - "/weston-screenshooter"); - if (ret < 0) { + + screenshooter_exe = wet_get_binary_path("weston-screenshooter"); + if (!screenshooter_exe) { weston_log("Could not construct screenshooter path.\n"); return; } diff --git a/compositor/weston.h b/compositor/weston.h index 5708aca4..8e1d2602 100644 --- a/compositor/weston.h +++ b/compositor/weston.h @@ -77,6 +77,9 @@ int module_init(struct weston_compositor *compositor, int *argc, char *argv[]); +char * +wet_get_binary_path(const char *name); + int wet_load_xwayland(struct weston_compositor *comp); diff --git a/desktop-shell/shell.c b/desktop-shell/shell.c index 42fc27c6..8b7a23ad 100644 --- a/desktop-shell/shell.c +++ b/desktop-shell/shell.c @@ -468,17 +468,12 @@ shell_configuration(struct desktop_shell *shell) { struct weston_config_section *section; char *s, *client; - int ret; int allow_zap; section = weston_config_get_section(wet_get_config(shell->compositor), "shell", NULL, NULL); - ret = asprintf(&client, "%s/%s", weston_config_get_libexec_dir(), - WESTON_SHELL_CLIENT); - if (ret < 0) - client = NULL; - weston_config_section_get_string(section, - "client", &s, client); + client = wet_get_binary_path(WESTON_SHELL_CLIENT); + weston_config_section_get_string(section, "client", &s, client); free(client); shell->client = s; diff --git a/libweston/compositor.c b/libweston/compositor.c index 91f311df..8e01eacc 100644 --- a/libweston/compositor.c +++ b/libweston/compositor.c @@ -6573,10 +6573,60 @@ weston_version(int *major, int *minor, int *micro) *micro = WESTON_VERSION_MICRO; } +/** + * Attempts to find a module path from the module map specified in the + * environment. If found, writes the full path into the path variable. + * + * The module map is a string in environment variable WESTON_MODULE_MAP, where + * each entry is of the form "name=path" and entries are separated by + * semicolons. Whitespace is significant. + * + * \param name The name to search for. + * \param path Where the path is written to if found. + * \param path_len Allocated bytes at \c path . + * \returns The length of the string written to path on success, or 0 if the + * module was not specified in the environment map or path_len was too small. + */ +WL_EXPORT size_t +weston_module_path_from_env(const char *name, char *path, size_t path_len) +{ + const char *mapping = getenv("WESTON_MODULE_MAP"); + const char *end; + const int name_len = strlen(name); + + if (!mapping) + return 0; + + end = mapping + strlen(mapping); + while (mapping < end && *mapping) { + const char *filename, *next; + + /* early out: impossibly short string */ + if (end - mapping < name_len + 1) + return 0; + + filename = &mapping[name_len + 1]; + next = strchrnul(mapping, ';'); + + if (strncmp(mapping, name, name_len) == 0 && + mapping[name_len] == '=') { + size_t file_len = next - filename; /* no trailing NUL */ + if (file_len >= path_len) + return 0; + strncpy(path, filename, file_len); + path[file_len] = '\0'; + return file_len; + } + + mapping = next + 1; + } + + return 0; +} + WL_EXPORT void * weston_load_module(const char *name, const char *entrypoint) { - const char *builddir = getenv("WESTON_BUILD_DIR"); char path[PATH_MAX]; void *module, *init; size_t len; @@ -6585,10 +6635,8 @@ weston_load_module(const char *name, const char *entrypoint) return NULL; if (name[0] != '/') { - if (builddir) - len = snprintf(path, sizeof path, "%s/.libs/%s", - builddir, name); - else + len = weston_module_path_from_env(name, path, sizeof path); + if (len == 0) len = snprintf(path, sizeof path, "%s/%s", LIBWESTON_MODULEDIR, name); } else { diff --git a/libweston/compositor.h b/libweston/compositor.h index 8942ab9a..fbf8a73d 100644 --- a/libweston/compositor.h +++ b/libweston/compositor.h @@ -2149,6 +2149,9 @@ weston_transformed_region(int width, int height, void * weston_load_module(const char *name, const char *entrypoint); +size_t +weston_module_path_from_env(const char *name, char *path, size_t path_len); + int weston_parse_transform(const char *transform, uint32_t *out); diff --git a/tests/ivi_layout-test-plugin.c b/tests/ivi_layout-test-plugin.c index 1f19c55f..0fe9212d 100644 --- a/tests/ivi_layout-test-plugin.c +++ b/tests/ivi_layout-test-plugin.c @@ -32,6 +32,7 @@ #include #include #include +#include #include "compositor.h" #include "compositor/weston.h" @@ -223,7 +224,6 @@ wet_module_init(struct weston_compositor *compositor, { struct wl_event_loop *loop; struct test_launcher *launcher; - const char *path; const struct ivi_layout_interface *iface; iface = ivi_layout_get_api(compositor); @@ -233,20 +233,18 @@ wet_module_init(struct weston_compositor *compositor, return -1; } - path = getenv("WESTON_BUILD_DIR"); - if (!path) { - weston_log("test setup failure: WESTON_BUILD_DIR not set\n"); - return -1; - } - launcher = zalloc(sizeof *launcher); if (!launcher) return -1; + if (weston_module_path_from_env("ivi-layout.ivi", launcher->exe, + sizeof launcher->exe) == 0) { + weston_log("test setup failure: WESTON_MODULE_MAP not set\n"); + return -1; + } + launcher->compositor = compositor; launcher->layout_interface = iface; - snprintf(launcher->exe, sizeof launcher->exe, - "%s/ivi-layout.ivi", path); if (wl_global_create(compositor->wl_display, &weston_test_runner_interface, 1, diff --git a/tests/weston-tests-env b/tests/weston-tests-env index ac2473f7..04648bf1 100755 --- a/tests/weston-tests-env +++ b/tests/weston-tests-env @@ -25,6 +25,19 @@ MODDIR=$abs_builddir/.libs SHELL_PLUGIN=$MODDIR/desktop-shell.so TEST_PLUGIN=$MODDIR/weston-test.so +WESTON_MODULE_MAP= +for mod in cms-colord cms-static desktop-shell drm-backend fbdev-backend \ + fullscreen-shell gl-renderer headless-backend hmi-controller \ + ivi-shell rdp-compositor screen-share wayland-backend \ + weston-test-desktop-shell x11-backend xwayland; do + WESTON_MODULE_MAP="${WESTON_MODULE_MAP}${mod}.so=${abs_builddir}/.libs/${mod}.so;" +done + +for exe in weston-desktop-shell weston-keyboard weston-screenshooter \ + weston-simple-im ivi-layout.ivi; do \ + WESTON_MODULE_MAP="${WESTON_MODULE_MAP}${exe}=${abs_builddir}/${exe};" +done + CONFIG_FILE="${TEST_NAME}.ini" if [ -e "${abs_builddir}/${CONFIG_FILE}" ]; then @@ -40,6 +53,7 @@ case $TEST_FILE in SHELL_PLUGIN=$MODDIR/ivi-shell.so set -x + WESTON_MODULE_MAP="${WESTON_MODULE_MAP}" \ WESTON_DATA_DIR=$abs_top_srcdir/data \ WESTON_BUILD_DIR=$abs_builddir \ WESTON_TEST_REFERENCE_PATH=$abs_top_srcdir/tests/reference \ @@ -53,6 +67,7 @@ case $TEST_FILE in ;; *.la|*.so) set -x + WESTON_MODULE_MAP="${WESTON_MODULE_MAP}" \ WESTON_DATA_DIR=$abs_top_srcdir/data \ WESTON_BUILD_DIR=$abs_builddir \ WESTON_TEST_REFERENCE_PATH=$abs_top_srcdir/tests/reference \ @@ -69,6 +84,7 @@ case $TEST_FILE in SHELL_PLUGIN=$MODDIR/ivi-shell.so set -x + WESTON_MODULE_MAP="${WESTON_MODULE_MAP}" \ WESTON_DATA_DIR=$abs_top_srcdir/data \ WESTON_BUILD_DIR=$abs_builddir \ WESTON_TEST_REFERENCE_PATH=$abs_top_srcdir/tests/reference \ @@ -84,6 +100,7 @@ case $TEST_FILE in ;; *) set -x + WESTON_MODULE_MAP="${WESTON_MODULE_MAP}" \ WESTON_DATA_DIR=$abs_top_srcdir/data \ WESTON_BUILD_DIR=$abs_builddir \ WESTON_TEST_REFERENCE_PATH=$abs_top_srcdir/tests/reference \