diff --git a/src/cjit.c b/src/cjit.c
index c49dad5..8c9e53e 100644
--- a/src/cjit.c
+++ b/src/cjit.c
@@ -194,13 +194,30 @@ bool cjit_setup(CJITState *cjit) {
 	return(true);
 }
 
-bool cjit_add_file(CJITState *cjit, const char *path) {
+static int has_source_extension(const char *path) {
 	char *ext;
 	size_t extlen;
-	bool is_source = false;
-	bool res = cwk_path_get_extension(path,(const char**)&ext,&extlen);
-	// no filename extension: still good to add
-	if(!res) {
+	bool is_source;
+	is_source = cwk_path_get_extension(path,(const char**)&ext,&extlen);
+	//_err("%s: extension: %s",__func__,ext);
+	if(!is_source) // no extension at all
+		return 0;
+	if(extlen==2 && (ext[1]=='c' || ext[1]=='C')) is_source = true;
+	else if(extlen==3
+	   && (ext[1]=='c' || ext[1]=='C')
+	   && (ext[2]=='c' || ext[2]=='C')) is_source = true;
+	else if(extlen==4
+	   && (ext[1]=='c' || ext[1]=='C')
+	   && (ext[2]=='x' || ext[2]=='X')
+	   && (ext[3]=='x' || ext[3]=='X')) is_source = true;
+	else is_source = false;
+	return (is_source? 1 : -1);
+}
+
+bool cjit_add_file(CJITState *cjit, const char *path) {
+	// _err("%s",__func__);
+	int is_source = has_source_extension(path);
+	if(is_source == 0) { // no extension, we still add
 		cjit_setup(cjit);
 		if(tcc_add_file(cjit->TCC, path)<0) {
 			_err("%s: tcc_add_file error",__func__);
@@ -208,16 +225,8 @@ bool cjit_add_file(CJITState *cjit, const char *path) {
 		}
 		return true;
 	}
-	// if C source then use tcc_compile_string
-	if(extlen==1 && (ext[1]=='c' || ext[1]=='C')) is_source = true;
-	if(extlen==3
-	   && (ext[1]=='c' || ext[1]=='C')
-	   && (ext[2]=='c' || ext[2]=='C')) is_source = true;
-	if(extlen==4
-	   && (ext[1]=='c' || ext[1]=='C')
-	   && (ext[2]=='x' || ext[2]=='X')
-	   && (ext[3]=='x' || ext[3]=='X')) is_source = true;
-	if(is_source) {
+	if(is_source>0) {
+		// _err("%s: is source(%i): %s",__func__, is_source, path);
 		long length = file_size(path);
 		if (length == -1) return false;
 		FILE *file = fopen(path, "r");
@@ -235,6 +244,15 @@ bool cjit_add_file(CJITState *cjit, const char *path) {
 		contents[length] = 0x0; // Null-terminate the string
 		fclose(file);
 		cjit_setup(cjit);
+		size_t dirname;
+		cwk_path_get_dirname(path,&dirname);
+		if(dirname) {
+			char *tmp = malloc(dirname+1);
+			strncpy(tmp,path,dirname);
+			tmp[dirname] = 0x0;
+			tcc_add_include_path(cjit->TCC,tmp);
+			free(tmp);
+		}
 		tcc_compile_string(cjit->TCC,contents);
 		free(contents);
 	} else {
@@ -248,32 +266,43 @@ bool cjit_add_file(CJITState *cjit, const char *path) {
 }
 
 bool cjit_compile_file(CJITState *cjit, const char *path) {
-	char *restrict tmp;
-	const char *basename;
-	char *ext;
-	size_t len;
-	cwk_path_get_basename((char*)path, &basename, &len);
-	tmp = malloc(len+2);
-	strncpy(tmp,basename,len+1);
+	int is_source = has_source_extension(path);
 	// _err("basename: %s",tmp);
-	if( !cwk_path_get_extension(tmp,(const char**)&ext,&len) ) {
+	if( is_source == 0) {
 		_err("%s: filename has no extension: %s",
 		     __func__,basename);
-		return 1;
+		return false;
 	}
-	// _err("extension: %s",ext);
-	if( *(ext+1) != 'c' ) {
+	if( is_source < 0) {
 		_err("%s: filename has wrong extension: %s",
 		     __func__,basename);
-		return 1;
+		return false;
 	}
-	strcpy(ext,".o");
 	cjit_setup(cjit);
 	tcc_add_file(cjit->TCC, path);
-	_err("Compiling: %s -> %s",path,tmp);
-	tcc_output_file(cjit->TCC,tmp);
-	free(tmp);
-	return 0;
+	if(cjit->output_filename) {
+		if(!cjit->quiet)
+			_err("Compiling: %s -> %s",path,
+			     cjit->output_filename);
+		tcc_output_file(cjit->TCC,
+				cjit->output_filename);
+	} else {
+		char *ext;
+		size_t extlen;
+		char *restrict tmp;
+		const char *basename;
+		size_t len;
+		cwk_path_get_basename((char*)path, &basename, &len);
+		tmp = malloc(len+2);
+		strncpy(tmp,basename,len+1);
+		cwk_path_get_extension(tmp,(const char**)&ext,&extlen);
+		strcpy(ext,".o");
+		if(!cjit->quiet)
+			_err("Compiling: %s -> %s",path,tmp);
+		tcc_output_file(cjit->TCC,tmp);
+		free(tmp);
+	}
+	return true;
 }
 
 int cjit_exec(CJITState *cjit, int argc, char **argv) {
diff --git a/src/main.c b/src/main.c
index 4639689..0a47c89 100644
--- a/src/main.c
+++ b/src/main.c
@@ -60,25 +60,28 @@ static int parse_value(char *str) {
 }
 
 const char cli_help[] =
-  "\n"
-  "Synopsis: cjit [options] files(*) -- app arguments\n"
-  "  (*) can be any source (.c) or built object (dll, dylib, .so)\n"
-  "Options:\n"
-  " -h \t print this help\n"
-  " -v \t print version information\n"
-  " -q \t stay quiet and only print errors and output\n"
-  " -D sym\t define a macro symbol or key=value\n"
-  " -C \t set compiler flags (default from env var CFLAGS)\n"
-  " -I dir\t also search folder 'dir' for header files\n"
-  " -l lib\t search the library named 'lib' when linking\n"
-  " -L dir\t also search inside folder 'dir' for -l libs\n"
-  " -e fun\t entry point function (default 'main')\n"
-  " -p pid\t write pid of executed program to file\n"
-  " --temp\t create the runtime temporary dir and exit\n"
+	"CJIT %s by Dyne.org\n"
+	"\n"
+	"Synopsis: cjit [options] files(*) -- app arguments\n"
+	"  (*) can be any source (.c) or built object (dll, dylib, .so)\n"
+	"Options:\n"
+	" -h \t print this help\n"
+	" -v \t print version information\n"
+	" -q \t stay quiet and only print errors and output\n"
+	" -D sym\t define a macro symbol or key=value\n"
+	" -C \t set compiler flags (default from env var CFLAGS)\n"
+	" -I dir\t also search folder 'dir' for header files\n"
+	" -l lib\t search the library named 'lib' when linking\n"
+	" -L dir\t also search inside folder 'dir' for -l libs\n"
+	" -e fun\t entry point function (default 'main')\n"
+	" -p pid\t write pid of executed program to file\n"
+	" -c \t compile a single source file, do not execute\n"
+	" -o exe\t compile to an 'exe' file, do not execute\n"
+	" --temp\t create the runtime temporary dir and exit\n"
 #if defined(SELFHOST)
-  " --src\t  extract source code to cjit_source\n"
+	" --src\t  extract source code to cjit_source\n"
 #endif
-  " --xtgz\t extract all contents from a USTAR tar.gz\n";
+	" --xtgz\t extract all contents from a USTAR tar.gz\n";
 
 
 int main(int argc, char **argv) {
@@ -101,7 +104,7 @@ int main(int argc, char **argv) {
   };
   ketopt_t opt = KETOPT_INIT;
   // tolerated and ignored: -f -W -O -g -U -E -S -M
-  while ((c = ketopt(&opt, argc, argv, 1, "qhvD:L:l:C:I:e:p:co:f:W:O:gU:ESM:", longopts)) >= 0) {
+  while ((c = ketopt(&opt, argc, argv, 1, "qhvD:L:l:C:I:e:p:co:f:W:O:gU:ESM:m:", longopts)) >= 0) {
 	  if(c == 'q') {
 		  CJIT->quiet = true;
 	  }
@@ -284,7 +287,7 @@ int main(int argc, char **argv) {
 			  // 3  : BOM found, UTF8
 			  if(res ==0) {
 				  cjit_setup(CJIT);
-				  tcc_add_file(CJIT->TCC, code_path);
+				  cjit_add_file(CJIT, code_path);
 			  } else if(res<0) {
 				  _err("Cannot open file: %s",code_path);
 				  _err("Execution aborted.");
diff --git a/test/cli.bats b/test/cli.bats
index d6b59d9..7d6f37a 100644
--- a/test/cli.bats
+++ b/test/cli.bats
@@ -18,6 +18,22 @@ load bats_setup
     assert_output --partial 'Please compile with -DALLOWED=1'
 }
 
+@test "Compile to object and execute" {
+      run ${CJIT} -c test/hello.c
+      assert_success
+      run ${CJIT} hello.o
+      assert_success
+      assert_output 'Hello World!'
+}
+
+@test "Compile to custom object and execute" {
+      run ${CJIT} -o world.o -c test/hello.c
+      assert_success
+      run ${CJIT} world.o
+      assert_success
+      assert_output 'Hello World!'
+}
+
 @test "Execute multiple files" {
     run ${CJIT} -q test/multifile/*
     assert_success