Here project also consists of 2 source files (utils.c
and main.c) and one header (utils.h).
Buildscript rebuilds both source files in parallel and also caches
objects that do not need to be changed.
The core of buildscript is almost the same as before - it contains
pointer to cbuild_proclist_t
array procs, scratchpad cbuild_cmd_run
cmd, uses in identical way cbuild_cmd_run
and then also calls cbuild_procs_wait
for sync. But now each call to cbuild_cmd_run
is wrapped into if block that checks if cbuild_compare_mtime
returns value greater than 0. This just checks if modification time of
input file (second argument) is newer than output file (first
argument).
Code
Directory structure:
examples/build/3.cache
├── src
│ ├── main.c
│ ├── utils.c
│ └── utils.h
├── cbuild.c
└── cbuild.h
App’s source code.
main.c
#include "stdio.h"
#include "utils.h"
int main(int argc, char** argv) {
printf("Hello, world!\nSum: %d\n", sum(1, 1));
return 0;
}
utils.h
#ifndef UTILS_H
#define UTILS_H
int sum(int a, int b);
#endif // UTILS_H
utils.c
#include "utils.h"
int sum(int a, int b) {
return a + b;
}
cbuild.c - Your buildscript:
#define CBUILD_IMPLEMENTATION
#define CBUILD_LOG_MIN_LEVEL CBUILD_LOG_TRACE
#include "cbuild.h"
int main(int argc, char** argv) {
cbuild_selfrebuild(argc, argv);
cbuild_proclist_t procs = {0};
cbuild_cmd_t cmd = {0};
if (cbuild_compare_mtime("main.o", "src/main.c") > 0) {
cbuild_cmd_append_many(&cmd, CC, "-c", "src/main.c", "-o", "main.o");
if (!cbuild_cmd_run(&cmd, .procs = &procs)) return 1;
cmd.size = 0;
}
if (cbuild_compare_mtime("utils.o", "src/utils.c") > 0) {
cbuild_cmd_append_many(&cmd, CC, "-c", "src/utils.c", "-o", "utils.o");
if (!cbuild_cmd_run(&cmd, .procs = &procs)) return 1;
cmd.size = 0;
}
cbuild_procs_wait(procs);
cbuild_cmd_append_many(&cmd, CC, "-o", "app.run", "utils.o", "main.o");
if (!cbuild_cmd_run(&cmd)) return 1;
cbuild_proclist_clear(&procs);
cbuild_cmd_clear(&cmd);
return 0;
}
cbuild.h - Build system core.
How to run
cc -o cbuild.run cbuild.c
./cbuild.run
./app.run