Re: Automatic secondary intermediate target deduction

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

 



Hi Jason,


On Sat, Nov 17, 2018 at 5:39 PM Jason A. Donenfeld <Jason@xxxxxxxxx> wrote:
>
> Hello,
>
> The tree used to put patterns in the .PRECIOUS target to prevent make
> from cleaning up intermediate files. Masahiro realized this was wrong
> and moved this to the .SECONDARY target instead, while also generally
> ensuring things wind up in the $(targets) variable, which is nice
> because it means those intermediate files are correctly cleaned up by
> `make clean`. This is great, but it comes with some issues, which I've
> now worked around, but I wanted to run the whole reasoning and
> solution by you.
>
> A great thing about the build system is that you can write "widgets-y
> += acmelib.o", and it will automatically figure out whether that
> should be built from a .c or a .o or from something else. But what if
> the chain is actually .pl -> .S -> .o? In that case it's standard to
> add a rule for that in the subdirectory's makefile:
>
> quiet_cmd_perlasm = PERLASM $@
>      cmd_perlasm = $(PERL) $< > $@
> %.S: %.pl
>        $(call cmd,perlasm)
>
> This works fine and is boring and standard, but we still need to add
> those intermediate .S files to $(targets).
>
> Consider a general structure of a makefile like this:
>
> widgeter_snickers-y := snickers/snickers.o
> widgeter_snickers-$(CONFIG_SNICKER_MEGA) += snickers/snickers-mega.o
> widgeter_snickers-$(CONFIG_SNICKER_TINY) += snickers/snickers-tiny.o
> obj-$(CONFIG_SNICKERVILLE) += widgeter_snickers.o
>
> widgeter_skittles-y := skittles/skittles.o
> widgeter_skittles-$(CONFIG_SKITTLE_BLUE) += skittles/skittles-blue.o
> widgeter_skittles-$(CONFIG_SKITTLE_RED) += skittles/skittles-red.o
> widgeter_skittles-$(CONFIG_SKITTLE_GREEN) += skittles/skittles-green.o
> obj-$(CONFIG_SKITTLEMESA) += widgeter_skittles.o
>
> Some of those .o might come from .c, others from .S, and others from
> .pl->.S->.o. Our goal is to compute a list of all of the file's .S
> that come from .pl. It's important that we allow this to work both
> when the CONFIG_* variables are present (Makefile.build) and when the
> CONFIG_* variables aren't present, since Makefile.clean doesn't
> include auto.conf. Here's how we're going to do it:
>
> 1. Expand obj-*, remove the .o suffix, and treat as a variable, and
> then expand the -* of those variables:
>
> part1 := $(foreach t,$(patsubst %.o,%,$(obj-) $(obj-m)
> $(obj-y)),$($(t)-) $($(t)-y))
>
> Now $(part1) contains all of the *.o files we wrote into the above file.
>
> 2. Replace all of the *.o files with a corresponding *.pl and tack on
> the full path:
>
> part2 := $(patsubst %.o,$(srctree)/$(src)/%.pl,$(part1))
>
> Now $(part2) contains full paths of potential .pl files.
>
> 3. Remove from the list all *.pl files that don't actually exist
> (since the .o might be coming from a .c or directly a .S instead):
>
> part3 := $(wildcard $(part2))
>
> Now $(part3) contains full paths of existing .pl files that correspond
> to the makefile's explicitly listed .o files.
>
> 4. Remove the full path prefix and change the .pl suffix to a .S
> suffix, so that it represents the intermediate file:
>
> part4 := $(patsubst $(srctree)/$(src)/%.pl,%.S,$(part3))
>
> Now $(part4) contains all of the intermediate .S targets that
> correspond with .pl sources and .o destinations. We can now add that
> to $(targets);
>
> targets += $(part4)
>
> And after this everything works perfectly. Putting it all together, we
> can simply add this single line to the makefile and everything
> functions exactly as expected:
>
> targets += $(patsubst $(srctree)/$(src)/%.pl,%.S,$(wildcard $(patsubst
> %.o,$(srctree)/$(src)/%.pl,$(foreach t,$(patsubst %.o,%,$(obj-)
> $(obj-m) $(obj-y)),$($(t)-) $($(t)-y)))))
>
> Cool! I mean, sort of. I really love make, and so this whole exercise
> is perversely enjoyable for me (maybe I should quit kernels and write
> lisp instead?), but I realize this isn't exactly a simple solution.
> It's sitting in my repo right now with a big comment, but I'm sort of
> hesitant to submit it. If that's okay with you, I'll send it upstream
> as part of something else I'm working on. But if these types of
> shenanigans don't really sit well, there are a few alternatives I can
> think of that you might weigh in on:
>
> a. The solution above, which achieves all objectives, but results in a
> sort of obtuse line.


How many intermediate .S files do you have?
Is it worthwhile computing them automatically?


> b. The solution above, but I split that line up into a few
> intermediate stages to make it more clear.
>
> c. I list the .pl files explicitly instead of depending on automatic
> inference like the above. This is simple, but not as slick and another
> thing developers have to remember to do when adding. But it's probably
> the least controversial and most obvious.


Kind of.
I'd recommend you to list the intermediate files in 'targets'.

For example, if you use .pl -> .S for arch/arm/crypto/Makefile,
the following should work.



diff --git a/arch/arm/crypto/Makefile b/arch/arm/crypto/Makefile
index bd5bcee..b463fcd 100644
--- a/arch/arm/crypto/Makefile
+++ b/arch/arm/crypto/Makefile
@@ -54,15 +54,13 @@ crct10dif-arm-ce-y  := crct10dif-ce-core.o
crct10dif-ce-glue.o
 crc32-arm-ce-y:= crc32-ce-core.o crc32-ce-glue.o
 chacha20-neon-y := chacha20-neon-core.o chacha20-neon-glue.o

-ifdef REGENERATE_ARM_CRYPTO
 quiet_cmd_perl = PERL    $@
       cmd_perl = $(PERL) $(<) > $(@)

-$(src)/sha256-core.S_shipped: $(src)/sha256-armv4.pl
+$(obj)/sha256-core.S: $(src)/sha256-armv4.pl
        $(call cmd,perl)

-$(src)/sha512-core.S_shipped: $(src)/sha512-armv4.pl
+$(obj)/sha512-core.S: $(src)/sha512-armv4.pl
        $(call cmd,perl)
-endif

 targets += sha256-core.S sha512-core.S




All you need to do for intermediate files is
targets += sha256-core.S sha512-core.S


Makefile.clean handles $(targets).






> d. Rather than going .pl -> .S, I go .perlasm.pl -> .perlasm.S, and
> then add the filetype to Makefile.build, where it has stanzas like
> "$(call intermediate_targets, .asn1.o, .asn1.c .asn1.h)". One
> significant downside of this is that I don't see any such stanzas in
> Makefile.clean, so I'm not sure that intermediate targets generated
> this way are getting cleaned up.
>
> e. I quit trying to be clever by ensuring that the .S in $(targets)
> corresponds with both a .pl and a .o listed in the tree of $(obj-*),
> and instead just wildcard my way to the relevant *.pl files with
> something like: targets += $(patsubst
> $(srctree)/$(src)/%.pl,%.S,$(wildcard $(srctree)/$(src)/*/*.pl)). This
> is slightly simpler than (a) and (b), but usually wildcard'ing on
> actual directories isn't the most bug-free way of using make.
>
> f. Something else?
>
> The answer is probably "just use (c)", but in case the topic interests
> you, I'm happy to discuss the various alternatives.
>
> Thanks,
> Jason



-- 
Best Regards
Masahiro Yamada



[Index of Archives]     [Linux&nblp;USB Development]     [Linux Media]     [Video for Linux]     [Linux Audio Users]     [Yosemite Secrets]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux