Cross compiling GCC with newlib for ARM: how to specify GCC options like -march?

Synthetix picture Synthetix · May 30, 2012 · Viewed 8.8k times · Source

I've compiled GCC along with newlib on Mac OS X for ARM targets. However, libc.a was compiled with -fshort-enums, and I don't want that because when I compile stuff for ARM, I use -fno-short-enums. This conflicts, of course:

ld: warning: /var/folders/9m/2wnjp9zd71x13cpdpf16y_4r0000gn/T//ccQuEnp6.o uses 32-bit enums yet the output is to use variable-size enums; use of enum values across objects may fail

Every time I try to run a "Hello, World!" executable, it segfaults. Could this be the reason?

Here's the command I used to compile hello.c:

arm-eabi-gcc \
hello.c -o hello \
/Users/user/gcc-arm-install/arm-eabi/lib/crt0.o \
/Users/user/gcc-arm-install/lib/gcc/arm-eabi/4.7.0/crtbegin.o \
/Users/user/gcc-arm-install/lib/gcc/arm-eabi/4.7.0/crti.o \
/Users/user/gcc-arm-install/lib/gcc/arm-eabi/4.7.0/crtn.o \
/Users/user/gcc-arm-install/lib/gcc/arm-eabi/4.7.0/crtend.o \
-v -nostdinc -nostdlib -static \
-march=armv7-a -mno-thumb-interwork -marm -mfpu=neon -mfloat-abi=softfp -fpic \
-ffunction-sections -fno-short-enums -fno-rtti -fno-exceptions \
-I/Users/user/gcc-arm-install/lib/gcc/arm-eabi/4.7.0/include \
-I/Users/user/gcc-arm-install/lib/gcc/arm-eabi/4.7.0/include-fixed \
-I/Users/user/gcc-arm-install/arm-eabi/include \
-I/Users/user/gcc-arm-install/arm-eabi/sys-include \
-L/Users/user/gcc-arm-install/arm-eabi/lib \
-L/Users/user/gcc-arm-install/lib/gcc/arm-eabi/4.7.0 \
-lm -lc -lgcc

Update:

Okay, I think I've narrowed the problem down to the combination of newlib's libc and the startup files (crt0.o). I tried compiling a test app with GCC 4.7.0 using libc.a and startup files from the Android NDK, and that worked on the phone when compiled static. In fact, it worked even though ld complained again about libgcc using "variable-size enums" (i.e., not compiled with -fno-short-enums like everything else). So, my hypothesis about -fno-short-enums being the culprit in my earlier crashing binaries was incorrect.

Here's what's working:

Binutils and GCC 4.7.0 compiled from source for target "arm-linux-eabi." I configured GCC using --with-newlib (newlib and libgloss in GCC's source tree). So, GCC was actually built with newlib and installed along with newlib, and it generates working binaries as long as I don't actually link with newlib's libc. At present, I must use libc from the Andoid NDK and its startup files instead.

My compile script looks something like this. The include and library paths point to the NDK includes and libc:

NDK_PATH="/Users/user/SOURCE/android-ndk-r8/platforms/android-9/arch-arm"
CFLAGS="-nostdinc -nostdlib -static -fno-short-enums -lc -lgcc -lc"

gcc $NDK_PATH/usr/lib/crtbegin_static.o \
hello.c -o hello $CFLAGS \
$NDK_PATH/usr/lib/crtend_android.o

I still want to get binaries compiled statically with newlib's libc working. Back to shell scripting...

Answer

chmeee picture chmeee · Aug 12, 2012

For work I cross-build for the Cortex-M3 platform, and I also use newlib. The following links may be helpful for you:

http://frank.harvard.edu/~coldwell/toolchain/ http://www.microbuilder.eu/Tutorials/SoftwareDevelopment/BuildingGCCToolchain.aspx

Although the following link is specific to Cortex-M3, it may provide some insight for you, I used it to script my toolchain build: http://www.johannes-bauer.com/mcus/cortex/?menuid=5

Your newlib may have been miscompiled (maybe with the host compiler? Highly unlikely since it links, but hey it's possible).