diff mbox

Switching to a two stage gcc build

Message ID 20140909155004.7bc426d7@free-electrons.com
State Not Applicable
Headers show

Commit Message

Thomas Petazzoni Sept. 9, 2014, 1:50 p.m. UTC
Alexey, Anton,

I'm currently working on switching from a three stage gcc build to a
two stage gcc build in Buildroot. Currently, what we do is:

 * host-gcc-initial
 * linux-headers
 * first build of C library, just to install the headers and start files
 * host-gcc-intermediate
 * complete build of C library
 * host-gcc-final

I'm switching to the simpler (and faster) solution which allows to
remove host-gcc-intermediate:

 * host-gcc-initial
 * linux-headers
 * complete build of C library
 * host-gcc-final

The attached patch works fine for ARM, but it doesn't work for ARC. The
problem is that with the two stage gcc build, we build libgcc in
host-gcc-initial instead of host-gcc-intermediate. This means that
libgcc is now built *before* the C library has installed its headers.
Unfortunately, the ARC version of libgcc uses some headers from the C
library, and therefore fails to build:

/home/test/outputs/arc-uclibc/build/host-gcc-initial-arc-2014.08/build/./gcc/xgcc -B/home/test/outputs/arc-uclibc/build/host-gcc-initial-arc-2014.08/build/./gcc/ -B/home/test/outputs/arc-uclibc/host/usr/arc-buildroot-linux-uclibc/bin/ -B/home/test/outputs/arc-uclibc/host/usr/arc-buildroot-linux-uclibc/lib/ -isystem /home/test/outputs/arc-uclibc/host/usr/arc-buildroot-linux-uclibc/include -isystem /home/test/outputs/arc-uclibc/host/usr/arc-buildroot-linux-uclibc/sys-include    -g -Os -O2  -g -Os -DIN_GCC -DCROSS_DIRECTORY_STRUCTURE  -W -Wall -Wwrite-strings -Wcast-qual -Wstrict-prototypes -Wmissing-prototypes -Wold-style-definition  -isystem ./include   -fPIC -g -DIN_LIBGCC2 -fbuilding-libgcc -fno-stack-protector -Dinhibit_libc  -fPIC -I. -I. -I../.././gcc -I../../../libgcc -I../../../libgcc/. -I../../../libgcc/../gcc -I../../../libgcc/../include    -o gmon.o -MT gmon.o -MD -MP -MF gmon.dep -isystem ../../../libgcc/config/arc/gmon -mno-sdata -c ../../../libgcc/config/arc/gmon/
 gmon.c \
        -fno-strict-aliasing \
        -Wno-extra # suppress inane warning about missing initializer.
In file included from ../../../libgcc/config/arc/gmon/mcount.c:40:0:
../../../libgcc/config/arc/gmon/sys/gmon.h:40:23: fatal error: sys/types.h: No such file or directory
 #include <sys/types.h>
                       ^
compilation terminated.
make[3]: *** [mcount.o] Error 1
make[3]: *** Waiting for unfinished jobs....
grep -v 'include.*fp-bit.h' ../../../libgcc/fp-bit.c >> dp-bit.c
In file included from ../../../libgcc/config/arc/gmon/gmon.c:34:0:
../../../libgcc/config/arc/gmon/sys/gmon.h:40:23: fatal error: sys/types.h: No such file or directory
 #include <sys/types.h>
                       ^
compilation terminated.
make[3]: *** [gmon.o] Error 1
make[2]: *** [all-target-libgcc] Error 2
make[1]: *** [/home/test/outputs/arc-uclibc/build/host-gcc-initial-arc-2014.08/.stamp_built] Error 2

You can reproduce this by applying the attached patch, and using the
following defconfig:

BR2_arcle=y
BR2_ENABLE_SSP=y
BR2_TOOLCHAIN_BUILDROOT_LARGEFILE=y
BR2_TOOLCHAIN_BUILDROOT_INET_IPV6=y
BR2_TOOLCHAIN_BUILDROOT_INET_RPC=y
BR2_TOOLCHAIN_BUILDROOT_WCHAR=y
BR2_TOOLCHAIN_BUILDROOT_USE_SSP=y
BR2_TOOLCHAIN_BUILDROOT_CXX=y

It is also worth mentioning that in the latest master (i.e without my
patch), the ARC toolchain builds fine, but it fails to build Busybox:

{standard input}: Assembler messages:
{standard input}:453: Error: operand out of range (128 is not between -128 and 127)
  CC      libbb/xregcomp.o
make[3]: *** [libbb/xfuncs.o] Error 1
make[3]: *** Waiting for unfinished jobs....

Could you help me solve those issues?

Thanks a lot!

Thomas

Comments

Anton Kolesov Sept. 9, 2014, 2:09 p.m. UTC | #1
Hi Thomas,

I haven't tried this yet, though I recall similar problems, when I've been trying to use our ancient releases of our tools.

In our own build scripts, we do following for the two stage build:

1. Install Linux headers
2. Install uClibc headers
3. Build stage 1
4. Build uClibc and install it
5. Build stage 2

I'm not arguing that this way is definitely better, in fact I'm not even the one who invented it, though I've made some changes there. This works pretty nice for us. Maybe that could work for Buildroot as well?

As of issue with assembler error - that means there is a compiler error, compiler generated wrong insturction. Let me try to reproduce this here and I will send a bugreport to our compiler developer. This might take a day or two for him, depending on his workload and complexity of this particular issues. I suppose I just need to do a default busybox configuration  with master for this error? No need to enable any additional features?

Anton


> -----Original Message-----
> From: Thomas Petazzoni [mailto:thomas.petazzoni@free-electrons.com]
> Sent: 09 September 2014 17:50
> To: Alexey Brodkin; Anton.Kolesov@synopsys.com
> Cc: buildroot@uclibc.org
> Subject: Switching to a two stage gcc build
> 
> Alexey, Anton,
> 
> I'm currently working on switching from a three stage gcc build to a
> two stage gcc build in Buildroot. Currently, what we do is:
> 
>  * host-gcc-initial
>  * linux-headers
>  * first build of C library, just to install the headers and start files
>  * host-gcc-intermediate
>  * complete build of C library
>  * host-gcc-final
> 
> I'm switching to the simpler (and faster) solution which allows to
> remove host-gcc-intermediate:
> 
>  * host-gcc-initial
>  * linux-headers
>  * complete build of C library
>  * host-gcc-final
> 
> The attached patch works fine for ARM, but it doesn't work for ARC. The
> problem is that with the two stage gcc build, we build libgcc in
> host-gcc-initial instead of host-gcc-intermediate. This means that
> libgcc is now built *before* the C library has installed its headers.
> Unfortunately, the ARC version of libgcc uses some headers from the C
> library, and therefore fails to build:
> 
> /home/test/outputs/arc-uclibc/build/host-gcc-initial-arc-
> 2014.08/build/./gcc/xgcc -B/home/test/outputs/arc-uclibc/build/host-gcc-
> initial-arc-2014.08/build/./gcc/ -B/home/test/outputs/arc-
> uclibc/host/usr/arc-buildroot-linux-uclibc/bin/ -B/home/test/outputs/arc-
> uclibc/host/usr/arc-buildroot-linux-uclibc/lib/ -isystem
> /home/test/outputs/arc-uclibc/host/usr/arc-buildroot-linux-uclibc/include -
> isystem /home/test/outputs/arc-uclibc/host/usr/arc-buildroot-linux-
> uclibc/sys-include    -g -Os -O2  -g -Os -DIN_GCC -
> DCROSS_DIRECTORY_STRUCTURE  -W -Wall -Wwrite-strings -Wcast-qual -
> Wstrict-prototypes -Wmissing-prototypes -Wold-style-definition  -isystem
> ./include   -fPIC -g -DIN_LIBGCC2 -fbuilding-libgcc -fno-stack-protector -
> Dinhibit_libc  -fPIC -I. -I. -I../.././gcc -I../../../libgcc -I../../../libgcc/. -
> I../../../libgcc/../gcc -I../../../libgcc/../include    -o gmon.o -MT gmon.o -MD -
> MP -MF gmon.dep -isystem ../../../libgcc/config/arc/gmon -mno-sdata -c
> ../../../libgcc/config/arc/gmon/
>  gmon.c \
>         -fno-strict-aliasing \
>         -Wno-extra # suppress inane warning about missing initializer.
> In file included from ../../../libgcc/config/arc/gmon/mcount.c:40:0:
> ../../../libgcc/config/arc/gmon/sys/gmon.h:40:23: fatal error: sys/types.h: No
> such file or directory
>  #include <sys/types.h>
>                        ^
> compilation terminated.
> make[3]: *** [mcount.o] Error 1
> make[3]: *** Waiting for unfinished jobs....
> grep -v 'include.*fp-bit.h' ../../../libgcc/fp-bit.c >> dp-bit.c
> In file included from ../../../libgcc/config/arc/gmon/gmon.c:34:0:
> ../../../libgcc/config/arc/gmon/sys/gmon.h:40:23: fatal error: sys/types.h: No
> such file or directory
>  #include <sys/types.h>
>                        ^
> compilation terminated.
> make[3]: *** [gmon.o] Error 1
> make[2]: *** [all-target-libgcc] Error 2
> make[1]: *** [/home/test/outputs/arc-uclibc/build/host-gcc-initial-arc-
> 2014.08/.stamp_built] Error 2
> 
> You can reproduce this by applying the attached patch, and using the
> following defconfig:
> 
> BR2_arcle=y
> BR2_ENABLE_SSP=y
> BR2_TOOLCHAIN_BUILDROOT_LARGEFILE=y
> BR2_TOOLCHAIN_BUILDROOT_INET_IPV6=y
> BR2_TOOLCHAIN_BUILDROOT_INET_RPC=y
> BR2_TOOLCHAIN_BUILDROOT_WCHAR=y
> BR2_TOOLCHAIN_BUILDROOT_USE_SSP=y
> BR2_TOOLCHAIN_BUILDROOT_CXX=y
> 
> It is also worth mentioning that in the latest master (i.e without my
> patch), the ARC toolchain builds fine, but it fails to build Busybox:
> 
> {standard input}: Assembler messages:
> {standard input}:453: Error: operand out of range (128 is not between -128
> and 127)
>   CC      libbb/xregcomp.o
> make[3]: *** [libbb/xfuncs.o] Error 1
> make[3]: *** Waiting for unfinished jobs....
> 
> Could you help me solve those issues?
> 
> Thanks a lot!
> 
> Thomas
> --
> Thomas Petazzoni, CTO, Free Electrons
> Embedded Linux, Kernel and Android engineering
> http://free-electrons.com
Thomas Petazzoni Sept. 9, 2014, 2:23 p.m. UTC | #2
Dear Anton Kolesov,

On Tue, 9 Sep 2014 14:09:14 +0000, Anton Kolesov wrote:

> I haven't tried this yet, though I recall similar problems, when I've
> been trying to use our ancient releases of our tools.
> 
> In our own build scripts, we do following for the two stage build:
> 
> 1. Install Linux headers
> 2. Install uClibc headers
> 3. Build stage 1
> 4. Build uClibc and install it
> 5. Build stage 2
> 
> I'm not arguing that this way is definitely better, in fact I'm not
> even the one who invented it, though I've made some changes there.
> This works pretty nice for us. Maybe that could work for Buildroot as
> well?

I don't know, I haven't put too much thought into this. Is it
reasonable for libgcc to depend on the C library? Or maybe the initial
gcc build should ensure to build a libgcc that doesn't depend on the C
library, and then in the final gcc build, it rebuilds a more complete
libgcc ?

> As of issue with assembler error - that means there is a compiler
> error, compiler generated wrong insturction. Let me try to reproduce
> this here and I will send a bugreport to our compiler developer. This
> might take a day or two for him, depending on his workload and
> complexity of this particular issues. I suppose I just need to do a
> default busybox configuration  with master for this error? No need to
> enable any additional features?

That indeed was just the default ARCle toolchain, with default Busybox
configuration. Let me know if you're not able to reproduce, and I'll
try to give more details.

Thanks!

Thomas
diff mbox

Patch

From e73d822793994a05b9fd73a29a756fde3dd2a33a Mon Sep 17 00:00:00 2001
From: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
Date: Sun, 7 Sep 2014 15:24:27 +0200
Subject: [PATCH] toolchain: use two stage gcc build

Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
---
 package/gcc/Config.in.host             | 9 +++++++++
 package/gcc/gcc-initial/gcc-initial.mk | 8 +++++++-
 package/glibc/glibc.mk                 | 3 +++
 package/musl/musl.mk                   | 3 ---
 package/uclibc/Config.in               | 1 +
 package/uclibc/uclibc.mk               | 2 ++
 toolchain/Config.in                    | 9 +++++++++
 7 files changed, 31 insertions(+), 4 deletions(-)

diff --git a/package/gcc/Config.in.host b/package/gcc/Config.in.host
index b536a66..48c424c 100644
--- a/package/gcc/Config.in.host
+++ b/package/gcc/Config.in.host
@@ -6,6 +6,12 @@  config BR2_GCC_NEEDS_MPC
 config BR2_GCC_SUPPORTS_GRAPHITE
 	bool
 
+# Until gcc 4.7, a three stage build process was needed when using
+# NPTL. This hidden option tells whether gcc is a version that
+# requires this three stage build process.
+config BR2_GCC_VERSION_NEEDS_THREE_STAGE_BUILD
+	bool
+
 choice
 	prompt "GCC compiler Version"
 	default BR2_GCC_VERSION_4_4_X if BR2_sparc_sparchfleon || BR2_sparc_sparchfleonv8 || BR2_sparc_sparcsfleon || BR2_sparc_sparcsfleonv8
@@ -21,6 +27,7 @@  choice
 	config BR2_GCC_VERSION_4_2_2_AVR32_2_1_5
 		depends on BR2_avr32
 		bool "gcc 4.2.2-avr32-2.1.5"
+		select BR2_GCC_VERSION_NEEDS_THREE_STAGE_BUILD
 
 	config BR2_GCC_VERSION_4_4_X
 		depends on !BR2_microblaze && !BR2_aarch64 && !BR2_arc && !BR2_avr32 && !BR2_cortex_a5 && !BR2_cortex_a7 && !BR2_cortex_a12 && !BR2_cortex_a15 && !BR2_x86_corei7 && !BR2_x86_atom && !BR2_x86_jaguar && !BR2_powerpc_476 && !BR2_powerpc_476fp && !BR2_fa526 && !BR2_pj4 && !BR2_powerpc64le
@@ -31,6 +38,7 @@  choice
 		depends on !BR2_ARM_FPU_VFPV4 && !BR2_ARM_FPU_VFPV4D16
 		# musl patches only for gcc 4.7+
 		depends on !BR2_TOOLCHAIN_BUILDROOT_MUSL
+		select BR2_GCC_VERSION_NEEDS_THREE_STAGE_BUILD
 
 	config BR2_GCC_VERSION_4_5_X
 		depends on !BR2_microblaze && !BR2_aarch64 && !BR2_arc && !BR2_avr32 && !BR2_cortex_a7 && !BR2_cortex_a12 && !BR2_cortex_a15 && !BR2_x86_corei7 && !BR2_x86_jaguar && !BR2_sparc_sparchfleon && !BR2_sparc_sparchfleonv8 && !BR2_sparc_sparcsfleon && !BR2_sparc_sparcsfleonv8 && !BR2_fa526 && !BR2_pj4 && !BR2_powerpc64le
@@ -39,6 +47,7 @@  choice
 		depends on !BR2_ARM_EABIHF
 		# musl patches only for gcc 4.7+
 		depends on !BR2_TOOLCHAIN_BUILDROOT_MUSL
+		select BR2_GCC_VERSION_NEEDS_THREE_STAGE_BUILD
 		bool "gcc 4.5.x"
 
 	config BR2_GCC_VERSION_4_7_X
diff --git a/package/gcc/gcc-initial/gcc-initial.mk b/package/gcc/gcc-initial/gcc-initial.mk
index bc5ad26..2dccd40 100644
--- a/package/gcc/gcc-initial/gcc-initial.mk
+++ b/package/gcc/gcc-initial/gcc-initial.mk
@@ -29,6 +29,7 @@  HOST_GCC_INITIAL_CONF_OPT = \
 	--enable-languages=c \
 	--disable-shared \
 	--without-headers \
+	--disable-threads \
 	--with-newlib \
 	--disable-largefile \
 	--disable-nls \
@@ -37,7 +38,12 @@  HOST_GCC_INITIAL_CONF_OPT = \
 HOST_GCC_INITIAL_CONF_ENV = \
 	$(HOST_GCC_COMMON_CONF_ENV)
 
-HOST_GCC_INITIAL_MAKE_OPT = all-gcc
+HOST_GCC_INITIAL_MAKE_OPT = all-gcc $(if $(BR2_TOOLCHAIN_HAS_SSP),gcc_cv_libc_provides_ssp=yes)
 HOST_GCC_INITIAL_INSTALL_OPT = install-gcc
 
+ifeq ($(BR2_TOOLCHAIN_NEEDS_THREE_STAGE_BUILD),)
+HOST_GCC_INITIAL_MAKE_OPT += all-target-libgcc
+HOST_GCC_INITIAL_INSTALL_OPT += install-target-libgcc
+endif
+
 $(eval $(host-autotools-package))
diff --git a/package/glibc/glibc.mk b/package/glibc/glibc.mk
index 4cbca88..651b326 100644
--- a/package/glibc/glibc.mk
+++ b/package/glibc/glibc.mk
@@ -79,6 +79,7 @@  define GLIBC_CONFIGURE_CMDS
 		$(SHELL) $(@D)/$(GLIBC_SRC_SUBDIR)/configure \
 		ac_cv_path_BASH_SHELL=/bin/bash \
 		libc_cv_forced_unwind=yes \
+		libc_cv_ssp=no \
 		--target=$(GNU_TARGET_NAME) \
 		--host=$(GNU_TARGET_NAME) \
 		--build=$(GNU_HOST_NAME) \
@@ -129,4 +130,6 @@  endef
 $(eval $(autotools-package))
 
 # Before (e)glibc is built, we must have the second stage cross-compiler
+ifeq ($(BR2_TOOLCHAIN_NEEDS_THREE_STAGE_BUILD),y)
 $(GLIBC_TARGET_BUILD): | host-gcc-intermediate
+endif
diff --git a/package/musl/musl.mk b/package/musl/musl.mk
index 63607f9..2eccb3d 100644
--- a/package/musl/musl.mk
+++ b/package/musl/musl.mk
@@ -68,6 +68,3 @@  define MUSL_INSTALL_TARGET_CMDS
 endef
 
 $(eval $(generic-package))
-
-# Before musl is built, we must have the second stage cross-compiler
-$(MUSL_TARGET_BUILD): | host-gcc-intermediate
diff --git a/package/uclibc/Config.in b/package/uclibc/Config.in
index d319ae7..7f9cfe2 100644
--- a/package/uclibc/Config.in
+++ b/package/uclibc/Config.in
@@ -124,6 +124,7 @@  choice
 		bool "Native POSIX Threading (NPTL)"
 		select BR2_TOOLCHAIN_HAS_THREADS
 		select BR2_TOOLCHAIN_HAS_THREADS_NPTL
+		select BR2_TOOLCHAIN_LIBC_NEEDS_THREE_STAGE_BUILD
 		depends on !BR2_arc
 		depends on !BR2_avr32
 		depends on !BR2_bfin
diff --git a/package/uclibc/uclibc.mk b/package/uclibc/uclibc.mk
index c68dc56..b28d86b 100644
--- a/package/uclibc/uclibc.mk
+++ b/package/uclibc/uclibc.mk
@@ -536,4 +536,6 @@  endef
 $(eval $(kconfig-package))
 
 # Before uClibc is built, we must have the second stage cross-compiler
+ifeq ($(BR2_TOOLCHAIN_NEEDS_THREE_STAGE_BUILD),y)
 $(UCLIBC_TARGET_BUILD): | host-gcc-intermediate
+endif
diff --git a/toolchain/Config.in b/toolchain/Config.in
index 54b5d17..deb6d34 100644
--- a/toolchain/Config.in
+++ b/toolchain/Config.in
@@ -6,6 +6,14 @@  config BR2_TOOLCHAIN
 	bool
 	default y
 
+config BR2_TOOLCHAIN_NEEDS_THREE_STAGE_BUILD
+	bool
+	default y if BR2_TOOLCHAIN_LIBC_NEEDS_THREE_STAGE_BUILD && \
+		BR2_GCC_VERSION_NEEDS_THREE_STAGE_BUILD
+
+config BR2_TOOLCHAIN_LIBC_NEEDS_THREE_STAGE_BUILD
+	bool
+
 # Should be selected for glibc or eglibc
 config BR2_TOOLCHAIN_USES_GLIBC
 	bool
@@ -18,6 +26,7 @@  config BR2_TOOLCHAIN_USES_GLIBC
 	select BR2_TOOLCHAIN_HAS_THREADS_NPTL
 	select BR2_TOOLCHAIN_HAS_SHADOW_PASSWORDS
 	select BR2_TOOLCHAIN_HAS_SSP
+	select BR2_TOOLCHAIN_LIBC_NEEDS_THREE_STAGE_BUILD
 
 config BR2_TOOLCHAIN_USES_UCLIBC
 	bool
-- 
2.0.0