From fc97214f7e153b3a36f06989d8a2b099e9ee9add Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Thu, 22 Aug 2013 01:56:28 +0200 Subject: [PATCH] * INSTALL: Document cross-compilation. * acinclude.m4: Determine whether nm support -P and --defined-only. * configure.ac: Add TARGET_ to all variables pertaining to target that don't have it yet. * gentpl.py: Likewise. * grub-core/Makefile.am: Likewise. * grub-core/genmod.sh.in: Likewise. * grub-core/gensyminfo.sh.in: Handle OpenBSD and other non-GNU nm as well. --- ChangeLog | 12 ++++++ INSTALL | 78 ++++++++++++++++++++++++++++++++++++++ acinclude.m4 | 54 ++++++++++++++++++++++++-- configure.ac | 45 ++++++++++++++-------- gentpl.py | 10 ++--- grub-core/Makefile.am | 4 +- grub-core/genmod.sh.in | 10 ++--- grub-core/gensyminfo.sh.in | 11 +++--- 8 files changed, 187 insertions(+), 37 deletions(-) diff --git a/ChangeLog b/ChangeLog index 5b7898cc7..8b458ca06 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,15 @@ +2013-08-21 Vladimir Serbinenko + + * INSTALL: Document cross-compilation. + * acinclude.m4: Determine whether nm support -P and --defined-only. + * configure.ac: Add TARGET_ to all variables pertaining to target + that don't have it yet. + * gentpl.py: Likewise. + * grub-core/Makefile.am: Likewise. + * grub-core/genmod.sh.in: Likewise. + * grub-core/gensyminfo.sh.in: Handle OpenBSD and other non-GNU nm + as well. + 2013-08-21 Ilya Bakulin * configure.ac: Remove -Wempty-body. It's not essential and needs diff --git a/INSTALL b/INSTALL index 7fe2450e7..95061b60c 100644 --- a/INSTALL +++ b/INSTALL @@ -108,6 +108,84 @@ The simplest way to compile this package is: all sorts of other programs in order to regenerate files that came with the distribution. +Cross-compiling the GRUB +======================== + +GRUB defines 3 platforms: + + - "Build" is the one which build systems runs on. + - "Host" is where you execute GRUB utils. + - "Target" is where GRUB itself runs. + +For grub-emu host and target must be the same but may differ from build. + +If build and host are different make check isn't available. + +As an example imagine you have a build system running on FreeBSD on sparc +which prepares packages for developpers running amd64 GNU/Linux laptop and +they need to make images for ARM board running U-boot. In this case: + +build=sparc64-freebsd +host=amd64-linux-gnu +target=arm-uboot + +For this example the configure line might look like (more details below) +(some options are optional and included here for completeness but some rarely +used options are omited): + +./configure BUILD_CC=gcc BUILD_FREETYPE=freetype-config --host=amd64-linux-gnu +CC=amd64-linux-gnu-gcc CFLAGS="-g -O2" FREETYPE=amd64-linux-gnu-freetype-config +--target=arm --with-platform=uboot TARGET_CC=arm-elf-gcc +TARGET_CFLAGS="-Os -march=armv6" TARGET_CCASFLAGS="-march=armv6" +TARGET_OBJCOPY="arm-elf-objcopy" TARGET_STRIP="arm-elf-strip" +TARGET_NM=arm-elf-nm LEX=gflex + +You need to use following options to specify tools and platforms. For minimum +version look at prerequisites. All tools not mentioned in this section under +corresponding platform are not needed for the platform in question. + + - For build + 1. BUILD_CC= to gcc able to compile for build. This is used, for + example, to compile build-gentrigtables which is then run to + generate sin and cos tables. + 2. BUILD_CFLAGS= for C options for build. + 3. BUILD_CPPFLAGS= for C preprocessor options for build. + 4. BUILD_FREETYPE= for freetype-config for build (optional). + + - For host + 1. --host= to autoconf name of host. + 2. CC= for gcc able to compile for host + 3. CFLAGS= for C options for host. + 4. CPPFLAGS= for C preprocessor options for host. + 5. LDFLAGS= for linker options for host. + 6. FREETYPE= for freetype-config for host (optional). + 7. Libdevmapper if any must be in standard linker folders (-ldevmapper) (optional). + 8. Libfuse if any must be in standard linker folders (-lfuse) (optional). + 9. Libzfs if any must be in standard linker folders (-lzfs) (optional). + 10. Liblzma if any must be in standard linker folders (-llzma) (optional). + + - For target + 1. --target= to autoconf cpu name of target. + 2. --with-platform to choose firmware. + 3. TARGET_CC= for gcc able to compile for target + 4. TARGET_CFLAGS= for C options for target. + 5. TARGET_CPPFLAGS= for C preprocessor options for target. + 6. TARGET_CCASFLAGS= for assembler options for target. + 7. TARGET_LDFLAGS= for linker options for target. + 8. TARGET_OBJCOPY= for objcopy for target. + 9. TARGET_STRIP= for strip for target. + 10. TARGET_NM= for nm for target. + + - Additionally for emu, for host and target. + 1. SDL is looked for in stadard linker directories (-lSDL) (optional) + 2. libpciaccess is looked for in stadard linker directories (-lpciaccess) (optional) + 3. libusb is looked for in stadard linker directories (-lusb) (optional) + + - Platform-agnostic tools and data. + 1. make is the tool you execute after ./configure. + 2. Bison is specified in YACC= variable + 3. Flex is specified in LEX= variable + 4. GNU unifont and Djvu sans are looked for in standard directories. Compiling For Multiple Architectures ==================================== diff --git a/acinclude.m4 b/acinclude.m4 index 08a05a03a..499465f31 100644 --- a/acinclude.m4 +++ b/acinclude.m4 @@ -74,7 +74,7 @@ AC_MSG_RESULT([$grub_cv_asm_uscore]) dnl Some versions of `objcopy -O binary' vary their output depending dnl on the link address. AC_DEFUN([grub_PROG_OBJCOPY_ABSOLUTE], -[AC_MSG_CHECKING([whether ${OBJCOPY} works for absolute addresses]) +[AC_MSG_CHECKING([whether ${TARGET_OBJCOPY} works for absolute addresses]) AC_CACHE_VAL(grub_cv_prog_objcopy_absolute, [cat > conftest.c <<\EOF void cmain (void); @@ -95,9 +95,9 @@ for link_addr in 0x2000 0x8000 0x7C00; do else AC_MSG_ERROR([${CC-cc} cannot link at address $link_addr]) fi - if AC_TRY_COMMAND([${OBJCOPY-objcopy} --only-section=.text -O binary conftest.exec conftest]); then : + if AC_TRY_COMMAND([${TARGET_OBJCOPY-objcopy} --only-section=.text -O binary conftest.exec conftest]); then : else - AC_MSG_ERROR([${OBJCOPY-objcopy} cannot create binary files]) + AC_MSG_ERROR([${TARGET_OBJCOPY-objcopy} cannot create binary files]) fi if test ! -f conftest.old || AC_TRY_COMMAND([cmp -s conftest.old conftest]); then mv -f conftest conftest.old @@ -134,6 +134,54 @@ if test "x$grub_cv_prog_ld_build_id_none" = xyes; then fi ]) +dnl Supply -P to nm +AC_DEFUN([grub_PROG_NM_MINUS_P], +[AC_MSG_CHECKING([whether nm accepts -P]) +AC_CACHE_VAL(grub_cv_prog_nm_minus_p, +[ +nm_minus_p_tmp_dir="$(mktemp -d "./confXXXXXX")" +AC_LANG_CONFTEST([AC_LANG_PROGRAM([[]], [[]])]) +$TARGET_CC conftest.c -o "$nm_minus_p_tmp_dir/ef" +if $TARGET_NM -P "$nm_minus_p_tmp_dir/ef" 2>&1 > /dev/null; then + grub_cv_prog_nm_minus_p=yes +else + grub_cv_prog_nm_minus_p=no +fi +rm "$nm_minus_p_tmp_dir/ef" +]) +AC_MSG_RESULT([$grub_cv_prog_nm_minus_p]) + +if test "x$grub_cv_prog_nm_minus_p" = xyes; then + TARGET_NMFLAGS_MINUS_P="-P" +else + TARGET_NMFLAGS_MINUS_P= +fi +]) + +dnl Supply --defined-only to nm +AC_DEFUN([grub_PROG_NM_DEFINED_ONLY], +[AC_MSG_CHECKING([whether nm accepts --defined-only]) +AC_CACHE_VAL(grub_cv_prog_nm_defined_only, +[ +nm_defined_only_tmp_dir="$(mktemp -d "./confXXXXXX")" +AC_LANG_CONFTEST([AC_LANG_PROGRAM([[]], [[]])]) +$TARGET_CC conftest.c -o "$nm_defined_only_tmp_dir/ef" +if $TARGET_NM --defined-only "$nm_defined_only_tmp_dir/ef" 2>&1 > /dev/null; then + grub_cv_prog_nm_defined_only=yes +else + grub_cv_prog_nm_defined_only=no +fi +rm "$nm_defined_only_tmp_dir/ef" +]) +AC_MSG_RESULT([$grub_cv_prog_nm_defined_only]) + +if test "x$grub_cv_prog_nm_defined_only" = xyes; then + TARGET_NMFLAGS_DEFINED_ONLY=--defined-only +else + TARGET_NMFLAGS_DEFINED_ONLY= +fi +]) + dnl Mass confusion! dnl Older versions of GAS interpret `.code16' to mean ``generate 32-bit diff --git a/configure.ac b/configure.ac index 83a2fa5e6..d46d95840 100644 --- a/configure.ac +++ b/configure.ac @@ -172,6 +172,10 @@ case "$host_os" in mingw32*) host_os=cygwin ;; esac +case "$target_os" in + mingw32*) target_os=cygwin ;; +esac + # This normalizes the names, and creates a new variable ("host_kernel") # while at it, since the mapping is not always 1:1 (e.g. different OSes # using the same kernel type). @@ -408,24 +412,28 @@ if test "x$target_alias" != x && test "x$host_alias" != "x$target_alias"; then AC_CHECK_TOOLS(TARGET_CC, [gcc egcs cc], [AC_MSG_ERROR([none of gcc, egcs and cc is found. set TARGET_CC manually.])]) - AC_CHECK_TOOL(OBJCOPY, objcopy) - AC_CHECK_TOOL(STRIP, strip) - AC_CHECK_TOOL(NM, nm) + AC_CHECK_TOOL(TARGET_OBJCOPY, objcopy) + AC_CHECK_TOOL(TARGET_STRIP, strip) + AC_CHECK_TOOL(TARGET_NM, nm) ac_tool_prefix="$tmp_ac_tool_prefix" else if test "x$TARGET_CC" = x; then TARGET_CC=$CC fi - AC_CHECK_TOOL(OBJCOPY, objcopy) - AC_CHECK_TOOL(STRIP, strip) - AC_CHECK_TOOL(NM, nm) + AC_CHECK_TOOL(TARGET_OBJCOPY, objcopy) + AC_CHECK_TOOL(TARGET_STRIP, strip) + AC_CHECK_TOOL(TARGET_NM, nm) fi + AC_SUBST(HOST_CC) AC_SUBST(BUILD_CC) AC_SUBST(BUILD_CFLAGS) AC_SUBST(BUILD_CPPFLAGS) AC_SUBST(TARGET_CC) +AC_SUBST(TARGET_NM) +AC_SUBST(TARGET_STRIP) +AC_SUBST(TARGET_OBJCOPY) # Test the C compiler for the target environment. tmp_CC="$CC" @@ -439,6 +447,11 @@ CPPFLAGS="$TARGET_CPPFLAGS" LDFLAGS="$TARGET_LDFLAGS" LIBS="" +grub_PROG_NM_MINUS_P +grub_PROG_NM_DEFINED_ONLY +AC_SUBST(TARGET_NMFLAGS_MINUS_P) +AC_SUBST(TARGET_NMFLAGS_DEFINED_ONLY) + # debug flags. WARN_FLAGS="-Wall -W -Wshadow -Wold-style-definition -Wpointer-arith -Wundef -Wextra -Waddress -Wattributes -Wcast-align -Wchar-subscripts -Wcomment -Wdeprecated-declarations -Wdisabled-optimization -Wdiv-by-zero -Wendif-labels -Wfloat-equal -Wformat-extra-args -Wformat-security -Wformat-y2k -Wimplicit -Wimplicit-function-declaration -Wimplicit-int -Winit-self -Wint-to-pointer-cast -Winvalid-pch -Wmain -Wmissing-braces -Wmissing-field-initializers -Wmissing-format-attribute -Wmissing-noreturn -Wmultichar -Wnonnull -Woverflow -Wparentheses -Wpointer-arith -Wpointer-to-int-cast -Wreturn-type -Wsequence-point -Wshadow -Wsign-compare -Wstrict-aliasing -Wswitch -Wtrigraphs -Wundef -Wunknown-pragmas -Wunused -Wunused-function -Wunused-label -Wunused-parameter -Wunused-value -Wunused-variable -Wvariadic-macros -Wvolatile-register-var -Wwrite-strings -Wnested-externs -Wstrict-prototypes -Wpointer-sign" HOST_CFLAGS="$HOST_CFLAGS $WARN_FLAGS" @@ -507,11 +520,11 @@ if test x$grub_cv_apple_target_cc = xyes ; then CFLAGS="$CFLAGS -fnested-functions" TARGET_APPLE_CC=1 - AC_CHECK_PROG([OBJCONV], [objconv], [objconv], []) - if test "x$OBJCONV" = x ; then - AC_CHECK_PROG([OBJCONV], [objconv], [./objconv], [], [.]) + AC_CHECK_PROG([TARGET_OBJCONV], [objconv], [objconv], []) + if test "x$TARGET_OBJCONV" = x ; then + AC_CHECK_PROG([TARGET_OBJCONV], [objconv], [./objconv], [], [.]) fi - if test "x$OBJCONV" = x ; then + if test "x$TARGET_OBJCONV" = x ; then AC_MSG_ERROR([objconv not found which is required when building with apple compiler]) fi TARGET_IMG_LDSCRIPT= @@ -524,10 +537,10 @@ else TARGET_APPLE_CC=0 TARGET_LDFLAGS_OLDMAGIC="-Wl,-N" # Use linker script if present, otherwise use builtin -N script. -if test -f "${srcdir}/${grub_coredir}/conf/${target_cpu}-${platform}-${host_os}-img-ld.sc"; then - TARGET_IMG_LDSCRIPT='$(top_srcdir)'"/${grub_coredir}/conf/${target_cpu}-${platform}-${host_os}-img-ld.sc" +if test -f "${srcdir}/${grub_coredir}/conf/${target_cpu}-${platform}-${target_os}-img-ld.sc"; then + TARGET_IMG_LDSCRIPT='$(top_srcdir)'"/${grub_coredir}/conf/${target_cpu}-${platform}-${target_os}-img-ld.sc" TARGET_IMG_LDFLAGS="-Wl,-T${TARGET_IMG_LDSCRIPT}" - TARGET_IMG_LDFLAGS_AC="-Wl,-T${srcdir}/${grub_coredir}/conf/${target_cpu}-${platform}-${host_os}-img-ld.sc" + TARGET_IMG_LDFLAGS_AC="-Wl,-T${srcdir}/${grub_coredir}/conf/${target_cpu}-${platform}-${target_os}-img-ld.sc" TARGET_IMG_BASE_LDOPT="-Wl,-Ttext" else TARGET_IMG_LDSCRIPT= @@ -542,7 +555,7 @@ AC_SUBST(TARGET_LDFLAGS_OLDMAGIC) # For platforms where ELF is not the default link format. AC_MSG_CHECKING([for command to convert module to ELF format]) -case "${host_os}" in +case "${target_os}" in cygwin) TARGET_OBJ2ELF='$(top_builddir)/grub-pe2elf'; # FIXME: put proper test here NEED_REGISTER_FRAME_INFO=1 @@ -695,7 +708,7 @@ GRUB_PLATFORM="${platform}" AC_SUBST(GRUB_TARGET_CPU) AC_SUBST(GRUB_PLATFORM) -AC_SUBST(OBJCONV) +AC_SUBST(TARGET_OBJCONV) AC_SUBST(TARGET_CPP) AC_SUBST(TARGET_CCAS) AC_SUBST(TARGET_OBJ2ELF) @@ -1261,7 +1274,7 @@ AM_CONDITIONAL([COND_ENABLE_BOOT_TIME_STATS], [test x$BOOT_TIME_STATS = x1]) AM_CONDITIONAL([COND_HAVE_CXX], [test x$HAVE_CXX = xyes]) AM_CONDITIONAL([COND_HAVE_ASM_USCORE], [test x$HAVE_ASM_USCORE = x1]) -AM_CONDITIONAL([COND_CYGWIN], [test x$host_os = xcygwin]) +AM_CONDITIONAL([COND_CYGWIN], [test x$target_os = xcygwin]) AM_CONDITIONAL([COND_STARFIELD], [test "x$starfield_excuse" = x]) # Output files. diff --git a/gentpl.py b/gentpl.py index 817f2b13d..b38cc1032 100644 --- a/gentpl.py +++ b/gentpl.py @@ -424,14 +424,14 @@ def kernel(platform): r += rule("[+ name +].img", "[+ name +].exec$(EXEEXT)", if_platform_tagged(platform, "nostrip", """if test x$(USE_APPLE_CC_FIXES) = xyes; then \ - $(OBJCONV) -f$(TARGET_MODULE_FORMAT) -nr:_grub_mod_init:grub_mod_init -nr:_grub_mod_fini:grub_mod_fini -ed2022 -wd1106 -nu -nd $< $@; \ + $(TARGET_OBJCONV) -f$(TARGET_MODULE_FORMAT) -nr:_grub_mod_init:grub_mod_init -nr:_grub_mod_fini:grub_mod_fini -ed2022 -wd1106 -nu -nd $< $@; \ elif test ! -z '$(TARGET_OBJ2ELF)'; then \ cp $< $@.bin; $(TARGET_OBJ2ELF) $@.bin && cp $@.bin $@ || (rm -f $@.bin; exit 1); \ else cp $< $@; fi""", """if test x$(USE_APPLE_CC_FIXES) = xyes; then \ - $(STRIP) $(""" + cname() + """) -o $@.bin $<; \ - $(OBJCONV) -f$(TARGET_MODULE_FORMAT) -nr:_grub_mod_init:grub_mod_init -nr:_grub_mod_fini:grub_mod_fini -ed2022 -wd1106 -nu -nd $@.bin $@; \ -else """ + "$(STRIP) $(" + cname() + "_STRIPFLAGS) -o $@ $<; \ + $(TARGET_STRIP) $(""" + cname() + """) -o $@.bin $<; \ + $(TARGET_OBJCONV) -f$(TARGET_MODULE_FORMAT) -nr:_grub_mod_init:grub_mod_init -nr:_grub_mod_fini:grub_mod_fini -ed2022 -wd1106 -nu -nd $@.bin $@; \ +else """ + "$(TARGET_STRIP) $(" + cname() + "_STRIPFLAGS) -o $@ $<; \ fi""")) return r @@ -458,7 +458,7 @@ def image(platform): if test x$(USE_APPLE_CC_FIXES) = xyes; then \ $(MACHO2IMG) $< $@; \ else \ - $(OBJCOPY) $(""" + cname() + """_OBJCOPYFLAGS) --strip-unneeded -R .note -R .comment -R .note.gnu.build-id -R .reginfo -R .rel.dyn -R .note.gnu.gold-version $< $@; \ + $(TARGET_OBJCOPY) $(""" + cname() + """_OBJCOPYFLAGS) --strip-unneeded -R .note -R .comment -R .note.gnu.build-id -R .reginfo -R .rel.dyn -R .note.gnu.gold-version $< $@; \ fi """) return r diff --git a/grub-core/Makefile.am b/grub-core/Makefile.am index 95cf3381d..9adc22d63 100644 --- a/grub-core/Makefile.am +++ b/grub-core/Makefile.am @@ -264,11 +264,11 @@ kern/emu/grub_emu_dyn-main.$(OBJEXT):grub_emu_init.h grub_emu_dyn-grub_emu_init.$(OBJEXT):grub_emu_init.h grub_emu_init.h: genemuinitheader.sh $(MOD_FILES) - rm -f $@; echo $(MOD_FILES) | sh $(srcdir)/genemuinitheader.sh $(NM) > $@ + rm -f $@; echo $(MOD_FILES) | sh $(srcdir)/genemuinitheader.sh $(TARGET_NM) > $@ CLEANFILES += grub_emu_init.h grub_emu_init.c: grub_emu_init.h genemuinit.sh $(MOD_FILES) - rm -f $@; echo $(MOD_FILES) | sh $(srcdir)/genemuinit.sh $(NM) > $@ + rm -f $@; echo $(MOD_FILES) | sh $(srcdir)/genemuinit.sh $(TARGET_NM) > $@ CLEANFILES += grub_emu_init.c endif diff --git a/grub-core/genmod.sh.in b/grub-core/genmod.sh.in index 76df0bbb4..95f4607c8 100644 --- a/grub-core/genmod.sh.in +++ b/grub-core/genmod.sh.in @@ -37,7 +37,7 @@ rm -f $tmpfile $outfile if test x@TARGET_APPLE_CC@ != x1; then # stripout .modname and .moddeps sections from input module - @OBJCOPY@ -R .modname -R .moddeps $infile $tmpfile + @TARGET_OBJCOPY@ -R .modname -R .moddeps $infile $tmpfile # Attach .modname and .moddeps sections t1=`mktemp "${TMPDIR:-/tmp}/tmp.XXXXXXXXXX"` || exit 1 @@ -47,9 +47,9 @@ if test x@TARGET_APPLE_CC@ != x1; then for dep in $deps; do printf "$dep\0" >> $t2; done if test -n "$deps"; then - @OBJCOPY@ --add-section .modname=$t1 --add-section .moddeps=$t2 $tmpfile + @TARGET_OBJCOPY@ --add-section .modname=$t1 --add-section .moddeps=$t2 $tmpfile else - @OBJCOPY@ --add-section .modname=$t1 $tmpfile + @TARGET_OBJCOPY@ --add-section .modname=$t1 $tmpfile fi rm -f $t1 $t2 @@ -57,7 +57,7 @@ if test x@TARGET_APPLE_CC@ != x1; then ./${TARGET_OBJ2ELF} $tmpfile || exit 1 fi if test x@platform@ != xemu; then - @STRIP@ --strip-unneeded \ + @TARGET_STRIP@ --strip-unneeded \ -K grub_mod_init -K grub_mod_fini \ -K _grub_mod_init -K _grub_mod_fini \ -R .note.gnu.gold-version -R .note.GNU-stack \ @@ -87,7 +87,7 @@ else mv $tmpfile2 $tmpfile cp $tmpfile $tmpfile.bin - @OBJCONV@ -f@TARGET_MODULE_FORMAT@ \ + @TARGET_OBJCONV@ -f@TARGET_MODULE_FORMAT@ \ -nr:_grub_mod_init:grub_mod_init \ -nr:_grub_mod_fini:grub_mod_fini \ -wd1106 -nu -nd $tmpfile.bin $tmpfile || exit 1 diff --git a/grub-core/gensyminfo.sh.in b/grub-core/gensyminfo.sh.in index d383f2640..af5ad9e71 100644 --- a/grub-core/gensyminfo.sh.in +++ b/grub-core/gensyminfo.sh.in @@ -22,14 +22,13 @@ module=$1 modname=`echo $module | sed -e 's@\.module.*$@@'` # Print all symbols defined by module -if test x@TARGET_APPLE_CC@ = x1; then - @NM@ -g -P -p $module | \ - grep -E '^[a-zA-Z0-9_]* [TDS]' | \ - sed "s@^\([^ ]*\).*@defined $modname \1@g" +if test x"@TARGET_NMFLAGS_DEFINED_ONLY@" = x; then + @TARGET_NM@ -g @TARGET_NMFLAGS_MINUS_P@ -p $module | \ + sed -n "s@^\([0-9a-fA-F]*\) *[TBRDS] *\([^ ]*\).*@defined $modname \2@p" else - @NM@ -g --defined-only -P -p $module | \ + @TARGET_NM@ -g --defined-only @TARGET_NMFLAGS_MINUS_P@ -p $module | \ sed "s@^\([^ ]*\).*@defined $modname \1@g" fi # Print all undefined symbols used by module -@NM@ -u -P -p $module | sed "s@^\([^ ]*\).*@undefined $modname \1@g" +@TARGET_NM@ -u @TARGET_NMFLAGS_MINUS_P@ -p $module | sed "s@^\([^ ]*\).*@undefined $modname \1@g"