~q3cpma/posix-build

A simple POSIX build system using sh(1) and make(1)
Fix install() into dir
Add todo to README and remove -z,now from example LDFLAGS
Improve README

refs

master
browse  log 

clone

read-only
https://git.sr.ht/~q3cpma/posix-build
read/write
git@git.sr.ht:~q3cpma/posix-build

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

                                  posix-build
                                  ===========

        Overview
        --------

For some time, I've been using GNU make with all its features to allow for some
complex operations without resorting to contraptions like cmake or meson. But
after a while I noticed that GNU make was just trying to fuse POSIX make with
sh, producing something not as simple as the former and not as extensible as
the latter.

So here's an almost (see Dependencies) POSIX compliant build system built on
POSIX sh and make. 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.
    * With the aforementioned detector, easy handling of LTO and PGO for both
      gcc and clang.
    * Some more 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
      `file.lex.c`).
    * No macro/environment mess like make, only use the environment since it's
      a nice builtin associative array that is automatically passed to
      subprocesses.
    * 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.


        Dependencies
        ------------

* A POSIX environment, obviously
* mktemp(1), only dependency I couldn't part with; it is available on GNU,
  FreeBSD, OpenBSD, NetBSD, DragonflyBSD, MacOS, Illumos, HP-UX and Tru64,
  though.
  mkstemp(3) itself being POSIX and easy to use, a wrapper could be written in
  no time.


        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:
$ PREFIX=prefix ./build.sh install
Installing prog into /home/user/posix-build/prefix/bin
Installing util.sh into /home/user/posix-build/prefix/share/prog
Installing README into /home/user/posix-build/prefix/share/doc/prog
prog-c.o feature1.o
c99 -O3 -std=c99 -pedantic -Wall -Wextra -D_DEFAULT_SOURCE -DPROG_NAME="\"prog-c\"" -DPROG_VERSION="\"27e976c5567633f6fbfc2d7504be40aba16f8b14\"" -DNDEBUG -DUSE_FEATURE1 -c prog-c.c
c99 -O3 -std=c99 -pedantic -Wall -Wextra -D_DEFAULT_SOURCE -DPROG_NAME="\"prog-c\"" -DPROG_VERSION="\"27e976c5567633f6fbfc2d7504be40aba16f8b14\"" -DNDEBUG -DUSE_FEATURE1 -c feature1.c
c99 -s -Wl,-O1 -Wl,-z,defs prog-c.o feature1.o -o prog-c -pthread -lm
Installing prog-c into /home/user/posix-build/prefix/bin/
Installing README to /home/user/posix-build/prefix/share/doc/prog/README_prog-c
$ tree prefix
prefix
├── bin
│   ├── prog
│   └── prog-c
└── share
    ├── doc
    │   └── prog
    │       ├── README
    │       └── README_prog-c
    └── prog
        └── util.sh

5 directories, 5 files


        To do
        -----

* Re(Add) profiling CONFIG for perf and for gprof
* Add lint action (clang-analyze/scan-build, cppcheck, frama-c, blast, infer)
* Separate sanitizers from CONFIG=debug and add clang's msan as option