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 <daniels@collabora.com>
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 <daniels@collabora.com>
Reviewed-by: Emre Ucan <eucan@de.adit-jv.com>
Suggested by Emil: Use a variable for strlen(name).
Signed-off-by: Pekka Paalanen <pekka.paalanen@collabora.co.uk>
Reviewed-by: Emil Velikov <emil.velikov@collabora.com>
diff --git a/compositor/main.c b/compositor/main.c
index 86e3782..a801be8 100644
--- a/compositor/main.c
+++ b/compositor/main.c
@@ -652,7 +652,6 @@
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 @@
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 @@
return init;
}
-
WL_EXPORT int
wet_load_module(struct weston_compositor *compositor,
const char *name, int *argc, char *argv[])
@@ -732,6 +728,24 @@
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 4d8c085..5424242 100644
--- a/compositor/text-backend.c
+++ b/compositor/text-backend.c
@@ -1047,14 +1047,10 @@
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 70afed4..0994cb4 100644
--- a/compositor/weston-screenshooter.c
+++ b/compositor/weston-screenshooter.c
@@ -117,12 +117,10 @@
{
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 5708aca..8e1d260 100644
--- a/compositor/weston.h
+++ b/compositor/weston.h
@@ -77,6 +77,9 @@
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 42fc27c..8b7a23a 100644
--- a/desktop-shell/shell.c
+++ b/desktop-shell/shell.c
@@ -468,17 +468,12 @@
{
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 91f311d..8e01eac 100644
--- a/libweston/compositor.c
+++ b/libweston/compositor.c
@@ -6573,10 +6573,60 @@
*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 @@
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 8942ab9..fbf8a73 100644
--- a/libweston/compositor.h
+++ b/libweston/compositor.h
@@ -2149,6 +2149,9 @@
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 1f19c55..0fe9212 100644
--- a/tests/ivi_layout-test-plugin.c
+++ b/tests/ivi_layout-test-plugin.c
@@ -32,6 +32,7 @@
#include <signal.h>
#include <string.h>
#include <assert.h>
+#include <limits.h>
#include "compositor.h"
#include "compositor/weston.h"
@@ -223,7 +224,6 @@
{
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 @@
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 ac2473f..04648bf 100755
--- a/tests/weston-tests-env
+++ b/tests/weston-tests-env
@@ -25,6 +25,19 @@
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 @@
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 @@
;;
*.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 @@
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 @@
;;
*)
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 \