From 53b4537160c84de51be0f57f220aa7de8a4486b2 Mon Sep 17 00:00:00 2001 From: Riccardo Schirone Date: Wed, 24 Feb 2021 11:15:50 +0100 Subject: [PATCH] Introduce `portable` build option to use relative paths `portable` makes rizin use paths relative to the executable binary path, so that all resource files (e.g. SDB files) can be retrieved without having an hard-coded prefix in the binary. By doing so, rizin installation directory can be moved from location to location and still work. This is useful when having a static rizin that you want to execute on another system. It makes sure that all PATHs defined in rz_userconf.h are just relative to the prefix and that, in the code, the prefix is prepended to all these paths. --- librz/bin/p/bin_any.c | 4 +++- librz/core/cconfig.c | 20 +++++--------------- librz/core/cfile.c | 4 ---- librz/core/cmd_eval.c | 4 +--- librz/include/rz_userconf.h.in | 2 ++ librz/lang/p/c.c | 6 +++++- librz/lang/p/cpipe.c | 8 ++++++-- librz/lang/p/rust.c | 6 +++++- librz/lang/p/vala.c | 6 +++++- librz/main/rizin.c | 20 ++++++++++---------- librz/socket/run.c | 4 ---- librz/syscall/syscall.c | 7 +++++-- librz/util/sys.c | 12 +++++++++--- meson.build | 18 +++++++----------- meson_options.txt | 3 ++- 15 files changed, 65 insertions(+), 59 deletions(-) diff --git a/librz/bin/p/bin_any.c b/librz/bin/p/bin_any.c index f94704366c..e312f38c50 100644 --- a/librz/bin/p/bin_any.c +++ b/librz/bin/p/bin_any.c @@ -15,7 +15,9 @@ static char *get_filetype(RzBuffer *b) { } const char *tmp = NULL; // TODO: dir.magic not honored here - rz_magic_load(ck, RZ_SDB_MAGIC); + char *m = rz_str_rz_prefix(RZ_SDB_MAGIC); + rz_magic_load(ck, m); + free(m); rz_buf_read_at(b, 0, buf, sizeof(buf)); tmp = rz_magic_buffer(ck, buf, sizeof(buf)); if (tmp) { diff --git a/librz/core/cconfig.c b/librz/core/cconfig.c index 48d9a1844b..bb32a30de7 100644 --- a/librz/core/cconfig.c +++ b/librz/core/cconfig.c @@ -2825,14 +2825,8 @@ RZ_API int rz_core_config_init(RzCore *core) { /* dir.prefix is used in other modules, set it first */ { char *pfx = rz_sys_getenv("RZ_PREFIX"); -#if __WINDOWS__ - const char *invoke_dir = rz_sys_prefix(NULL); - if (!pfx && invoke_dir) { - pfx = strdup(invoke_dir); - } -#endif if (!pfx) { - pfx = strdup(RZ_PREFIX); + pfx = strdup(rz_sys_prefix(NULL)); } SETCB("dir.prefix", pfx, (RzConfigCallback)&cb_dirpfx, "Default prefix rizin was compiled for"); free(pfx); @@ -3425,16 +3419,12 @@ RZ_API int rz_core_config_init(RzCore *core) { SETPREF("http.index", "index.html", "Main html file to check in directory"); SETPREF("http.bind", "localhost", "Server address"); SETPREF("http.homeroot", RZ_JOIN_2_PATHS("~", RZ_HOME_WWWROOT), "http home root directory"); -#if __WINDOWS__ - { - char *wwwroot = rz_str_newf("%s\\share\\www", rz_sys_prefix(NULL)); - SETPREF("http.root", wwwroot, "http root directory"); - free(wwwroot); - } -#elif __ANDROID__ +#if __ANDROID__ SETPREF("http.root", "/data/data/org.rizin.rizininstaller/www", "http root directory"); #else - SETPREF("http.root", RZ_WWWROOT, "http root directory"); + char *wwwroot = rz_str_rz_prefix(RZ_WWWROOT); + SETPREF("http.root", wwwroot, "http root directory"); + free(wwwroot); #endif SETPREF("http.port", "9090", "HTTP server port"); SETPREF("http.maxport", "9999", "Last HTTP server port"); diff --git a/librz/core/cfile.c b/librz/core/cfile.c index bc02bfb67d..62bb9dd8b4 100644 --- a/librz/core/cfile.c +++ b/librz/core/cfile.c @@ -758,11 +758,7 @@ static bool try_loadlib(RzCore *core, const char *lib, ut64 addr) { RZ_API bool rz_core_file_loadlib(RzCore *core, const char *lib, ut64 libaddr) { const char *dirlibs = rz_config_get(core->config, "dir.libs"); bool free_libdir = true; -#ifdef __WINDOWS__ char *libdir = rz_str_rz_prefix(RZ_LIBDIR); -#else - char *libdir = strdup(RZ_LIBDIR); -#endif if (!libdir) { libdir = RZ_LIBDIR; free_libdir = false; diff --git a/librz/core/cmd_eval.c b/librz/core/cmd_eval.c index 2f1e3cc012..1ae5f5d94e 100644 --- a/librz/core/cmd_eval.c +++ b/librz/core/cmd_eval.c @@ -164,9 +164,7 @@ RZ_IPI bool rz_core_load_theme(RzCore *core, const char *name) { if (load_theme(core, name)) { curtheme = rz_str_dup(curtheme, name); } else { - char *absfile = rz_file_abspath(name); - eprintf("eco: cannot open colorscheme profile (%s)\n", absfile); - free(absfile); + eprintf("eco: cannot open colorscheme profile (%s)\n", name); failed = true; } } diff --git a/librz/include/rz_userconf.h.in b/librz/include/rz_userconf.h.in index 1f100d2001..067ba4fd8f 100644 --- a/librz/include/rz_userconf.h.in +++ b/librz/include/rz_userconf.h.in @@ -31,6 +31,8 @@ #define WITH_GPL @WITH_GPL@ #define HAVE_JEMALLOC @HAVE_JEMALLOC@ +#define RZ_IS_PORTABLE @IS_PORTABLE@ + #define RZ_PREFIX "@PREFIX@" #define RZ_LIBDIR "@LIBDIR@" #define RZ_INCDIR "@INCLUDEDIR@" diff --git a/librz/lang/p/c.c b/librz/lang/p/c.c index 64759d04b3..948621c57f 100644 --- a/librz/lang/p/c.c +++ b/librz/lang/p/c.c @@ -51,15 +51,19 @@ static int lang_c_file(RzLang *lang, const char *file) { if (RZ_STR_ISEMPTY(cc)) { cc = strdup("gcc"); } + char *libdir = rz_str_rz_prefix(RZ_LIBDIR); + char *pkgconf_path = rz_file_path_join(libdir, "pkgconfig"); char *file_esc = rz_str_escape_sh(file); char *libpath_esc = rz_str_escape_sh(libpath); char *libname_esc = rz_str_escape_sh(libname); char *buf = rz_str_newf("%s -fPIC -shared \"%s\" -o \"%s/lib%s." RZ_LIB_EXT "\"" " $(PKG_CONFIG_PATH=%s pkg-config --cflags --libs rz_core)", - cc, file_esc, libpath_esc, libname_esc, RZ_LIBDIR "/pkgconfig"); + cc, file_esc, libpath_esc, libname_esc, pkgconf_path); free(libname_esc); free(libpath_esc); free(file_esc); + free(libdir); + free(pkgconf_path); free(cc); if (rz_sys_system(buf) != 0) { free(buf); diff --git a/librz/lang/p/cpipe.c b/librz/lang/p/cpipe.c index 9bdd1b5067..f453788fee 100644 --- a/librz/lang/p/cpipe.c +++ b/librz/lang/p/cpipe.c @@ -42,19 +42,22 @@ static int lang_cpipe_file(RzLang *lang, const char *file) { free(cc); cc = strdup("gcc"); } + char *libdir = rz_str_rz_prefix(RZ_LIBDIR); + char *pkgconf_path = rz_file_path_join(libdir, "pkgconfig"); char *file_esc = rz_str_escape_sh(file); char *libpath_esc = rz_str_escape_sh(libpath); char *libname_esc = rz_str_escape_sh(libname); char *buf = rz_str_newf("%s \"%s\" -o \"%s/bin%s\"" " $(PKG_CONFIG_PATH=%s pkg-config --cflags --libs rz_socket)", - cc, file_esc, libpath_esc, libname_esc, RZ_LIBDIR "/pkgconfig"); + cc, file_esc, libpath_esc, libname_esc, pkgconf_path); free(libname_esc); free(libpath_esc); free(file_esc); + free(pkgconf_path); free(cc); if (rz_sys_system(buf) == 0) { char *o_ld_path = rz_sys_getenv("LD_LIBRARY_PATH"); - rz_sys_setenv("LD_LIBRARY_PATH", RZ_LIBDIR); + rz_sys_setenv("LD_LIBRARY_PATH", libdir); char *binfile = rz_str_newf("%s/bin%s", libpath, libname); lang_pipe_run(lang, binfile, -1); rz_file_rm(binfile); @@ -62,6 +65,7 @@ static int lang_cpipe_file(RzLang *lang, const char *file) { free(o_ld_path); free(binfile); } + free(libdir); free(buf); return 0; } diff --git a/librz/lang/p/rust.c b/librz/lang/p/rust.c index 590ba2bcd5..db31760e3f 100644 --- a/librz/lang/p/rust.c +++ b/librz/lang/p/rust.c @@ -31,7 +31,11 @@ static int lang_rust_file(RzLang *lang, const char *file) { libpath = "."; libname = name; } - rz_sys_setenv("PKG_CONFIG_PATH", RZ_LIBDIR "/pkgconfig"); + char *libdir = rz_str_rz_prefix(RZ_LIBDIR); + char *pkgconf_path = rz_file_path_join(libdir, "pkgconfig"); + rz_sys_setenv("PKG_CONFIG_PATH", pkgconf_path); + free(pkgconf_path); + free(libdir); p = strstr(name, ".rs"); if (p) *p = 0; diff --git a/librz/lang/p/vala.c b/librz/lang/p/vala.c index adaa6bdd61..485f21dfe8 100644 --- a/librz/lang/p/vala.c +++ b/librz/lang/p/vala.c @@ -37,7 +37,11 @@ static int lang_vala_file(RzLang *lang, const char *file, bool silent) { libname = strdup(file); strcpy(srcdir, "."); } - rz_sys_setenv("PKG_CONFIG_PATH", RZ_LIBDIR "/pkgconfig"); + char *libdir = rz_str_rz_prefix(RZ_LIBDIR); + char *pkgconf_path = rz_file_path_join(libdir, "pkgconfig"); + rz_sys_setenv("PKG_CONFIG_PATH", pkgconf_path); + free(pkgconf_path); + free(libdir); vapidir = rz_sys_getenv("VAPIDIR"); char *tail = silent ? " > /dev/null 2>&1" : ""; char *src = rz_file_slurp(name, NULL); diff --git a/librz/main/rizin.c b/librz/main/rizin.c index 142f3b885a..34a51ad9e5 100644 --- a/librz/main/rizin.c +++ b/librz/main/rizin.c @@ -139,6 +139,8 @@ static int main_help(int line) { } if (line == 2) { char *datahome = rz_str_home(RZ_HOME_DATADIR); + char *incdir = rz_str_rz_prefix(RZ_INCDIR); + char *libdir = rz_str_rz_prefix(RZ_LIBDIR); const char *dirPrefix = rz_sys_prefix(NULL); printf( "Scripts:\n" @@ -160,11 +162,13 @@ static int main_help(int line) { " RZ_RDATAHOME %s\n" // TODO: rename to RHOME RZHOME? " RZ_VERSION contains the current version of rizin\n" "Paths:\n" - " RZ_PREFIX " RZ_PREFIX "\n" - " RZ_INCDIR " RZ_INCDIR "\n" - " RZ_LIBDIR " RZ_LIBDIR "\n" + " RZ_PREFIX %s\n" + " RZ_INCDIR %s\n" + " RZ_LIBDIR %s\n" " RZ_LIBEXT " RZ_LIB_EXT "\n", - dirPrefix, datahome, dirPrefix); + dirPrefix, datahome, dirPrefix, dirPrefix, incdir, libdir); + free(libdir); + free(incdir); free(datahome); } return 0; @@ -172,13 +176,9 @@ static int main_help(int line) { static int main_print_var(const char *var_name) { int i = 0; -#ifdef __WINDOWS__ + const char *prefix = rz_sys_prefix(NULL); char *incdir = rz_str_rz_prefix(RZ_INCDIR); char *libdir = rz_str_rz_prefix(RZ_LIBDIR); -#else - char *incdir = strdup(RZ_INCDIR); - char *libdir = strdup(RZ_LIBDIR); -#endif char *confighome = rz_str_home(RZ_HOME_CONFIGDIR); char *datahome = rz_str_home(RZ_HOME_DATADIR); char *cachehome = rz_str_home(RZ_HOME_CACHEDIR); @@ -191,7 +191,7 @@ static int main_print_var(const char *var_name) { const char *value; } rz_vars[] = { { "RZ_VERSION", RZ_VERSION }, - { "RZ_PREFIX", RZ_PREFIX }, + { "RZ_PREFIX", prefix }, { "RZ_MAGICPATH", magicpath }, { "RZ_INCDIR", incdir }, { "RZ_LIBDIR", libdir }, diff --git a/librz/socket/run.c b/librz/socket/run.c index df4a25e1a1..084c28c798 100644 --- a/librz/socket/run.c +++ b/librz/socket/run.c @@ -1009,11 +1009,7 @@ RZ_API int rz_run_config_env(RzRunProfile *p) { if (p->_preload) { eprintf("WARNING: Only one library can be opened at a time\n"); } -#ifdef __WINDOWS__ p->_preload = rz_str_rz_prefix(RZ_JOIN_2_PATHS(RZ_LIBDIR, "librz." RZ_LIB_EXT)); -#else - p->_preload = strdup(RZ_LIBDIR "/librz." RZ_LIB_EXT); -#endif } if (p->_libpath) { #if __WINDOWS__ diff --git a/librz/syscall/syscall.c b/librz/syscall/syscall.c index a5bb3e5276..356d0e6a04 100644 --- a/librz/syscall/syscall.c +++ b/librz/syscall/syscall.c @@ -44,8 +44,11 @@ RZ_API void rz_syscall_free(RzSyscall *s) { static bool load_sdb(Sdb **db, const char *name) { rz_return_val_if_fail(db, false); - char *file = rz_str_newf(RZ_JOIN_3_PATHS("%s", RZ_SDB, "%s.sdb"), - rz_sys_prefix(NULL), name); + char *sdb_path = rz_str_rz_prefix(RZ_SDB); + char *file_name = rz_str_newf("%s.sdb", name); + char *file = rz_file_path_join(sdb_path, file_name); + free(file_name); + free(sdb_path); if (rz_file_exists(file)) { if (*db) { sdb_reset(*db); diff --git a/librz/util/sys.c b/librz/util/sys.c index ba03e5e8d6..354caf8d39 100644 --- a/librz/util/sys.c +++ b/librz/util/sys.c @@ -1291,8 +1291,14 @@ RZ_API int rz_sys_getpid(void) { RZ_API const char *rz_sys_prefix(const char *pfx) { static char *prefix = NULL; if (!prefix) { -#if __WINDOWS__ - prefix = rz_sys_get_src_dir_w32(); +#if RZ_IS_PORTABLE + char *pid_to_path = rz_sys_pid_to_path(rz_sys_getpid()); + if (pid_to_path) { + char *t = rz_file_dirname(pid_to_path); + free(pid_to_path); + prefix = rz_file_dirname(t); + free(t); + } if (!prefix) { prefix = strdup(RZ_PREFIX); } @@ -1300,7 +1306,7 @@ RZ_API const char *rz_sys_prefix(const char *pfx) { prefix = strdup(RZ_PREFIX); #endif } - if (pfx) { + if (RZ_STR_ISNOTEMPTY(pfx)) { free(prefix); prefix = strdup(pfx); } diff --git a/meson.build b/meson.build index c03f331278..d24ca5995b 100644 --- a/meson.build +++ b/meson.build @@ -150,6 +150,7 @@ rizin_incdir = get_option('includedir') / 'librz' rizin_datdir = get_option('datadir') if host_machine.system() == 'windows' rizin_prefix = rizin_prefix / '' + rizin_datdir_rz = rizin_datdir / '' rizin_wwwroot = rizin_datdir / 'www' rizin_sdb = rizin_datdir / '' rizin_zigns = rizin_datdir / 'zigns' @@ -278,25 +279,20 @@ message('RZ_CHECKS_LEVEL: @0@'.format(checks_level)) userconf = configuration_data() userconf.set('RZ_CHECKS_LEVEL', checks_level) +userconf.set10('IS_PORTABLE', get_option('portable')) userconf.set10('HAVE_LIB_MAGIC', sys_magic.found()) userconf.set10('USE_LIB_MAGIC', sys_magic.found()) userconf.set10('HAVE_LIB_XXHASH', xxhash_dep.found()) userconf.set10('USE_LIB_XXHASH', xxhash_dep.found()) userconf.set10('DEBUGGER', has_debugger) userconf.set('PREFIX', rizin_prefix) -if host_machine.system() == 'windows' - userconf.set('LIBDIR', rizin_libdir) - userconf.set('INCLUDEDIR', rizin_incdir) - userconf.set('DATADIR_RZ', rizin_datdir) -else - userconf.set('LIBDIR', rizin_prefix / rizin_libdir) - userconf.set('INCLUDEDIR', rizin_prefix / rizin_incdir) - userconf.set('DATADIR_RZ', rizin_datdir_rz) -endif +userconf.set('LIBDIR', rizin_libdir) +userconf.set('INCLUDEDIR', rizin_incdir) +userconf.set('DATADIR_RZ', rizin_datdir_rz) is_ppc = host_machine.cpu_family() == 'ppc' or host_machine.cpu_family() == 'ppc64' userconf.set10('HAVE_JEMALLOC', host_machine.system() != 'windows' and (host_machine.system() != 'darwin' or not is_ppc)) -userconf.set('DATADIR', rizin_prefix / rizin_datdir) -userconf.set('WWWROOT', rizin_prefix / rizin_wwwroot) +userconf.set('DATADIR', rizin_datdir) +userconf.set('WWWROOT', rizin_wwwroot) userconf.set('SDB', rizin_sdb) userconf.set('ZIGNS', rizin_zigns) userconf.set('THEMES', rizin_themes) diff --git a/meson_options.txt b/meson_options.txt index 0bfca27af6..19908a4b9f 100644 --- a/meson_options.txt +++ b/meson_options.txt @@ -5,6 +5,7 @@ option('static_runtime', type: 'boolean', value: false, description: 'Set to tru option('local', type: 'feature', value: 'auto', description: 'Adds support for local/side-by-side installation (sets rpath if needed)') option('blob', type: 'boolean', value: false, description: 'Compile just one binary which dispatch to the right handlers based on the name used to call it') option('subprojects_check', type: 'boolean', value: true, description: 'Check if git subprojects are up-to-date. Might be useful to disable this when developing on a different subproject version') +option('portable', type: 'boolean', value: false, description: 'Make rizin installation moveable, by using relative paths instead of absolute ones') option('rizin_wwwroot', type: 'string', value: '', description: 'Install path for www files') option('rizin_sdb', type: 'string', value: '', description: '') @@ -24,7 +25,7 @@ option('use_sys_capstone', type: 'feature', value: 'disabled') option('use_capstone_version', type: 'combo', choices: ['v3', 'v4', 'next', 'bundled'], value: 'bundled', description: 'Specify which version of capstone to use') option('use_sys_magic', type: 'feature', value: 'disabled') option('use_sys_libzip', type: 'feature', value: 'disabled') -option('use_sys_libzip_openssl', type: 'boolean', value: true, description: 'Whether to use or not system openssl dependency to build libzip') +option('use_sys_libzip_openssl', type: 'boolean', value: false, description: 'Whether to use or not system openssl dependency to build libzip') option('use_sys_zlib', type: 'feature', value: 'disabled') option('use_sys_lz4', type: 'feature', value: 'disabled') option('use_sys_xxhash', type: 'feature', value: 'disabled')