Search code examples
makefileposix

Are slashes allowed in targets of POSIX Makefiles?


I am trying to write portable (POSIX) Makefiles, and POSIX has to say:

Applications shall select target names from the set of characters consisting solely of periods, underscores, digits, and alphabetics from the portable character set

(emphasis mine)

Quite restrictive. I did not expect this.

And what's weird is: It is explicitly mentioned that inference rules cannot contain slashes:

  1. Inference rules, which have one target name with at least one <period> ( '.' ) and no <slash> ( '/' )

And again:

The application shall ensure that the target portion is a valid target name (see Target Rules) of the form .s2 or .s1.s2 (where [...] s1 and s2 do not contain any <slash> or <period> characters.)

(emphasis partly mine)

Why explicitly mention that slashes are not allowed if slashes are disallowed anyway because it needs to be a "valid target name"? What am I missing here?


Solution

  • What am I missing here?

    In the first place, POSIX explicitly says that "Implementations may allow other characters in target names as extensions," and it is extremely common for implementations to exercise that allowance. In fact, I doubt you could find a POSIX-conforming make implementation in use anywhere that does not allow slash characters in target names by default.

    Given, then, that implementations can allow slashes in target names as an extension, and that that has special implications on the behavior of make, the specification accounts for it in the provisions for suffix rules. That it forbids slashes in the target names in such rules is moot for hypothetical implementations that do not allow slashes in any target names. It is relevant and important for all the real-world implementations.

    So,

    Are slashes allowed in targets of POSIX Makefiles?

    In principle, a POSIX-conforming make implementation could reject all target names containing slashes. In practice, all POSIX-conforming make implementations accept slashes in target names, except possibly when input or command-line options instruct them to disable extensions and implement strict POSIX semantics.