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.
This commit is contained in:
Riccardo Schirone 2021-02-24 11:15:50 +01:00 committed by Anton Kochkov
parent aa6c11292b
commit 53b4537160
15 changed files with 65 additions and 59 deletions

View file

@ -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) {

View file

@ -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");

View file

@ -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;

View file

@ -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;
}
}

View file

@ -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@"

View file

@ -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);

View file

@ -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;
}

View file

@ -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;

View file

@ -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);

View file

@ -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 },

View file

@ -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__

View file

@ -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);

View file

@ -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);
}

View file

@ -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)

View file

@ -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')