From 0c928da96d5fb8fe8f929db40b2d807053113f35 Mon Sep 17 00:00:00 2001 From: Kirill Smelkov Date: Sun, 20 Jun 2010 20:08:12 +0400 Subject: tcc: Draft suppoprt for -MD/-MF options In build systems, this is used to automatically collect target dependencies, e.g. ---- 8< (hello.c) ---- #include "hello.h" #include int main() { printf("Hello World!\n"); return 0; } $ tcc -MD -c hello.c # -> hello.o, hello.d $ cat hello.d hello.o : \ hello.c \ hello.h \ /usr/include/stdio.h \ /usr/include/features.h \ /usr/include/bits/predefs.h \ /usr/include/sys/cdefs.h \ /usr/include/bits/wordsize.h \ /usr/include/gnu/stubs.h \ /usr/include/bits/wordsize.h \ /usr/include/gnu/stubs-32.h \ /home/kirr/local/tcc/lib/tcc/include/stddef.h \ /usr/include/bits/types.h \ /usr/include/bits/wordsize.h \ /usr/include/bits/typesizes.h \ /usr/include/libio.h \ /usr/include/_G_config.h \ /usr/include/wchar.h \ /home/kirr/local/tcc/lib/tcc/include/stdarg.h \ /usr/include/bits/stdio_lim.h \ /usr/include/bits/sys_errlist.h \ NOTE: gcc supports -MD only for .c -> .o, but in tcc, we generate dependencies for whatever action is being taken. E.g. for .c -> exe, the result will be: $ tcc -MD -o hello hello.c # -> hello, hello.d hello: \ /usr/lib/crt1.o \ /usr/lib/crti.o \ hello.c \ hello.h \ /usr/include/stdio.h \ /usr/include/features.h \ /usr/include/bits/predefs.h \ /usr/include/sys/cdefs.h \ /usr/include/bits/wordsize.h \ /usr/include/gnu/stubs.h \ /usr/include/bits/wordsize.h \ /usr/include/gnu/stubs-32.h \ /home/kirr/local/tcc/lib/tcc/include/stddef.h \ /usr/include/bits/types.h \ /usr/include/bits/wordsize.h \ /usr/include/bits/typesizes.h \ /usr/include/libio.h \ /usr/include/_G_config.h \ /usr/include/wchar.h \ /home/kirr/local/tcc/lib/tcc/include/stdarg.h \ /usr/include/bits/stdio_lim.h \ /usr/include/bits/sys_errlist.h \ /usr/lib/libc.so \ /lib/libc.so.6 \ /usr/lib/ld-linux.so.2 \ /lib/ld-linux.so.2 \ /usr/lib/libc_nonshared.a \ /lib/libc.so.6 \ /usr/lib/libc_nonshared.a \ /home/kirr/local/tcc/lib/tcc/libtcc1.a \ /usr/lib/crtn.o \ So tcc dependency generator is a bit more clever than one used in gcc :) Also, I've updated TODO and Changelog (in not-yet-released section). v2: (Taking inputs from grischka and me myself) - put code to generate deps file into a function. - used tcc_fileextension() instead of open-coding - generate deps only when compilation/preprocessing was successful v3: - use pstrcpy instead of snprintf(buf, sizeof(buf), "%s", ...) --- libtcc.c | 39 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) (limited to 'libtcc.c') diff --git a/libtcc.c b/libtcc.c index 1c963b5..92c7cad 100644 --- a/libtcc.c +++ b/libtcc.c @@ -1041,6 +1041,7 @@ LIBTCCAPI void tcc_delete(TCCState *s1) 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); @@ -1092,6 +1093,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; @@ -1585,3 +1590,37 @@ LIBTCCAPI const char *tcc_default_target(TCCState *s) 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; inb_target_deps; ++i) + fprintf(depout, "\t%s \\\n", s->target_deps[i]); + fprintf(depout, "\n"); + fclose(depout); +} -- cgit v1.3.1