[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [Question] Set a variable while building a specific target
From: |
Masahiro Yamada |
Subject: |
Re: [Question] Set a variable while building a specific target |
Date: |
Sat, 22 May 2021 23:58:52 +0900 |
Hi Paul,
Thanks for the comments.
On Sat, May 22, 2021 at 10:33 PM Paul Smith <psmith@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