Austin Group Defect Tracker

Aardvark Mark IV


Viewing Issue Simple Details Jump to Notes ] Issue History ] Print ]
ID Category Severity Type Date Submitted Last Update
0001890 [1003.1(2024)/Issue8] Shell and Utilities Editorial Clarification Requested 2024-12-11 17:36 2025-01-17 22:15
Reporter steffen View Status public  
Assigned To
Priority normal Resolution Accepted As Marked  
Status Resolved  
Name steffen
Organization
User Reference
Section make
Page Number ~3146 ff.
Line Number ~106054 ff.
Interp Status ---
Final Accepted Text Note: 0007051
Summary 0001890: make: inference rules: clarify relation to relative paths
Description This relates a bit to c17(1)s saying
<code>
  If the -c option is specified and the -o option is not
  specified, for all pathname operands of the form file.c or
  file.i, the files:
    $(basename pathname .c).o
  ...
  respectively shall be created as the result of successful compilation.
</code>

make says (on page 3135)
<code>
105578 For each pathname so identified, in the order specified:
105579 • If the pathname does not begin with a '/', it shall be treated as relative to the current
105580 working directory of the process, not relative to the directory containing the makefile.
</code>

So these are relative paths which may include directory components.
Yet inference rules use eg
<code>
106068 .c.o:
106069 $(CC) $(CFLAGS) -c $<
</code>
Not all, though, unless i am mistaken:
<code>
106055 .c:
106056 $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $<
</code>

It happened to me that a little project ran against the wall when cross-testing. It worked with GNU make, but failed with (Free/Net)BSD make (bmake) as well as Jörgs smake:

<code>
  ...
  gcc -O1 -g -std=c99 -Ilibdivsufsort -I. -c -o libdivsufsort/trsort.o libdivsufsort/trsort.c
  gcc -O1 -g -std=c99 -Ilibdivsufsort -I. -c -o s-bspatch.o s-bspatch.c
  ar crs libsbsdipa.a s-bsdiff.o libdivsufsort/divsufsort.o libdivsufsort/sssort.o libdivsufsort/trsort.o s-bspatch.o

versus

  ...
  gcc -O1 -g -std=c99 -Ilibdivsufsort -I. -c libdivsufsort/trsort.c
  gcc -O1 -g -std=c99 -Ilibdivsufsort -I. -c s-bspatch.c
  ar crs libsbsdipa.a s-bsdiff.o libdivsufsort/divsufsort.o libdivsufsort/sssort.o libdivsufsort/trsort.o s-bspatch.o
  ar: libdivsufsort/divsufsort.o: No such file or directory
</code>
Desired Action If it were me i would clarify that paths must be kept intact.
This may include adjustment of the example inference rules.
I am not unrolling this now (but could give it a shot shall it be desired).
Tags tc1-2024
Attached Files

- Relationships

-  Notes
(0007004)
steffen (reporter)
2024-12-12 19:04

P.S.: the wonderful Simon Gerraty, (one of the) author(s) of bmake, pointed out to that bmake just this year (2024-01-28) got a new (yet undocumented) feature which results in the behaviour that "i want".
I have thus added the following magical line to the makefile of my project:
<code>
OBJS_SRCS_FILTER = T R
</code>
(0007005)
steffen (reporter)
2024-12-12 19:27

P.P.S.: just to add he explained it as
<code>
it gets applied as

OBJS+= ${SRCS:N*.h:${OBJS_SRCS_FILTER:ts:}:S/$/.o/g}
</code>
so that everybody knows.
(0007007)
steffen (reporter)
2024-12-13 17:36

P.P.P.S.: if i understood Simon right he would be willing to do something under .POSIX aegis.
(I will test the project on Solaris and OpenBSD soon, then one more post from myself.)
(0007008)
steffen (reporter)
2024-12-14 01:55

Or, how about changing the default inference rule to

<code>
  .c.o:
        $(CC) $(CFLAGS) -o $(<:.c=.o) -c $<
</code>

If one includes .y in .SUFFIXES, and in some top makefile eg

<code>
SUBDIRS = lib s-bsdipa

.SUFFIXES: # 4 smake
.DEFAULT:
        for i in $(SUBDIRS); do (cd "$$i" && $(MAKE) $@) || exit; done

distclean: clean
</code>

and empty .SUFFIXES so that smake does not try to do something like

<code>
$ smake all
...for i in lib s-bsdipa; do (cd "$i" && smake all.y) || exit; done
</code>

then this is just nicely supported it seems.
Anyhow the bmake trick from above does not work, i do not know why it worked yesterday, today it does not.
A nice weekend everybody, i wish.
(0007009)
psmith (developer)
2024-12-16 14:46

Using $(<:.c=.o) is not a good idea. When make invokes a recipe it puts the target that it expects to be built in $@. If a recipe does not build that target, then the recipe is malformed and make will not work correctly.

If $@ is not the same file as $(<:.c=.o), then the next time make is invoked it will check the existence / modification time of the target that it expects to be built, it will not have been updated by the previous invocation of make since make built some other file, and it will re-run that recipe again.
(0007040)
geoffclare (manager)
2025-01-09 17:03

After page 3148 line 106150 section make (APPLICATION USAGE), add a paragraph:
The default .c.o rule and other default inference rules that use <tt>$(CC)</tt> with the -c option can only portably be used to operate on files in the current directory. This is because the c17 utility creates the .o file in the current directory, even if the .c file is in a different directory. An explicit .c.o rule can operate on files in other directories by using the -o option in addition to -c.
(0007042)
psmith (developer)
2025-01-09 17:45

Geoff, I think "an explicit .c.o rule" is a bit confusing, by suggesting an explicit inference rule. I wonder if we shouldn't choose a different word just to be cautious. Maybe suggest that the default .c.o inference rule can be redefined to use the -o option in addition to -c?
(0007043)
steffen (reporter)
2025-01-09 17:58

Any portability hint would be appreciated i think.
(I kept on using $(<:.c=.o) despite Paul's comment since i am in the lucky position that the subdirectory files come from an external project and are thus "constant" from our point of view.)
(0007051)
geoffclare (manager)
2025-01-16 16:25

After page 3148 line 106150 section make (APPLICATION USAGE), add a paragraph:
The default .c.o rule and other default inference rules that use <tt>$(CC)</tt> with the -c option can only portably be used to operate on files in the current directory. This is because the c17 utility creates the .o file in the current directory, even if the .c file is in a different directory. A .c.o rule in the makefile (overriding the default rule) can operate on files in other directories by using the -o option in addition to -c. For example:
.c.o:
    $(CC) $(CFLAGS) -c -o $@ $<
(0007053)
psmith (developer)
2025-01-16 18:08

Looks very readable (and correct) thanks for that effort Geoff!
(0007054)
steffen (reporter)
2025-01-17 22:15

Yes, i concur. Thanks for the effort. (I changed the project accordingly, with credit.)

- Issue History
Date Modified Username Field Change
2024-12-11 17:36 steffen New Issue
2024-12-11 17:36 steffen Name => steffen
2024-12-11 17:36 steffen Section => make
2024-12-11 17:36 steffen Page Number => ~3146 ff.
2024-12-11 17:36 steffen Line Number => ~106054 ff.
2024-12-12 19:04 steffen Note Added: 0007004
2024-12-12 19:27 steffen Note Added: 0007005
2024-12-13 17:36 steffen Note Added: 0007007
2024-12-14 01:55 steffen Note Added: 0007008
2024-12-16 14:46 psmith Note Added: 0007009
2025-01-09 17:03 geoffclare Note Added: 0007040
2025-01-09 17:04 geoffclare Interp Status => ---
2025-01-09 17:04 geoffclare Final Accepted Text => Note: 0007040
2025-01-09 17:04 geoffclare Status New => Resolved
2025-01-09 17:04 geoffclare Resolution Open => Accepted As Marked
2025-01-09 17:05 geoffclare Tag Attached: tc1-2024
2025-01-09 17:45 psmith Note Added: 0007042
2025-01-09 17:58 steffen Note Added: 0007043
2025-01-16 16:25 geoffclare Note Added: 0007051
2025-01-16 16:27 geoffclare Final Accepted Text Note: 0007040 => Note: 0007051
2025-01-16 18:08 psmith Note Added: 0007053
2025-01-17 22:15 steffen Note Added: 0007054


Mantis 1.1.6[^]
Copyright © 2000 - 2008 Mantis Group
Powered by Mantis Bugtracker