Skip to content

Instantly share code, notes, and snippets.

@rexim
Created October 12, 2019 18:00
Show Gist options
  • Save rexim/0e1e00c8b9a04cb993216f4950a7ae13 to your computer and use it in GitHub Desktop.
Save rexim/0e1e00c8b9a04cb993216f4950a7ae13 to your computer and use it in GitHub Desktop.
Self-hosted build tool
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/wait.h>
void rebuild_if_modified(int argc, char *argv[])
{
assert(argc > 0);
const char *binary = argv[0];
const char *source = __FILE__;
struct stat source_stat;
if (stat(source, &source_stat) < 0) {
fprintf(stderr, "[ERROR] Can't check time of `%s` file: %s\n",
source, strerror(errno));
exit(1);
}
struct stat binary_stat;
if (stat(binary, &binary_stat) < 0) {
fprintf(stderr, "[ERROR] Can't check time of `%s` file: %s\n",
binary, strerror(errno));
exit(1);
}
if (source_stat.st_mtime > binary_stat.st_mtime) {
printf("%s is modified. Rebuilding myself...\n", source);
pid_t pid = fork();
if (pid) {
int status = 0;
waitpid(pid, &status, 0);
if ((!WIFEXITED(status)) || (WEXITSTATUS(status) != 0)) {
fprintf(stderr, "[ERROR] Could not rebuild myself!\n");
exit(1);
}
// TODO: rebuild_if_modified loses original binary flags
// TODO: rebuild_if_modified can easily go into recursion
execlp(binary, binary, NULL);
} else {
printf("Building ./build\n");
// TODO: can build.c remember which flags it was compiled with?
execlp("gcc", "gcc", "-o", binary, source, NULL);
}
}
}
#define EXECUTABLE_NAME "test"
int main(int argc, char *argv[])
{
rebuild_if_modified(argc, argv);
pid_t pid = fork();
if (!pid) {
execlp("gcc", "gcc", "-Wall", "-Werror", "-o", EXECUTABLE_NAME, "main.c", NULL);
}
int status;
waitpid(pid, &status, 0);
if ((!WIFEXITED(status)) || (WEXITSTATUS(status) != 0)) {
fprintf(stderr, "[ERROR] Build failed\n");
exit(1);
}
printf("Created ./%s executable\n", EXECUTABLE_NAME);
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment