distclean: clean
-$(quiet-@)test -f build.ninja && $(NINJA) $(NINJAFLAGS) -t clean -g || :
- rm -f config-host.mak
+ rm -f config-host.mak qemu-bundle
rm -f tests/tcg/config-*.mak
rm -f config.status
rm -f roms/seabios/config.mak
The project aims to support the two most recent versions of Windows that are
still supported by the vendor. The minimum Windows API that is currently
-targeted is "Windows 7", so theoretically the QEMU binaries can still be run
+targeted is "Windows 8", so theoretically the QEMU binaries can still be run
on older versions of Windows, too. However, such old versions of Windows are
not tested anymore, so it is recommended to use one of the latest versions of
Windows instead.
* @dir: the directory (typically a `CONFIG_*DIR` variable) to be relocated.
*
* Returns a path for @dir that uses the directory of the running executable
- * as the prefix. For example, if `bindir` is `/usr/bin` and @dir is
- * `/usr/share/qemu`, the function will append `../share/qemu` to the
- * directory that contains the running executable and return the result.
+ * as the prefix.
+ *
+ * When a directory named `qemu-bundle` exists in the directory of the running
+ * executable, the path to the directory will be prepended to @dir. For
+ * example, if the directory of the running executable is `/qemu/build` @dir
+ * is `/usr/share/qemu`, the result will be
+ * `/qemu/build/qemu-bundle/usr/share/qemu`. The directory is expected to exist
+ * in the build tree.
+ *
+ * Otherwise, the directory of the running executable will be used as the
+ * prefix and it appends the relative path from `bindir` to @dir. For example,
+ * if the directory of the running executable is `/opt/qemu/bin`, `bindir` is
+ * `/usr/bin` and @dir is `/usr/share/qemu`, the result will be
+ * `/opt/qemu/bin/../share/qemu`.
+ *
* The returned string should be freed by the caller.
*/
char *get_relocated_path(const char *dir);
add_test_setup('slow', exclude_suites: ['thorough'], env: ['G_TEST_SLOW=1', 'SPEED=slow'])
add_test_setup('thorough', env: ['G_TEST_SLOW=1', 'SPEED=thorough'])
+meson.add_postconf_script(find_program('scripts/symlink-install-tree.py'))
+
not_found = dependency('', required: false)
keyval = import('keyval')
ss = import('sourceset')
hvf = not_found
midl = not_found
widl = not_found
+pathcch = not_found
host_dsosuf = '.so'
if targetos == 'windows'
midl = find_program('midl', required: false)
widl = find_program('widl', required: false)
+ pathcch = cc.find_library('pathcch')
socket = cc.find_library('ws2_32')
winmm = cc.find_library('winmm')
--- /dev/null
+#!/usr/bin/env python3
+
+from pathlib import PurePath
+import errno
+import json
+import os
+import subprocess
+import sys
+
+def destdir_join(d1: str, d2: str) -> str:
+ if not d1:
+ return d2
+ # c:\destdir + c:\prefix must produce c:\destdir\prefix
+ return str(PurePath(d1, *PurePath(d2).parts[1:]))
+
+introspect = os.environ.get('MESONINTROSPECT')
+out = subprocess.run([*introspect.split(' '), '--installed'],
+ stdout=subprocess.PIPE, check=True).stdout
+for source, dest in json.loads(out).items():
+ assert os.path.isabs(source)
+ bundle_dest = destdir_join('qemu-bundle', dest)
+ path = os.path.dirname(bundle_dest)
+ try:
+ os.makedirs(path, exist_ok=True)
+ except BaseException as e:
+ print(f'error making directory {path}', file=sys.stderr)
+ raise e
+ try:
+ os.symlink(source, bundle_dest)
+ except BaseException as e:
+ if not isinstance(e, OSError) or e.errno != errno.EEXIST:
+ print(f'error making symbolic link {dest}', file=sys.stderr)
+ raise e
#include <sys/sysctl.h>
#endif
+#ifdef G_OS_WIN32
+#include <pathcch.h>
+#include <wchar.h>
+#endif
+
#include "qemu/ctype.h"
#include "qemu/cutils.h"
#include "qemu/error-report.h"
/* Fail if qemu_init_exec_dir was not called. */
assert(exec_dir[0]);
- if (!starts_with_prefix(dir) || !starts_with_prefix(bindir)) {
- return g_strdup(dir);
- }
result = g_string_new(exec_dir);
+ g_string_append(result, "/qemu-bundle");
+ if (access(result->str, R_OK) == 0) {
+#ifdef G_OS_WIN32
+ size_t size = mbsrtowcs(NULL, &dir, 0, &(mbstate_t){0}) + 1;
+ PWSTR wdir = g_new(WCHAR, size);
+ mbsrtowcs(wdir, &dir, size, &(mbstate_t){0});
+
+ PCWSTR wdir_skipped_root;
+ PathCchSkipRoot(wdir, &wdir_skipped_root);
+
+ size = wcsrtombs(NULL, &wdir_skipped_root, 0, &(mbstate_t){0});
+ char *cursor = result->str + result->len;
+ g_string_set_size(result, result->len + size);
+ wcsrtombs(cursor, &wdir_skipped_root, size + 1, &(mbstate_t){0});
+ g_free(wdir);
+#else
+ g_string_append(result, dir);
+#endif
+ } else if (!starts_with_prefix(dir) || !starts_with_prefix(bindir)) {
+ g_string_assign(result, dir);
+ } else {
+ g_string_assign(result, exec_dir);
+
+ /* Advance over common components. */
+ len_dir = len_bindir = prefix_len;
+ do {
+ dir += len_dir;
+ bindir += len_bindir;
+ dir = next_component(dir, &len_dir);
+ bindir = next_component(bindir, &len_bindir);
+ } while (len_dir && len_dir == len_bindir && !memcmp(dir, bindir, len_dir));
+
+ /* Ascend from bindir to the common prefix with dir. */
+ while (len_bindir) {
+ bindir += len_bindir;
+ g_string_append(result, "/..");
+ bindir = next_component(bindir, &len_bindir);
+ }
- /* Advance over common components. */
- len_dir = len_bindir = prefix_len;
- do {
- dir += len_dir;
- bindir += len_bindir;
- dir = next_component(dir, &len_dir);
- bindir = next_component(bindir, &len_bindir);
- } while (len_dir && len_dir == len_bindir && !memcmp(dir, bindir, len_dir));
-
- /* Ascend from bindir to the common prefix with dir. */
- while (len_bindir) {
- bindir += len_bindir;
- g_string_append(result, "/..");
- bindir = next_component(bindir, &len_bindir);
+ if (*dir) {
+ assert(G_IS_DIR_SEPARATOR(dir[-1]));
+ g_string_append(result, dir - 1);
+ }
}
- if (*dir) {
- assert(G_IS_DIR_SEPARATOR(dir[-1]));
- g_string_append(result, dir - 1);
- }
return g_string_free(result, false);
}
util_ss.add(when: 'CONFIG_WIN32', if_true: files('oslib-win32.c'))
util_ss.add(when: 'CONFIG_WIN32', if_true: files('qemu-thread-win32.c'))
util_ss.add(when: 'CONFIG_WIN32', if_true: winmm)
+util_ss.add(when: 'CONFIG_WIN32', if_true: pathcch)
util_ss.add(files('envlist.c', 'path.c', 'module.c'))
util_ss.add(files('host-utils.c'))
util_ss.add(files('bitmap.c', 'bitops.c'))