gcc.c 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154
  1. /* ----- gcc.c ----- */
  2. strlist* parse_gcc_dep_file(char* dep_file_path, time_t* newest_mtime) {
  3. size_t dep_src_len = 0;
  4. strlist* dep_list;
  5. time_t newest = 0;
  6. char* dep_src = read_whole_file(dep_file_path, &dep_src_len);
  7. if(!dep_src) return NULL;
  8. dep_list = strlist_new();
  9. // skip the first filename junk
  10. char* s = strchr(dep_src, ':');
  11. s++;
  12. int ret = 0;
  13. // gather dep strings, ignoring line continuations
  14. while(*s) {
  15. do {
  16. s = strskip(s, " \t\r\n");
  17. if(*s == '\\') {
  18. if(s[1] == '\r') s++;
  19. if(s[1] == '\n') s++;
  20. }
  21. } while(isspace(*s));
  22. int dlen = span_path(s);
  23. if(dlen == 0) break;
  24. time_t dep_mtime;
  25. char* dep_fake = strncache(s, dlen);
  26. char* dep_real = resolve_path(dep_fake, &dep_mtime);
  27. if(dep_mtime > newest) newest = dep_mtime;
  28. strlist_push(dep_list, dep_real);
  29. struncache(dep_fake);
  30. struncache(dep_real);
  31. s += dlen;
  32. }
  33. free(dep_src);
  34. if(newest_mtime) *newest_mtime = newest;
  35. return dep_list;
  36. }
  37. int gen_deps(char* src_path, char* dep_path, time_t src_mtime, time_t obj_mtime, objfile* obj) {
  38. time_t dep_mtime = 0;
  39. time_t newest_mtime = 0;
  40. char* real_dep_path = resolve_path(dep_path, &dep_mtime);
  41. if(dep_mtime < src_mtime) {
  42. //gcc -MM -MG -MT $1 -MF "build/$1.d" $1 $CFLAGS $LDADD
  43. // printf(" generating deps\n");
  44. char* cmd = sprintfdup("gcc -MM -MG -MT '' -MF %s %s %s", dep_path, src_path, obj->gcc_opts_flat);
  45. system(cmd);
  46. free(cmd);
  47. }
  48. strlist* deps = parse_gcc_dep_file(real_dep_path, &newest_mtime);
  49. // free or process deps
  50. return newest_mtime > obj_mtime;
  51. FAIL:
  52. return 0;
  53. }
  54. char* default_compile_source(char* src_path, char* obj_path, objfile* obj) {
  55. char* cmd = sprintfdup("gcc -c -o %s %s %s", obj_path, src_path, obj->gcc_opts_flat);
  56. if(obj->verbose) puts(cmd);
  57. return cmd;
  58. }
  59. void check_source(char* raw_src_path, strlist* objs, objfile* o) {
  60. time_t src_mtime, obj_mtime = 0, dep_mtime = 0;
  61. char* src_path = resolve_path(raw_src_path, &src_mtime);
  62. char* src_dir = dir_name(raw_src_path);
  63. char* base = base_name(src_path);
  64. // char* build_base = "debug";
  65. char* src_build_dir = path_join(o->build_dir, src_dir);
  66. char* obj_path = path_join(src_build_dir, base);
  67. // cheap and dirty
  68. size_t olen = strlen(obj_path);
  69. obj_path[olen-1] = 'o';
  70. strlist_push(objs, obj_path);
  71. char* dep_path = strcatdup(src_build_dir, "/", base, ".d");
  72. mkdirp_cached(src_build_dir, 0755);
  73. char* real_obj_path = resolve_path(obj_path, &obj_mtime);
  74. if(obj_mtime < src_mtime) {
  75. // printf(" objtime compile\n");
  76. strlist_push(&o->compile_cache, o->compile_source_cmd(src_path, real_obj_path, o));
  77. return;
  78. }
  79. if(gen_deps(src_path, dep_path, src_mtime, obj_mtime, o)) {
  80. // printf(" deep dep compile\n");
  81. strlist_push(&o->compile_cache, o->compile_source_cmd(src_path, real_obj_path, o));
  82. }
  83. //gcc -c -o $2 $1 $CFLAGS $LDADD
  84. }
  85. int compile_cache_execute(objfile* o) {
  86. int ret = 0;
  87. struct child_process_info** cpis;
  88. // printf("compile cache length %d", compile_cache.len);
  89. ret = execute_mt(&o->compile_cache, g_nprocs, "Compiling... %s", &cpis);
  90. if(ret) {
  91. for(int i = 0; i < o->compile_cache.len; i++ ) {
  92. if(cpis[i]->exit_status) {
  93. printf("%.*s\n", (int)cpis[i]->buf_len, cpis[i]->output_buffer);
  94. }
  95. }
  96. }
  97. // TODO free compile cache
  98. // TODO free cpis
  99. return ret;
  100. }
  101. /* -END- gcc.c ----- */