aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKirill Smelkov <kirr@mns.spb.ru>2010-06-21 20:50:32 +0400
committerKirill Smelkov <kirr@mns.spb.ru>2010-06-21 20:50:41 +0400
commit9775aea1ab634a74cd4254df85e93d4cbf098cce (patch)
treedbdf8823c5c64ef3d4d40749401c9cb129f3521d
parent3ba37e1e3f1d942c3115406cdccf01ce84d53bee (diff)
parent2fe5210a33556ed18bc878046d39e25964a52840 (diff)
downloadtinycc-9775aea1ab634a74cd4254df85e93d4cbf098cce.tar.gz
tinycc-9775aea1ab634a74cd4254df85e93d4cbf098cce.tar.bz2
Merge branch 'kirr/tcc-MD' into mob
Hello up there. I'm trying to change gcc to tcc for faster develpment on slow machines, and the first obstacle that turned out was lack of dependency generation on tcc side. Attached patches try to fix that. Thanks, Kirill * tcc-MD: .gitignore += tags tcc: Explicitly require -l<lib> for libraries Document what tcc_fileextension does tcc -E: Let output_default be <file>.o instead of a.out tcc: Draft suppoprt for -MD/-MF options tcc: Refactor "compute default outfile name" into libtcc function Add input files/libs and reloc_output switch to TCCState tcc: Fix typo in error (it's '%s', not '%s) chmod a-x i386-gen.c .gitignore += *.o *.a .cvsignore -> .gitignore
-rw-r--r--.gitignore (renamed from .cvsignore)5
-rw-r--r--Changelog4
-rw-r--r--TODO1
-rw-r--r--[-rwxr-xr-x]i386-gen.c0
-rw-r--r--libtcc.c81
-rw-r--r--libtcc.h14
-rw-r--r--tcc.c63
-rw-r--r--tcc.h13
-rw-r--r--tccpp.c3
9 files changed, 150 insertions, 34 deletions
diff --git a/.cvsignore b/.gitignore
index 95daa1f..a845ddc 100644
--- a/.cvsignore
+++ b/.gitignore
@@ -1,3 +1,5 @@
+*.o
+*.a
tcc_g
tcc
tc2.c
@@ -34,4 +36,5 @@ tcc.pod
config.h
config.mak
config.texi
-tests \ No newline at end of file
+tests
+tags
diff --git a/Changelog b/Changelog
index b271054..528d927 100644
--- a/Changelog
+++ b/Changelog
@@ -1,3 +1,7 @@
+not released:
+
+- Add support for -MD/-MF (automatically generate dependencies for make)
+
version 0.9.25:
- first support for x86-64 target (Shinichiro Hamaji)
diff --git a/TODO b/TODO
index 6f49c5d..9d19153 100644
--- a/TODO
+++ b/TODO
@@ -46,7 +46,6 @@ Missing features:
- disable-asm and disable-bcheck options
- __builtin_expect()
- improve '-E' option.
-- add '-MD' option
- atexit (Nigel Horne)
- packed attribute
- C99: add variable size arrays (gcc 3.2 testsuite issue)
diff --git a/i386-gen.c b/i386-gen.c
index f8795c1..f8795c1 100755..100644
--- a/i386-gen.c
+++ b/i386-gen.c
diff --git a/libtcc.c b/libtcc.c
index f0da4de..5f064dd 100644
--- a/libtcc.c
+++ b/libtcc.c
@@ -168,6 +168,10 @@ PUB_FUNC char *tcc_basename(const char *name)
return p;
}
+/* extract extension part of a file
+ *
+ * (if no extension, return pointer to end-of-string)
+ */
PUB_FUNC char *tcc_fileextension (const char *name)
{
char *b = tcc_basename(name);
@@ -1038,6 +1042,11 @@ LIBTCCAPI void tcc_delete(TCCState *s1)
dynarray_reset(&s1->sysinclude_paths, &s1->nb_sysinclude_paths);
tcc_free(s1->tcc_lib_path);
+
+ dynarray_reset(&s1->input_files, &s1->nb_input_files);
+ dynarray_reset(&s1->input_libs, &s1->nb_input_libs);
+ dynarray_reset(&s1->target_deps, &s1->nb_target_deps);
+
#ifdef HAVE_SELINUX
munmap (s1->write_mem, s1->mem_size);
munmap (s1->runtime_mem, s1->mem_size);
@@ -1088,6 +1097,10 @@ ST_FUNC int tcc_add_file_internal(TCCState *s1, const char *filename, int flags)
goto the_end;
}
+ /* update target deps */
+ dynarray_add((void ***)&s1->target_deps, &s1->nb_target_deps,
+ tcc_strdup(filename));
+
if (flags & AFF_PREPROCESS) {
ret = tcc_preprocess(s1);
goto the_end;
@@ -1184,6 +1197,8 @@ the_end:
LIBTCCAPI int tcc_add_file(TCCState *s, const char *filename)
{
+ dynarray_add((void ***)&s->input_files, &s->nb_input_files, tcc_strdup(filename));
+
if (s->output_type == TCC_OUTPUT_PREPROCESS)
return tcc_add_file_internal(s, filename, AFF_PRINT_ERROR | AFF_PREPROCESS);
else
@@ -1220,6 +1235,8 @@ LIBTCCAPI int tcc_add_library(TCCState *s, const char *libraryname)
{
char buf[1024];
int i;
+
+ dynarray_add((void ***)&s->input_libs, &s->nb_input_libs, tcc_strdup(libraryname));
/* first we look for the dynamic library if not static linking */
if (!s->static_link) {
@@ -1549,3 +1566,67 @@ PUB_FUNC void set_num_callers(int n)
num_callers = n;
#endif
}
+
+
+LIBTCCAPI const char *tcc_default_target(TCCState *s)
+{
+ /* FIXME will break in multithreaded case */
+ static char outfile_default[1024];
+
+ char *ext;
+ const char *name =
+ strcmp(s->input_files[0], "-") == 0 ? "a"
+ : tcc_basename(s->input_files[0]);
+ pstrcpy(outfile_default, sizeof(outfile_default), name);
+ ext = tcc_fileextension(outfile_default);
+#ifdef TCC_TARGET_PE
+ if (s->output_type == TCC_OUTPUT_DLL)
+ strcpy(ext, ".dll");
+ else
+ if (s->output_type == TCC_OUTPUT_EXE)
+ strcpy(ext, ".exe");
+ else
+#endif
+ if (( (s->output_type == TCC_OUTPUT_OBJ && !s->reloc_output) ||
+ (s->output_type == TCC_OUTPUT_PREPROCESS) )
+ && *ext)
+ strcpy(ext, ".o");
+ else
+ pstrcpy(outfile_default, sizeof(outfile_default), "a.out");
+
+ return outfile_default;
+}
+
+
+LIBTCCAPI void tcc_gen_makedeps(TCCState *s, const char *target, const char *filename)
+{
+ FILE *depout;
+ char buf[1024], *ext;
+ int i;
+
+ if (!target)
+ target = tcc_default_target(s);
+
+ if (!filename) {
+ /* compute filename automatically
+ * dir/file.o -> dir/file.d */
+ pstrcpy(buf, sizeof(buf), target);
+ ext = tcc_fileextension(buf);
+ pstrcpy(ext, sizeof(buf) - (ext-buf), ".d");
+ filename = buf;
+ }
+
+ if (s->verbose)
+ printf("<- %s\n", filename);
+
+ /* XXX return err codes instead of error() ? */
+ depout = fopen(filename, "w");
+ if (!depout)
+ error("could not open '%s'", filename);
+
+ fprintf(depout, "%s : \\\n", target);
+ for (i=0; i<s->nb_target_deps; ++i)
+ fprintf(depout, "\t%s \\\n", s->target_deps[i]);
+ fprintf(depout, "\n");
+ fclose(depout);
+}
diff --git a/libtcc.h b/libtcc.h
index 339dec1..bf328d3 100644
--- a/libtcc.h
+++ b/libtcc.h
@@ -103,6 +103,20 @@ LIBTCCAPI void *tcc_get_symbol(TCCState *s, const char *name);
/* set CONFIG_TCCDIR at runtime */
LIBTCCAPI void tcc_set_lib_path(TCCState *s, const char *path);
+
+/*****************************/
+/* Miscellaneous */
+
+/* Get default target filename for this compilation */
+LIBTCCAPI const char *tcc_default_target(TCCState *s);
+
+/* Generate make dependencies for target and store them into file
+ *
+ * !target - use default target name
+ * !filename - use (target.o -> target.d)
+ */
+LIBTCCAPI void tcc_gen_makedeps(TCCState *s, const char *target, const char *filename);
+
#ifdef __cplusplus
}
#endif
diff --git a/tcc.c b/tcc.c
index d0ed8f6..136612e 100644
--- a/tcc.c
+++ b/tcc.c
@@ -32,6 +32,8 @@ static int output_type;
static int reloc_output;
static const char *outfile;
static int do_bench = 0;
+static int gen_deps;
+static const char *deps_outfile;
#define TCC_OPTION_HAS_ARG 0x0001
#define TCC_OPTION_NOSEP 0x0002 /* cannot have space before option and arg */
@@ -74,6 +76,9 @@ static void help(void)
#ifdef CONFIG_TCC_BACKTRACE
" -bt N show N callers in stack traces\n"
#endif
+ "Misc options:\n"
+ " -MD generate target dependencies for make\n"
+ " -MF depfile put generated dependencies here\n"
);
}
@@ -115,6 +120,8 @@ enum {
TCC_OPTION_w,
TCC_OPTION_pipe,
TCC_OPTION_E,
+ TCC_OPTION_MD,
+ TCC_OPTION_MF,
TCC_OPTION_x,
};
@@ -154,6 +161,8 @@ static const TCCOption tcc_options[] = {
{ "w", TCC_OPTION_w, 0 },
{ "pipe", TCC_OPTION_pipe, 0},
{ "E", TCC_OPTION_E, 0},
+ { "MD", TCC_OPTION_MD, 0},
+ { "MF", TCC_OPTION_MF, TCC_OPTION_HAS_ARG },
{ "x", TCC_OPTION_x, TCC_OPTION_HAS_ARG },
{ NULL },
};
@@ -374,6 +383,12 @@ static int parse_args(TCCState *s, int argc, char **argv)
case TCC_OPTION_E:
output_type = TCC_OUTPUT_PREPROCESS;
break;
+ case TCC_OPTION_MD:
+ gen_deps = 1;
+ break;
+ case TCC_OPTION_MF:
+ deps_outfile = optarg;
+ break;
case TCC_OPTION_x:
break;
default:
@@ -393,7 +408,6 @@ int main(int argc, char **argv)
int i;
TCCState *s;
int nb_objfiles, ret, optind;
- char objfilename[1024];
int64_t start_time = 0;
s = tcc_new();
@@ -444,29 +458,7 @@ int main(int argc, char **argv)
} else {
s->outfile = fopen(outfile, "w");
if (!s->outfile)
- error("could not open '%s", outfile);
- }
- } else if (output_type != TCC_OUTPUT_MEMORY) {
- if (!outfile) {
- /* compute default outfile name */
- char *ext;
- const char *name =
- strcmp(files[0], "-") == 0 ? "a" : tcc_basename(files[0]);
- pstrcpy(objfilename, sizeof(objfilename), name);
- ext = tcc_fileextension(objfilename);
-#ifdef TCC_TARGET_PE
- if (output_type == TCC_OUTPUT_DLL)
- strcpy(ext, ".dll");
- else
- if (output_type == TCC_OUTPUT_EXE)
- strcpy(ext, ".exe");
- else
-#endif
- if (output_type == TCC_OUTPUT_OBJ && !reloc_output && *ext)
- strcpy(ext, ".o");
- else
- pstrcpy(objfilename, sizeof(objfilename), "a.out");
- outfile = objfilename;
+ error("could not open '%s'", outfile);
}
}
@@ -475,13 +467,14 @@ int main(int argc, char **argv)
}
tcc_set_output_type(s, output_type);
+ s->reloc_output = reloc_output;
/* compile or add each files or library */
for(i = 0; i < nb_files && ret == 0; i++) {
const char *filename;
filename = files[i];
- if (filename[0] == '-' && filename[1]) {
+ if (filename[0] == '-' && filename[1] == 'l') {
if (tcc_add_library(s, filename + 2) < 0) {
error_noabort("cannot find %s", filename);
ret = 1;
@@ -501,13 +494,21 @@ int main(int argc, char **argv)
if (do_bench)
tcc_print_stats(s, getclock_us() - start_time);
- if (s->output_type == TCC_OUTPUT_PREPROCESS) {
- if (outfile)
- fclose(s->outfile);
- } else if (s->output_type == TCC_OUTPUT_MEMORY)
+ if (s->output_type == TCC_OUTPUT_MEMORY)
ret = tcc_run(s, argc - optind, argv + optind);
- else
- ret = tcc_output_file(s, outfile) ? 1 : 0;
+ else {
+ if (s->output_type == TCC_OUTPUT_PREPROCESS) {
+ if (outfile)
+ fclose(s->outfile);
+ } else {
+ ret = tcc_output_file(s, outfile ? outfile : tcc_default_target(s));
+ ret = ret ? 1 : 0;
+ }
+
+ /* dump collected dependencies */
+ if (gen_deps && !ret)
+ tcc_gen_makedeps(s, outfile, deps_outfile);
+ }
}
tcc_delete(s);
diff --git a/tcc.h b/tcc.h
index 29953a6..bb3eb9f 100644
--- a/tcc.h
+++ b/tcc.h
@@ -397,7 +397,8 @@ typedef struct ASMOperand {
#endif
struct TCCState {
- int output_type;
+ unsigned output_type : 8;
+ unsigned reloc_output : 1;
BufferedFile **include_stack_ptr;
int *ifdef_stack_ptr;
@@ -518,6 +519,16 @@ struct TCCState {
/* output file for preprocessing */
FILE *outfile;
+ /* input files and libraries for this compilation */
+ char **input_files;
+ int nb_input_files;
+ char **input_libs;
+ int nb_input_libs;
+
+ /* automatically collected dependencies for this compilation */
+ char **target_deps;
+ int nb_target_deps;
+
/* for tcc_relocate */
int runtime_added;
void *runtime_mem;
diff --git a/tccpp.c b/tccpp.c
index 9a4cbca..2b735d1 100644
--- a/tccpp.c
+++ b/tccpp.c
@@ -1491,6 +1491,9 @@ ST_FUNC void preprocess(int is_bof)
#ifdef INC_DEBUG
printf("%s: including %s\n", file->filename, buf1);
#endif
+ /* update target deps */
+ dynarray_add((void ***)&s1->target_deps, &s1->nb_target_deps,
+ tcc_strdup(buf1));
/* XXX: fix current line init */
/* push current file in stack */