A simple POSIX build system using sh(1) and make(1)
embed_as_string better comment
Improvements here and there
Make embed_as_string interact correctly with the preprocessor


browse  log 



You can also use your local clone with git send-email.



Have you ever said "if only this was sh, it would be easy", while using make
(even less portable ones like GNU Make)? Have you tried to extend it beyond
basic use while fighting its warts?

I have, and that's why I've come up with a collection of (mostly) POSIX sh
functions to wrap around POSIX make (which is used as intended: a recipe

Here are some of its features:
    * Proper install/uninstall without needing install(1) nor readlink(1) -f to
      normalize PREFIX.
    * Simple runtime path rewriting for sh(1) scripts, allowing for inplace and
      installed use alike.
    * A compiler flag detector (autoconf like features left as exercise to those
      who need it).
    * With the aforementioned detector, easy handling of LTO and PGO for both
      gcc and clang.
    * Some default compilation variables like NATIVE and STATIC or flag presets
      in the form of CONFIG.
    * gperf and lex files handling (note: a `file.lex` or `file.gperf` is
      expected to produce a `file.c`, because SUFFIX rules don't allow for
    * No macro/environment mess like make, only use the environment since it's
      a nice builtin associative array that is automatically passed to
    * Since it's sh, it's as extensible as your sh writing skills, no need to
      bolt so much on make, and with a different syntax to boot.

Note that since this uses make, it inherits its awful lack of whitespace
handling. Also note that this project is really C oriented, use with C++ and
other programming languages would need a lot of small edits.


* A POSIX environment, obviously
* sed -E for detect_intermediate_src (included in the next POSIX, present on
  GNU, *BSD and Illumos).
* A /bin/sh with local or typeset support (almost all of them).

        Command line description

A typical use (build then install) using bmake with 4 jobs:
    $ CC=c99 MAKE=bmake JOBS=4 LTO=false PGO=false NATIVE=false STATIC=false \
          USE_FEATURE1=true USE_FEATURE2=false ./build.sh
    # PREFIX=/opt ./build.sh install

Here's the more detailed usage message:
| SYNOPSIS                                                                         |
|     build.sh [ACTION]                                                            |
|     PGO=true build.sh CMD [ARGS]                                                 |
|                                                                                  |
| DESCRIPTION                                                                      |
|     Build script getting its configuration from the environment and accepting    |
|     the following ACTIONs:                                                       |
|         * clean                                                                  |
|         * install                                                                |
|         * uninstall                                                              |
|         * help                                                                   |
|                                                                                  |
|     When no ACTION is given, the program is built.                               |
|     When PGO is selected through the environment, CMD [ARGS] is run to profile   |
|     the program before rebuilding.                                               |
|                                                                                  |
|     This notice is generic, read the README for possibly more.                   |
|                                                                                  |
| ENVIRONMENT                                                                      |
|     CC                                                                           |
|         C compiler to use. Defaults to c99(1p).                                  |
|                                                                                  |
|     LD                                                                           |
|         Linker passed to CC via -fuse-ld (if available).                         |
|                                                                                  |
|     CFLAGS                                                                       |
|         Additional flags passed to CC when compiling sources files into          |
|         objects.                                                                 |
|                                                                                  |
|     LDFLAGS                                                                      |
|         Additional flags passed to CC when linking the objects into the final    |
|         executable.                                                              |
|                                                                                  |
|     PREFIX and DESTDIR                                                           |
|         The program and its files are installed into or uninstalled from         |
|         "$DESTDIR$PREFIX/". PREFIX defaults to "/usr/local" and DESTDIR to       |
|         empty.                                                                   |
|                                                                                  |
|     MAKE                                                                         |
|         Executable to use as make(1p). Defaults to "make".                       |
|                                                                                  |
|     JOBS                                                                         |
|         If some steps in the compilation support parallel processing, choose     |
|         the number of parallel jobs to run. Defaults to 1.                       |
|                                                                                  |
|     LTO                                                                          |
|         Try to use link-time optimization when value is "true". Defaults to      |
|         "false".                                                                 |
|                                                                                  |
|     PGO                                                                          |
|         Try to use profile-guided optimization using the arguments as a command  |
|         to run to profile the program when value is "true". Defaults to "false". |
|                                                                                  |
|     STATIC                                                                       |
|         Try to link statically when value is "true". Defaults to "false".        |
|                                                                                  |
|     NATIVE                                                                       |
|         Try to enable optimizations specific to the host CPU when value is       |
|         "true". Defaults to "false".                                             |
|                                                                                  |
|     CONFIG                                                                       |
|         Choose a flag preset corresponding to a build type. Available values     |
|         are "release", "debug" and "profile". Defaults to "release".             |
|                                                                                  |

        Example description

This repo is given as an example, build.sh and prog-c/build.sh should be
inspected and modified before copy-pasting them. Only build_util.sh should be
kept untouched.

The example is a project containing a sh script and a subproject with a C
program called by the script.
This configuration shows most of the functionalities available.

Here's what the installation looks like after installing:
$ LTO=true CC=gcc ./build.sh
gcc -O3 -std=c99 -pedantic -Wall -Wextra -flto -fno-fat-lto-objects -D_DEFAULT_SOURCE -DPROG_NAME="\"prog-c\"" -DPROG_VERSION="\"fa5eb349c3fcbb295b664256f6e792b55051fdfa\"" -DNDEBUG -DUSE_FEATURE1 -o prog-c.o -c prog-c.c
gcc -O3 -std=c99 -pedantic -Wall -Wextra -flto -fno-fat-lto-objects -D_DEFAULT_SOURCE -DPROG_NAME="\"prog-c\"" -DPROG_VERSION="\"fa5eb349c3fcbb295b664256f6e792b55051fdfa\"" -DNDEBUG -DUSE_FEATURE1 -o feature1.o -c feature1.c
gcc -s -Wl,-O1 -Wl,-z,defs -flto=1  -O3 -std=c99 -pedantic -Wall -Wextra prog-c.o feature1.o -o prog-c -pthread -lm
$ PREFIX=prefix ./build.sh install
Installing prog into /home/user/Programming/posix-build/prefix/bin/prog
Installing util.sh into /home/user/Programming/posix-build/prefix/share/example-project/util.sh
Installing README into /home/user/Programming/posix-build/prefix/share/doc/example-project/README
Installing prog-c into /home/user/Programming/posix-build/prefix/bin/prog-c
Installing README to /home/user/Programming/posix-build/prefix/share/doc/example-project/README_prog-c
$ tree prefix
├── bin
│   ├── prog
│   └── prog-c
└── share
    ├── doc
    │   └── example-project
    │       ├── README
    │       └── README_prog-c
    └── example-project
        └── util.sh
$ prefix/bin/prog hello world
prog-c 40d2902b89fa6e5340798d13201842f851041537
Feature1 enabled, feature1 value: 1
Here's my source code:

        To do

* Re(Add) profiling CONFIG for perf and for gprof
* Add lint action (clang-analyze/scan-build, cppcheck, frama-c, blast, infer)
* Integrate optional features so that the build system always know the full source list