-
Notifications
You must be signed in to change notification settings - Fork 1.7k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
26 changed files
with
1,307 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
--- | ||
AlignConsecutiveAssignments: 'true' | ||
AlignConsecutiveDeclarations: 'true' | ||
AlignOperands: 'true' | ||
AlignTrailingComments: 'true' | ||
PointerAlignment: Left | ||
UseTab: Never | ||
|
||
... |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
/*build* | ||
!meson.build |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,93 @@ | ||
#include "common.h" | ||
|
||
#include <libgen.h> | ||
#include <stdio.h> | ||
#include <stdlib.h> | ||
#include <string.h> | ||
|
||
int g_verbose; | ||
|
||
void info_autofill_paths(AppRunInfo_t* info, const char* exe_name) { | ||
if (!info) { | ||
DIE("invalid argument to info_autofill_paths"); | ||
} | ||
|
||
if (!info->appdir && exe_name) { | ||
// First sanity check that we are run in an environment set by AppRun | ||
info->appdir = getenv("APPDIR"); | ||
if (!info->appdir) { | ||
LOG("Wrapper %s run without AppRun", exe_name); | ||
info->appdir = dirname(realpath("/proc/self/exe", NULL)); | ||
|
||
// Calculate the appdir root | ||
int components = 1; | ||
for (const char* c = FAKEBIN; *c; c++) { | ||
if (*c == '/') { | ||
components++; | ||
} | ||
} | ||
|
||
for (int i = 0; i < components; i++) { | ||
info->appdir = dirname(info->appdir); | ||
} | ||
} | ||
} | ||
|
||
if (!info->appdir) { | ||
DIE("info->appdir was not set or could not be computed"); | ||
} | ||
|
||
info->path = absolute(info, FAKEBIN); | ||
info->ld_linux = absolute(info, "usr/lib/ld-linux.so"); | ||
info->pythonhome = absolute(info, "usr"); | ||
|
||
if (exe_name) { | ||
char* bin_dir = absolute(info, "usr/bin"); | ||
info->exe_path = absolute_raw(bin_dir, exe_name); | ||
free(bin_dir); | ||
} | ||
} | ||
|
||
void logArgs(char** args) { | ||
if (!g_verbose) { | ||
return; | ||
} | ||
|
||
int counter = 0; | ||
printf("\nArguments:\n"); | ||
counter = 0; | ||
while (1) { | ||
if (!args[counter]) { | ||
break; | ||
} | ||
printf(" %2d: %s\n", counter, args[counter]); | ||
counter++; | ||
} | ||
|
||
printf("\n"); | ||
fflush(stdout); | ||
} | ||
|
||
char* absolute_raw(const char *base, const char* relpath) { | ||
const size_t absLen = strlen(base) + strlen(relpath) + 2; | ||
char* abs = malloc(sizeof(char) * absLen); | ||
snprintf(abs, absLen, "%s/%s", base, relpath); | ||
return abs; | ||
} | ||
|
||
char* absolute(AppRunInfo_t* info, const char* relpath) { | ||
return absolute_raw(info->appdir, relpath); | ||
} | ||
|
||
void envPrepend(const char* var, const char* val) { | ||
char* curr = getenv(var); | ||
if (!curr) { | ||
setenv(var, val, 1); | ||
return; | ||
} | ||
|
||
const size_t len = strlen(var) + strlen(val) + strlen(curr) + 3; | ||
char* res = malloc(sizeof(char) * len); | ||
snprintf(res, len, "%s=%s:%s", var, val, curr); | ||
putenv(res); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
#pragma once | ||
|
||
// Some global defines to enable functions | ||
#define _XOPEN_SOURCE 500 | ||
#define _DEFAULT_SOURCE | ||
#define _BSD_SOURCE | ||
#define _GNU_SOURCE | ||
|
||
extern int g_verbose; | ||
|
||
#define LOG(fmt, ...) \ | ||
if (g_verbose) { \ | ||
printf(fmt "\n", ##__VA_ARGS__); \ | ||
fflush(stdout); \ | ||
} | ||
|
||
#define DIE(fmt, ...) \ | ||
{ \ | ||
fprintf(stderr, "\x1b[31;1mFATAL ERROR:\x1b[0;1m " fmt "\x1b[0m\n", \ | ||
##__VA_ARGS__); \ | ||
fflush(stderr); \ | ||
exit(1); \ | ||
} | ||
|
||
typedef struct AppRunInfo { | ||
char* appdir; | ||
char* appimage_path; | ||
|
||
// basic path inf | ||
char* exe_path; | ||
char* path; | ||
char* ld_linux; | ||
char* pythonhome; | ||
} AppRunInfo_t; | ||
|
||
void info_autofill_paths(AppRunInfo_t* inf, const char* exe_name); | ||
|
||
char* absolute_raw(const char *base, const char* relpath); | ||
char* absolute(AppRunInfo_t* inf, const char* relpath); | ||
void envPrepend(const char* var, const char* val); | ||
|
||
void logArgs(char** args); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
project('apprun', ['c'], | ||
default_options: [ | ||
'warning_level=3', | ||
'optimization=s', | ||
'werror=true', | ||
'debug=false', | ||
'strip=true', | ||
'b_lto=true', | ||
'prefix=/', | ||
], | ||
version: '1.0', | ||
) | ||
|
||
fakebin_dir = 'fakebin' | ||
c_flags = [ | ||
'-Wno-pedantic', | ||
'-DAPPRUN_VERSION="@0@"'.format(meson.project_version()), | ||
'-DFAKEBIN="@0@"'.format(fakebin_dir), | ||
] | ||
link_flags = ['-static'] | ||
|
||
common = static_library('common', ['common.c'], c_args : c_flags) | ||
|
||
wrappers = { | ||
'meson': ['-DIS_PYTHON_SCRIPT=1'], | ||
'ninja': [], | ||
#'cmake': [], | ||
'pkgconf': [], | ||
'python3': [], | ||
} | ||
|
||
foreach name, extra_flags : wrappers | ||
base_flags = ['-DREAL_EXE="' + name + '"'] | ||
|
||
executable(name, ['wrapper.c'], | ||
link_with: [common], | ||
c_args: c_flags + base_flags + extra_flags, | ||
link_args: link_flags, | ||
install: true, | ||
install_dir: fakebin_dir | ||
) | ||
endforeach |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
#include "common.h" | ||
|
||
#include <stdio.h> | ||
#include <stdlib.h> | ||
#include <string.h> | ||
#include <unistd.h> | ||
|
||
// Assume that IS_PYTHON_SCRIPT is either 0 or 1 | ||
#ifndef IS_PYTHON_SCRIPT | ||
#define IS_PYTHON_SCRIPT 0 | ||
#endif | ||
|
||
#ifndef STATICALLY_LINKED | ||
#define STATICALLY_LINKED 0 | ||
#endif | ||
|
||
int main(int argc, char* argv[]) { | ||
AppRunInfo_t info; | ||
char* args[argc + 3]; | ||
int counter; | ||
|
||
g_verbose = 0; | ||
|
||
memset(&info, 0, sizeof(info)); | ||
memset(&args, 0, sizeof(args)); | ||
|
||
// Check for verbose output | ||
char* verbose = getenv("VERBOSE"); | ||
if (verbose && verbose[0] != '0') { | ||
g_verbose = 1; | ||
} | ||
|
||
info_autofill_paths(&info, REAL_EXE); | ||
|
||
LOG("Meson exe wrapper " APPRUN_VERSION); | ||
LOG("Running " REAL_EXE); | ||
LOG("Extracted AppDir: %s", info.appdir); | ||
LOG("Real exe location: %s", info.exe_path); | ||
LOG("PATH fragment: %s", info.path); | ||
LOG("Is Python script: %d", IS_PYTHON_SCRIPT); | ||
LOG("Statically linked: %d", STATICALLY_LINKED); | ||
|
||
// Set the commandline arguments for exeve | ||
// Again, IS_PYTHON_SCRIPT and STATICALLY_LINKED must be either 0 or 1 | ||
counter = 2 + IS_PYTHON_SCRIPT - STATICALLY_LINKED; | ||
for (int i = 1; i < argc; i++) { | ||
args[counter++] = argv[i]; | ||
} | ||
|
||
args[counter++] = NULL; | ||
|
||
#if IS_PYTHON_SCRIPT | ||
args[0] = info.ld_linux; | ||
args[1] = absolute(&info, "usr/bin/python3"); | ||
args[2] = info.exe_path; | ||
#elif STATICALLY_LINKED | ||
args[0] = info.exe_path; | ||
#else | ||
args[0] = info.ld_linux; | ||
args[1] = info.exe_path; | ||
#endif | ||
|
||
// Set the env vars | ||
envPrepend("PATH", info.path); | ||
setenv("PYTHONHOME", info.pythonhome, 1); | ||
putenv("PYTHONDONTWRITEBYTECODE=1"); | ||
|
||
logArgs(args); | ||
|
||
if (execv(args[0], args) != 0) { | ||
DIE("execv failed"); | ||
} | ||
|
||
// We are technically leaking memory here, but all memory is freed once the | ||
// program exits anyway... | ||
return 0; | ||
} |
Oops, something went wrong.