Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feat/elflibs #95

Merged
merged 9 commits into from
Jan 5, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 0 additions & 3 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -64,9 +64,6 @@ jobs:
runs-on: "ubuntu-latest"
steps:
- uses: actions/checkout@v4
- name: install dependencies
run: |
sudo apt install -yq make gcc xxd
- name: Build x86_64 with Linux
run: |
make linux-x86
Expand Down
5 changes: 4 additions & 1 deletion GNUmakefile
Original file line number Diff line number Diff line change
Expand Up @@ -64,16 +64,19 @@ _: ##

check: ## 🧪 Run all tests using the currently built binary ./cjit
@./test/bats/bin/bats test/cli.bats
@if [ -r .build_done_linux ]; then ./test/bats/bin/bats test/linux.bats; fi
@./test/bats/bin/bats test/windows.bats
@./test/bats/bin/bats test/muntar.bats
@if [ -r .build_done_linux ]; then ./test/bats/bin/bats test/dmon.bats; fi


check-ci: ## 🧪 Run all tests using the currently built binary ./cjit
@./test/bats/bin/bats test/cli.bats
@if [ -r .build_done_linux ]; then ./test/bats/bin/bats test/linux.bats; fi
@./test/bats/bin/bats test/windows.bats
@./test/bats/bin/bats test/muntar.bats

# dmon filesystem monitoring doesn't works in CI

_: ##
clean: ## 🧹 Clean the source from all built objects
$(MAKE) -f build/deps.mk clean
Expand Down
2 changes: 0 additions & 2 deletions build/linux.mk
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
include build/init.mk

cc := gcc

cflags += -DLIBC_GNU -D_GNU_SOURCE
cflags += -DKILO_SUPPORTED
cflags += -DCJIT_BUILD_LINUX
Expand Down
14 changes: 7 additions & 7 deletions build/pack-examples.sh
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,12 @@ function fetch() {
>&2 echo "Script error: \$odir not set"
exit 1
}
out="$1"
url="$2"
REPO_OWNER="$3"
REPO_NAME="$4"
TAG="$5"
FILE_NAME="$out"
local out="$1"
local url="$2"
local REPO_OWNER="$3"
local REPO_NAME="$4"
local TAG="$5"
local FILE_NAME="$out"
if [ -r ${odir}/${out} ]; then
>&2 echo "Found : ${odir}/${out}"
else
Expand Down Expand Up @@ -115,5 +115,5 @@ fetch ${file} ${url}/${file} ${org} ${proj} glew-${ver}

tar --format ustar -cf cjit-demo.tar cjit-demo
gzip -f -9 cjit-demo.tar
rm -rf cjit-demo
# rm -rf cjit-demo
exit 0
1 change: 1 addition & 0 deletions src/array.c
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ xarray_data_t *XArray_NewData(void *pData, size_t nSize, uint32_t nKey)

memcpy(pNewData->pData, pData, nSize);
pNewData->nSize = nSize;
((char*)pNewData->pData)[nSize] = 0x0;
}
else
{
Expand Down
123 changes: 76 additions & 47 deletions src/cjit.c
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,6 @@
#include <inttypes.h>
#include <sys/stat.h> // fstat(2)

#define MAX_PATH 260 // rather short paths
#define MAX_STRING 20480 // max 20KiB strings

#define tcc(cjit) (TCCState*)cjit->TCC
#define setup if(!cjit->done_setup)cjit_setup(cjit)
#define debug(fmt,par) if(cjit->verbose)_err(fmt,par)
Expand Down Expand Up @@ -135,8 +132,7 @@
cjit->tcc_output = TCC_OUTPUT_MEMORY;
// call the generated function to populate the tmpdir
if(!extract_assets(cjit)) {
_err("Error extracting assets in temp dir: %s",
strerror(errno));
fail("error extracting assets in temp dir");
return(NULL);
}
// error handler callback for TCC
Expand All @@ -145,9 +141,23 @@
cjit->sources = (void*)XArray_New(2, 0);
cjit->libs = (void*)XArray_New(2, 0);
cjit->libpaths = (void*)XArray_New(2, 0);
cjit->reallibs = (void*)XArray_New(2, 0);
return(cjit);
}

void cjit_free(CJITState *cjit) {
if(cjit->tmpdir) free(cjit->tmpdir);
if(cjit->write_pid) free(cjit->write_pid);
if(cjit->entry) free(cjit->entry);
if(cjit->output_filename) free(cjit->output_filename);
if(cjit->TCC) tcc_delete(tcc(cjit));
XArray_Free((xarray_t**)&cjit->sources);
XArray_Free((xarray_t**)&cjit->libs);
XArray_Free((xarray_t**)&cjit->libpaths);
XArray_Free((xarray_t**)&cjit->reallibs);
free(cjit);
}

static bool cjit_setup(CJITState *cjit) {
// set output in memory for just in time execution
if(cjit->done_setup) {
Expand Down Expand Up @@ -185,8 +195,8 @@
}
}
tcc_add_sysinclude_path(tcc(cjit), cjit->tmpdir);
// tcc_add_sysinclude_path(tcc(cjit), ".");
// tcc_add_sysinclude_path(tcc(cjit), "include"); // TODO: check if exists
tcc_add_sysinclude_path(tcc(cjit), ".");
tcc_add_sysinclude_path(tcc(cjit), "include"); // TODO: check if exists

Check warning on line 199 in src/cjit.c

View workflow job for this annotation

GitHub Actions / cpplint

[cpplint] src/cjit.c#L199

Missing username in TODO; it should look like "// TODO(my_username): Stuff." [readability/todo] [2]
Raw output
src/cjit.c:199:  Missing username in TODO; it should look like "// TODO(my_username): Stuff."  [readability/todo] [2]

#if defined(WINDOWS)
{
Expand Down Expand Up @@ -284,6 +294,16 @@
for(int i=0;i<used;i++)
_err("+ %s",XArray_GetData(cjit->libs,i));
}
#if defined(UNIX)
resolve_libs(cjit);
used = XArray_Used(cjit->reallibs);
if(used) {
_err("Lib files (%u)",used);
for(int i=0;i<used;i++)

Check warning on line 302 in src/cjit.c

View workflow job for this annotation

GitHub Actions / cpplint

[cpplint] src/cjit.c#L302

Missing space after ; [whitespace/semicolon] [3]
Raw output
src/cjit.c:302:  Missing space after ;  [whitespace/semicolon] [3]
_err("+ %s",XArray_GetData(cjit->reallibs,i));
}
#endif

Check warning on line 306 in src/cjit.c

View workflow job for this annotation

GitHub Actions / cpplint

[cpplint] src/cjit.c#L306

Redundant blank line at the end of a code block should be deleted. [whitespace/blank_line] [3]
Raw output
src/cjit.c:306:  Redundant blank line at the end of a code block should be deleted.  [whitespace/blank_line] [3]
}
return true;
}
Expand Down Expand Up @@ -313,23 +333,20 @@
int res;
int fd = open(filename, O_RDONLY | O_BINARY);
if(fd<0) {
_err("%s: error opening file: %s",__func__,filename);
_err("%s",strerror(errno));
fail(filename);
return -1;
}
struct stat st;
if (fstat(fd, &st) == -1) {
_err("%s: error analyzing file: %s",__func__,filename);
_err("%s",strerror(errno));
fail(filename);
close(fd);
return -1;
}
*filesize = st.st_size;
res = read(fd,bom,3);
close(fd);
if (res!=3) {
_err("%s: error reading file: %s",__func__,filename);
_err("%s",strerror(errno));
fail(filename);
return -1;
}
// _err("%s bom: %x %x %x",filename,bom[0],bom[1],bom[2]);
Expand All @@ -345,18 +362,19 @@
}

bool cjit_add_buffer(CJITState *cjit, const char *buffer) {
int res;
setup;
tcc_compile_string(tcc(cjit),buffer);
res = tcc_compile_string(tcc(cjit),buffer);
debug("+B %p",buffer);
return((res<0)?false:true);
}

bool cjit_add_source(CJITState *cjit, const char *path) {
setup;
size_t length;
int res = detect_bom(path,&length);
if(res<0) {
_err("Cannot open file: %s",path);
_err("Execution aborted.");
fail(path);
return false;
} else if(res>0) {
_err("UTF BOM detected in file: %s",path);
Expand All @@ -365,12 +383,12 @@
}
FILE *file = fopen(path, "rb");
if (!file) {
_err("%s: fopen error: ", __func__, strerror(errno));
fail(path);
return false;
}
char *spath = (char*)malloc((strlen(path)+16)*sizeof(char));
if (!spath) {
_err("%s: malloc error: %s",__func__, strerror(errno));
fail(path);
fclose(file);
return false;
}
Expand All @@ -381,14 +399,18 @@
((spath_len + length + 1)
* sizeof(char));
if (!contents) {
_err("%s: malloc error: %s",__func__, strerror(errno));
fail(path);
free(spath);
fclose(file);
return false;
}
strcpy(contents,spath);
free(spath);
fread(contents+spath_len, 1, length, file);
if(0== fread(contents+spath_len, 1, length, file)) {
fail(file);
fclose(file);
return false;
}
contents[length+spath_len] = 0x0;
fclose(file);
{ // if inside a dir then add dir to includes too
Expand All @@ -413,19 +435,20 @@
int is_source = has_source_extension(path);
if(is_source == 0) { // no extension, we still add
if(tcc_add_file(tcc(cjit), path)<0) {
_err("%s: tcc_add_file error: %s",__func__,path);
fail(path);
return false;
}
return true;
}
if(is_source>0) {
if(!cjit_add_source(cjit, path)) {
_err("%s: error: %s",__func__,path);
fail(path);
return false;
}
return true;
} else {
if(tcc_add_file(tcc(cjit), path)<0) {
_err("%s: tcc_add_file error: %s",__func__,path);
fail(path);
return false;
}
}
Expand All @@ -437,13 +460,13 @@
int is_source = has_source_extension(path);
// _err("basename: %s",tmp);
if( is_source == 0) {
_err("%s: filename has no extension: %s",
__func__,path);
fail(path);
_err("filename has no extension");
return false;
}
if( is_source < 0) {
_err("%s: filename has wrong extension: %s",
__func__,path);
fail(path);
_err("filename has wrong extension");
return false;
}
setup;
Expand Down Expand Up @@ -495,6 +518,16 @@
_err("%s: CJIT already executed once",__func__);
return 1;
}
// resolve library files on UNIX systems
#if defined(UNIX)
int found = resolve_libs(cjit);
for(int i=0;i<found;i++) {

Check warning on line 524 in src/cjit.c

View workflow job for this annotation

GitHub Actions / cpplint

[cpplint] src/cjit.c#L524

Missing space after ; [whitespace/semicolon] [3]
Raw output
src/cjit.c:524:  Missing space after ;  [whitespace/semicolon] [3]
char *f = XArray_GetData(cjit->reallibs,i);
if(f) {
tcc_add_file(tcc(cjit), f);
}
}
#endif
int res = 1;
int (*_ep)(int, char**);
// relocate the code (link symbols)
Expand All @@ -513,8 +546,8 @@
pid_t pid = getpid();
FILE *fd = fopen(cjit->write_pid, "w");
if(!fd) {
_err("Cannot create pid file %s: %s",
cjit->write_pid, strerror(errno));
fail(cjit->write_pid);
_err("Cannot create pid file");
return -1;
}
fprintf(fd,"%d\n",pid);
Expand All @@ -535,8 +568,8 @@
// pid_t pid = getpid();
FILE *fd = fopen(cjit->write_pid, "w");
if(!fd) {
_err("Cannot create pid file %s: %s",
cjit->write_pid, strerror(errno));
fail(cjit->write_pid);
_err("Cannot create pid file");
return -1;
}
fprintf(fd,"%d\n",pid);
Expand All @@ -546,7 +579,7 @@
int ret;
ret = waitpid(pid, &status, WUNTRACED | WCONTINUED);
if (ret != pid){
_err("Wait error in source: %s","main");
_err("Wait error in source: %s",cjit->entry);
}
if (WIFEXITED(status)) {
res = WEXITSTATUS(status);
Expand All @@ -568,18 +601,6 @@
#endif // cjit_exec with fork()
}

void cjit_free(CJITState *cjit) {
if(cjit->tmpdir) free(cjit->tmpdir);
if(cjit->write_pid) free(cjit->write_pid);
if(cjit->entry) free(cjit->entry);
if(cjit->output_filename) free(cjit->output_filename);
if(cjit->TCC) tcc_delete(tcc(cjit));
XArray_Free((xarray_t**)&cjit->sources);
XArray_Free((xarray_t**)&cjit->libs);
XArray_Free((xarray_t**)&cjit->libpaths);
free(cjit);
}


// wrappers to make TCC opaque
void cjit_set_output(CJITState *cjit, int output) {
Expand Down Expand Up @@ -609,22 +630,30 @@
_err("%s: absolute path error: %s",__func__,path);
return;
}
tcc_add_library_path(tcc(cjit), toadd);
#if defined(UNIX)
add(libpaths,toadd);
free(toadd);
#else
tcc_add_library_path(tcc(cjit), toadd);
#endif
debug("+L %s",toadd);
free(toadd);
}
// TODO: temporary, to be reimplemented in linker.c
void cjit_add_library(CJITState *cjit, const char *path) {
tcc_add_library(tcc(cjit), path);
#if defined(UNIX)
add(libs,path);
#else
tcc_add_library(tcc(cjit), path);
#endif
debug("+l %s",path);
}
void cjit_set_tcc_options(CJITState *cjit, const char *opts) {
tcc_set_options(tcc(cjit),opts);
debug("+O %s",opts);
}

#define MAX_STRING 508

// stdout message free from context
void _out(const char *fmt, ...) {
char msg[MAX_STRING+4];
Expand Down
6 changes: 5 additions & 1 deletion src/cjit.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,11 @@
#include <platforms.h>
#include <stdbool.h>

#if !defined(PATH_MAX)
#define PATH_MAX 1024
#endif
#if !defined(MAX_PATH)
#define MAX_PATH 512
#define MAX_PATH PATH_MAX
#endif

// passed to cjit_exec with CJIT execution parameters
Expand All @@ -51,6 +54,7 @@ struct CJITState {
void *sources;
void *libs;
void *libpaths;
void *reallibs;
};
typedef struct CJITState CJITState;

Expand Down
Loading
Loading