Hi Paul, I don't know if this is related to gcc support of c++20. But mentioning target.o ("x.o") and recipe or not in my Makefile, does have different result. My test follows.
Thanks --- 1. error: with target.o ("x.o"), without recipe $ ls a.cpp b.cpp c.cpp d.cpp main.cpp Makefile $ $ cat Makefile CXXFLAGS = -Wall -Wextra -std=c++2a -fmodules-ts -g # -O3 -fPIC main : c.o b.o a.o d.o main.o # $(CXX) $^ -o $@ $ make g++ -Wall -Wextra -std=c++2a -fmodules-ts -g -c -o main.o main.cpp In module imported at main.cpp:1:1: A: error: failed to read compiled module: No such file or directory A: note: compiled module file is ??gcm.cache/A.gcm?? A: note: imports must be built before being imported A: fatal error: returning to the gate for a mechanical issue compilation terminated. make: *** [<builtin>: main.o] Error 1 $ 2. ok: without target.o and recipe $ rm -fr *.o gcm.cache main $ cat Makefile CXXFLAGS = -Wall -Wextra -std=c++2a -fmodules-ts -g # -O3 -fPIC main : c.o b.o a.o d.o # main.o # $(CXX) $^ -o $@ $ make g++ -Wall -Wextra -std=c++2a -fmodules-ts -g -c -o c.o c.cpp g++ -Wall -Wextra -std=c++2a -fmodules-ts -g -c -o b.o b.cpp g++ -Wall -Wextra -std=c++2a -fmodules-ts -g -c -o a.o a.cpp g++ -Wall -Wextra -std=c++2a -fmodules-ts -g -c -o d.o d.cpp g++ -Wall -Wextra -std=c++2a -fmodules-ts -g main.cpp c.o b.o a.o d.o -o main $ 3. ok: with target.o and recipe $ rm -fr *.o gcm.cache main $ cat Makefile CXXFLAGS = -Wall -Wextra -std=c++2a -fmodules-ts -g # -O3 -fPIC main : c.o b.o a.o d.o main.o $(CXX) $^ -o $@ $ make g++ -Wall -Wextra -std=c++2a -fmodules-ts -g -c -o c.o c.cpp g++ -Wall -Wextra -std=c++2a -fmodules-ts -g -c -o b.o b.cpp g++ -Wall -Wextra -std=c++2a -fmodules-ts -g -c -o a.o a.cpp g++ -Wall -Wextra -std=c++2a -fmodules-ts -g -c -o d.o d.cpp g++ -Wall -Wextra -std=c++2a -fmodules-ts -g -c -o main.o main.cpp g++ c.o b.o a.o d.o main.o -o main $ $ make --version GNU Make 4.3 Built for x86_64-pc-linux-gnu Copyright (C) 1988-2020 Free Software Foundation, Inc. License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html> This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law. $ ------------------ ???????? ------------------ ??????: "psmith"<psm...@gnu.org>; ????????: 2022??8??11??(??????) ????2:31 ??????: "ljh"<l...@qq.com>; "bug-make"<bug-make@gnu.org>; ????: Re: Implicit rule for linking multiple object files On Thu, 2022-08-11 at 01:58 +0800, ljh wrote: > I have three c source files: x.c, y.c, z.c and I name x as the target > on left. Can I put x.o in the prerequisites on the right too? Are > they the same, with or without x.o in the prerequisites on the right? > ?0?2 ?0?2 > ?0?2 ?0?2 x: y.o z.o x.o ?0?2# with x.o It is correct to do this. These two rules do not behave exactly the same: x: y.o z.o versus x: y.o z.o x.o (you can see the difference for yourself by running "make" both ways) but the result of both of these will give you the same working program. > Is it correct for me to use patsubst function to include all object > files? > ?0?2 ?0?2 x: $(patsubst %.c,%.o,$(wildcard *.c)) This is fine too. > In my test the rule with patsubst works on most cases. But if my code > uses C++20 modules, I need to omit x.o if I want to omit the recipe: > ?0?2 ?0?2 x: y.o z.o ?0?2# without x.o and recipe > > if I include x.o, I can't omit the recipe: > ?0?2 ?0?2 ` x: y.o z.o x.o ` # with x.o?0?2 > ?0?2 ?0?2 ` ?0?2 ?0?2$ (CXX) $ (LDFLAGS) $^ $(LDLIBS) -o $@ ` # with recipe I don't know why you keep referring to C++20 modules. Make doesn't know anything about C++20 modules, it doesn't even know what version of C++ the compiler is building with. It barely even knows that there is such a thing as C++: all it knows is "some source files end in .cpp or .cc or .cxx and those should be built with a recipe that uses variables CXX and CXXFLAGS". In any event, I see no reason why an implicit rule without a recipe and with x.o as a prerequisite wouldn't work. In fact, it works fine for me: $ ls Makefile x.c y.c z.c $ cat Makefile x: $(patsubst %.c,%.o,$(wildcard *.c)) $ make cc -c -o x.o x.c cc -c -o y.o y.c cc -c -o z.o z.c cc x.o y.o z.o -o x