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