Skip to content

Commit acd3efa

Browse files
committed
feat: add Linux launcher binary
Add linux/launcher.c which: - Locates and dlopen's libSimpleGraphic.so from its own directory - Resolves the Lua script path to absolute (so basePath inside the engine resolves correctly) - Sets SG_BASE_PATH to <pob_root>/runtime so the engine finds its data files (fonts, config) - Sets LUA_PATH to include <pob_root>/runtime/lua - Sets LUA_CPATH to include the build directory for Lua C modules - Calls RunLuaFileAsWin(argc-1, argv+1) Usage: ./PathOfBuilding src/Launch.lua
1 parent 6b7e507 commit acd3efa

2 files changed

Lines changed: 110 additions & 0 deletions

File tree

CMakeLists.txt

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -412,3 +412,10 @@ target_link_libraries(lzip
412412

413413
install(TARGETS lzip RUNTIME DESTINATION ".")
414414
install(FILES $<TARGET_RUNTIME_DLLS:lzip> DESTINATION ".")
415+
416+
# Linux launcher
417+
if (CMAKE_SYSTEM_NAME MATCHES "Linux")
418+
add_executable(PathOfBuilding linux/launcher.c)
419+
target_link_libraries(PathOfBuilding PRIVATE ${CMAKE_DL_LIBS})
420+
install(TARGETS PathOfBuilding RUNTIME DESTINATION ".")
421+
endif()

linux/launcher.c

Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
// Linux launcher for SimpleGraphic / Path of Building
2+
// Loads libSimpleGraphic.so from the same directory and calls RunLuaFileAsWin.
3+
4+
#include <dlfcn.h>
5+
#include <libgen.h>
6+
#include <limits.h>
7+
#include <stdio.h>
8+
#include <stdlib.h>
9+
#include <string.h>
10+
#include <unistd.h>
11+
12+
typedef int (*RunLuaFileAsWin_t)(int argc, char** argv);
13+
14+
int main(int argc, char** argv)
15+
{
16+
// Resolve our own executable's directory
17+
char exePath[PATH_MAX];
18+
ssize_t len = readlink("/proc/self/exe", exePath, sizeof(exePath) - 1);
19+
if (len == -1) {
20+
perror("readlink /proc/self/exe");
21+
return 1;
22+
}
23+
exePath[len] = '\0';
24+
25+
char exeDir[PATH_MAX];
26+
strncpy(exeDir, exePath, sizeof(exeDir));
27+
char* dir = dirname(exeDir);
28+
29+
// Load libSimpleGraphic.so from the same directory
30+
char libPath[PATH_MAX];
31+
snprintf(libPath, sizeof(libPath), "%s/libSimpleGraphic.so", dir);
32+
33+
void* lib = dlopen(libPath, RTLD_LAZY | RTLD_GLOBAL);
34+
if (!lib) {
35+
fprintf(stderr, "Failed to load %s: %s\n", libPath, dlerror());
36+
return 1;
37+
}
38+
39+
RunLuaFileAsWin_t runLua = (RunLuaFileAsWin_t)dlsym(lib, "RunLuaFileAsWin");
40+
if (!runLua) {
41+
fprintf(stderr, "dlsym RunLuaFileAsWin: %s\n", dlerror());
42+
return 1;
43+
}
44+
45+
// argv[0] for RunLuaFileAsWin must be the Lua script path.
46+
// Skip our own argv[0] (the launcher binary).
47+
if (argc < 2) {
48+
fprintf(stderr, "Usage: %s <script.lua> [args...]\n", argv[0]);
49+
return 1;
50+
}
51+
52+
// Resolve script path to absolute so basePath resolution inside SimpleGraphic works correctly.
53+
// basePath is derived from /proc/self/exe (the launcher's dir), so a relative script path
54+
// would be resolved relative to the build dir rather than the current working directory.
55+
char scriptAbs[PATH_MAX];
56+
if (realpath(argv[1], scriptAbs) == NULL) {
57+
perror(argv[1]);
58+
return 1;
59+
}
60+
argv[1] = scriptAbs;
61+
62+
// Derive the PoB root from the script location:
63+
// script = <pob_root>/src/Launch.lua → script_dir = <pob_root>/src → pob_root = <pob_root>
64+
// (the runtime Lua modules live at <pob_root>/runtime/lua/)
65+
char scriptDirBuf[PATH_MAX];
66+
strncpy(scriptDirBuf, scriptAbs, sizeof(scriptDirBuf));
67+
char* scriptDir = dirname(scriptDirBuf);
68+
69+
char pobRoot[PATH_MAX];
70+
snprintf(pobRoot, sizeof(pobRoot), "%s/..", scriptDir);
71+
char pobRootAbs[PATH_MAX];
72+
if (!realpath(pobRoot, pobRootAbs))
73+
strncpy(pobRootAbs, pobRoot, sizeof(pobRootAbs));
74+
75+
// Tell SimpleGraphic where the runtime data (fonts, etc.) lives.
76+
// On Windows the exe lives in runtime/ so basePath == runtime/.
77+
// On Linux the exe is in build/, so we must point it to the right place.
78+
if (!getenv("SG_BASE_PATH")) {
79+
char sgBasePath[PATH_MAX];
80+
snprintf(sgBasePath, sizeof(sgBasePath), "%s/runtime", pobRootAbs);
81+
setenv("SG_BASE_PATH", sgBasePath, 1);
82+
}
83+
84+
// Set LUA_PATH to include the PoB runtime Lua directory.
85+
// Work around pob-wide-crt.patch bug: _lua_getenvcopy() calls strdup(getenv(name))
86+
// which crashes on NULL, so we always set these even if we're not overriding.
87+
if (!getenv("LUA_PATH")) {
88+
char luaPath[PATH_MAX * 4];
89+
snprintf(luaPath, sizeof(luaPath),
90+
"%s/runtime/lua/?.lua;%s/runtime/lua/?/init.lua;;",
91+
pobRootAbs, pobRootAbs);
92+
setenv("LUA_PATH", luaPath, 1);
93+
}
94+
95+
// Set LUA_CPATH to include the build dir (where our .so modules live without lib prefix).
96+
if (!getenv("LUA_CPATH")) {
97+
char luaCPath[PATH_MAX * 4];
98+
snprintf(luaCPath, sizeof(luaCPath), "%s/?.so;;", dir);
99+
setenv("LUA_CPATH", luaCPath, 1);
100+
}
101+
102+
return runLua(argc - 1, argv + 1);
103+
}

0 commit comments

Comments
 (0)