3 ms·
Does the "?=" operator behave like ":=" or like "=" ?
by ufo 8y ago
Does the "?=" operator behave like ":=" or like "=" ?
- jgrahamc 8y agoBoth $ cat Makefile $(info FOO $(flavor FOO)) FOO ?= foo $(info FOO $(flavor FOO)) BAR := $(info BAR $(flavor BAR)) BAR ?= bar $(info BAR $(flavor BAR)) BAZ = $(info BAZ $(flavor BAZ)) BAZ ?= baz $(info BAZ $(flavor BAZ)) $ make FOO undefined FOO recursive BAR simple BAR simple BAZ recursive BAZ recursive If undefined then becomes recursive, otherwise the flavour is preserved.
- wahern 8y agoMake variable expansions are always recursive. For what you're describing I think the proper term as used by the GNU Manual is deferred. In other languages the phrase lazy evaluation is common. The one thing I've always had trouble remembering with GNU Make is precedence. Variables defined as command-line arguments (make FOO=bar) override assignments, but environment variables (FOO=bar make) only override ?= assignments. != is both immediate (the shell expansion) and deferred (the result of the shell expansion). I feel like there's some inconsistency when variables are inherited across recursive invocations, but in a simple test with make 3.81 (macOS) I couldn't find any. Maybe my suspicion is just a byproduct of my weird inability to remember the precedence rules. I normally try to stick to portable make these days, anyhow. Between the ancient version of GNU Make on macOS, OpenBSD Make, and NetBSD Make, you're mostly stuck with POSIX syntax. If you add Solaris' default make, and especially if you add AIX' make, you can't rely on any extensions at all. For me sticking with portable make is easier than installing and maintaining GNU Make on every flavor of operating system I test on, and definitely easier than installing autotools or installing and maintaining the most recent version of CMake.
- jgrahamc 8y agoThe GNU Make manual defines two variable types: recursively expanded and simple (see: https://www.gnu.org/software/make/manual/html_node/Flavors.html https://www.gnu.org/software/make/manual/html_node/Flavors.h...).