Home > Software engineering >  Predefined macro to determine if running on a Raspberry?
Predefined macro to determine if running on a Raspberry?

Time:12-18

I'm maintaining an application that runs on GNU/Linux (x86, x86_64), Windows (x86, x86_64), Bionic/Android (armeabi-v7a, arm64-v8a, x86, x86_64) and also on Raspberry Pi (armhf). Since Raspberry OS is actually a modified version of GNU/Linux Debian, i can determine if i'm running linux (__linux__) on ARM (__arm__), but i can't discern if it's hard-float or not. (Yes, this may be an XY Problem.)

I need a way to pinpoint raspberry as some parts of the code are not to be implemented on Android. Yes, i could use -DRASPBERRY at compile time but was wondering if the compiler already does that for me. Preferably a standard macro instead of a compiler-specific one, but i'm cross-compiling on linux with gcc.

I'm considering __ARM_FP, but not sure.

This software runs on models 2 and up, any tips are appreciated.

Edit 1

To determine this, i've been using the output of the native gcc on linux x86_64, the 4 NDK variants and a mingw crross-compiler for x86. These caught my attention:

__ARM_ARCH is on all
__ARM_32BIT_STATE and __ARM_64BIT_STATE may be useful
__ARM_EABI__ and __ARMEL__ seem to only appear in Android's armeabi-v7a and the gcc in Raspbian, so may be good candidates
__ARM_FP has a different value on all of them, which may also be useful once i figure out what it means

CodePudding user response:

Approach the problem generally. How do you determine what flags are available? Use GCC dump preprocessor defines .

i can't discern if it's hard-float or not.

That's trivial:

  • list all compiler macros with hard float
  • list all compiler macros without hard float
  • show the difference

For exmaple: I take arm-none-eabi-gcc and cortex-m7 has hardware float support. I do:

$ get() { arm-none-eabi-gcc -mcpu=cortex-m7 -dM -E - < /dev/null "$@" | sort; }
$ diff <(get -mfloat-abi=soft) <(get -mfloat-abi=hard)
26c26,27
< #define __ARM_PCS 1
---
> #define __ARM_FP 14
> #define __ARM_PCS_VFP 1
132a134,139
> #define __FP_FAST_FMA 1
> #define __FP_FAST_FMAF 1
> #define __FP_FAST_FMAF32 1
> #define __FP_FAST_FMAF32x 1
> #define __FP_FAST_FMAF64 1
> #define __FP_FAST_FMAL 1
153,154c160,161
< #define __GCC_IEC_559 0
< #define __GCC_IEC_559_COMPLEX 0
---
> #define __GCC_IEC_559 2
> #define __GCC_IEC_559_COMPLEX 2
299d305
< #define __SOFTFP__ 1

__SOFTFP__ might be super interesting for you (when using that particular compiler).

Predefined macro to determine if running on a Raspberry?

Well, you can't know what your code will be running on, only the architecture it is compiled for. Seeing the output of:

diff <(ssh myraspberry gcc -dM -E - < /dev/null | sort) <(gcc -dM -E - </dev/null | sort)

Those macros might sound interesting:

< #define __ARM_32BIT_STATE 1
< #define __ARM_ARCH 6
< #define __ARM_ARCH_6__ 1
< #define __ARM_ARCH_ISA_ARM 1
< #define __ARM_ARCH_ISA_THUMB 1
< #define __ARM_EABI__ 1
< #define __ARM_FEATURE_CLZ 1
< #define __ARM_FEATURE_COPROC 15
< #define __ARM_FEATURE_DSP 1
< #define __ARM_FEATURE_LDREX 4
< #define __ARM_FEATURE_QBIT 1
< #define __ARM_FEATURE_SAT 1
< #define __ARM_FEATURE_SIMD32 1
< #define __ARM_FEATURE_UNALIGNED 1
< #define __ARM_FP 12
< #define __ARM_PCS_VFP 1

CodePudding user response:

Well, according to Arm C Language Extensions

5.5.1 Hardware floating point
__ARM_FP is set if hardware floating-point is available. ...and proceeds to enumerate the possible valid values as 0x04, 0x6, 0xC and 0xE.

The NDK sets 0xC for armeabi-v7a and 0xE for arm64-v8a and i got a bit confused because the gcc compiler in Raspberry OS sets it to 12... which is 0x0C.

  • Related