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
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…
For work I cross-build for the Cortex-M3 platform, and I also use newlib. The following links may be helpful for you:
Although the following link is specific to Cortex-M3, it may provide some insight for you, I used it to script my toolchain build:
Your newlib may have been miscompiled (maybe with the host compiler? Highly unlikely since it links, but hey it’s possible).
I think you could first write a shell script to choose the work env, like you will work under gcc or arm-gcc. in this script, you could make an alternative lib link to different lib you want, like if you login and choose gcc, the lib file will be normal libc and if you choose arm-gcc, the lib will be the different one