Re: linux-next: build failure after merge of the origin tree

From: Linus Torvalds
Date: Mon Sep 13 2021 - 21:29:49 EST


On Mon, Sep 13, 2021 at 5:58 PM Stephen Rothwell <sfr@xxxxxxxxxxxxxxxx> wrote:
>
> > I have no idea why it then complains about removal of the GCC4 macros.
>
> Me neither :-(

Ooh.

So I'm looking at gcc sources, just to see if "maybe this thing is
somehow conditional".

And bingo.

In cpp_init_special_builtins(), gcc does

if (b->value == BT_HAS_ATTRIBUTE
&& (CPP_OPTION (pfile, lang) == CLK_ASM
|| pfile->cb.has_attribute == NULL))
continue;

which basically says that if we're pre-processing an ASM file, the
magical pre-processor symbol for __has_attribute is not defined.

I'm not sure what that 'pfile->cb.has_attribute == NULL' thing means,
but the libcpp/ChangeLog file also mentions this:

(cpp_init_special_builtins): Don't initialize __has_attribute
or __has_cpp_attribute if CLK_ASM or pfile->cb.has_attribute is NULL.

So this is a very very special magical thing: if building an *.S file,
__has_attribute magically goes away.

And sure enough, that's exactly what is going on. It's during that
build of arch/powerpc/boot/crt0.S, and the reason this hits on powerpc
is that in arch/powerpc/boot/Makefile we have

-include $(srctree)/include/linux/compiler_attributes.h

as part of BOOTCFLAGS, and then it does

BOOTAFLAGS := -D__ASSEMBLY__ $(BOOTCFLAGS) -nostdinc

to also include that header file when building ASM files.

And our old GCC4 code silently hid this all, and made it work, because
for a *.S file you'd then (completely illogically) get those fake
gcc-4 attribute macros.

Now, do I know *why* that ppc Makefile it does that? No. Neither do I
know why the gcc people decided to just make ASM preprocessor so
special.

But at least I understand how the odd error happens.

This was too damn subtle. When you have to go read the compiler
sources to figure things like this out, you know you are too deep.

The fix should be pretty simple: remove almost all of BOOTCFLAGS from
BOOTAFLAGS.

But sadly, "almost all" isn't "all". There's the include path stuff,
there's the ABI and endianness, and there's the bit size ones.

So I think the fix is either

(a) remove that

-include $(srctree)/include/linux/compiler_attributes.h

thing entirely, and add it as required to the C files.

OR

(b) something like this ENTIRELY UNTESTED ATTACHED patch

I will leave it to the powerpc people to make the right choice.

Linus
arch/powerpc/boot/Makefile | 26 ++++++++++++++------------
1 file changed, 14 insertions(+), 12 deletions(-)

diff --git a/arch/powerpc/boot/Makefile b/arch/powerpc/boot/Makefile
index 6900d0ac2421..9bcf62d65509 100644
--- a/arch/powerpc/boot/Makefile
+++ b/arch/powerpc/boot/Makefile
@@ -32,28 +32,30 @@ else
BOOTAR := $(AR)
endif

-BOOTCFLAGS := -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs \
- -fno-strict-aliasing -O2 -msoft-float -mno-altivec -mno-vsx \
- -pipe -fomit-frame-pointer -fno-builtin -fPIC -nostdinc \
- -include $(srctree)/include/linux/compiler_attributes.h \
- $(LINUXINCLUDE)
+BOOTCOREFLAGS := $(LINUXINCLUDE)

ifdef CONFIG_PPC64_BOOT_WRAPPER
-BOOTCFLAGS += -m64
+BOOTCOREFLAGS += -m64
else
-BOOTCFLAGS += -m32
+BOOTCOREFLAGS += -m32
endif

-BOOTCFLAGS += -isystem $(shell $(BOOTCC) -print-file-name=include)
+BOOTCOREFLAGS += -isystem $(shell $(BOOTCC) -print-file-name=include)

ifdef CONFIG_CPU_BIG_ENDIAN
-BOOTCFLAGS += -mbig-endian
+BOOTCOREFLAGS += -mbig-endian
else
-BOOTCFLAGS += -mlittle-endian
-BOOTCFLAGS += $(call cc-option,-mabi=elfv2)
+BOOTCOREFLAGS += -mlittle-endian
+BOOTCOREFLAGS += $(call cc-option,-mabi=elfv2)
endif

-BOOTAFLAGS := -D__ASSEMBLY__ $(BOOTCFLAGS) -nostdinc
+BOOTCFLAGS := -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs \
+ -fno-strict-aliasing -O2 -msoft-float -mno-altivec -mno-vsx \
+ -pipe -fomit-frame-pointer -fno-builtin -fPIC -nostdinc \
+ -include $(srctree)/include/linux/compiler_attributes.h \
+ $(BOOTCOREFLAGS)
+
+BOOTAFLAGS := -D__ASSEMBLY__ $(BOOTCOREFLAGS) -nostdinc

BOOTARFLAGS := -crD