bug-make
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Implicit rule for linking multiple object files


From: Philip Guenther
Subject: Re: Implicit rule for linking multiple object files
Date: Wed, 10 Aug 2022 22:12:24 -0900

The first place to consult in understanding how to build your code is the documentation of your compiler.  C++20 *module* support is very new in at least gcc and they have not provided direct guidance on how to use modules with 'make', at least I don't see any such guidance here:
  https://gcc.gnu.org/onlinedocs/gcc-12.1.0/gcc/C_002b_002b-Modules.html#C_002b_002b-Modules

Instead they have a link to an outside whitepaper.  Ideally, the gcc developers would work with the GNU make developers to provide rules and documentation that would solve your problems.  They have not yet done so.  Your choices are:
 * to work it out
 * to wait until they provide that guidance
 * to find another compiler and/or build system

To be blunt, the questions you're asking about make behavior indicate that it will require a dedicated effort for you to develop the correct rules yourself.  While at least one workaround has already been proposed (declare a.o, b.o, c.o, and d.o. as prerequisites of main.o) that is almost certainly specific to the modules and classes involved here and if this project grows a more complex module/class layout additional, possibly conflicting rules will be required.  A solution which is robust to future code/design changes really requires a broad view of the dependency structure of the C++ module implementation...which is where guidance from the C++ compiler developers would *really* be useful.

Good luck.

Philip Guenther


On Wed, Aug 10, 2022 at 9:19 PM ljh <ljhm@qq.com> wrote:
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"<psmith@gnu.org>;
发送时间: 2022年8月11日(星期四) 凌晨2:31
收件人: "ljh"<ljhm@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?
>    
>     x: y.o z.o x.o  # 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?
>     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:
>     x: y.o z.o  # without x.o and recipe

> if I include x.o, I can't omit the recipe:
>     ` x: y.o z.o x.o ` # with x.o 
>     `    $ (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

reply via email to

[Prev in Thread] Current Thread [Next in Thread]