[edk2,RFC] BaseTools GCC: add support for GCC/X64 and GCC/AARCH64 in LTO mode

Message ID 1468819587-3029-1-git-send-email-ard.biesheuvel@linaro.org
State New
Headers show

Commit Message

Ard Biesheuvel July 18, 2016, 5:26 a.m.
This introduces support for a new toolchain GCC5 which is identical to
GCC49, except for the fact that it enables LTO for X64 and AARCH64.

In order to allow the same FAMILY and BUILDRULEFAMILY to be reused, a
shell script is used that translates LD arguments to GCC arguments on
the fly. I.e., most -xxx arguments are translated to their -Wl,xxx
pass throught equivalent, and some other arguments are interpreted
by the script directly.

Using the same FAMILY and BUILDRULEFAMILY is important, since many .DSC
and .INF files contain [BuildOptions] sections that set DLINK flags for,
e.g., all GCC/X64 targets, and so using GCC as the linker instead of LD
(which LTO requires) would either require a complete new toolchain FAMILY
(which would make the GCC5 unavailable without changes to many packages,
including out of tree ones), or a new BUILDRULEFAMILY, which has similar
problems.

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>

---

Again, this is not an attempt to interfere with the great work Steven is
doing. I am simply concerned that adding a new FAMILY or BUILDRULEFAMILY
for GCC in LTO mode further fragments the support for GCC, which is
already difficult to maintain. For example, packages that set BuildOptions
only for the GCC/LTO FAMILY could not be built with GCC4x without changes.

The use of a shell script is a hack, and to support this approach for GCC
on Windows, we should probably change it to a shell script. We may even
add BaseTools support for converting a LD command line string to a GCC
one directly. The point of this RFC is to illustrate is that such translation
is feasible, and avoids the pitfall of having to introduce a new FAMILY or
BUILDRULEFAMILY

I have included LTO support for AARCH64 as well to illustrate that the
same approach works there too. Note that the resulting build is BROKEN,
i.e., LTO for AARCH64 does not actually work at the moment, but this is
under investigation.

 BaseTools/Conf/tools_def.template   | 156 ++++++++++++++++++++
 BaseTools/Scripts/lto-ld-wrapper.sh |  26 ++++
 2 files changed, 182 insertions(+)

-- 
1.9.1

_______________________________________________
edk2-devel mailing list
edk2-devel@lists.01.org
https://lists.01.org/mailman/listinfo/edk2-devel

Comments

Ard Biesheuvel July 18, 2016, 5:27 a.m. | #1
On 18 July 2016 at 07:26, Ard Biesheuvel <ard.biesheuvel@linaro.org> wrote:
> This introduces support for a new toolchain GCC5 which is identical to

> GCC49, except for the fact that it enables LTO for X64 and AARCH64.

>

> In order to allow the same FAMILY and BUILDRULEFAMILY to be reused, a

> shell script is used that translates LD arguments to GCC arguments on

> the fly. I.e., most -xxx arguments are translated to their -Wl,xxx

> pass throught equivalent, and some other arguments are interpreted

> by the script directly.

>

> Using the same FAMILY and BUILDRULEFAMILY is important, since many .DSC

> and .INF files contain [BuildOptions] sections that set DLINK flags for,

> e.g., all GCC/X64 targets, and so using GCC as the linker instead of LD

> (which LTO requires) would either require a complete new toolchain FAMILY

> (which would make the GCC5 unavailable without changes to many packages,

> including out of tree ones), or a new BUILDRULEFAMILY, which has similar

> problems.

>

> Contributed-under: TianoCore Contribution Agreement 1.0

> Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>

> ---

>

> Again, this is not an attempt to interfere with the great work Steven is

> doing. I am simply concerned that adding a new FAMILY or BUILDRULEFAMILY

> for GCC in LTO mode further fragments the support for GCC, which is

> already difficult to maintain. For example, packages that set BuildOptions

> only for the GCC/LTO FAMILY could not be built with GCC4x without changes.

>

> The use of a shell script is a hack, and to support this approach for GCC

> on Windows, we should probably change it to a shell script.


*python* script

> We may even

> add BaseTools support for converting a LD command line string to a GCC

> one directly. The point of this RFC is to illustrate is that such translation

> is feasible, and avoids the pitfall of having to introduce a new FAMILY or

> BUILDRULEFAMILY

>

> I have included LTO support for AARCH64 as well to illustrate that the

> same approach works there too. Note that the resulting build is BROKEN,

> i.e., LTO for AARCH64 does not actually work at the moment, but this is

> under investigation.

>

>  BaseTools/Conf/tools_def.template   | 156 ++++++++++++++++++++

>  BaseTools/Scripts/lto-ld-wrapper.sh |  26 ++++

>  2 files changed, 182 insertions(+)

>

> diff --git a/BaseTools/Conf/tools_def.template b/BaseTools/Conf/tools_def.template

> index f9b26fad44de..647450c1c232 100644

> --- a/BaseTools/Conf/tools_def.template

> +++ b/BaseTools/Conf/tools_def.template

> @@ -197,6 +197,9 @@ DEFINE GCC48_X64_PREFIX        = ENV(GCC48_BIN)

>  DEFINE GCC49_IA32_PREFIX       = ENV(GCC49_BIN)

>  DEFINE GCC49_X64_PREFIX        = ENV(GCC49_BIN)

>

> +DEFINE GCC5_IA32_PREFIX        = ENV(GCC5_BIN)

> +DEFINE GCC5_X64_PREFIX         = ENV(GCC5_BIN)

> +

>  DEFINE UNIX_IASL_BIN           = ENV(IASL_PREFIX)iasl

>  DEFINE WIN_ASL_BIN_DIR         = C:\ASL

>  DEFINE WIN_IASL_BIN            = DEF(WIN_ASL_BIN_DIR)\iasl.exe

> @@ -4450,6 +4453,27 @@ DEFINE GCC49_AARCH64_DLINK2_FLAGS    = DEF(GCC48_AARCH64_DLINK2_FLAGS)

>  DEFINE GCC49_ARM_ASLDLINK_FLAGS      = DEF(GCC48_ARM_ASLDLINK_FLAGS)

>  DEFINE GCC49_AARCH64_ASLDLINK_FLAGS  = DEF(GCC48_AARCH64_ASLDLINK_FLAGS)

>

> +DEFINE GCC5_IA32_CC_FLAGS           = DEF(GCC49_IA32_CC_FLAGS)

> +DEFINE GCC5_X64_CC_FLAGS            = DEF(GCC49_X64_CC_FLAGS)

> +DEFINE GCC5_IA32_X64_DLINK_COMMON   = DEF(GCC49_IA32_X64_DLINK_COMMON)

> +DEFINE GCC5_IA32_X64_ASLDLINK_FLAGS = DEF(GCC49_IA32_X64_ASLDLINK_FLAGS)

> +DEFINE GCC5_IA32_X64_DLINK_FLAGS    = DEF(GCC49_IA32_X64_DLINK_FLAGS)

> +DEFINE GCC5_IA32_DLINK2_FLAGS       = DEF(GCC49_IA32_DLINK2_FLAGS)

> +DEFINE GCC5_X64_DLINK_FLAGS         = DEF(GCC49_X64_DLINK_FLAGS)

> +DEFINE GCC5_X64_DLINK2_FLAGS        = DEF(GCC49_X64_DLINK2_FLAGS)

> +DEFINE GCC5_ASM_FLAGS               = DEF(GCC49_ASM_FLAGS)

> +DEFINE GCC5_ARM_ASM_FLAGS           = DEF(GCC49_ARM_ASM_FLAGS)

> +DEFINE GCC5_AARCH64_ASM_FLAGS       = DEF(GCC49_AARCH64_ASM_FLAGS)

> +DEFINE GCC5_ARM_CC_FLAGS            = DEF(GCC49_ARM_CC_FLAGS)

> +DEFINE GCC5_AARCH64_CC_FLAGS        = DEF(GCC49_AARCH64_CC_FLAGS)

> +DEFINE GCC5_AARCH64_CC_XIPFLAGS     = DEF(GCC49_AARCH64_CC_XIPFLAGS)

> +DEFINE GCC5_ARM_DLINK_FLAGS         = DEF(GCC49_ARM_DLINK_FLAGS)

> +DEFINE GCC5_ARM_DLINK2_FLAGS        = DEF(GCC49_ARM_DLINK2_FLAGS)

> +DEFINE GCC5_AARCH64_DLINK_FLAGS     = DEF(GCC49_AARCH64_DLINK_FLAGS)

> +DEFINE GCC5_AARCH64_DLINK2_FLAGS    = DEF(GCC49_AARCH64_DLINK2_FLAGS)

> +DEFINE GCC5_ARM_ASLDLINK_FLAGS      = DEF(GCC49_ARM_ASLDLINK_FLAGS)

> +DEFINE GCC5_AARCH64_ASLDLINK_FLAGS  = DEF(GCC49_AARCH64_ASLDLINK_FLAGS)

> +

>  ####################################################################################

>  #

>  # Unix GCC And Intel Linux ACPI Compiler

> @@ -5183,6 +5207,138 @@ RELEASE_GCC49_AARCH64_DLINK_FLAGS  = DEF(GCC49_AARCH64_DLINK_FLAGS)

>

>  ####################################################################################

>  #

> +# GCC 5 - This configuration is used to compile under Linux to produce

> +#         PE/COFF binaries using GCC 5

> +#

> +####################################################################################

> +*_GCC5_*_*_FAMILY               = GCC

> +

> +*_GCC5_*_MAKE_PATH                    = DEF(GCC5_IA32_PREFIX)make

> +*_GCC5_*_*_DLL                        = ENV(GCC5_DLL)

> +*_GCC5_*_ASL_PATH                     = DEF(UNIX_IASL_BIN)

> +

> +*_GCC5_*_PP_FLAGS                     = DEF(GCC_PP_FLAGS)

> +*_GCC5_*_ASLPP_FLAGS                  = DEF(GCC_ASLPP_FLAGS)

> +*_GCC5_*_ASLCC_FLAGS                  = DEF(GCC_ASLCC_FLAGS)

> +*_GCC5_*_VFRPP_FLAGS                  = DEF(GCC_VFRPP_FLAGS)

> +*_GCC5_*_APP_FLAGS                    =

> +*_GCC5_*_ASL_FLAGS                    = DEF(IASL_FLAGS)

> +*_GCC5_*_ASL_OUTFLAGS                 = DEF(IASL_OUTFLAGS)

> +

> +##################

> +# GCC5 IA32 definitions

> +##################

> +*_GCC5_IA32_OBJCOPY_PATH         = DEF(GCC5_IA32_PREFIX)objcopy

> +*_GCC5_IA32_CC_PATH              = DEF(GCC5_IA32_PREFIX)gcc

> +*_GCC5_IA32_SLINK_PATH           = DEF(GCC5_IA32_PREFIX)ar

> +*_GCC5_IA32_DLINK_PATH           = DEF(GCC5_IA32_PREFIX)ld

> +*_GCC5_IA32_ASLDLINK_PATH        = DEF(GCC5_IA32_PREFIX)ld

> +*_GCC5_IA32_ASM_PATH             = DEF(GCC5_IA32_PREFIX)gcc

> +*_GCC5_IA32_PP_PATH              = DEF(GCC5_IA32_PREFIX)gcc

> +*_GCC5_IA32_VFRPP_PATH           = DEF(GCC5_IA32_PREFIX)gcc

> +*_GCC5_IA32_ASLCC_PATH           = DEF(GCC5_IA32_PREFIX)gcc

> +*_GCC5_IA32_ASLPP_PATH           = DEF(GCC5_IA32_PREFIX)gcc

> +*_GCC5_IA32_RC_PATH              = DEF(GCC5_IA32_PREFIX)objcopy

> +

> +*_GCC5_IA32_ASLCC_FLAGS          = DEF(GCC_ASLCC_FLAGS) -m32

> +*_GCC5_IA32_ASLDLINK_FLAGS       = DEF(GCC5_IA32_X64_ASLDLINK_FLAGS) -m elf_i386

> +*_GCC5_IA32_ASM_FLAGS            = DEF(GCC5_ASM_FLAGS) -m32 -march=i386

> +*_GCC5_IA32_DLINK_FLAGS          = DEF(GCC5_IA32_X64_DLINK_FLAGS) -m elf_i386 --oformat=elf32-i386

> +*_GCC5_IA32_DLINK2_FLAGS         = DEF(GCC5_IA32_DLINK2_FLAGS)

> +*_GCC5_IA32_RC_FLAGS             = DEF(GCC_IA32_RC_FLAGS)

> +*_GCC5_IA32_OBJCOPY_FLAGS        =

> +*_GCC5_IA32_NASM_FLAGS           = -f elf32

> +

> +  DEBUG_GCC5_IA32_CC_FLAGS       = DEF(GCC5_IA32_CC_FLAGS) -Os

> +RELEASE_GCC5_IA32_CC_FLAGS       = DEF(GCC5_IA32_CC_FLAGS) -Os -Wno-unused-but-set-variable

> +

> +##################

> +# GCC5 X64 definitions

> +##################

> +*_GCC5_X64_OBJCOPY_PATH         = DEF(GCC5_X64_PREFIX)objcopy

> +*_GCC5_X64_CC_PATH              = DEF(GCC5_X64_PREFIX)gcc

> +*_GCC5_X64_SLINK_PATH           = DEF(GCC5_X64_PREFIX)gcc-ar

> +*_GCC5_X64_DLINK_PATH           = $(EDK_TOOLS_PATH)/Scripts/lto-ld-wrapper.sh

> +*_GCC5_X64_ASLDLINK_PATH        = DEF(GCC5_X64_PREFIX)ld

> +*_GCC5_X64_ASM_PATH             = DEF(GCC5_X64_PREFIX)gcc

> +*_GCC5_X64_PP_PATH              = DEF(GCC5_X64_PREFIX)gcc

> +*_GCC5_X64_VFRPP_PATH           = DEF(GCC5_X64_PREFIX)gcc

> +*_GCC5_X64_ASLCC_PATH           = DEF(GCC5_X64_PREFIX)gcc

> +*_GCC5_X64_ASLPP_PATH           = DEF(GCC5_X64_PREFIX)gcc

> +*_GCC5_X64_RC_PATH              = DEF(GCC5_X64_PREFIX)objcopy

> +

> +*_GCC5_X64_ASLCC_FLAGS          = DEF(GCC_ASLCC_FLAGS) -m64 -fno-lto

> +*_GCC5_X64_ASLDLINK_FLAGS       = DEF(GCC5_IA32_X64_ASLDLINK_FLAGS) -m elf_x86_64

> +*_GCC5_X64_ASM_FLAGS            = DEF(GCC5_ASM_FLAGS) -m64

> +*_GCC5_X64_DLINK_FLAGS          = --cc "DEF(GCC5_X64_PREFIX)gcc" DEF(GCC5_X64_DLINK_FLAGS)

> +*_GCC5_X64_DLINK2_FLAGS         = DEF(GCC5_X64_DLINK2_FLAGS)

> +*_GCC5_X64_RC_FLAGS             = DEF(GCC_X64_RC_FLAGS)

> +*_GCC5_X64_OBJCOPY_FLAGS        =

> +*_GCC5_X64_NASM_FLAGS           = -f elf64

> +

> +  DEBUG_GCC5_X64_CC_FLAGS       = DEF(GCC5_X64_CC_FLAGS) -flto

> +RELEASE_GCC5_X64_CC_FLAGS       = DEF(GCC5_X64_CC_FLAGS) -flto -Wno-unused-but-set-variable

> +

> +##################

> +# GCC5 ARM definitions

> +##################

> +*_GCC5_ARM_CC_PATH              = ENV(GCC5_ARM_PREFIX)gcc

> +*_GCC5_ARM_SLINK_PATH           = ENV(GCC5_ARM_PREFIX)ar

> +*_GCC5_ARM_DLINK_PATH           = ENV(GCC5_ARM_PREFIX)ld

> +*_GCC5_ARM_ASLDLINK_PATH        = ENV(GCC5_ARM_PREFIX)ld

> +*_GCC5_ARM_ASM_PATH             = ENV(GCC5_ARM_PREFIX)gcc

> +*_GCC5_ARM_PP_PATH              = ENV(GCC5_ARM_PREFIX)gcc

> +*_GCC5_ARM_VFRPP_PATH           = ENV(GCC5_ARM_PREFIX)gcc

> +*_GCC5_ARM_ASLCC_PATH           = ENV(GCC5_ARM_PREFIX)gcc

> +*_GCC5_ARM_ASLPP_PATH           = ENV(GCC5_ARM_PREFIX)gcc

> +*_GCC5_ARM_RC_PATH              = ENV(GCC5_ARM_PREFIX)objcopy

> +

> +*_GCC5_ARM_ARCHCC_FLAGS         = -mthumb

> +*_GCC5_ARM_ASLCC_FLAGS          = DEF(GCC_ASLCC_FLAGS)

> +*_GCC5_ARM_ASLDLINK_FLAGS       = DEF(GCC5_ARM_ASLDLINK_FLAGS)

> +*_GCC5_ARM_ASM_FLAGS            = DEF(GCC5_ARM_ASM_FLAGS)

> +*_GCC5_ARM_DLINK_FLAGS          = DEF(GCC5_ARM_DLINK_FLAGS)

> +*_GCC5_ARM_DLINK2_FLAGS         = DEF(GCC5_ARM_DLINK2_FLAGS)

> +*_GCC5_ARM_PLATFORM_FLAGS       = -march=armv7-a

> +*_GCC5_ARM_PP_FLAGS             = $(ARCHCC_FLAGS) $(PLATFORM_FLAGS) DEF(GCC_PP_FLAGS)

> +*_GCC5_ARM_RC_FLAGS             = DEF(GCC_ARM_RC_FLAGS)

> +*_GCC5_ARM_VFRPP_FLAGS          = $(ARCHCC_FLAGS) $(PLATFORM_FLAGS) DEF(GCC_VFRPP_FLAGS)

> +

> +  DEBUG_GCC5_ARM_CC_FLAGS       = DEF(GCC5_ARM_CC_FLAGS) -O0

> +RELEASE_GCC5_ARM_CC_FLAGS       = DEF(GCC5_ARM_CC_FLAGS) -Wno-unused-but-set-variable

> +

> +##################

> +# GCC5 AARCH64 definitions

> +##################

> +*_GCC5_AARCH64_CC_PATH          = ENV(GCC5_AARCH64_PREFIX)gcc

> +*_GCC5_AARCH64_SLINK_PATH       = ENV(GCC5_AARCH64_PREFIX)gcc-ar

> +*_GCC5_AARCH64_DLINK_PATH       = $(EDK_TOOLS_PATH)/Scripts/lto-ld-wrapper.sh

> +*_GCC5_AARCH64_ASLDLINK_PATH    = ENV(GCC5_AARCH64_PREFIX)ld

> +*_GCC5_AARCH64_ASM_PATH         = ENV(GCC5_AARCH64_PREFIX)gcc

> +*_GCC5_AARCH64_PP_PATH          = ENV(GCC5_AARCH64_PREFIX)gcc

> +*_GCC5_AARCH64_VFRPP_PATH       = ENV(GCC5_AARCH64_PREFIX)gcc

> +*_GCC5_AARCH64_ASLCC_PATH       = ENV(GCC5_AARCH64_PREFIX)gcc

> +*_GCC5_AARCH64_ASLPP_PATH       = ENV(GCC5_AARCH64_PREFIX)gcc

> +*_GCC5_AARCH64_RC_PATH          = ENV(GCC5_AARCH64_PREFIX)objcopy

> +

> +*_GCC5_AARCH64_ASLCC_FLAGS      = DEF(GCC_ASLCC_FLAGS) -fno-lto

> +*_GCC5_AARCH64_ASLDLINK_FLAGS   = DEF(GCC5_AARCH64_ASLDLINK_FLAGS)

> +*_GCC5_AARCH64_ASM_FLAGS        = DEF(GCC5_AARCH64_ASM_FLAGS)

> +*_GCC5_AARCH64_DLINK2_FLAGS     = DEF(GCC5_AARCH64_DLINK2_FLAGS)

> +*_GCC5_AARCH64_PLATFORM_FLAGS   =

> +*_GCC5_AARCH64_PP_FLAGS         = $(ARCHCC_FLAGS) $(PLATFORM_FLAGS) DEF(GCC_PP_FLAGS)

> +*_GCC5_AARCH64_RC_FLAGS         = DEF(GCC_AARCH64_RC_FLAGS)

> +*_GCC5_AARCH64_VFRPP_FLAGS      = $(ARCHCC_FLAGS) $(PLATFORM_FLAGS) DEF(GCC_VFRPP_FLAGS)

> +*_GCC5_AARCH64_CC_XIPFLAGS      = DEF(GCC5_AARCH64_CC_XIPFLAGS)

> +

> +  DEBUG_GCC5_AARCH64_CC_FLAGS     = DEF(GCC5_AARCH64_CC_FLAGS) -O0 -mcmodel=small

> +  DEBUG_GCC5_AARCH64_DLINK_FLAGS  = --cc "ENV(GCC5_AARCH64_PREFIX)gcc" DEF(GCC5_AARCH64_DLINK_FLAGS) -z common-page-size=0x1000

> +

> +RELEASE_GCC5_AARCH64_CC_FLAGS     = DEF(GCC5_AARCH64_CC_FLAGS) -flto -Wno-unused-but-set-variable -mcmodel=tiny

> +RELEASE_GCC5_AARCH64_DLINK_FLAGS  = --cc "ENV(GCC5_AARCH64_PREFIX)gcc" DEF(GCC5_AARCH64_DLINK_FLAGS)

> +

> +####################################################################################

> +#

>  # CLANG35   - This configuration is used to compile under Linux to produce

>  #             PE/COFF binaries using the clang compiler and assembler (v3.5 and up)

>  #             and GNU linker

> diff --git a/BaseTools/Scripts/lto-ld-wrapper.sh b/BaseTools/Scripts/lto-ld-wrapper.sh

> new file mode 100755

> index 000000000000..325a8390f668

> --- /dev/null

> +++ b/BaseTools/Scripts/lto-ld-wrapper.sh

> @@ -0,0 +1,26 @@

> +#!/bin/sh

> +

> +while [ $# -gt 0 ]

> +do

> +       OPT="$1"

> +       shift

> +

> +       case "$OPT" in

> +       --cc)

> +               BIN="$1"

> +               shift

> +               ;;

> +       -o)

> +               OUT="$1"

> +               shift

> +               ;;

> +       -nostdlib)

> +               GCC_ARGS="$GCC_ARGS $OPT"

> +               ;;

> +       *)

> +               LD_ARGS="$LD_ARGS,$OPT"

> +               ;;

> +       esac

> +done

> +

> +exec "$BIN" -o "$OUT" $GCC_ARGS -Wl,$LD_ARGS

> --

> 1.9.1

>

_______________________________________________
edk2-devel mailing list
edk2-devel@lists.01.org
https://lists.01.org/mailman/listinfo/edk2-devel
Ard Biesheuvel July 18, 2016, 5:43 a.m. | #2
On 18 July 2016 at 07:39, Gao, Liming <liming.gao@intel.com> wrote:
> Ard:

>   I would like to enable LTO for all ARCHs in new GCC5 tool chain, at least IA32 and X64.

>

>   I like idea to reuse the same build rule. Your patch adds lto-ld-wrapper.sh. But, this doesn't work in Windows. As you know, we can build tips with GCC in windows OS. (https://sourceforge.net/projects/edk2developertoolsforwindows/files). I would still support it. Have we other way to do it?

>


I mentioned in the commit log that this indeed does not work on
Windows. I don't use Windows, so I will not be able to test any
alternatives, but I think there are two solutions possible:
- use a python script
- add support to BaseTools to translate a GNU/LD command line to a
GNU/GCC command line.

In either case, I suppose it would be implemented in python. The only
difference is how to wire it up, i.e., either add it to tools_def.txt
(as I have demonstrated),  or update the existing build rules for GCC
to take the script into account in some way.

Regards,
Ard.
_______________________________________________
edk2-devel mailing list
edk2-devel@lists.01.org
https://lists.01.org/mailman/listinfo/edk2-devel
Ard Biesheuvel July 18, 2016, 5:55 a.m. | #3
On 18 July 2016 at 07:46, Gao, Liming <liming.gao@intel.com> wrote:
> Ard:

>   Yes. I will evaluate to add this support in BaseTools instead of adding shell script or python script.

>

>   Besides, I also request to enable LTO for all ARCHs in new GCC5 tool chain, at least IA32 and X64.

>


OK. Do you agree to enable it for both DEBUG and RELEASE (in the IA32
and X64 case)? For ARM, I would like to keep the existing practice of
having a DEBUG build that is suitable for single step debugging in
GDB, and I am not sure yet how this is supposed to work under LTO, so
there I only added it to RELEASE for now.

-- 
Ard.

>> -----Original Message-----

>> From: edk2-devel [mailto:edk2-devel-bounces@lists.01.org] On Behalf Of

>> Ard Biesheuvel

>> Sent: Monday, July 18, 2016 1:44 PM

>> To: Gao, Liming <liming.gao@intel.com>

>> Cc: Justen, Jordan L <jordan.l.justen@intel.com>; edk2-devel@lists.01.org;

>> afish@apple.com; Kinney, Michael D <michael.d.kinney@intel.com>;

>> lersek@redhat.com

>> Subject: Re: [edk2] [RFC PATCH] BaseTools GCC: add support for GCC/X64

>> and GCC/AARCH64 in LTO mode

>>

>> On 18 July 2016 at 07:39, Gao, Liming <liming.gao@intel.com> wrote:

>> > Ard:

>> >   I would like to enable LTO for all ARCHs in new GCC5 tool chain, at least

>> IA32 and X64.

>> >

>> >   I like idea to reuse the same build rule. Your patch adds lto-ld-wrapper.sh.

>> But, this doesn't work in Windows. As you know, we can build tips with GCC

>> in windows OS.

>> (https://sourceforge.net/projects/edk2developertoolsforwindows/files). I

>> would still support it. Have we other way to do it?

>> >

>>

>> I mentioned in the commit log that this indeed does not work on

>> Windows. I don't use Windows, so I will not be able to test any

>> alternatives, but I think there are two solutions possible:

>> - use a python script

>> - add support to BaseTools to translate a GNU/LD command line to a

>> GNU/GCC command line.

>>

>> In either case, I suppose it would be implemented in python. The only

>> difference is how to wire it up, i.e., either add it to tools_def.txt

>> (as I have demonstrated),  or update the existing build rules for GCC

>> to take the script into account in some way.

>>

>> Regards,

>> Ard.

>> _______________________________________________

>> edk2-devel mailing list

>> edk2-devel@lists.01.org

>> https://lists.01.org/mailman/listinfo/edk2-devel

_______________________________________________
edk2-devel mailing list
edk2-devel@lists.01.org
https://lists.01.org/mailman/listinfo/edk2-devel

Patch

diff --git a/BaseTools/Conf/tools_def.template b/BaseTools/Conf/tools_def.template
index f9b26fad44de..647450c1c232 100644
--- a/BaseTools/Conf/tools_def.template
+++ b/BaseTools/Conf/tools_def.template
@@ -197,6 +197,9 @@  DEFINE GCC48_X64_PREFIX        = ENV(GCC48_BIN)
 DEFINE GCC49_IA32_PREFIX       = ENV(GCC49_BIN)
 DEFINE GCC49_X64_PREFIX        = ENV(GCC49_BIN)
 
+DEFINE GCC5_IA32_PREFIX        = ENV(GCC5_BIN)
+DEFINE GCC5_X64_PREFIX         = ENV(GCC5_BIN)
+
 DEFINE UNIX_IASL_BIN           = ENV(IASL_PREFIX)iasl
 DEFINE WIN_ASL_BIN_DIR         = C:\ASL
 DEFINE WIN_IASL_BIN            = DEF(WIN_ASL_BIN_DIR)\iasl.exe
@@ -4450,6 +4453,27 @@  DEFINE GCC49_AARCH64_DLINK2_FLAGS    = DEF(GCC48_AARCH64_DLINK2_FLAGS)
 DEFINE GCC49_ARM_ASLDLINK_FLAGS      = DEF(GCC48_ARM_ASLDLINK_FLAGS)
 DEFINE GCC49_AARCH64_ASLDLINK_FLAGS  = DEF(GCC48_AARCH64_ASLDLINK_FLAGS)
 
+DEFINE GCC5_IA32_CC_FLAGS           = DEF(GCC49_IA32_CC_FLAGS)
+DEFINE GCC5_X64_CC_FLAGS            = DEF(GCC49_X64_CC_FLAGS)
+DEFINE GCC5_IA32_X64_DLINK_COMMON   = DEF(GCC49_IA32_X64_DLINK_COMMON)
+DEFINE GCC5_IA32_X64_ASLDLINK_FLAGS = DEF(GCC49_IA32_X64_ASLDLINK_FLAGS)
+DEFINE GCC5_IA32_X64_DLINK_FLAGS    = DEF(GCC49_IA32_X64_DLINK_FLAGS)
+DEFINE GCC5_IA32_DLINK2_FLAGS       = DEF(GCC49_IA32_DLINK2_FLAGS)
+DEFINE GCC5_X64_DLINK_FLAGS         = DEF(GCC49_X64_DLINK_FLAGS)
+DEFINE GCC5_X64_DLINK2_FLAGS        = DEF(GCC49_X64_DLINK2_FLAGS)
+DEFINE GCC5_ASM_FLAGS               = DEF(GCC49_ASM_FLAGS)
+DEFINE GCC5_ARM_ASM_FLAGS           = DEF(GCC49_ARM_ASM_FLAGS)
+DEFINE GCC5_AARCH64_ASM_FLAGS       = DEF(GCC49_AARCH64_ASM_FLAGS)
+DEFINE GCC5_ARM_CC_FLAGS            = DEF(GCC49_ARM_CC_FLAGS)
+DEFINE GCC5_AARCH64_CC_FLAGS        = DEF(GCC49_AARCH64_CC_FLAGS)
+DEFINE GCC5_AARCH64_CC_XIPFLAGS     = DEF(GCC49_AARCH64_CC_XIPFLAGS)
+DEFINE GCC5_ARM_DLINK_FLAGS         = DEF(GCC49_ARM_DLINK_FLAGS)
+DEFINE GCC5_ARM_DLINK2_FLAGS        = DEF(GCC49_ARM_DLINK2_FLAGS)
+DEFINE GCC5_AARCH64_DLINK_FLAGS     = DEF(GCC49_AARCH64_DLINK_FLAGS)
+DEFINE GCC5_AARCH64_DLINK2_FLAGS    = DEF(GCC49_AARCH64_DLINK2_FLAGS)
+DEFINE GCC5_ARM_ASLDLINK_FLAGS      = DEF(GCC49_ARM_ASLDLINK_FLAGS)
+DEFINE GCC5_AARCH64_ASLDLINK_FLAGS  = DEF(GCC49_AARCH64_ASLDLINK_FLAGS)
+
 ####################################################################################
 #
 # Unix GCC And Intel Linux ACPI Compiler
@@ -5183,6 +5207,138 @@  RELEASE_GCC49_AARCH64_DLINK_FLAGS  = DEF(GCC49_AARCH64_DLINK_FLAGS)
 
 ####################################################################################
 #
+# GCC 5 - This configuration is used to compile under Linux to produce
+#         PE/COFF binaries using GCC 5
+#
+####################################################################################
+*_GCC5_*_*_FAMILY               = GCC
+
+*_GCC5_*_MAKE_PATH                    = DEF(GCC5_IA32_PREFIX)make
+*_GCC5_*_*_DLL                        = ENV(GCC5_DLL)
+*_GCC5_*_ASL_PATH                     = DEF(UNIX_IASL_BIN)
+
+*_GCC5_*_PP_FLAGS                     = DEF(GCC_PP_FLAGS)
+*_GCC5_*_ASLPP_FLAGS                  = DEF(GCC_ASLPP_FLAGS)
+*_GCC5_*_ASLCC_FLAGS                  = DEF(GCC_ASLCC_FLAGS)
+*_GCC5_*_VFRPP_FLAGS                  = DEF(GCC_VFRPP_FLAGS)
+*_GCC5_*_APP_FLAGS                    =
+*_GCC5_*_ASL_FLAGS                    = DEF(IASL_FLAGS)
+*_GCC5_*_ASL_OUTFLAGS                 = DEF(IASL_OUTFLAGS)
+
+##################
+# GCC5 IA32 definitions
+##################
+*_GCC5_IA32_OBJCOPY_PATH         = DEF(GCC5_IA32_PREFIX)objcopy
+*_GCC5_IA32_CC_PATH              = DEF(GCC5_IA32_PREFIX)gcc
+*_GCC5_IA32_SLINK_PATH           = DEF(GCC5_IA32_PREFIX)ar
+*_GCC5_IA32_DLINK_PATH           = DEF(GCC5_IA32_PREFIX)ld
+*_GCC5_IA32_ASLDLINK_PATH        = DEF(GCC5_IA32_PREFIX)ld
+*_GCC5_IA32_ASM_PATH             = DEF(GCC5_IA32_PREFIX)gcc
+*_GCC5_IA32_PP_PATH              = DEF(GCC5_IA32_PREFIX)gcc
+*_GCC5_IA32_VFRPP_PATH           = DEF(GCC5_IA32_PREFIX)gcc
+*_GCC5_IA32_ASLCC_PATH           = DEF(GCC5_IA32_PREFIX)gcc
+*_GCC5_IA32_ASLPP_PATH           = DEF(GCC5_IA32_PREFIX)gcc
+*_GCC5_IA32_RC_PATH              = DEF(GCC5_IA32_PREFIX)objcopy
+
+*_GCC5_IA32_ASLCC_FLAGS          = DEF(GCC_ASLCC_FLAGS) -m32
+*_GCC5_IA32_ASLDLINK_FLAGS       = DEF(GCC5_IA32_X64_ASLDLINK_FLAGS) -m elf_i386
+*_GCC5_IA32_ASM_FLAGS            = DEF(GCC5_ASM_FLAGS) -m32 -march=i386
+*_GCC5_IA32_DLINK_FLAGS          = DEF(GCC5_IA32_X64_DLINK_FLAGS) -m elf_i386 --oformat=elf32-i386
+*_GCC5_IA32_DLINK2_FLAGS         = DEF(GCC5_IA32_DLINK2_FLAGS)
+*_GCC5_IA32_RC_FLAGS             = DEF(GCC_IA32_RC_FLAGS)
+*_GCC5_IA32_OBJCOPY_FLAGS        =
+*_GCC5_IA32_NASM_FLAGS           = -f elf32
+
+  DEBUG_GCC5_IA32_CC_FLAGS       = DEF(GCC5_IA32_CC_FLAGS) -Os
+RELEASE_GCC5_IA32_CC_FLAGS       = DEF(GCC5_IA32_CC_FLAGS) -Os -Wno-unused-but-set-variable
+
+##################
+# GCC5 X64 definitions
+##################
+*_GCC5_X64_OBJCOPY_PATH         = DEF(GCC5_X64_PREFIX)objcopy
+*_GCC5_X64_CC_PATH              = DEF(GCC5_X64_PREFIX)gcc
+*_GCC5_X64_SLINK_PATH           = DEF(GCC5_X64_PREFIX)gcc-ar
+*_GCC5_X64_DLINK_PATH           = $(EDK_TOOLS_PATH)/Scripts/lto-ld-wrapper.sh
+*_GCC5_X64_ASLDLINK_PATH        = DEF(GCC5_X64_PREFIX)ld
+*_GCC5_X64_ASM_PATH             = DEF(GCC5_X64_PREFIX)gcc
+*_GCC5_X64_PP_PATH              = DEF(GCC5_X64_PREFIX)gcc
+*_GCC5_X64_VFRPP_PATH           = DEF(GCC5_X64_PREFIX)gcc
+*_GCC5_X64_ASLCC_PATH           = DEF(GCC5_X64_PREFIX)gcc
+*_GCC5_X64_ASLPP_PATH           = DEF(GCC5_X64_PREFIX)gcc
+*_GCC5_X64_RC_PATH              = DEF(GCC5_X64_PREFIX)objcopy
+
+*_GCC5_X64_ASLCC_FLAGS          = DEF(GCC_ASLCC_FLAGS) -m64 -fno-lto
+*_GCC5_X64_ASLDLINK_FLAGS       = DEF(GCC5_IA32_X64_ASLDLINK_FLAGS) -m elf_x86_64
+*_GCC5_X64_ASM_FLAGS            = DEF(GCC5_ASM_FLAGS) -m64
+*_GCC5_X64_DLINK_FLAGS          = --cc "DEF(GCC5_X64_PREFIX)gcc" DEF(GCC5_X64_DLINK_FLAGS)
+*_GCC5_X64_DLINK2_FLAGS         = DEF(GCC5_X64_DLINK2_FLAGS)
+*_GCC5_X64_RC_FLAGS             = DEF(GCC_X64_RC_FLAGS)
+*_GCC5_X64_OBJCOPY_FLAGS        =
+*_GCC5_X64_NASM_FLAGS           = -f elf64
+
+  DEBUG_GCC5_X64_CC_FLAGS       = DEF(GCC5_X64_CC_FLAGS) -flto
+RELEASE_GCC5_X64_CC_FLAGS       = DEF(GCC5_X64_CC_FLAGS) -flto -Wno-unused-but-set-variable
+
+##################
+# GCC5 ARM definitions
+##################
+*_GCC5_ARM_CC_PATH              = ENV(GCC5_ARM_PREFIX)gcc
+*_GCC5_ARM_SLINK_PATH           = ENV(GCC5_ARM_PREFIX)ar
+*_GCC5_ARM_DLINK_PATH           = ENV(GCC5_ARM_PREFIX)ld
+*_GCC5_ARM_ASLDLINK_PATH        = ENV(GCC5_ARM_PREFIX)ld
+*_GCC5_ARM_ASM_PATH             = ENV(GCC5_ARM_PREFIX)gcc
+*_GCC5_ARM_PP_PATH              = ENV(GCC5_ARM_PREFIX)gcc
+*_GCC5_ARM_VFRPP_PATH           = ENV(GCC5_ARM_PREFIX)gcc
+*_GCC5_ARM_ASLCC_PATH           = ENV(GCC5_ARM_PREFIX)gcc
+*_GCC5_ARM_ASLPP_PATH           = ENV(GCC5_ARM_PREFIX)gcc
+*_GCC5_ARM_RC_PATH              = ENV(GCC5_ARM_PREFIX)objcopy
+
+*_GCC5_ARM_ARCHCC_FLAGS         = -mthumb
+*_GCC5_ARM_ASLCC_FLAGS          = DEF(GCC_ASLCC_FLAGS)
+*_GCC5_ARM_ASLDLINK_FLAGS       = DEF(GCC5_ARM_ASLDLINK_FLAGS)
+*_GCC5_ARM_ASM_FLAGS            = DEF(GCC5_ARM_ASM_FLAGS)
+*_GCC5_ARM_DLINK_FLAGS          = DEF(GCC5_ARM_DLINK_FLAGS)
+*_GCC5_ARM_DLINK2_FLAGS         = DEF(GCC5_ARM_DLINK2_FLAGS)
+*_GCC5_ARM_PLATFORM_FLAGS       = -march=armv7-a
+*_GCC5_ARM_PP_FLAGS             = $(ARCHCC_FLAGS) $(PLATFORM_FLAGS) DEF(GCC_PP_FLAGS)
+*_GCC5_ARM_RC_FLAGS             = DEF(GCC_ARM_RC_FLAGS)
+*_GCC5_ARM_VFRPP_FLAGS          = $(ARCHCC_FLAGS) $(PLATFORM_FLAGS) DEF(GCC_VFRPP_FLAGS)
+
+  DEBUG_GCC5_ARM_CC_FLAGS       = DEF(GCC5_ARM_CC_FLAGS) -O0
+RELEASE_GCC5_ARM_CC_FLAGS       = DEF(GCC5_ARM_CC_FLAGS) -Wno-unused-but-set-variable
+
+##################
+# GCC5 AARCH64 definitions
+##################
+*_GCC5_AARCH64_CC_PATH          = ENV(GCC5_AARCH64_PREFIX)gcc
+*_GCC5_AARCH64_SLINK_PATH       = ENV(GCC5_AARCH64_PREFIX)gcc-ar
+*_GCC5_AARCH64_DLINK_PATH       = $(EDK_TOOLS_PATH)/Scripts/lto-ld-wrapper.sh
+*_GCC5_AARCH64_ASLDLINK_PATH    = ENV(GCC5_AARCH64_PREFIX)ld
+*_GCC5_AARCH64_ASM_PATH         = ENV(GCC5_AARCH64_PREFIX)gcc
+*_GCC5_AARCH64_PP_PATH          = ENV(GCC5_AARCH64_PREFIX)gcc
+*_GCC5_AARCH64_VFRPP_PATH       = ENV(GCC5_AARCH64_PREFIX)gcc
+*_GCC5_AARCH64_ASLCC_PATH       = ENV(GCC5_AARCH64_PREFIX)gcc
+*_GCC5_AARCH64_ASLPP_PATH       = ENV(GCC5_AARCH64_PREFIX)gcc
+*_GCC5_AARCH64_RC_PATH          = ENV(GCC5_AARCH64_PREFIX)objcopy
+
+*_GCC5_AARCH64_ASLCC_FLAGS      = DEF(GCC_ASLCC_FLAGS) -fno-lto
+*_GCC5_AARCH64_ASLDLINK_FLAGS   = DEF(GCC5_AARCH64_ASLDLINK_FLAGS)
+*_GCC5_AARCH64_ASM_FLAGS        = DEF(GCC5_AARCH64_ASM_FLAGS)
+*_GCC5_AARCH64_DLINK2_FLAGS     = DEF(GCC5_AARCH64_DLINK2_FLAGS)
+*_GCC5_AARCH64_PLATFORM_FLAGS   =
+*_GCC5_AARCH64_PP_FLAGS         = $(ARCHCC_FLAGS) $(PLATFORM_FLAGS) DEF(GCC_PP_FLAGS)
+*_GCC5_AARCH64_RC_FLAGS         = DEF(GCC_AARCH64_RC_FLAGS)
+*_GCC5_AARCH64_VFRPP_FLAGS      = $(ARCHCC_FLAGS) $(PLATFORM_FLAGS) DEF(GCC_VFRPP_FLAGS)
+*_GCC5_AARCH64_CC_XIPFLAGS      = DEF(GCC5_AARCH64_CC_XIPFLAGS)
+
+  DEBUG_GCC5_AARCH64_CC_FLAGS     = DEF(GCC5_AARCH64_CC_FLAGS) -O0 -mcmodel=small
+  DEBUG_GCC5_AARCH64_DLINK_FLAGS  = --cc "ENV(GCC5_AARCH64_PREFIX)gcc" DEF(GCC5_AARCH64_DLINK_FLAGS) -z common-page-size=0x1000
+
+RELEASE_GCC5_AARCH64_CC_FLAGS     = DEF(GCC5_AARCH64_CC_FLAGS) -flto -Wno-unused-but-set-variable -mcmodel=tiny
+RELEASE_GCC5_AARCH64_DLINK_FLAGS  = --cc "ENV(GCC5_AARCH64_PREFIX)gcc" DEF(GCC5_AARCH64_DLINK_FLAGS)
+
+####################################################################################
+#
 # CLANG35   - This configuration is used to compile under Linux to produce
 #             PE/COFF binaries using the clang compiler and assembler (v3.5 and up)
 #             and GNU linker
diff --git a/BaseTools/Scripts/lto-ld-wrapper.sh b/BaseTools/Scripts/lto-ld-wrapper.sh
new file mode 100755
index 000000000000..325a8390f668
--- /dev/null
+++ b/BaseTools/Scripts/lto-ld-wrapper.sh
@@ -0,0 +1,26 @@ 
+#!/bin/sh
+
+while [ $# -gt 0 ]
+do
+	OPT="$1"
+	shift
+
+	case "$OPT" in
+	--cc)
+		BIN="$1"
+		shift
+		;;
+	-o)
+		OUT="$1"
+		shift
+		;;
+	-nostdlib)
+		GCC_ARGS="$GCC_ARGS $OPT"
+		;;
+	*)
+		LD_ARGS="$LD_ARGS,$OPT"
+		;;
+	esac
+done
+
+exec "$BIN" -o "$OUT" $GCC_ARGS -Wl,$LD_ARGS