Hi Paul, Thanks for the comments. On Sat, May 22, 2021 at 10:33 PM Paul Smith <psm...@gnu.org> wrote: > > On Sat, 2021-05-22 at 21:13 +0900, Masahiro Yamada wrote: > > - 'make vmlinux modules' builds __common with > > BUILDING_VMLINUX=y and BUILDING_MODULES=y > > > > I know the example above does not work like that. > > This is the part that won't work; the rest works fine AFAICS. > > The problem is a common misconception, that make targets are like > functions or subroutines. They are not: they are recipes to build > files. Even .PHONY targets. > > This means that once a target is built one time in a makefile it will > _never be built again_ (in that run of make). So, unlike a function or > a subroutine you can't "call" a target multiple times in a makefile. > > So you cannot collect a "common part" of a recipe into a separate > target that is depended on by multiple other targets, if you need that > common part to be run multiple times. It just doesn't work like that.
I do not want to run the common part multiple times. I want to avoid race in parallel builds (see below). This is what I want to achieve: In Linux kernel build system, the __common part is a sub-make ($(MAKE) -C common) to build: (a) objects only needed for vmlinux (b) objects only needed for modules (c) objects needed by both of them If the BUILDING_VMLINUX flag is set, I want to build (a) + (c) in the sub-make. If the BUILDING_MODULES flag is set, I want to build (b) + (c) in the sub-make. If both of the flags are set, I want to build (a) + (b) + (c) in the sub-make. > You could put the common part into a variable and then use that > variable in all the targets, something like this: > > define __common > @echo BUILDING_VMLINUX is $(BUILDING_VMLINUX) > @echo > BUILDING_MODULES is $(BUILDING_MODULES) > [ common build rules, > which internally uses > BUILDING_{VMLINUX,MODULES} conditionals > ] > endef > > .PHONY: vmlinux modules > > vmlinux: export BUILDING_VMLINUX=y > modules: export BUILDING_MODULES=y > > vmlinux modules: > $(__common) If I implement this way, "make linux modules -j<N>" is a problem for me; two threads would try to build (c) simultaneously, then end up with corrupted files. If I use the grouped target, vmlinux modules &: $(__common) The $(__common) is run just once, but BUILDING_MODULE is not set. -- Best Regards Masahiro Yamada