Anonymous | Login | 2024-12-12 16:21 UTC |
Main | My View | View Issues | Change Log | Docs |
Viewing Issue Simple Details [ Jump to Notes ] | [ Issue History ] [ Print ] | ||||||
ID | Category | Severity | Type | Date Submitted | Last Update | ||
0000514 | [1003.1(2008)/Issue 7] Shell and Utilities | Objection | Enhancement Request | 2011-11-17 00:21 | 2024-06-11 08:53 | ||
Reporter | dwheeler | View Status | public | ||||
Assigned To | ajosey | ||||||
Priority | normal | Resolution | Accepted As Marked | ||||
Status | Closed | ||||||
Name | David A. Wheeler | ||||||
Organization | |||||||
User Reference | |||||||
Section | make | ||||||
Page Number | 2918 | ||||||
Line Number | 95928-95954 | ||||||
Interp Status | --- | ||||||
Final Accepted Text | Note: 0005962 | ||||||
Summary | 0000514: Enhance internal macros in make | ||||||
Description |
The set of make's internal macros is expanded in some make implementations, or have various restrictions removed. The "$<" value has special-case restrictions; remove them. Also, add $^ (list all prerequisites without dups) and $+ (list all prerequisites with dups - e.g., for linking). |
||||||
Desired Action |
Change the definition of "$<" to: The name of the first prerequisite. (Note that this generalizes $<, eliminating special-case restrictions.) Add: $^ A list of all the prerequisites, with a space or tab between each. Duplicates are removed. If a prerequisite is an archive member, only the named member is used. $+ A list of all prerequisites, with a space or tab between each. Duplicates are not removed, and must be duplicated in the order they were listed in the makefile. { This is like `$^', but prerequisites listed more than once are duplicated in the order they were listed in the makefile. This is primarily useful for use in linking commands where it is meaningful to repeat library file names in a particular order. |
||||||
Tags | issue8 | ||||||
Attached Files | |||||||
|
Relationships | |||||||
|
Notes | |
(0001026) joerg (reporter) 2011-11-17 11:08 |
If $< is discussed, then $* needs to be discussed at the same time. I strongly object to remove the restrictions from $< and $* as the fact that some implementations (e.g. SunPro make and gmake) return a non-blank value for $< and $* for non-inference rules is a non-portable side-effect of the respective implementation. smake's implementation does not have this side effect and smake for this reason explicitely warns that a non-portable makefile was encountered. Also note that SunPro make and gmake return different results for $< and $* as the expansion for these variables depends on different side effects. For a non-inference rule, it is (in gneneral) not possible to define an "implicit source" ($<). For s non-inference rule, it is typically impossible to define a "file name base" without "suffix" as only a matching suffix rule is able to define the suffix to strip. Note that a sketchy test for the behavior of $< with SunPro make and gmake may return the same results, the behavior differs general. |
(0001030) Konrad_Schwarz (reporter) 2011-11-17 16:30 |
Using $^ or $+ to specify the prerequistes of a link command together with automatic make dependency creation is asking for trouble. If a makefile contains a dependency of the form a.out: timestamp.c and the compiler is invoked such as to create dependency files, any file header.h included by timestamp.c will be turned into a dependency of a.out, causing the next build to invoke $(CC) $(CFLAGS) timestamp.c header.h -o a.out On the other hand, if you have, say, a dependency upon a linker script file which must be adjacent to some flag -T, the $^ mechanism is again insufficient. So the utility of $^ and $+ is limited. |
(0001088) psmith (developer) 2012-01-07 00:06 |
Regarding comment #1026: This bug doesn't discuss $* and I don't agree with the statement "$* needs to be discussed at the same time"... why is that a requirement? $* is a difficult question for non-inference rules, I agree, and it should be handled under a different bug, if at all. As for $<, I don't agree with the statement "for a non-inference rule, it is ... not possible to define ... $<". There is a simple algorithm for determining $< for any rule, inference or non-inference, which yields a deterministic, useful result. Regarding comment #1030: It may be true that $^ and $+ are not useful in the specific situation you describe, but it's easy to come up with many other situations where they are useful. Jumping from "they won't help in the case XYZ" to "[their] utility is limited" is not warranted. Where they don't work, there's no need to use them. Make is used for a LOT of other purposes than linking of C-like code. |
(0001193) joerg (reporter) 2012-04-10 16:38 |
Expanding $< for explicit rules seems to be a GNUism and is not implemented in important other make programs see: echo > a echo > b cat Makefile all: a b echo "'"$<"'" gmake echo "'"a"'" 'a' make # this is the Solaris make program echo "'""'" '' smake # This is the Schily smake program smake: WARNING: requesting implicit dynmac '$<' for explicit target 'all' smake: WARNING: expanding implicit dynmac '$<' to '' smake: WARNING: Current working directory: '/tmp', Makefile 'Makefile' echo "'""'" '' As an important note: the internal data structures, used by various make programs are expected to differ from those used in gmake. Something that works in gmake may not be easy to implement in other make versions. I believe that the original reporter should verify that his expected new behavior may be implemented with the important make implementations without causing problems. Given the differences while discussing $^ and $+, it may be a good idea to delay the discussion for these macros. A discussion of $^ and $+ could be started after an agreement on $< could be found. |
(0004703) Love4Boobies (reporter) 2019-12-25 10:20 |
Regarding comment #0001030: That is not at all how $^ is supposed to be used. It's supposed to be used to generate library or executable files from object files. It seems very important to add this to make for the following reason: executable: obj1 obj2 $(CC) $(LDFLAGS) -o $@ $? If we touch obj1 or obj2 but not the other one, then our rule will not work properly. However, if $^ is used instead, then both obj1 and obj2 would be linked. This is really a must-have. |
(0004709) Konrad_Schwarz (reporter) 2020-01-07 09:14 |
Re Note: 0004703: I stand by my assertion, you have misunderstood the note. To expand on Note: 0001030 : Non-trivial applications will tend to have executable files depend not only on object files, but also on (say) C files. A typical example is a C file containing the timestamp of the link, this could be coded as file "timestamp.c" char const my_executables_link_time [] = __DATE__ " " __TIME__; This file should include a header file declaring the global variable my_executable_link_time, say "header.h", so it starts off with # include "header.h" By far the best way to handle header file dependency lists is for the compiler to generate them automatically, ideally as a by-product of the previous compilation, e.g. using GCC's -MD flag (the dependency files can be included using -include *.d in the Makefile, thus causing no error during the first compilation). The rule of the form a.out: timestamp.c causes an additional dependency of the form a.out: header.h to be generated. This is entirely correct, since a change to header.h should cause a.out to be recompiled. However, if your link rule uses $^ instead of explicitly listing the object files (possibly via a macro such as $(OBJS), the linker receives the "header.h" as a file to be linked (or possibly compiled), which is wrong. Hence my assertion that use of $^ is asking for trouble. I invariably end up listing the object files explicitly in an OBJS macro. I don't think standardizing $^ or $+ is worth the trouble. |
(0004711) psmith (developer) 2020-01-07 14:41 |
Regarding the comments in http://austingroupbugs.net/view.php?id=514#c4709: [^] I don't think anyone is arguing that $^ is useful in the environment you describe. But as I noted above, suggesting that anything that is not useful when using make to compile C (and C-like) binaries is too limited. Make is used for many, many purposes beyond that and lots of them do not have the issues you raise. Further, many makefiles don't have easy access to all the dependency files in a single variable: they may use multiple target/dependency statements possibly scattered all over the place, possibly even across included makefiles: all: ; @echo "built targets $+ out of $^" all: foo ... all: bar ... all: baz Finally, even in C/C-like languages your use-case is actually pretty rare. It's almost never the case that people list header files as prerequisites of _programs_: header files are prerequisites of _object files_. Most makefiles separate compilation and linkage into two different rules, otherwise changes to any header or source file requires the entire program to be recompiled. This means that linking rules list only object files as prerequisites, not header files, and $^ is perfect for this. |
(0004723) Love4Boobies (reporter) 2020-01-13 04:53 edited on: 2020-01-13 05:19 |
I don't think I've misunderstood the note, it's just that you want to use $^ as a replacement for something that it's not supposed to replace. Its use lies elsewhere, where there is nothing in the standard that offers a replacement. Another example would be pattern rules. You cannot use a variable like that in a pattern rule because each target has its own set of prerequisites. Consider the following: foo.a: foo.c %.a: %.b echo $^ This would echo "foo.b foo.c" for target "foo.a" and only "bar.b" for target "bar.a". It is impossible to do this with user-defined variables, except if you give up pattern rules and define each rule explicitly, as "foo.a" has extra prerequisites to process. The $@ variable would only print "foo.b" since it has nothing to do with the rule being evaluated so we'd miss an important prerequisite. I don't think that putting an artificial limitation on the standard because we can contrive examples where people might use a feature in an unintended way and get unwanted results is the way to go. The $^ variable is already used in practice and it helps to write more maintainable makefiles. |
(0004726) Konrad_Schwarz (reporter) 2020-01-13 09:19 |
Re: Note: 0004723 From my point of view, a better way to solve this problem is via recursive macro expansion: .SUFFIXES: .a .b .b.a: echo $< $(EXTRA_$*) EXTRA_foo = foo.c foo.a: $(EXTRA_foo) |
(0004727) Love4Boobies (reporter) 2020-01-13 09:29 |
I don't see how having to scan the makefiles for variable definitions and trying to figure out what things expand to is simpler than simply using $^, which is clear as day. Not to mention that you can't really do that if EXTRA_foo's contents come from an automatically generated dependency file without going further down the hackery rabbit hole. Also, computed variables, like $(EXTRA_$*), are not even part of POSIX make. |
(0005962) geoffclare (manager) 2022-09-08 15:53 edited on: 2022-09-08 15:54 |
On D2.1 page 2947 line 98895, after applying bug 1520, change:The $^ macro shall evaluate to the list of prerequisites for the current target.to: The $^ macro shall evaluate to the list of prerequisites for the current target, with any duplicates (except the first) removed. On D2.1 page 2947 after line 98895 add: $+The $+ macro shall be equivalent to $^, except that duplicates shall not be removed; all prerequisites shall appear in the order they were listed in the makefile. |
Issue History | |||
Date Modified | Username | Field | Change |
2011-11-17 00:21 | dwheeler | New Issue | |
2011-11-17 00:21 | dwheeler | Status | New => Under Review |
2011-11-17 00:21 | dwheeler | Assigned To | => ajosey |
2011-11-17 00:21 | dwheeler | Name | => David A. Wheeler |
2011-11-17 00:21 | dwheeler | Section | => make |
2011-11-17 00:21 | dwheeler | Page Number | => 2918 |
2011-11-17 00:21 | dwheeler | Line Number | => 95928-95954 |
2011-11-17 11:08 | joerg | Note Added: 0001026 | |
2011-11-17 16:30 | Konrad_Schwarz | Note Added: 0001030 | |
2012-01-07 00:06 | psmith | Note Added: 0001088 | |
2012-04-10 16:38 | joerg | Note Added: 0001193 | |
2019-12-25 10:20 | Love4Boobies | Note Added: 0004703 | |
2020-01-07 04:33 | Love4Boobies | Issue Monitored: Love4Boobies | |
2020-01-07 09:14 | Konrad_Schwarz | Note Added: 0004709 | |
2020-01-07 14:41 | psmith | Note Added: 0004711 | |
2020-01-13 04:53 | Love4Boobies | Note Added: 0004723 | |
2020-01-13 04:53 | Love4Boobies | Note Added: 0004724 | |
2020-01-13 04:54 | Love4Boobies | Note Deleted: 0004724 | |
2020-01-13 05:04 | Love4Boobies | Note Edited: 0004723 | |
2020-01-13 05:06 | Love4Boobies | Note Edited: 0004723 | |
2020-01-13 05:07 | Love4Boobies | Note Edited: 0004723 | |
2020-01-13 05:08 | Love4Boobies | Note Edited: 0004723 | |
2020-01-13 05:10 | Love4Boobies | Note Edited: 0004723 | |
2020-01-13 05:19 | Love4Boobies | Note Edited: 0004723 | |
2020-01-13 09:19 | Konrad_Schwarz | Note Added: 0004726 | |
2020-01-13 09:29 | Love4Boobies | Note Added: 0004727 | |
2022-09-08 15:20 | geoffclare | Relationship added | related to 0001520 |
2022-09-08 15:53 | geoffclare | Note Added: 0005962 | |
2022-09-08 15:54 | geoffclare | Note Edited: 0005962 | |
2022-09-08 15:55 | geoffclare | Interp Status | => --- |
2022-09-08 15:55 | geoffclare | Final Accepted Text | => Note: 0005962 |
2022-09-08 15:55 | geoffclare | Status | Under Review => Resolved |
2022-09-08 15:55 | geoffclare | Resolution | Open => Accepted As Marked |
2022-09-08 15:55 | geoffclare | Tag Attached: issue8 | |
2022-10-21 09:12 | geoffclare | Status | Resolved => Applied |
2024-06-11 08:53 | agadmin | Status | Applied => Closed |
Mantis 1.1.6[^] Copyright © 2000 - 2008 Mantis Group |