For Immediate Variable Assignment, double colon or one? - makefile

In the GNU make manual, I see
Simply expanded variables are defined by lines using ‘:=’ or ‘::=’ (see
Setting Variables). Both forms are equivalent in GNU make; however only the
‘::=’ form is described by the POSIX standard (support for ‘::=’ was added to
the POSIX standard in 2012, so older versions of make won’t accept this form
either).
I thought this meant that ::= was part of the standard, and := was vendor dependent. But I rarely see the double colon.
Which should I use for maximum portability?

The ::= syntax has been approved by the POSIX standards group, in 2011, along with ?= and +=. See http://austingroupbugs.net/view.php?id=330 for information on the process and why a new assignment operator was chosen instead of standardizing on :=.
I can't say which versions of make, other than GNU make, support this syntax yet.

Related

Supported implicit variables in Makefile

The GNU Makefile has a documentation page which lists standard implicit variables for various compilation contexts, such as CC, CFLAGS, etc. They are well defined, and pretty safe to employ (I use them all the time).
Looking though extended documentation, beyond the GNU website, I regularly see other variables which are not listed on the GNU documentation, such as COMPILER.c, LINK.o, etc.
Such variables are present in multiple recipes when looking over Github or Internet, and frequently from authors which seem to have a pretty good understanding regarding how make works.
The question is:
How reliable is it to use such variables?
They are not documented on the GNU make documentation website, but they seem stable enough that several authors have decided to rely on them. Is it a sane thing to do?
I'd say that they are documented and are pretty safe to use with GNU make (they are not in POSIX make).
However, the recipes in built-in implicit rules actually use variables such as COMPILE.c, LINK.p, and PREPROCESS.S, whose values contain the recipes listed above.
make follows the convention that the rule to compile a .x source file uses the variable COMPILE.x. Similarly, the rule to produce an executable from a .x file uses LINK.x; and the rule to preprocess a .x file uses PREPROCESS.x.

Makefile rule with no target

I'm debugging a makefile, and in a macro expansion it creates a rule with no target (as so:)
: | directoryA
#echo running $#
...
I've looked it up online, and the makefile documentation seems to hint (but not explicitly state) that there should be at least one target.
With my current version of make (gnu Make 4.2.1), it's not killing me, but I'm just wondering whether this is considered undefined behavior or whether this is supported, and if so, what it should do.
I've looked it up online, and the makefile documentation seems to hint (but not explicitly state) that there should be at least one target.
Different makes may behave differently. They may even exhibit variant handling of specific makefile syntax matters depending on the content of the makefile -- for example, a makefile may be interpreted differently if it starts with a rule for the .POSIX: special target than an otherwise identical makefile without that rule is interpreted.
Overall, however, if you want some sort of general idea of what should be considered correct then the POSIX standard's defintion of make is a reasonably good baseline. It says:
Target rules are formatted as follows:
target [target...]: [prerequisite...][;command]
[<tab>command<tab>command...]
line that does not begin with <tab>
Target entries are specified by a <blank>-separated, non-null list of
targets, then a <colon>, [...]
(emphasis added). It furthermore goes on to say that
Applications shall select target names from the set of characters
consisting solely of periods, underscores, digits, and alphabetics
from the portable character set
, from which we can infer that the syntax description is talking about the rule text after macro expansion, since macro references can appear in the target lists of rules (or literally anywhere in a makefile, per the spec), but the characters $, (, ), {, and } appearing in macro references are not among those that can appear in targets.
That specification of makefiles' expected contents does explicitly state that target lists are non-empty, and it is reasonable to treat it as authoritative where your specific make's documentation does not override it.
I'm just wondering whether [an empty target list] is considered undefined behavior or
whether this is supported
Your combination of makefile and runtime macro values does not conform to the requirements of POSIX make. The spec does not define what should happen in this case, so in that sense the behavior is undefined, but "undefined behavior" isn't as strong a concept in this area as it is in, say, the C and C++ language specifications.
In view of that, I would account it a makefile flaw for any rule's target list to be empty (after macro expansion). Although the make you are presently using may accept it without complaint, other makes, including future versions of your present make, may reject it or worse.
Rule does expect one or more targets, there really are no two ways about it in the docs. For instance GNU make docs notation:
targets : prerequisites
recipe
Or 1p section manpage:
target [target...]: [prerequisite...][;command]
Illumos:
target [:|::] [dependency] ... [; command] ...
[command]
...
After all how would you refer to a target that had no name? I would assume no target rule should be an error...
However, I've tried different flavors of make (BSD, Illumos, GNU) and with varying degree of leniency (GNU make for instance seemed to also not care about syntax of prerequisites any more) or lack thereof they all seemed to have processed the line and possibly following tab indented block as a rule (with a recipe)... which then was ignored (also for the purpose of determining the default target).
I guess a rationale for this actually being consider valid Makefile... you could end up in this situation also with:
$(VAR):
#echo foobar
other:
#echo barbaz
In case VAR is undefined or empty, you'd end up with a such empty target as well.

Short/long options with option argument - is this some sort of convention? [duplicate]

This question already has answers here:
What is the general syntax of a Unix shell command?
(4 answers)
Closed 7 years ago.
It seems that most (a lot of) commands implement option arguments like this:
if a short option requires an option argument, the option is separated by a space from the option argument, e.g.
$ head -n 10
if a long option requires an option argument, the option is separated by a = from the option argument, e.g.
$ head --lines=10
Is this some sort of convention and yes, where can I find it? Besides, what's the reasoning?
Why e.g. is it not
$ head --lines 10
?
The short option rationale is documented in the POSIX Utility Conventions. Most options parsers allow the value to be 'attached' to the letter (-n10), mainly because of extensive historical precedent.
The long option rationale is specified by GNU in their Coding Standards and in the manual page for getopt_long().
Once upon a long time ago, in a StackOverflow of long ago, there was a question about command option styles. Not perhaps a good question, but I think the answers rescued it (but I admit to bias). Anyway, it has since been deleted, so I'm going to resuscitate my answer here because (a) it was a painful process to rediscover the answer and (b) it has useful information in it related to options.
How many different types of options do you recognize? I can think of many, including:
Single-letter options preceded by single dash, groupable when there is no argument, argument can be attached to option letter or in next argument (many, many Unix commands; most POSIX commands).
Single-letter options preceded by single dash, grouping not allowed, arguments must be attached (RCS).
Single-letter options preceded by single dash, grouping not allowed, arguments must be separate (pre-POSIX SCCS, IIRC).
Multi-letter options preceded by single dash, arguments may be attached or in next argument (X11 programs).
Multi-letter options preceded by single dash, may be abbreviated (Atria Clearcase).
Multi-letter options preceded by single plus (obsolete).
Multi-letter options preceded by double dash; arguments may follow '=' or be separate (GNU utilities).
Options without prefix/suffix, some names have abbreviations or are implied, arguments must be separate. (AmigaOS Shell, added by porneL)
Options taking an optional argument sometimes must be attached, sometimes must follow an '=' sign. POSIX doesn't support optional arguments meaningfully (the POSIX getopt() only allows them for the last option on the command line).
All sensible option systems use an option consisting of double-dash ('--') alone to mean "end of options" - the following arguments are "non-option arguments" (usually file names) even if they start with a dash. (I regard supporting this notation as an imperative.) Note that if you have a command cmd with an option -f that expects an argument, then if you invoke it with -- in place of the argument (cmd -f -- -other, many versions of getopt() will treat the -- as the file name for -f and then parse -other as regular options. That is, -- does not terminate the options if it has to be interpreted as an argument to another option.
Many but not all programs accept single dash as a file name to mean standard input (usually) or standard output (occasionally). Sometimes, as with GNU 'tar', both can be used in a single command line:
tar -cf - -F - | ...
The first solo dash means 'write to stdout'; the second means 'read file names from stdin'.
Some programs use other conventions — that is, options not preceded by a dash. Many of these are from the oldest days of Unix. For example, 'tar' and 'ar' both accept options without a dash, so:
tar cvzf /tmp/somefile.tgz some/directory
The dd command uses opt=value exclusively:
dd if=/some/file of=/another/file bs=16k count=200
Some programs allow you to interleave options and other arguments completely; the C compiler, make and the GNU utilities run without POSIXLY_CORRECT in the environment are examples. Many programs expect the options to precede the other arguments.
Modern programs such as git increasingly seem to use a base command name (git) followed by a sub-command (commit) followed by options (-m "Commit message"). This was presaged by the sccs interface to the SCCS commands, and then by cvs, and is used by svn too (and they are all version control systems). However, other big suites of commands adopt similar styles when it seems appropriate.
I don't have strong preferences between the different systems. When there are few enough options, then single letters with mnemonic value are convenient. GNU supports this, but recommends backing it up with multi-letter options preceded by a double-dash.
There are some things I do object to. One of the worst is the same option letter being used with different meanings depending on what other option letters have preceded it. In my book, that's a no-no, but I know of software where it is done.
Another objectionable behaviour is inconsistency in style of handling arguments (especially for a single program, but also within a suite of programs). Either require attached arguments or require detached arguments (or allow either), but do not have some options requiring an attached argument and others requiring a detached argument. And be consistent about whether '=' may be used to separate the option and the argument.
As with many, many (software-related) things — consistency is more important than the individual decisions.
Whatever you do, please, read the TAOUP's Command-Line Options and consider Standards for Command Line Interfaces. (Added by J F Sebastian — thanks; I agree.)

Is there a specification for a man page's SYNOPSIS section?

I'm trying to write some specifications to be shared between a small team and getting picky about the format I put some command listings in. Is there any formal definition of the syntax used in the SYNOPSIS section of man pages?
From the Wikimedia Commons, here's an example of a man page with the SYNOPSIS section I'm talking about, where the command is listed with the required and optional arguments it understands.
There is no formal definition of a manpage anywhere, not even in the POSIX standard. The man(1) manpage in your example is pretty typical: you write out the various ways a program can be used (often just one) with [] denoting optional, bold (or typewriter font with the mdoc macros) denoting literal command line input and italics denoting variables.
The manpages man(7) and mdoc(7) will explain the most important conventions. man(7) is for old-style Unix manpages and is still popular on Linux (see man-pages(7)); mdoc(7) comes from 4.4BSD and is popular in its derivatives. The latter maintains a stricter separation of content and presentation and can produce (IMHO) prettier PDF/HTML output
The utility conventions for utilities are documented in in Chapter 12. Utility conventions of the IEEE Std 1003.1, 2004 Edition.
A newer edition of this document exists here
man 7 man-pages:
briefly describes the command or function's interface. For commands,
this shows the syntax of the command and its arguments (including
options); boldface is used for as-is text and italics are used to
indicate replaceable arguments. Brackets ([]) surround optional
arguments, vertical bars (|) separate choices, and ellipses (...) can
be repeated. For functions, it shows any required data declarations
or #include directives, followed by the function declaration.

How similar/different are gnu make, microsoft nmake and posix standard make?

How similar/different are gnu make, microsoft nmake and posix standard make?
Obviously there's things like "which OS?", "which compiler?" and "which linker?", but I'm referring specifically to the syntax, semantics and command-line options of the makefiles themselves.
If I write makefiles based on manuals for gnu make, what are the most important portability issues that I need to be aware of?
GNU Make and POSIX Make share a common core so that GNU Make understands makefiles intended for POSIX Make and interprets them the same way - with very few exceptions. However, many GNU Makefiles use features that are only available in GNU Make. Sometimes this is deliberate and conscious; sometimes it isn't (and "sometimes isn't" is a problem). I'm less familiar with Microsoft nmake; I believe it is likely to hew close to the POSIX Make semantics at its core, but it will have its own divergent set of extensions.
Generally speaking, what the programs like autoconf produce are close to portable Makefiles.
The main things to be beware of using GNU Make are all the extended function notations for mapping file names (macros) into useful values. While they are undoubtedly useful, they are also a trap for portability.
The '%.x' notations for suffix rules are not defined by the POSIX specification for make — they are recognized as a common extension:
The interpretation of targets containing the characters '%' and '"' is implementation-defined.

Resources