make grub2 compile with libc-less crosscompilers
PATCH 1/1 make grub2 compile with libc-less crosscompilers
Hi,
I'll work on LinuxBIOS as part of the GSoC 2007 and I'm tasked to enable grub2 as payload for LinuxBIOSv3.
Currently, I'm preparing my workspace, and I had some issues with getting grub2 to build on my Solaris machine as solaris-gccs tend to use sun as and sun ld in the back end which have a different interface than the gnu variants.
I'm now using a cross compiler with target "i386-elf", ie. no operating system specification, which works fine so far. With grub2 I had an issue in the configuration process as some tests try to build executables with the target compiler that link libc (and potentially even more libs) - which don't exist in my configuration.
As those are not necessary, I decided to modify grub2 instead of messing around even more with the not-so-nice gcc build system.
The attached patch does the following:
1. provide a new macro, that changes CFLAGS for a limited context
2. uses that macro to build all tests for _start, __bss_start, _end and their variants with "-nostdlib -fno-builtin" to avoid _any_ complication (-fno-builtin could very likely be left out here)
3. makes the _start/start test not fail
3. is probably the most controversial change.
I decided that this is okay, as the startup code (at least on i386/pc) provides both symbols itself. maybe the check for _start/start could be left out entirely, but I kept it, so that on systems where _start or start get defined in the compiler context somehow, the defined name is used. This should guarantee that this change doesn't affect any system where grub2 built before.
Comments welcome!
Regards,
Patrick Georgi
Index: aclocal.m4
===================================================================
RCS file: /sources/grub/grub2/aclocal.m4,v
retrieving revision 1.6
aclocal.m4 +18 -1
@@ -188,10 +188,20 @@ AC_MSG_RESULT([$grub_cv_i386_asm_absolute_without_asterisk])]) +dnl Build wrapped code with different cflags, restore cflags at the end +dnl Written by Patrick Georgi +dnl grub_WRAP_FOR_CFLAGS([CFLAGS],[actual code]) +AC_DEFUN(grub_WRAP_FOR_CFLAGS, +[save_CFLAGS=$CFLAGS +CFLAGS="$1" +$2 +CFLAGS=$save_CFLAGS]) + dnl Check what symbol is defined as a start symbol. dnl Written by Yoshinori K. Okuji. AC_DEFUN(grub_CHECK_START_SYMBOL, [AC_REQUIRE([AC_PROG_CC]) +grub_WRAP_FOR_CFLAGS([-nostdlib -fno-builtin],[ AC_MSG_CHECKING([if start is defined by the compiler]) AC_CACHE_VAL(grub_cv_check_start_symbol, [AC_TRY_LINK([], [asm ("incl start")],
@@ -215,14 +225,18 @@ elif test "x$grub_cv_check_uscore_start_symbol" = xyes; then AC_DEFINE([START_SYMBOL], [_start]) else - AC_MSG_ERROR([neither start nor _start is defined]) + dnl assume some default in case none exists (eg. libc-less xcompiler) + dnl the code provides both of them + AC_DEFINE([START_SYMBOL], [_start]) fi ]) +]) dnl Check what symbol is defined as a bss start symbol. dnl Written by Michael Hohmoth and Yoshinori K. Okuji. AC_DEFUN(grub_CHECK_BSS_START_SYMBOL, [AC_REQUIRE([AC_PROG_CC]) +grub_WRAP_FOR_CFLAGS([-nostdlib -fno-builtin],[ AC_MSG_CHECKING([if __bss_start is defined by the compiler]) AC_CACHE_VAL(grub_cv_check_uscore_uscore_bss_start_symbol, [AC_TRY_LINK([], [asm ("incl __bss_start")],
@@ -259,11 +273,13 @@ AC_MSG_ERROR([none of __bss_start, edata or _edata is defined]) fi ]) +]) dnl Check what symbol is defined as an end symbol. dnl Written by Yoshinori K. Okuji. AC_DEFUN(grub_CHECK_END_SYMBOL, [AC_REQUIRE([AC_PROG_CC]) +grub_WRAP_FOR_CFLAGS([-nostdlib -fno-builtin],[ AC_MSG_CHECKING([if end is defined by the compiler]) AC_CACHE_VAL(grub_cv_check_end_symbol, [AC_TRY_LINK([], [asm ("incl end")],
@@ -290,6 +306,7 @@ AC_MSG_ERROR([neither end nor _end is defined]) fi ]) +]) dnl Check if the C compiler has a bug while using nested functions when dnl mregparm is used on the i386. Some gcc versions do not pass the third
Quoted 7 lines · Patrick Georgi
I'm now using a cross compiler with target "i386-elf", ie. no operating system specification, which works fine so far. With grub2 I had an issue in the configuration process as some tests try to build executables with the target compiler that link libc (and potentially even more libs) - which don't exist in my configuration.
As those are not necessary, I decided to modify grub2 instead of messing around even more with the not-so-nice gcc build system.
They are necessary. Otherwise, you cannot make a core image, for example. Also, without grub-emu, how do you plan to debug GRUB?
BTW I can hardly believe that it is so difficult to use gnu build tools on solaris. Otherwise, how are opensolaris developers building GRUB?
Okuji
Quoted 10 lines · Yoshinori K. Okuji
Quoted 5 lines · Patrick Georgi
the target compiler that link libc (and potentially even more libs) - which don't exist in my configuration.
As those are not necessary, I decided to modify grub2 instead of messing around even more with the not-so-nice gcc build system.They are necessary. Otherwise, you cannot make a core image, for example.
uhm. where do you expect a target compiled file (ie. one that's run at boot time) to use libc?
I'm _not_ talking about the host compiler - here everything works fine, after all, there's no linker abuse going on there, just the average compile+link process.
Quoted 2 lines
Also, without grub-emu, how do you plan to debug GRUB?
qemu - the portions I work on need it anyway
Quoted 2 lines
BTW I can hardly believe that it is so difficult to use gnu build tools on solaris. Otherwise, how are opensolaris developers building GRUB?
Compiling gcc 4.2 (or 4.1.2) with gnu as and gnu ld in the back end resulted in compile errors here, when I tried to do a "normal" build.
The grub (0.95 btw!) in the OpenSolaris tree features a parallel makefile hierarchy that uses /usr/sfw/bin/gcc (which uses Sun tools in the back end) and, it seems, manual invocations of gnu ld. so here you are - they basically link by hand
Regards,
Patrick Georgi
Quoted 8 lines · Yoshinori K. Okuji
Quoted 7 lines · Patrick Georgi
I'm now using a cross compiler with target "i386-elf", ie. no operating system specification, which works fine so far. With grub2 I had an issue in the configuration process as some tests try to build executables with the target compiler that link libc (and potentially even more libs) - which don't exist in my configuration.
As those are not necessary, I decided to modify grub2 instead of messing around even more with the not-so-nice gcc build system.
I second this patch. Cleaning out platform dependencies where there should be none is a good goal on the long and stony road to portable software.
Quoted 2 lines
They are necessary. Otherwise, you cannot make a core image, for example. Also, without grub-emu, how do you plan to debug GRUB?
Can you please explain this? I would think grub-emu is something that needs to be compiled with the host compiler, not the target compiler. If you need the target, it is not an emulation, thus pretty useless.
Quoted 2 lines
BTW I can hardly believe that it is so difficult to use gnu build tools on solaris. Otherwise, how are opensolaris developers building GRUB?
Well, niche products are always hard to maintain. Try cross-compiling a driver from the mainstream operating system windows under the niche OS Linux and you will find lots of trouble, too. Not hard to believe. Cross compiling a Linux/BSD only product like Grub under Solaris is for sure easier, but not exactly trivial. Not hard to believe that one would not start fixing auto tools code without a reason ;-)
Stefan
Signature · 3 lines
coresystems GmbH • Brahmsstr. 16 • D-79104 Freiburg i. Br.
Tel.: +49 761 7668825 • Fax: +49 761 7664613
Email: [email protected] • http://www.coresystems.de/Quoted 1 line · Yoshinori K. Okuji
Also, without grub-emu, how do you plan to debug GRUB?
I'd have some questions relating to that to improve the patch, if possible.
But first, please note that grub-emu currently can't work because argp.h and its features aren't provided on Solaris, so I can't test the proper operation of it.
As for grub-emu, does it use the target-built objects (ie. .mod files) and loads them in the host system? If so, is this why you need the _start/start (and the other) detection, so the modules contain the right symbol for the host? In this case, the right solution would probably be to do those tests using the host compiler, not the target's.
The target doesn't care one way or the other (there is no non-grub code around that looks for symbols at boot time), so it can just inherit, what the host is doing.
I can provide a patch that takes this into account, if my guesses are correct, but I'd need some more insights in what exactly is required.
Thanks,
Patrick Georgi
Hi,
any more comments or questions on this patch, so I can improve it if necessary?
Thanks,
Patrick Georgi
Index: aclocal.m4
===================================================================
RCS file: /sources/grub/grub2/aclocal.m4,v
retrieving revision 1.6
aclocal.m4 +18 -1
@@ -188,10 +188,20 @@ AC_MSG_RESULT([$grub_cv_i386_asm_absolute_without_asterisk])]) +dnl Build wrapped code with different cflags, restore cflags at the end +dnl Written by Patrick Georgi +dnl grub_WRAP_FOR_CFLAGS([CFLAGS],[actual code]) +AC_DEFUN(grub_WRAP_FOR_CFLAGS, +[save_CFLAGS=$CFLAGS +CFLAGS="$1" +$2 +CFLAGS=$save_CFLAGS]) + dnl Check what symbol is defined as a start symbol. dnl Written by Yoshinori K. Okuji. AC_DEFUN(grub_CHECK_START_SYMBOL, [AC_REQUIRE([AC_PROG_CC]) +grub_WRAP_FOR_CFLAGS([-nostdlib -fno-builtin],[ AC_MSG_CHECKING([if start is defined by the compiler]) AC_CACHE_VAL(grub_cv_check_start_symbol, [AC_TRY_LINK([], [asm ("incl start")],
@@ -215,14 +225,18 @@ elif test "x$grub_cv_check_uscore_start_symbol" = xyes; then AC_DEFINE([START_SYMBOL], [_start]) else - AC_MSG_ERROR([neither start nor _start is defined]) + dnl assume some default in case none exists (eg. libc-less xcompiler) + dnl the code provides both of them + AC_DEFINE([START_SYMBOL], [_start]) fi ]) +]) dnl Check what symbol is defined as a bss start symbol. dnl Written by Michael Hohmoth and Yoshinori K. Okuji. AC_DEFUN(grub_CHECK_BSS_START_SYMBOL, [AC_REQUIRE([AC_PROG_CC]) +grub_WRAP_FOR_CFLAGS([-nostdlib -fno-builtin],[ AC_MSG_CHECKING([if __bss_start is defined by the compiler]) AC_CACHE_VAL(grub_cv_check_uscore_uscore_bss_start_symbol, [AC_TRY_LINK([], [asm ("incl __bss_start")],
@@ -259,11 +273,13 @@ AC_MSG_ERROR([none of __bss_start, edata or _edata is defined]) fi ]) +]) dnl Check what symbol is defined as an end symbol. dnl Written by Yoshinori K. Okuji. AC_DEFUN(grub_CHECK_END_SYMBOL, [AC_REQUIRE([AC_PROG_CC]) +grub_WRAP_FOR_CFLAGS([-nostdlib -fno-builtin],[ AC_MSG_CHECKING([if end is defined by the compiler]) AC_CACHE_VAL(grub_cv_check_end_symbol, [AC_TRY_LINK([], [asm ("incl end")],
@@ -290,6 +306,7 @@ AC_MSG_ERROR([neither end nor _end is defined]) fi ]) +]) dnl Check if the C compiler has a bug while using nested functions when dnl mregparm is used on the i386. Some gcc versions do not pass the third