#include #include #include #include #include #include #include #define GLOBAL_INCLUDE "-Iinclude/" #define CC "gcc", "-fsanitize=address", "-g", GLOBAL_INCLUDE #define ENGINE_O "output/engine.o" #define UCI_O "output/uci.o" #define IPC_O "output/ipc.o" #define MAIN_O "output/main.o" int status; #define RUN_CMD(...) do { \ if (fork() == 0) { \ char* args[] = __VA_ARGS__; \ print_cmd(args); \ execvp(args[0], args); \ return 0; \ } else { \ wait(&status); \ } \ } while (0); void print_cmd(char** args) { int i = 0; while (args[i] != NULL) { printf("%s ", args[i++]); } printf("\n"); } int clean_mode(int run_mode); int test_mode(int run_mode); int uci_mode(int run_mode); // https://github.com/tsoding/nob.h/blob/0a08926d8094fc4ae678155c5d73ae21d1f96f3f/nob.h#L2413 int needs_rebuild(char* bin_file, char* source_file) { struct stat statbuf = {0}; if (stat(bin_file, &statbuf) < 0) { if (errno == ENOENT) return 1; return -1; } time_t output_path_time = statbuf.st_mtime; if (stat(source_file, &statbuf) < 0) { fprintf(stderr, "could not stat %s: %s", source_file, strerror(errno)); return -1; } time_t input_path_time = statbuf.st_mtime; return input_path_time > output_path_time; } int main(int argc, char** argv) { if (needs_rebuild(argv[0], __FILE__)) { RUN_CMD({CC, __FILE__, "-o", argv[0], NULL}); if (status != 0) { // cc error return 0; } print_cmd(argv); execvp(argv[0], argv); } RUN_CMD({"mkdir", "-p", "output", NULL}); if (argc <= 1) return 1; int run_mode = argc == 3; if (strcmp(argv[1], "test") == 0) { return test_mode(run_mode); } if (strcmp(argv[1], "clean") == 0) { return clean_mode(run_mode); } return uci_mode(run_mode); } int clean_mode(int _) { char* args[] = {"rm", "-r", "output", NULL}; print_cmd(args); execvp(args[0], args); return 0; } int test_mode(int run_mode) { if (run_mode) { char* args[] = {"./output/test.o", NULL}; print_cmd(args); execvp(args[0], args); } RUN_CMD({CC, "tests/find_tests.c", "-o", "output/find_tests.o", NULL}); RUN_CMD({"./output/find_tests.o", NULL}); printf("\n"); RUN_CMD({CC, "tests/main.c", "-o", "output/test.o", NULL}); return status != 0; } int uci_mode(int run_mode) { if (run_mode) { char* args[] = {MAIN_O, NULL}; print_cmd(args); execvp(args[0], args); } RUN_CMD({CC, "-c", "src/ipc.c", "-o", IPC_O, NULL}); RUN_CMD({CC, "-c", "src/engine.c", "-o", ENGINE_O, NULL}); RUN_CMD({CC, "-c", "src/uci.c", "-o", UCI_O, NULL}); RUN_CMD({CC, "src/main.c", UCI_O, ENGINE_O, IPC_O, "-o", MAIN_O, NULL}); return status != 0; }