#include "util.h" #include "../run-python.h" #include #include #include #define EXPORT __attribute__((visibility("default"))) #define EXE "@executable_path/.." static const char *env_vars[] = { ENV_VARS }; static const char *env_var_vals[] = { ENV_VAR_VALS }; static void set_env_vars(const char* contents_path) { char buf[3*PATH_MAX]; const char *env_var, *val; for (size_t i = 0; i < arraysz(env_vars); i++) { env_var = env_vars[i]; val = env_var_vals[i]; if (strstr(val, EXE) == val && strlen(val) >= sizeof(EXE)) { snprintf(buf, sizeof(buf) - 1, "%s%s", contents_path, val + sizeof(EXE) - 1); setenv(env_var, buf, 1); } else setenv(env_var, val, 1); } return; } static void get_paths() { char pathbuf[PROC_PIDPATHINFO_MAXSIZE], realpath_buf[PROC_PIDPATHINFO_MAXSIZE * 5]; pid_t pid = getpid(); int ret = proc_pidpath(pid, pathbuf, sizeof(pathbuf)); if (ret <= 0) fatal("failed to get executable path for current pid with error: %s", strerror(errno)); char *path = realpath(pathbuf, realpath_buf); if (path == NULL) fatal("failed to get realpath for executable path with error: %s", strerror(errno)); decode_char_buf(path, interpreter_data.exe_path); for (unsigned i = 0; i < 3; i++) { char *t = rindex(path, '/'); if (t == NULL) fatal("Failed to determine bundle path."); >>>>>>> The Apple build is working *t = '\0'; } if (strstr(path, "/calibre.app/Contents/") != NULL) { // We are one of the duplicate executables created to workaround codesign's limitations for (unsigned i = 0; i < 2; i++) { char *t = rindex(path, '/'); if (t == NULL) fatal("Failed to resolve bundle path in dummy executable"); *t = '\0'; } } #define cat_literal(func, path, literal) func(path, literal, arraysz(literal) - 1) cat_literal(strncat, path, "/Contents"); set_env_vars(path); decode_char_buf(path, interpreter_data.bundle_resource_path); #define set_path(which, fmt, ...) swprintf(interpreter_data.which, arraysz(interpreter_data.which), fmt, interpreter_data.bundle_resource_path, __VA_ARGS__) set_path(python_home_path, L"%ls/Resources/Python", NULL); set_path(frameworks_path, L"%ls/Frameworks", NULL); set_path(python_lib_path, L"%ls/Resources/Python/lib/python%d.%d", PY_VERSION_MAJOR, PY_VERSION_MINOR); set_path(extensions_path, L"%ls/Frameworks/plugins", NULL); set_path(resources_path, L"%ls/Resources/resources", NULL); set_path(executables_path, L"%ls/MacOS", NULL); #undef set_path cat_literal(wcsncat, interpreter_data.bundle_resource_path, L"/Resources"); #undef cat_literal } EXPORT void run(const wchar_t *program, const wchar_t *module, const wchar_t *function, bool gui_app, int argc, char * const *argv) { interpreter_data.argc = argc; interpreter_data.argv = argv; interpreter_data.basename = program; interpreter_data.module = module; interpreter_data.function = function; pre_initialize_interpreter(gui_app); get_paths(); run_interpreter(); }