diff --git a/README.md b/README.md index ab54f04..13ad7dd 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,6 @@ # IncludeBuild -A build system in one C header. Build scripts are C; there is no generator, -package, or build language to install. +Put `build.h` next to `build.c`. ```c #define BUILD_IMPLEMENTATION @@ -15,22 +14,20 @@ int main(int argc, char** argv) { ``` ```sh -cc -o build build.c # bootstrap once -./build # parallel incremental debug build -./build release # optimized build -./build run # build and run the first executable +cc -o build build.c +./build +./build release +./build run ./build clean -./build compdb # write compile_commands.json +./build compdb ./build help ``` -`./build` recompiles itself when `build.c` or `build.h` changes. Source and -header timestamps, compiler depfiles, and the exact command line determine -what rebuilds. Use `./build -v` to see every decision. +`./build` recompiles itself when `build.c` or `build.h` changes. It also checks +compiler depfiles and the command used for each object. `./build -v` prints the +commands and rebuild reasons. -## API - -Target constructors take a name and an initial source path or glob: +## Targets ```c Target* executable(const char* name, const char* pattern); @@ -48,7 +45,7 @@ void use(Target* target, Target* library); patterns are sorted and deduplicated. A pattern that matches nothing is an error. -Configuration is one global struct: +## Configuration ```c Target* app = executable("app", "src/**.c"); @@ -63,16 +60,15 @@ if (config.release) { } ``` -Libraries passed to `use` are linked transitively in dependency order. Their -include directories propagate to users, and static libraries used by shared -libraries receive `-fPIC` automatically where required. +`use(app, library)` adds the library, its dependencies, and its include +directories. Static libraries linked into shared libraries are compiled with +`-fPIC` on Linux and macOS. ## Requirements -C99 and a GCC-compatible driver: GCC, Clang, or MinGW on Linux, macOS, or -Windows. `$CC`, `$CXX`, and `$AR` are honored. +C99. GCC, Clang, and MinGW are supported on Linux, macOS, and Windows. Compiler +defaults can be changed with `$CC`, `$CXX`, and `$AR`. -See [includebuild.com](https://includebuild.com) for the same reference and a -direct `build.h` download. The complete development repository, including -tests and the site source, is on [Forgejo](https://korze.org/code/includebuild). -GitHub is the minimal distribution mirror. Released under [CC0 1.0](LICENSE). +[Website](https://includebuild.com) · +[Development repository](https://korze.org/code/includebuild) · +[CC0](LICENSE) diff --git a/build.h b/build.h index ef5deee..53e7f19 100644 --- a/build.h +++ b/build.h @@ -1,4 +1,4 @@ -/* IncludeBuild: a build system in one C header. +/* IncludeBuild #define BUILD_IMPLEMENTATION #include "build.h" @@ -9,8 +9,10 @@ return build(); } - Bootstrap once with `cc -o build build.c`, then use `./build`. - GCC-compatible C/C++ toolchains, C99, Linux/macOS/Windows, CC0. + cc -o build build.c + ./build + + C99; GCC, Clang, or MinGW; Linux, macOS, or Windows; CC0. https://includebuild.com */ @@ -30,9 +32,8 @@ extern "C" { typedef struct Target Target; -/* Global configuration, read by build(). Assign fields after build_init and - before build. String fields must outlive build (literals are - perfect). Command-line flags override the corresponding fields. */ +/* Set after build_init and before build. String values must remain valid until + build returns. Command-line options override the corresponding fields. */ typedef struct BuildConfig { const char* root; /* project root; default "." */ const char* output_dir; /* artifact directory; default: root */ @@ -54,33 +55,31 @@ typedef struct BuildConfig { extern BuildConfig config; -/* Capture argv and parse the command line. Must be the first call. */ +/* Parse argv. Call before declaring targets. */ #define build_init(argc, argv) build_init_from((argc), (argv), __FILE__) void build_init_from(int argc, char** argv, const char* script_source); -/* Declare targets. Names must be portable file names. */ +/* Names must be portable file names. */ Target* executable(const char* name, const char* pattern); Target* static_library(const char* name, const char* pattern); Target* shared_library(const char* name, const char* pattern); -/* Add sources by path or glob: `*` and `?` match within a path segment, - and `**` matches across directories, so "**.c" means every C file in the - tree (a leading directory, as in "src" + "**.c", narrows it). Patterns - that match nothing are an error. May be called repeatedly. */ +/* Add a path or glob. `*` and `?` stop at directory boundaries; `**` does not. + "**.c" matches every C file. Prefix the pattern with a directory to limit + the search. Unmatched patterns are errors. */ void sources(Target* target, const char* pattern); -/* Add an include directory (-I). Propagates to targets that use this. */ +/* Add an include directory. Users inherit it. */ void include_dir(Target* target, const char* dir); -/* Append target-specific compile / link flags. */ +/* Append target-specific flags. */ void compile_flags(Target* target, const char* flags); void link_flags(Target* target, const char* flags); -/* Link a library target into another target and inherit its include dirs. */ +/* Add a library dependency. */ void use(Target* target, Target* library); -/* Execute whatever the command line asked for. Returns the process exit - code — `return build();` from main. */ +/* Run the selected command and return its exit status. */ int build(void); #ifdef __cplusplus @@ -241,7 +240,7 @@ static void incb_color_on(void) { } /* ----------------------------------------------------------------- memory */ -/* Everything lives in one arena released at exit; nothing else to manage. */ +/* Arena freed at exit. */ typedef struct incb_blk { struct incb_blk* next; size_t used, cap; } incb_blk; static incb_blk* incb_mem; @@ -1199,7 +1198,7 @@ static const char* incb_usage = "usage: ./build [debug|release] [verb] [options]\n" "\n" "verbs:\n" - " build compile and link everything (default)\n" + " build compile and link all targets (default)\n" " run [target] build one executable, then run it (its args after --)\n" " clean remove build outputs and state\n" " compdb write compile_commands.json (auto-refreshed after)\n" @@ -2006,7 +2005,7 @@ static int incb_verb_build(void) { (unsigned)linked, linked == 1 ? "" : "s", incb_now() - t0, incb_g.jobs, INCB_COFF); } else { - incb_say("%severything up to date%s", INCB_CGRN, INCB_COFF); + incb_say("%sall targets up to date%s", INCB_CGRN, INCB_COFF); } return 0; } diff --git a/examples/README.md b/examples/README.md index 1a1c883..b345222 100644 --- a/examples/README.md +++ b/examples/README.md @@ -1,10 +1,8 @@ # Examples -Every example follows the same two steps: - ```bash -cc -o build build.c # bootstrap once -./build # from here on, ./build does everything +cc -o build build.c +./build ``` Try `./build run`, `./build release`, `./build -v`, `./build compdb`, @@ -12,6 +10,6 @@ Try `./build run`, `./build release`, `./build -v`, `./build compdb`, | Example | Shows | | --- | --- | -| [basic](basic/) | The smallest possible build script | +| [basic](basic/) | One source and one executable | | [config](config/) | Global and target flags for debug/release | | [library](library/) | A static library used by an executable | diff --git a/examples/basic/README.md b/examples/basic/README.md index 13b092a..619bd53 100644 --- a/examples/basic/README.md +++ b/examples/basic/README.md @@ -1,14 +1,10 @@ # Basic Example -The smallest possible IncludeBuild project: one source file, one executable, -a six-line build script. +One source file and one executable. ```bash -cc -o build build.c # once -./build # build it -./build run # build it and run it -./build clean # remove outputs and .build/ +cc -o build build.c +./build +./build run +./build clean ``` - -After the first compile you never touch `cc` again — if you edit `build.c`, -`./build` recompiles itself before doing anything else. diff --git a/examples/config/README.md b/examples/config/README.md index 800bf7e..26e5638 100644 --- a/examples/config/README.md +++ b/examples/config/README.md @@ -1,10 +1,9 @@ # Configuration -Debug and release are built in: `./build` uses `config.debug_flags`, -`./build release` uses `config.release_flags`, and each mode keeps its own -object tree so switching back and forth never rebuilds the world. +`./build` uses `config.debug_flags`. `./build release` uses +`config.release_flags`. Debug and release objects are stored separately. -The build script is ordinary C, so per-mode logic is an `if` on `config.release`: +Use `config.release` for mode-specific settings: ```c if (config.release) { diff --git a/www/build.h b/www/build.h index ef5deee..53e7f19 100644 --- a/www/build.h +++ b/www/build.h @@ -1,4 +1,4 @@ -/* IncludeBuild: a build system in one C header. +/* IncludeBuild #define BUILD_IMPLEMENTATION #include "build.h" @@ -9,8 +9,10 @@ return build(); } - Bootstrap once with `cc -o build build.c`, then use `./build`. - GCC-compatible C/C++ toolchains, C99, Linux/macOS/Windows, CC0. + cc -o build build.c + ./build + + C99; GCC, Clang, or MinGW; Linux, macOS, or Windows; CC0. https://includebuild.com */ @@ -30,9 +32,8 @@ extern "C" { typedef struct Target Target; -/* Global configuration, read by build(). Assign fields after build_init and - before build. String fields must outlive build (literals are - perfect). Command-line flags override the corresponding fields. */ +/* Set after build_init and before build. String values must remain valid until + build returns. Command-line options override the corresponding fields. */ typedef struct BuildConfig { const char* root; /* project root; default "." */ const char* output_dir; /* artifact directory; default: root */ @@ -54,33 +55,31 @@ typedef struct BuildConfig { extern BuildConfig config; -/* Capture argv and parse the command line. Must be the first call. */ +/* Parse argv. Call before declaring targets. */ #define build_init(argc, argv) build_init_from((argc), (argv), __FILE__) void build_init_from(int argc, char** argv, const char* script_source); -/* Declare targets. Names must be portable file names. */ +/* Names must be portable file names. */ Target* executable(const char* name, const char* pattern); Target* static_library(const char* name, const char* pattern); Target* shared_library(const char* name, const char* pattern); -/* Add sources by path or glob: `*` and `?` match within a path segment, - and `**` matches across directories, so "**.c" means every C file in the - tree (a leading directory, as in "src" + "**.c", narrows it). Patterns - that match nothing are an error. May be called repeatedly. */ +/* Add a path or glob. `*` and `?` stop at directory boundaries; `**` does not. + "**.c" matches every C file. Prefix the pattern with a directory to limit + the search. Unmatched patterns are errors. */ void sources(Target* target, const char* pattern); -/* Add an include directory (-I). Propagates to targets that use this. */ +/* Add an include directory. Users inherit it. */ void include_dir(Target* target, const char* dir); -/* Append target-specific compile / link flags. */ +/* Append target-specific flags. */ void compile_flags(Target* target, const char* flags); void link_flags(Target* target, const char* flags); -/* Link a library target into another target and inherit its include dirs. */ +/* Add a library dependency. */ void use(Target* target, Target* library); -/* Execute whatever the command line asked for. Returns the process exit - code — `return build();` from main. */ +/* Run the selected command and return its exit status. */ int build(void); #ifdef __cplusplus @@ -241,7 +240,7 @@ static void incb_color_on(void) { } /* ----------------------------------------------------------------- memory */ -/* Everything lives in one arena released at exit; nothing else to manage. */ +/* Arena freed at exit. */ typedef struct incb_blk { struct incb_blk* next; size_t used, cap; } incb_blk; static incb_blk* incb_mem; @@ -1199,7 +1198,7 @@ static const char* incb_usage = "usage: ./build [debug|release] [verb] [options]\n" "\n" "verbs:\n" - " build compile and link everything (default)\n" + " build compile and link all targets (default)\n" " run [target] build one executable, then run it (its args after --)\n" " clean remove build outputs and state\n" " compdb write compile_commands.json (auto-refreshed after)\n" @@ -2006,7 +2005,7 @@ static int incb_verb_build(void) { (unsigned)linked, linked == 1 ? "" : "s", incb_now() - t0, incb_g.jobs, INCB_COFF); } else { - incb_say("%severything up to date%s", INCB_CGRN, INCB_COFF); + incb_say("%sall targets up to date%s", INCB_CGRN, INCB_COFF); } return 0; } diff --git a/www/index.html b/www/index.html index 24d0a36..fd2c9d2 100644 --- a/www/index.html +++ b/www/index.html @@ -3,7 +3,7 @@ - + @@ -25,10 +25,8 @@
-

IncludeBuild

-

A build system for C and C++ contained in one C header.

-

Build definitions are C programs. Include build.h, declare the targets, - compile build.c, and run the resulting executable.

+

build.h

+

Declare C and C++ targets in build.c.

Download build.h Forgejo @@ -59,22 +57,8 @@ int main(int argc, char** argv) { ./build clean
-

Compile build.c once. Subsequent runs rebuild and restart the build - executable when build.c or build.h changes.

-
- -
-

Build behavior

- -

./build -v prints commands and rebuild reasons.

+

./build recompiles itself when build.c or + build.h changes. ./build -v prints commands and rebuild reasons.

@@ -94,6 +78,7 @@ void use(Target* target, Target* library); int build(void);

Constructors take a target name and an initial source path or glob. Use sources to add more. A pattern that matches no files is an error.

+

use adds a library, its dependencies, and its include directories.

Configuration

Set configuration after build_init and before build. @@ -122,8 +107,8 @@ config.jobs = 8;

Requirements

-

C99 and a GCC-compatible compiler driver: GCC, Clang, or MinGW. The tool reads - CC, CXX, and AR.

+

C99. GCC, Clang, or MinGW on Linux, macOS, or Windows. Compiler defaults can be + changed with CC, CXX, and AR.

curl -LO https://includebuild.com/build.h
diff --git a/www/source.html b/www/source.html index bd3faed..3f60ff3 100644 --- a/www/source.html +++ b/www/source.html @@ -3,7 +3,7 @@ - + @@ -27,7 +27,6 @@

build.h

-

This is the header served by the download link.

Download build.h