Skip to content

Commit

Permalink
feat: windows build
Browse files Browse the repository at this point in the history
all seems working, just missing headers since we don't yet set them up into the
temporary execution dir. This commit also activates a release of a Windows
x86_64 unsigned binary.
  • Loading branch information
jaromil committed Sep 30, 2024
1 parent 598bc42 commit 823579d
Show file tree
Hide file tree
Showing 5 changed files with 119 additions and 8 deletions.
12 changes: 11 additions & 1 deletion .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ jobs:
build/release-intro.md
- name: Install build deps
run: |
sudo apt install -qy make musl-tools musl-dev upx-ucl
sudo apt install -qy make musl-tools musl-dev upx-ucl gcc-mingw-w64
- name: Build x86_64 with musl-system
run: |
make musl-linux
Expand All @@ -122,6 +122,16 @@ jobs:
name: release-musl-linux-x86_64
path: |
cjit
- name: Build x86_64 with mingw64
run: |
make -f build/win.mk
upx-ucl -q cjit.exe
- name: Upload artifact win64
uses: actions/upload-artifact@v4
with:
name: release-mingw-windows-x86_64
path: |
cjit.exe
- name: Clean for next build
run: make clean

Expand Down
5 changes: 3 additions & 2 deletions build/init.mk
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,15 @@ ifdef CCACHE
cc := ccache ${cc}
endif

CFLAGS ?= -Og -ggdb -DDEBUG=1 -Wall -Wextra -pedantic
CFLAGS ?= -Og -ggdb -DDEBUG=1 -Wall -Wextra

ifdef RELEASE
CFLAGS := -O2 -fomit-frame-pointer
endif

cflags := ${CFLAGS} -Isrc -Ilib/tinycc
cflags += -fstack-protector-all -D_FORTIFY_SOURCE=2 -fno-strict-overflow

cflags_stack_protect := -fstack-protector-all -D_FORTIFY_SOURCE=2 -fno-strict-overflow

SOURCES := src/io.o src/file.o src/cflag.o \
src/cjit.o src/embed-libtcc1.o src/embed-musl-libc.o
Expand Down
18 changes: 18 additions & 0 deletions build/win.mk
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
include build/init.mk

cc := x86_64-w64-mingw32-gcc
ar := x86_64-w64-mingw32-ar
cflags += -DLIBC_MINGW32 -D_GNU_SOURCE
ldadd += -lrpcrt4 -lshlwapi
ldflags += -static-libgcc

all: deps cjit

cjit: ${SOURCES}
$(cc) $(cflags) -o $@ $(SOURCES) ${ldflags} ${ldadd}

deps: lib/tinycc/libtcc.a

tinycc_config += --targetos=WIN32

include build/deps.mk
47 changes: 42 additions & 5 deletions src/cjit.c
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,14 @@
#include <stdbool.h>
#include <errno.h>

#ifndef LIBC_MINGW32
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/wait.h>
#endif

#include <cflag.h>
#include <libtcc.h>
#include <sys/wait.h>
#include <unistd.h>

// from embed-libtcc1 generated from lib/tinycc/libtcc1.a
Expand All @@ -42,6 +44,9 @@ extern long file_size(const char *filename);
extern char* file_load(const char *filename);
extern bool write_to_file(char *path, char *filename, char *buf, unsigned int len);
extern bool rm_recursive(char *path);
#ifdef LIBC_MINGW32
extern char *win32_mkdtemp();
#endif

// from io.c
extern void _out(const char *fmt, ...);
Expand All @@ -52,7 +57,21 @@ void handle_error(void *n, const char *m) {
_err("%s",m);
}

static int cjit_exec(TCCState *TCC, const char *ep, int argc, char **argv)
static int cjit_exec_win(TCCState *TCC, const char *ep, int argc, char **argv) {
int res = 1;
int (*_ep)(int, char**);
_ep = tcc_get_symbol(TCC, ep);
if (!_ep) {
_err("Symbol not found in source: %s","main");
return -1;
}
_err("Execution start\n---");
res = _ep(argc, argv);
return(res);
}

#ifndef LIBC_MINGW32
static int cjit_exec_fork(TCCState *TCC, const char *ep, int argc, char **argv)
{
pid_t pid;
int res = 1;
Expand Down Expand Up @@ -92,6 +111,7 @@ static int cjit_exec(TCCState *TCC, const char *ep, int argc, char **argv)
}
return res;
}
#endif

static int cjit_cli(TCCState *TCC)
{
Expand All @@ -111,6 +131,9 @@ static int cjit_cli(TCCState *TCC)
else
_err("Not running from a terminal though.\n");

#ifdef LIBC_MINGW32
_err("Missing source code argument");
#else
while (1) {
// don't print prompt if we are in a pipe
if (isatty(fileno(stdin)))
Expand Down Expand Up @@ -151,7 +174,11 @@ static int cjit_cli(TCCState *TCC)
_err("Running code\n");
_err("-----------------------------------\n");
#endif
res = cjit_exec(TCC, "main", 0, NULL);
#ifndef LIBC_MINGW32
res = cjit_exec_fork(TCC, "main", 0, NULL);
#else
res = cjit_exec_win(TCC, "main", 0, NULL);
#endif
free(code);
code = NULL;
break;
Expand All @@ -166,6 +193,7 @@ static int cjit_cli(TCCState *TCC)
free(line);
line = NULL;
}
#endif
return res;
}

Expand Down Expand Up @@ -589,11 +617,16 @@ int main(int argc, char **argv) {
tcc_set_error_func(TCC, stderr, handle_error);

// initialize the tmpdir for execution
#ifndef LIBC_MINGW32
tmpdir = mkdtemp(tmptemplate);
#else
tmpdir = win32_mkdtemp();
#endif
if(!tmpdir) {
_err("Error creating temp dir %s: %s",tmptemplate,strerror(errno));
goto endgame;
}
} // else
// _err("Temporary execution dir: %s",tmpdir);
tcc_set_lib_path(TCC,tmpdir);
tcc_add_library_path(TCC,tmpdir);

Expand Down Expand Up @@ -638,7 +671,11 @@ int main(int argc, char **argv) {
goto endgame;
}

res = cjit_exec(TCC, "main", argc, argv);
#ifndef LIBC_MINGW32
res = cjit_exec_fork(TCC, "main", argc, argv);
#else
res = cjit_exec_win(TCC, "main", argc, argv);
#endif

endgame:
// free TCC
Expand Down
45 changes: 45 additions & 0 deletions src/file.c
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,18 @@
#include <stdbool.h>
#include <string.h>
#include <errno.h>
#include <time.h>

#include <ftw.h> // _GNU_SOURCE

#ifdef LIBC_MINGW32
#include <windows.h>
#include <shlwapi.h>
#include <rpc.h>
#pragma comment(lib, "rpcrt4.lib")
#pragma comment(lib, "shlwapi.lib")
#endif

extern void _err(const char *fmt, ...);

// Function to get the length of a file in bytes
Expand Down Expand Up @@ -105,3 +114,39 @@ bool rm_recursive(char *path) {
}
return true;
}

#ifdef LIBC_MINGW32
///////////////
// WINDOWS SHIT
char *win32_mkdtemp() {
static char tempDir[MAX_PATH];
char tempPath[MAX_PATH];
char *filename = "CJIT-XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX";
// Get the temporary path
if (GetTempPath(MAX_PATH, tempPath) == 0) {
_err("Failed to get temporary path");
return NULL;
}
// else
// _err("Temporary path is %s",tempPath);
// randomize the temp dir name
const char charset[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
size_t charset_size = sizeof(charset) - 1;
char *str = &filename[5];
// Seed the random number generator
srand((unsigned int)time(NULL));
for (size_t i = 0; i < 16; i++) {
int key = rand() % charset_size;
*str = charset[key];
str++;
}
*str = '\0'; // Null-terminate the string
PathCombine(tempDir, tempPath, filename);
// Create the temporary directory
if (CreateDirectory(tempDir, NULL) == 0) {
_err("Failed to create temporary dir: %s",tempDir);
return;
}
return(tempDir);
}
#endif

0 comments on commit 823579d

Please sign in to comment.