build_matrix.c 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138
  1. #define STB_DEFINE
  2. #include "stb.h"
  3. // true if no error
  4. int run_command(char *batch_file, char *command)
  5. {
  6. char buffer[4096];
  7. if (batch_file[0]) {
  8. sprintf(buffer, "%s && %s", batch_file, command);
  9. return system(buffer) == 0;
  10. } else {
  11. return system(command) == 0;
  12. }
  13. }
  14. typedef struct
  15. {
  16. char *compiler_name;
  17. char *batchfile;
  18. char *objdir;
  19. char *compiler;
  20. char *args;
  21. char *link;
  22. } compiler_info;
  23. compiler_info *compilers;
  24. char *shared_args;
  25. char *shared_link;
  26. typedef struct
  27. {
  28. char *filelist;
  29. } project_info;
  30. project_info *projects;
  31. enum { NONE, IN_COMPILERS, IN_ARGS, IN_PROJECTS, IN_LINK };
  32. int main(int argc, char **argv)
  33. {
  34. int state = NONE;
  35. int i,j,n;
  36. char **line;
  37. if (argc != 2) stb_fatal("Usage: stb_build_matrix {build-file}\n");
  38. line = stb_stringfile(argv[1], &n);
  39. if (line == 0) stb_fatal("Couldn't open file '%s'\n", argv[1]);
  40. for (i=0; i < n; ++i) {
  41. char *p = stb_trimwhite(line[i]);
  42. if (p[0] == 0) continue;
  43. else if (p[0] == '#') continue;
  44. else if (0 == stricmp(p, "[compilers]")) { state = IN_COMPILERS; }
  45. else if (0 == stricmp(p, "[args]" )) { state = IN_ARGS ; shared_args = NULL; }
  46. else if (0 == stricmp(p, "[projects]" )) { state = IN_PROJECTS ; }
  47. else if (0 == stricmp(p, "[link]" )) { state = IN_LINK ; shared_link = NULL; }
  48. else {
  49. switch (state) {
  50. case NONE: stb_fatal("Invalid text outside section at line %d.", i+1);
  51. case IN_COMPILERS: {
  52. char buffer[4096];
  53. int count;
  54. compiler_info ci;
  55. char **tokens = stb_tokens_stripwhite(p, ",", &count), *batch;
  56. if (count > 3) stb_fatal("Expecting name and batch file name at line %d.", i+1);
  57. batch = (count==1 ? tokens[0] : tokens[1]);
  58. if (strlen(batch))
  59. sprintf(buffer, "c:\\%s.bat", batch);
  60. else
  61. strcpy(buffer, "");
  62. ci.compiler_name = strdup(tokens[0]);
  63. ci.batchfile = strdup(buffer);
  64. ci.compiler = count==3 ? strdup(tokens[2]) : "cl";
  65. if (0==strnicmp(batch, "vcvars_", 7))
  66. ci.objdir = strdup(stb_sprintf("vs_%s_%d", batch+7, i));
  67. else
  68. ci.objdir = strdup(stb_sprintf("%s_%d", batch, i));
  69. ci.args = shared_args;
  70. ci.link = shared_link;
  71. stb_arr_push(compilers, ci);
  72. break;
  73. }
  74. case IN_ARGS: {
  75. stb_arr_push(shared_args, ' ');
  76. for (j=0; p[j] != 0; ++j)
  77. stb_arr_push(shared_args, p[j]);
  78. break;
  79. }
  80. case IN_LINK: {
  81. stb_arr_push(shared_link, ' ');
  82. for (j=0; p[j] != 0; ++j)
  83. stb_arr_push(shared_link, p[j]);
  84. break;
  85. }
  86. case IN_PROJECTS: {
  87. project_info pi;
  88. pi.filelist = strdup(p);
  89. stb_arr_push(projects, pi);
  90. break;
  91. }
  92. }
  93. }
  94. }
  95. _mkdir("obj");
  96. for (j=0; j < stb_arr_len(compilers); ++j) {
  97. char command[4096];
  98. for (i=0; i < stb_arr_len(projects); ++i) {
  99. int r;
  100. _mkdir(stb_sprintf("obj/%s", compilers[j].objdir));
  101. if (stb_suffix(compilers[j].compiler, "cl"))
  102. sprintf(command, "%s %.*s %s /link %.*s",
  103. compilers[j].compiler,
  104. stb_arr_len(compilers[j].args), compilers[j].args,
  105. projects[i].filelist,
  106. stb_arr_len(compilers[j].link), compilers[j].link);
  107. else
  108. sprintf(command, "%s %.*s %s %.*s",
  109. compilers[j].compiler,
  110. stb_arr_len(compilers[j].args), compilers[j].args,
  111. projects[i].filelist,
  112. stb_arr_len(compilers[j].link), compilers[j].link);
  113. r = run_command(compilers[j].batchfile, command);
  114. stbprint("{%c== Compiler %s == Building %s}\n", r ? '$' : '!', compilers[j].compiler_name, projects[i].filelist);
  115. stb_copyfile("a.exe", stb_sprintf("obj/%s/a.exe", compilers[j].objdir));
  116. //printf("Copy: %s to %s\n", "a.exe", stb_sprintf("obj/%s/a.exe", compilers[j].objdir));
  117. stb_copyfile("temp.exe", stb_sprintf("obj/%s/temp.exe", compilers[j].objdir));
  118. system("if EXIST a.exe del /q a.exe");
  119. system("if EXIST temp.exe del /q temp.exe");
  120. system("if EXIST *.obj del /q *.obj");
  121. system("if EXIST *.o del /q *.o");
  122. if (!r)
  123. return 1;
  124. }
  125. }
  126. return 0;
  127. }