Variables in GNU Make recipes, is that possible?

Thanks to

This is the solution to change a variable in a recipe:

        $(eval variablename=whatever)

This doesn't work because the make tool starts a new shell process for each recipe line. And shell variables – even 'exported' environment variables – cannot possibly propagate "upwards"; they're gone as soon as the shell process exits.

  • The traditional method is to join the recipe lines using \ in the Makefile:

    foo: bar baz
        line1; \
        line2; \

    (Note that the commands must be separated using ; or &&, because the backslashes are also passed to the shell which does the same line-joining.)

    See also info make "Splitting Lines" and info make "Splitting Recipe Lines" in the GNU Make manual.

  • The other method is to tell make to always use one shell process for the entire recipe, using the .ONESHELL directive:

    foo: bar baz

    See info make "One Shell".

    (Note that while .ONESHELL is recommended by POSIX, not all make versions support it; e.g. BSD make only has a command-line flag for it. This shouldn't be a problem though.)