Porting to linux
This commit is contained in:
86
build.sh
86
build.sh
@@ -1,6 +1,84 @@
|
||||
mkdir build
|
||||
pushd build
|
||||
clang -o build_tool.exe ../src/build_tool/build_tool_main.cpp -fdiagnostics-absolute-paths -g -nostdlib++ -fno-exceptions
|
||||
popd
|
||||
cd build
|
||||
|
||||
build/build_tool.exe
|
||||
if [ ! -f "lbaselib.o" ]; then
|
||||
clang -g -I../src/external/lua/src -I../src/external/glad \
|
||||
../src/external/lua/src/lbaselib.c \
|
||||
../src/external/lua/src/lctype.c \
|
||||
../src/external/lua/src/ldo.c \
|
||||
../src/external/lua/src/lgc.c \
|
||||
../src/external/lua/src/liolib.c \
|
||||
../src/external/lua/src/lmem.c \
|
||||
../src/external/lua/src/lopcodes.c \
|
||||
../src/external/lua/src/lstate.c \
|
||||
../src/external/lua/src/ltable.c \
|
||||
../src/external/lua/src/lundump.c \
|
||||
../src/external/lua/src/lzio.c \
|
||||
../src/external/lua/src/lapi.c \
|
||||
../src/external/lua/src/lcode.c \
|
||||
../src/external/lua/src/ldblib.c \
|
||||
../src/external/lua/src/ldump.c \
|
||||
../src/external/lua/src/llex.c \
|
||||
../src/external/lua/src/loadlib.c \
|
||||
../src/external/lua/src/loslib.c \
|
||||
../src/external/lua/src/lstring.c \
|
||||
../src/external/lua/src/ltablib.c \
|
||||
../src/external/lua/src/lutf8lib.c \
|
||||
../src/external/lua/src/lauxlib.c \
|
||||
../src/external/lua/src/lcorolib.c \
|
||||
../src/external/lua/src/ldebug.c \
|
||||
../src/external/lua/src/lfunc.c \
|
||||
../src/external/lua/src/linit.c \
|
||||
../src/external/lua/src/lmathlib.c \
|
||||
../src/external/lua/src/lobject.c \
|
||||
../src/external/lua/src/lparser.c \
|
||||
../src/external/lua/src/lstrlib.c \
|
||||
../src/external/lua/src/ltm.c \
|
||||
../src/external/lua/src/lvm.c \
|
||||
../src/external/glad/glad.c \
|
||||
-c
|
||||
fi
|
||||
|
||||
clang ../src/text_editor/text_editor.cpp ../src/basic/unix.cpp \
|
||||
-o te_linux.exe \
|
||||
-nostdlib++ -fno-exceptions -fdiagnostics-absolute-paths -g \
|
||||
-Wno-writable-strings \
|
||||
-I../src/external/SDL/include \
|
||||
-I../src/external/lua/src \
|
||||
-I../src/external/glad \
|
||||
-I../src/ \
|
||||
-lm \
|
||||
../src/external/SDL/build/libSDL3.a \
|
||||
lbaselib.o \
|
||||
lctype.o \
|
||||
ldo.o \
|
||||
lgc.o \
|
||||
liolib.o \
|
||||
lmem.o \
|
||||
lopcodes.o \
|
||||
lstate.o \
|
||||
ltable.o \
|
||||
lundump.o \
|
||||
lzio.o \
|
||||
lapi.o \
|
||||
lcode.o \
|
||||
ldblib.o \
|
||||
ldump.o \
|
||||
llex.o \
|
||||
loadlib.o \
|
||||
loslib.o \
|
||||
lstring.o \
|
||||
ltablib.o \
|
||||
lutf8lib.o \
|
||||
lauxlib.o \
|
||||
lcorolib.o \
|
||||
ldebug.o \
|
||||
lfunc.o \
|
||||
linit.o \
|
||||
lmathlib.o \
|
||||
lobject.o \
|
||||
lparser.o \
|
||||
lstrlib.o \
|
||||
ltm.o \
|
||||
lvm.o \
|
||||
glad.o \
|
||||
|
||||
@@ -147,7 +147,7 @@ int CompileTextEditorLinux() {
|
||||
For2(lib, libs) For(lib.include_paths) cmd.add(Fmt("-I %.*s", S8_Expand(it)));
|
||||
For2(lib, libs) For(lib.defines) cmd.add(it);
|
||||
// cmd.add("-L../src/external/SDL/build/");
|
||||
cmd.add("-I../src/external/SDL/build/include");
|
||||
cmd.add("-I../src/external/SDL/include");
|
||||
cmd.add("-lm");
|
||||
cmd.add("../src/external/SDL/build/libSDL3.a");
|
||||
For2(lib, libs) For(lib.link) cmd.add(it);
|
||||
@@ -294,7 +294,7 @@ void GenerateConfig() {
|
||||
style.add({"IndentSize", "4"});
|
||||
style.add({"FontSize", "15"});
|
||||
style.add({"FontFilter", "0"}); // nearest = 0, linear = 1 - seems like nearest always better?
|
||||
style.add({"Font", "C:/Windows/Fonts/consola.ttf"});
|
||||
style.add({"Font", "/home/krz/text_editor/package/CascadiaMono.ttf"});
|
||||
style.add({"VCVarsall", "C:/Program Files/Microsoft Visual Studio/2022/Community/VC/Auxiliary/Build/vcvars64.bat"});
|
||||
|
||||
{
|
||||
|
||||
@@ -795,6 +795,7 @@ String SkipToLastSlash(String s);
|
||||
String SkipToLastPeriod(String s);
|
||||
String Copy(Allocator allocator, String string);
|
||||
Int GetSize(Array<String> array);
|
||||
Array<String> Split(Allocator allocator, String string, String delimiter);
|
||||
/*
|
||||
Hash table implementation:
|
||||
Pointers to values
|
||||
|
||||
@@ -46,7 +46,7 @@ struct Process {
|
||||
Process SpawnProcess(String command_line, String working_dir, String write_stdin = {}, Array<String> enviroment = {});
|
||||
bool IsValid(Process *process);
|
||||
void KillProcess(Process *process);
|
||||
String PollStdout(Allocator allocator, Process *process);
|
||||
String PollStdout(Allocator allocator, Process *process, bool force_read);
|
||||
void WriteStdin(Process *process, String string);
|
||||
void CloseStdin(Process *process);
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/syscall.h>
|
||||
#include <sys/wait.h>
|
||||
#include <sys/mman.h>
|
||||
#include <linux/limits.h>
|
||||
#include <unistd.h>
|
||||
@@ -11,6 +12,9 @@
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <spawn.h>
|
||||
#include <poll.h>
|
||||
|
||||
|
||||
void (*Error)(const char *, ...);
|
||||
|
||||
@@ -212,28 +216,204 @@ FileIter IterateFiles(Allocator alo, String path) {
|
||||
return it;
|
||||
}
|
||||
|
||||
// struct Process {
|
||||
// bool is_valid;
|
||||
// int exit_code;
|
||||
// char platform[6 * 8];
|
||||
//
|
||||
// int64_t view_id; // text editor view
|
||||
// bool scroll_to_end;
|
||||
// };
|
||||
|
||||
struct UnixProcess {
|
||||
pid_t pid;
|
||||
int child_stdout_read;
|
||||
int stdin_write;
|
||||
};
|
||||
|
||||
Array<char *> SplitCommand(Allocator allocator, String command_line) {
|
||||
Array<char *> cmd = {allocator};
|
||||
|
||||
String curr = {};
|
||||
for (int i = 0; i < command_line.len; i += 1) {
|
||||
if (command_line.data[i] == ' ') {
|
||||
if (curr.len > 0) {
|
||||
Add(&cmd, Copy(allocator, curr).data);
|
||||
curr = {};
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if (curr.len == 0) {
|
||||
curr.data = command_line.data + i;
|
||||
}
|
||||
curr.len += 1;
|
||||
}
|
||||
|
||||
if (curr.len > 0) {
|
||||
Add(&cmd, Copy(allocator, curr).data);
|
||||
}
|
||||
|
||||
return cmd;
|
||||
}
|
||||
|
||||
Process SpawnProcess(String command_line, String working_dir, String write_stdin, Array<String> enviroment) {
|
||||
return {};
|
||||
const int PIPE_READ = 0;
|
||||
const int PIPE_WRITE = 1;
|
||||
bool error = false;
|
||||
|
||||
Scratch scratch;
|
||||
Process process = {};
|
||||
UnixProcess *plat = (UnixProcess *)&process.platform;
|
||||
Array<char *> args = SplitCommand(scratch, command_line);
|
||||
Array<char *> env = {scratch};
|
||||
|
||||
For (enviroment) {
|
||||
Add(&env, Copy(scratch, it).data);
|
||||
}
|
||||
|
||||
int stdout_desc[2] = {};
|
||||
int stdin_desc[2] = {};
|
||||
posix_spawn_file_actions_t actions = {};
|
||||
|
||||
if (posix_spawn_file_actions_init(&actions) != 0) {
|
||||
perror("posix_spawn_file_actions_init");
|
||||
return process;
|
||||
}
|
||||
defer {
|
||||
posix_spawn_file_actions_destroy(&actions);
|
||||
};
|
||||
|
||||
if (pipe(stdout_desc) == -1) {
|
||||
perror("pipe");
|
||||
return process;
|
||||
}
|
||||
defer {
|
||||
if (error) {
|
||||
close(stdout_desc[PIPE_READ]);
|
||||
close(stdout_desc[PIPE_WRITE]);
|
||||
} else {
|
||||
close(stdout_desc[PIPE_WRITE]);
|
||||
}
|
||||
};
|
||||
|
||||
if (pipe(stdin_desc) == -1) {
|
||||
perror("pipe");
|
||||
return process;
|
||||
}
|
||||
defer {
|
||||
if (error) {
|
||||
close(stdin_desc[PIPE_READ]);
|
||||
close(stdin_desc[PIPE_WRITE]);
|
||||
} else {
|
||||
close(stdin_desc[PIPE_READ]);
|
||||
}
|
||||
};
|
||||
|
||||
error = posix_spawn_file_actions_addclose(&actions, stdout_desc[PIPE_READ]) != 0;
|
||||
if (error) {
|
||||
perror("posix_spawn_file_actions_addclose");
|
||||
return process;
|
||||
}
|
||||
|
||||
error = posix_spawn_file_actions_adddup2(&actions, stdout_desc[PIPE_WRITE], STDOUT_FILENO) != 0;
|
||||
if (error) {
|
||||
perror("posix_spawn_file_actions_adddup2 STDOUT_FILENO");
|
||||
return process;
|
||||
}
|
||||
|
||||
error = posix_spawn_file_actions_adddup2(&actions, stdout_desc[PIPE_WRITE], STDERR_FILENO) != 0;
|
||||
if (error) {
|
||||
perror("posix_spawn_file_actions_adddup2 STDERR_FILENO");
|
||||
return process;
|
||||
}
|
||||
|
||||
error = posix_spawn_file_actions_addclose(&actions, stdin_desc[PIPE_WRITE]) != 0;
|
||||
if (error) {
|
||||
perror("posix_spawn_file_actions_addclose");
|
||||
return process;
|
||||
}
|
||||
|
||||
error = posix_spawn_file_actions_adddup2(&actions, stdin_desc[PIPE_READ], STDIN_FILENO) != 0;
|
||||
if (error) {
|
||||
perror("posix_spawn_file_actions_adddup2 STDIN_FILENO");
|
||||
return process;
|
||||
}
|
||||
|
||||
pid_t process_pid = 0;
|
||||
error = posix_spawnp(&process_pid, args[0], &actions, NULL, args.data, env.data) != 0;
|
||||
if (error) {
|
||||
perror("failed to create process\n");
|
||||
return process;
|
||||
}
|
||||
|
||||
|
||||
process.is_valid = true;
|
||||
plat->child_stdout_read = stdout_desc[PIPE_READ];
|
||||
plat->stdin_write = stdin_desc[PIPE_WRITE];
|
||||
|
||||
if (write_stdin.len) {
|
||||
WriteStdin(&process, write_stdin);
|
||||
CloseStdin(&process);
|
||||
}
|
||||
|
||||
|
||||
|
||||
return process;
|
||||
}
|
||||
|
||||
bool IsValid(Process *process) {
|
||||
UnixProcess *plat = (UnixProcess *)&process->platform;
|
||||
if (process->is_valid == false) {
|
||||
return false;
|
||||
}
|
||||
|
||||
int status = 0;
|
||||
pid_t result = waitpid(plat->pid, &status, WNOHANG);
|
||||
if (result >= 0) {
|
||||
if (WIFSIGNALED(status) || WIFEXITED(status)) {
|
||||
process->exit_code = WEXITSTATUS(status);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void KillProcess(Process *process) {
|
||||
|
||||
Assert(process->is_valid);
|
||||
UnixProcess *plat = (UnixProcess *)process->platform;
|
||||
kill(plat->pid, SIGKILL);
|
||||
process->exit_code = -1;
|
||||
}
|
||||
|
||||
String PollStdout(Allocator allocator, Process *process) {
|
||||
return "";
|
||||
String PollStdout(Allocator allocator, Process *process, bool force_read) {
|
||||
Assert(process->is_valid);
|
||||
UnixProcess *plat = (UnixProcess *)process->platform;
|
||||
|
||||
String result = {};
|
||||
result.data = AllocArray(allocator, char, 16 * 4096);
|
||||
|
||||
pollfd p = {};
|
||||
p.fd = plat->child_stdout_read;
|
||||
p.events = POLLIN;
|
||||
int res = poll(&p, 1, 0);
|
||||
if (res == 1 || force_read) {
|
||||
result.len = read(plat->child_stdout_read, result.data, 4 * 4096);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
void WriteStdin(Process *process, String string) {
|
||||
if (string.len == 0) return;
|
||||
Assert(process->is_valid);
|
||||
|
||||
UnixProcess *plat = (UnixProcess *)process->platform;
|
||||
ssize_t size = write(plat->stdin_write, string.data, string.len);
|
||||
|
||||
Assert(size == string.len);
|
||||
}
|
||||
|
||||
void CloseStdin(Process *process) {
|
||||
UnixProcess *plat = (UnixProcess *)process->platform;
|
||||
close(plat->stdin_write);
|
||||
}
|
||||
|
||||
@@ -458,7 +458,7 @@ void KillProcess(Process *process) {
|
||||
process->exit_code = -1;
|
||||
}
|
||||
|
||||
String PollStdout(Allocator allocator, Process *process) {
|
||||
String PollStdout(Allocator allocator, Process *process, bool force_read) {
|
||||
Assert(process->is_valid);
|
||||
Win32Process *p = (Win32Process *)process->platform;
|
||||
|
||||
|
||||
@@ -66,7 +66,7 @@ Style.DrawScrollbar = 1
|
||||
Style.IndentSize = 4
|
||||
Style.FontSize = 15
|
||||
Style.FontFilter = 0
|
||||
Style.Font = "C:/Windows/Fonts/consola.ttf"
|
||||
Style.Font = "/home/krz/text_editor/package/CascadiaMono.ttf"
|
||||
Style.VCVarsall = "C:/Program Files/Microsoft Visual Studio/2022/Community/VC/Auxiliary/Build/vcvars64.bat"
|
||||
Style.TrimWhitespaceOnSave = true
|
||||
Style.ClangFormatOnSave = false
|
||||
|
||||
@@ -63,5 +63,5 @@ Int StyleDrawScrollbar = 1;
|
||||
Int StyleIndentSize = 4;
|
||||
Int StyleFontSize = 15;
|
||||
Int StyleFontFilter = 0;
|
||||
String StyleFont = "C:/Windows/Fonts/consola.ttf";
|
||||
String StyleFont = "/home/krz/text_editor/package/CascadiaMono.ttf";
|
||||
String StyleVCVarsall = "C:/Program Files/Microsoft Visual Studio/2022/Community/VC/Auxiliary/Build/vcvars64.bat";
|
||||
@@ -117,8 +117,8 @@ int Lua_KillWindow(lua_State *L) {
|
||||
static void HookLuaForceExit(lua_State *L, lua_Debug *debug) {
|
||||
SDL_PumpEvents();
|
||||
int numkeys = 0;
|
||||
const uint8_t *keys = SDL_GetKeyboardState(&numkeys);
|
||||
if (keys[SDL_SCANCODE_F9] > 0)
|
||||
const bool *keys = SDL_GetKeyboardState(&numkeys);
|
||||
if (keys[SDL_SCANCODE_F9])
|
||||
luaL_error(L, "lua execution got interrupted");
|
||||
}
|
||||
|
||||
|
||||
@@ -5,23 +5,41 @@ Array<Process> ActiveProcesses = {};
|
||||
// and platform independent one
|
||||
Array<String> Enviroment = {};
|
||||
|
||||
struct UnixProcess {
|
||||
pid_t pid;
|
||||
int child_stdout_read;
|
||||
};
|
||||
|
||||
// WARNING: seems that this maybe can't work reliably?
|
||||
// in case of 'git grep a' it's possible that child process spawns it's own
|
||||
// child process and then it won't print anything because it won't have
|
||||
// the appropriate handles. This happens in this case when git grep calls
|
||||
// 'less' program which errors out and doesn't print anything
|
||||
// @todo: maybe I should ask someone smarter about this!
|
||||
|
||||
|
||||
// @todo: rework to fit both linux and windows!
|
||||
void UpdateProcesses() {
|
||||
IterRemove(ActiveProcesses) {
|
||||
IterRemovePrepare(ActiveProcesses);
|
||||
Scratch scratch;
|
||||
String poll = PollStdout(scratch, &it);
|
||||
View *view = GetView({it.view_id});
|
||||
|
||||
String poll = PollStdout(scratch, &it, false);
|
||||
if (poll.len) {
|
||||
Command_Append(view, poll, it.scroll_to_end);
|
||||
}
|
||||
if (!IsValid(&it)) {
|
||||
for (;;) {
|
||||
String poll = PollStdout(scratch, &it, true);
|
||||
if (poll.len) {
|
||||
Command_Append(view, poll, it.scroll_to_end);
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Command_Append(view, Format(scratch, "process exited with code: %d\n", it.exit_code), it.scroll_to_end);
|
||||
remove_item = true;
|
||||
}
|
||||
@@ -45,7 +63,7 @@ Buffer *ExecAndWait(Allocator allocator, String cmd, String working_dir, String
|
||||
Buffer *temp_buffer = CreateTempBuffer(allocator, 4096 * 4);
|
||||
for (Process process = SpawnProcess(cmd, working_dir, stdin_string, Enviroment); IsValid(&process);) {
|
||||
Scratch scratch(allocator);
|
||||
String poll = PollStdout(scratch, &process);
|
||||
String poll = PollStdout(scratch, &process, true);
|
||||
if (poll.len) RawAppend(temp_buffer, poll);
|
||||
}
|
||||
|
||||
|
||||
@@ -334,7 +334,7 @@ int main(int argc, char **argv)
|
||||
SDL_free(sdl_config_path.data);
|
||||
}
|
||||
|
||||
if (SDL_Init(SDL_INIT_VIDEO) == -1) {
|
||||
if (!SDL_Init(SDL_INIT_VIDEO)) {
|
||||
ReportErrorf("Couldn't initialize SDL! %s", SDL_GetError());
|
||||
return 1;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user