diff options
Diffstat (limited to 'build.c')
| -rw-r--r-- | build.c | 126 |
1 files changed, 126 insertions, 0 deletions
@@ -0,0 +1,126 @@ +#include <sys/wait.h> +#include <sys/stat.h> +#include <unistd.h> +#include <linux/limits.h> +#include <stdio.h> +#include <stdlib.h> +#include <errno.h> +#include <time.h> +#include <string.h> + +#define RELEASE_MODE + +#ifdef RELEASE_MODE +#define CC "gcc", "-O3" +#else +#define CC "gcc", "-fsanitize=address", "-g" +#endif + +#define EXE_NAME "backbencher" + +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"); +} + +// 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; +} + +void getlibgit2(char *output, int output_max_size) { + int link[2]; + pid_t pid; + + pipe(link); + pid = fork(); + + if (pid == 0) { + dup2(link[1], STDOUT_FILENO); + close(link[0]); + close(link[1]); + execl("/usr/bin/pkg-config", "--cflags", "--libs", "libgit2", (char*)0); + exit(0); + } + + close(link[1]); + int nbytes = read(link[0], output, output_max_size); + wait(NULL); + + int i = -1; + while (++i < nbytes) { + if (output[i] >= 32) continue; + nbytes = i - 1; + break; + } + output[nbytes] = 0; + return; +} + +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); + } + + if (argc >= 2 && strcmp(argv[1], "install") == 0) { + printf("install -m 755 " EXE_NAME " /usr/local/bin/" EXE_NAME); + char dest[PATH_MAX]; + snprintf(dest, sizeof(dest), "/usr/local/bin/%s", EXE_NAME); + char *install_args[] = {"install", "-m", "755", EXE_NAME, dest, NULL}; + execvp("install", install_args); + perror("execvp"); + return 0; + } + if (argc >= 2 && strcmp(argv[1], "release") == 0) { + char libgit[4096]; + getlibgit2(libgit, 4096); + RUN_CMD({CC, "src/main.c", libgit, "-o", EXE_NAME, "-O3", NULL}); + return 0; + } + + char libgit[4096]; + getlibgit2(libgit, 4096); + RUN_CMD({CC, "src/main.c", libgit, "-o", EXE_NAME, NULL}); + + if (status == 0 && argc >= 2) { + argv[1] = malloc(1024); + strncpy(argv[1], "./" EXE_NAME, 1024); + print_cmd(argv + 1); + execvp(argv[1], argv + 1); + } +} |
