A Red Hat employee introduced the Goals build system. Release of GNU Make 4.2

Richard W.M. Jones, author libguestfsworking at Red Hat, presented new build tool Goals, aimed at eliminating shortcomings and problems in the make utility while maintaining the overall simplicity and understandability of scripts. The make utility was designed in 1976 and has a number of conceptual flaws, Goals plans to fix these flaws without changing the overall concept.
Goals source code spreads licensed under GPLv2+.

Solved problems:

  • Support for only one dependency resolution tactic - "the assembly instruction is run if the target file is missing or older than one of the dependencies." Goals plans to implement other tactics, such as checking for the presence of a URL, comparing modification times with any file, evaluating the build of a package in Which, checksum comparison, running test suites with selective skipping of tests.
  • When processing build targets, make does not separate files and rule names, and as a result, there is no check that running a rule will actually create the file it claims to create. For example, if there is a rule called "test" that runs scripts with tests, if a file named "test" is accidentally created, then the tests will no longer be called, because make will consider that the target has been built and does not require any action (for to bypass the problem in make, you can specify the directive ".PHONY: test"). Goals explicitly separates files and rule names.

    A Red Hat employee introduced the Goals build system. Release of GNU Make 4.2

  • Problem with providing only one parameter for assembly instructions.

    A Red Hat employee introduced the Goals build system. Release of GNU Make 4.2

    Goals suggests using an arbitrary number of named parameters. For example, you can separate the sign of a debug file from the name:

    A Red Hat employee introduced the Goals build system. Release of GNU Make 4.2

  • Problems of interaction with the shell-interpreter. For example, the need to control the escaping of spaces in file and directory names, the waste of resources to launch a separate shell interpreter for each command, the double interpretation of the "$" character (used in both the shell and make), accounting for indentation.

    These problems are solved in Goals by using the "%" symbol instead of "$" for assembly variables ("$" remains only for the shell), using a parser LALR(1), which requires quotes around paths and file names and curly braces around code blocks. The entire command block is run in a single command shell instance, and arbitrary code formatting is allowed inside the block, without being tied to special spaces.

    It was:
    target: foo.o bar.o
    ${CC} ${CFLAGS} $< -o $@

    After:
    "target": "foo.o", "bar.o" {
    %CC %CFLAGS %< -o %@
    }

Other features of Goals:

  • Optional support for setting arbitrary names and parameters:

    goal all = : "target"

    goal link=
    "target" : "foo.o", "bar.o" { ... }

    goal compile (name) =
    "%name.o" : "%name.c", "dep.h" { %CC %CFLAGS -c $^ -o $@ }

  • Two run modes: make mode for matching build targets to filenames (for example, the file "foo.o" matches the target "%name.o"), and direct compilation run mode:

    goal all = : link

    goal link=
    "target" : "foo.o", compile("bar") { ... }

    goal compile (name) =
    "%name.o" : "%name.c", "dep.h" { %CC %CFLAGS -c $^ -o $@ }

  • The build tactics are defined by special rules, which can be used to determine the need to rebuild the build target. If a binding is made to the presence of a file, then this is explicitly determined through the corresponding flag ("target" for the rule name and *file("target") for checking the file).

    "target" : "foo.o", "bar.o" { ... }

    *file("target") : *file("foo.o"), *file("bar.o") { ... }

  • The developer can define arbitrary attributes of assembly tactics. The attribute "*file" is defined by default (@{...} indicates the suppression of the output, and "exit 99" signals the need for a rebuild):

    tactical *file (filename) = @{
    test -f %filename || exit 99
    for f in %

    Source: opennet.ru

Add a comment