From 3d1d3b3b7760166879ea87911b7057884ce9f93f Mon Sep 17 00:00:00 2001 From: Kayne Ruse Date: Fri, 27 Sep 2024 22:53:10 +1000 Subject: [PATCH] Working on repl, not fully working yet, read more After a few hours struggling with the linker, I've got the main.c file running correctly, with caveats: - must be executed from out/ - only building on linux for the moment - no tests written yet I will write some CI jobs to see if the repl works eventually. --- makefile | 18 ++++++---- repl/.gitkeep | 0 repl/main.c | 52 +++++++++++++++++++++++++++++ repl/makefile | 76 ++++++++++++++++++++++++++++++++++++++++++ source/makefile | 87 +++++++++++++++++++++++++++++++++++++++++++++++++ tests/makefile | 2 +- 6 files changed, 227 insertions(+), 8 deletions(-) delete mode 100644 repl/.gitkeep create mode 100644 repl/main.c create mode 100644 repl/makefile create mode 100644 source/makefile diff --git a/makefile b/makefile index 4305bf4..e19d1bb 100644 --- a/makefile +++ b/makefile @@ -1,22 +1,26 @@ #compiler settings CC=gcc CFLAGS+=-std=c17 -pedantic -Werror -LIBS=-lm +LIBS+=-lm #directories export TOY_SOURCEDIR=source export TOY_OUTDIR=out export TOY_OBJDIR=obj -#file names -export TOY_SOURCEFILES=$(wildcard $(TOY_SOURCEDIR)/*.c) - #targets -all: clean tests - @echo no targets ready +all: tests + +.PHONY: source +source: + $(MAKE) -C source -k + +.PHONY: repl +repl: source + $(MAKE) -C repl -k .PHONY: tests -tests: +tests: clean $(MAKE) -C tests -k .PHONY: tests-gdb diff --git a/repl/.gitkeep b/repl/.gitkeep deleted file mode 100644 index e69de29..0000000 diff --git a/repl/main.c b/repl/main.c new file mode 100644 index 0000000..a57adbe --- /dev/null +++ b/repl/main.c @@ -0,0 +1,52 @@ +#include "toy_memory.h" + +#include + +unsigned char* readFile(const char* path, int* size) { + //open the file + FILE* file = fopen(path, "rb"); + if (file == NULL) { + return NULL; + } + + //determine the file's length + fseek(file, 0L, SEEK_END); + *size = ftell(file); + rewind(file); + + //make some space + unsigned char* buffer = TOY_ALLOCATE(unsigned char, *size); + if (buffer == NULL) { + fclose(file); + return NULL; + } + + // + if (fread(buffer, sizeof(unsigned char), *size, file) < *size) { + fclose(file); + *size = -1; //singal a read error + return NULL; + } + + fclose(file); + return buffer; +} + + +int main(int argc, char* argv[]) { + int size = 0; + unsigned char* buffer = readFile("../repl/main.c", &size); //for now, just grab the main.c file as a test + + if (buffer == NULL) { + fprintf(stderr, "Failed to open the file\n"); + } + + if (size < 0) { + fprintf(stderr, "Failed to read the file\n"); + } + + TOY_FREE_ARRAY(unsigned char, buffer, size); + + printf("All good\n"); + return 0; +} diff --git a/repl/makefile b/repl/makefile new file mode 100644 index 0000000..9f844e9 --- /dev/null +++ b/repl/makefile @@ -0,0 +1,76 @@ +#compiler settings +CC=gcc +CFLAGS+=-g -Wall -Werror -Wno-unused-parameter -Wno-unused-function -Wno-unused-variable +LIBS+=-lm -lToy +LDFLAGS+=-Wl,-rpath,'.' + +#directories +REPL_ROOTDIR=.. +REPL_REPLDIR=. +REPL_SOURCEDIR=$(REPL_ROOTDIR)/source + +REPL_OUTDIR=$(REPL_ROOTDIR)/out +REPL_OBJDIR=obj + +#file names +REPL_REPLFILES=$(wildcard $(REPL_REPLDIR)/*.c) +REPL_OBJFILES=$(addprefix $(REPL_OBJDIR)/,$(notdir $(REPL_REPLFILES:.c=.o))) +REPL_TARGETNAME=repl.exe + +#linker fix +LDFLAGS+=-L$(realpath $(shell pwd)/$(REPL_OUTDIR)) + +#build the object files, compile the test cases, and run +all: clean build link + +#targets for each step +.PHONY: build +build: $(REPL_OBJDIR) $(REPL_OBJFILES) + +.PHONY: link +link: $(REPL_OUTDIR) $(REPL_OUTDIR)/$(REPL_TARGETNAME) + +#util targets +$(REPL_OUTDIR): + mkdir $(REPL_OUTDIR) + +$(REPL_OBJDIR): + mkdir $(REPL_OBJDIR) + +#compilation steps +$(REPL_OBJDIR)/%.o: $(REPL_REPLDIR)/%.c + $(CC) -c -o $@ $< $(addprefix -I,$(REPL_REPLDIR)) $(addprefix -I,$(REPL_SOURCEDIR)) $(CFLAGS) + +$(REPL_OUTDIR)/$(REPL_TARGETNAME): $(REPL_OBJFILES) + $(CC) -DTOY_IMPORT $(CFLAGS) -o $@ $(REPL_OBJFILES) $(LDFLAGS) $(LIBS) + +#util commands +.PHONY: clean +clean: +ifeq ($(shell uname),Linux) + find . -type f -name '*.o' -delete + find . -type f -name '*.a' -delete + find . -type f -name '*.exe' -delete + find . -type f -name '*.dll' -delete + find . -type f -name '*.lib' -delete + find . -type f -name '*.so' -delete + find . -type f -name '*.dylib' -delete + find . -type d -name 'out' -delete + find . -type d -name 'obj' -delete +else ifeq ($(OS),Windows_NT) + $(RM) *.o *.a *.exe *.dll *.lib *.so *.dylib + $(RM) out + $(RM) obj +else ifeq ($(shell uname),Darwin) + find . -type f -name '*.o' -delete + find . -type f -name '*.a' -delete + find . -type f -name '*.exe' -delete + find . -type f -name '*.dll' -delete + find . -type f -name '*.lib' -delete + find . -type f -name '*.so' -delete + find . -type f -name '*.dylib' -delete + find . -type d -name 'out' -delete + find . -type d -name 'obj' -delete +else + @echo "Deletion failed - what platform is this?" +endif diff --git a/source/makefile b/source/makefile new file mode 100644 index 0000000..e45e02e --- /dev/null +++ b/source/makefile @@ -0,0 +1,87 @@ +#compiler settings +CC=gcc +CFLAGS+=-g -Wall -Werror -Wno-unused-parameter -Wno-unused-function -Wno-unused-variable +LIBS+=-lm +LDFLAGS+= + +#directories +SRC_ROOTDIR=.. +SRC_SOURCEDIR=. + +SRC_OUTDIR=$(SRC_ROOTDIR)/out +SRC_OBJDIR=obj + +#file names +SRC_SOURCEFILES=$(wildcard $(SRC_SOURCEDIR)/*.c) +SRC_OBJFILES=$(addprefix $(SRC_OBJDIR)/,$(notdir $(SRC_SOURCEFILES:.c=.o))) +SRC_TARGETNAME=Toy + +#TODO: fix windows & macos +#SRC_LIBLINE is a fancy way of making the linker work correctly +ifeq ($(shell uname),Linux) + SRC_TARGETEXT=.so + SRC_LIBLINE=-Wl,-rpath,. -Wl,--out-implib=$(SRC_OUTDIR)/lib$(SRC_TARGETNAME).a -Wl,--whole-archive $(SRC_OBJFILES) -Wl,--no-whole-archive + CFLAGS+=-fPIC +# else ifeq ($(OS),Windows_NT) +# SRC_TARGETEXT=.dll +# SRC_LIBLINE=-Wl,-rpath,. -Wl,--out-implib=$(SRC_OUTDIR)/lib$(OUTNAME).dll.a -Wl,--export-all-symbols -Wl,--enable-auto-import -Wl,--whole-archive $(SRC_OBJFILES) -Wl,--no-whole-archive +# else ifeq ($(shell uname),Darwin) +# SRC_TARGETEXT=.dylib +# SRC_LIBLINE=$(SRC_OBJFILES) +else + @echo "Platform test failed - what platform is this?" + exit 1 +endif + +#build the object files, compile the test cases, and run +all: clean build link + +#targets for each step +.PHONY: build +build: $(SRC_OUTDIR) $(SRC_OBJDIR) $(SRC_OBJFILES) + +.PHONY: link +link: $(SRC_OUTDIR) + $(CC) -DTOY_EXPORT $(CFLAGS) -shared -o $(SRC_OUTDIR)/lib$(SRC_TARGETNAME)$(SRC_TARGETEXT) $(SRC_LIBLINE) + +#util targets +$(SRC_OUTDIR): + mkdir $(SRC_OUTDIR) + +$(SRC_OBJDIR): + mkdir $(SRC_OBJDIR) + +#compilation steps +$(SRC_OBJDIR)/%.o: $(SRC_SOURCEDIR)/%.c + $(CC) -c -o $@ $< $(addprefix -I,$(SRC_SOURCEDIR)) $(CFLAGS) + +#util commands +.PHONY: clean +clean: +ifeq ($(shell uname),Linux) + find . -type f -name '*.o' -delete + find . -type f -name '*.a' -delete + find . -type f -name '*.exe' -delete + find . -type f -name '*.dll' -delete + find . -type f -name '*.lib' -delete + find . -type f -name '*.so' -delete + find . -type f -name '*.dylib' -delete + find . -type d -name 'out' -delete + find . -type d -name 'obj' -delete +else ifeq ($(OS),Windows_NT) + $(RM) *.o *.a *.exe *.dll *.lib *.so *.dylib + $(RM) out + $(RM) obj +else ifeq ($(shell uname),Darwin) + find . -type f -name '*.o' -delete + find . -type f -name '*.a' -delete + find . -type f -name '*.exe' -delete + find . -type f -name '*.dll' -delete + find . -type f -name '*.lib' -delete + find . -type f -name '*.so' -delete + find . -type f -name '*.dylib' -delete + find . -type d -name 'out' -delete + find . -type d -name 'obj' -delete +else + @echo "Deletion failed - what platform is this?" +endif diff --git a/tests/makefile b/tests/makefile index 87869f1..132b0e8 100644 --- a/tests/makefile +++ b/tests/makefile @@ -22,7 +22,7 @@ TEST_OUTDIR=out TEST_OBJDIR=obj #file names -TEST_SOURCEFILES=$(addprefix $(TOY_ROOTDIR)/,$(TOY_SOURCEFILES)) +TEST_SOURCEFILES=$(wildcard $(TEST_SOURCEDIR)/*.c) TEST_CASESFILES=$(wildcard $(TEST_CASESDIR)/*.c) #build the object files, compile the test cases, and run