Compiling NEON code on an Odroid XU4 - arm

I have a ROS node that contains code generated by Matlab coder. This code has been generated to make use of the NEON instruction set on ARM Cortex A CPUs. I want to compile this code on a Hardkernel Odroid XU4 (which runs on a Samsung Exynos5422 Cortex™-A15 2Ghz and Cortex™-A7 Octa core CPU). However I am not successful in compiling/linking my code.
I have added the the following compiler flags in the packages CMakeLists.txt:
-mfloat-abi=softfp -mfpu=neon -O2.
Yet, during compilation I get the following error message:
/usr/lib/gcc/arm-linux-gnueabihf/4.8/include/arm_neon.h:32:2: error:
#error You must enable NEON instructions (e.g. -mfloat-abi=softfp -mfpu=neon) to use arm_neon.h
This is followed by many more errors about unknown types:
/home/odroid/catkin_ws/src/vio_ros/src/codegen/mw_neon.c:12:2: error: unknown type name ‘float32x4_t’
/home/odroid/catkin_ws/src/vio_ros/src/codegen/mw_neon.c:36:2: error: unknown type name ‘int32x4_t’
...
And many more. All of these types seem to be defined in arm_neon.h
What do I need to do to be able to compile my code?
Thanks for your help

I have figured out what the problem was. Since some of the code being compiled in this C++ project was C code, I also have to set the compiler flags for C.
Including the following in the CMakeLists.txt makes the code compile:
set(NEON_FLAGS "-DENABLE_NEON -mfloat-abi=hard -mfpu=neon-vfpv4 -mcpu=cortex-a15 -Ofast")
set(CMAKE_CXX_FLAGS "-std=c++0x ${CMAKE_CXX_FLAGS} -Wno-format-security ${NEON_FLAGS}")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${NEON_FLAGS}")

Related

clang ARM neon support

I just cross-compiled the clang compiler for ARM on my x86 machine with instructions from here. I am trying to compile a c code containing NEON intrinsics with clang compiler. It is giving error, (which i do not encounter with arm-linux-gnueabi-gcc)
$ clang -march=armv7-a -mfpu=neon -mfloat-abi=soft -integrated-as test.c -o test
In file included from test.c:2:
/home/junaid/llvm/build/Release+Asserts/bin/../lib/clang/3.2/include/arm_neon.h:28:2: error:
"NEON support not enabled"
The line test.c:2 is #include arm_neon.h
It will be the -mfloat-abi=soft. I'm surprised that works for you with an arm-none-linux-gnueabi toolchain.
For Neon support you will want to be targetting either the softfp, or hard float ABI, with either -mfloat-abi=softfp or -mfloat-abi=hard

Format for setting Optimization flags in cBench

I am new to Compiler related work. I want to analyse some source code before and after optimising with -O1, -O2, -O3 flags. I am using Intel's PIN tool for analysis purposes. I am using source code from cBench Benchmark suite. But I am not getting that how to set optimization option in that.
Tutorial of cBench mentions following statement.
use __compile batch script with compiler name as the first parameter to compile the benchmark with a specific compiler, i.e. gcc, open64, pathscale or intel. In the second parameter you can specify optimization flags.
So I compile every source code with these three optimization flags as follows
./__compile gcc -O3
./__compile gcc -O2
./__compile gcc -O1
But when I analyse the object file in PIN tool, I am not able to find any difference in any of the 24 program set of cBench.
What is the point where I am missing.?

Error: selected processor does not support ARM mode `wfi'

I'm getting the following errors while trying to compile an ARM embedded C program (I'm using YAGARTO as my cross compiler). I'm trying to work out what this error means and what are the steps to correct it. From the research I've done so far, the issue it seems to be wfi, and wfe are not ASM instruction. How could I fix this?
\cc9e5oJe.s: Assembler messages:
\cc9e5oJe.s:404: Error: selected processor does not support ARM mode `wfi'
\cc9e5oJe.s:414: Error: selected processor does not support ARM mode `wfe'
\cc9e5oJe.s:477: Error: selected processor does not support ARM mode `wfi'
make: *** [STM32F10x_StdPeriph_Driver/src/stm32f10x_pwr.o] Error 1
You might miss some vital compiler options for your STM32F10x - which is a Cortex M3:
-mcpu=cortex-m3 -mthumb -mno-thumb-interwork -mfpu=vfp -msoft-float -mfix-cortex-m3-ldrd

Can I skip cmake compiler tests or avoid "error: unrecognized option '-rdynamic'"

compilation options for cmake (on windows) for ARM target system but when I run configure it's starting compiler tests:
CMake Error at D:/Program Files/CMake 2.8/share/cmake-2.8/Modules/CMakeTestCCompiler.cmake:52 (MESSAGE):
The C compiler "D:/Program Files/yagarto/bin/arm-none-eabi-gcc.exe" is not
able to compile a simple test program.
It fails with the following output:
Change Dir: D:/merge/complex/build/CMakeFiles/CMakeTmp
Run Build Command:D:/PROGRA~1/YAGART~1/bin/make.exe "cmTryCompileExec/fast"
D:/PROGRA~1/YAGART~1/bin/make.exe -f
CMakeFiles/cmTryCompileExec.dir/build.make
CMakeFiles/cmTryCompileExec.dir/build
make.exe[1]: Entering directory
`D:/merge/complex/build/CMakeFiles/CMakeTmp'
"D:/Program Files/CMake 2.8/bin/cmake.exe" -E cmake_progress_report
D:/merge/complex/build/CMakeFiles/CMakeTmp/CMakeFiles 1
Building C object CMakeFiles/cmTryCompileExec.dir/testCCompiler.c.o
"D:/Program Files/yagarto/bin/arm-none-eabi-gcc.exe" -o
CMakeFiles/cmTryCompileExec.dir/testCCompiler.c.o -c
D:/merge/complex/build/CMakeFiles/CMakeTmp/testCCompiler.c
Linking C executable cmTryCompileExec
"D:/Program Files/yagarto/bin/arm-none-eabi-gcc.exe"
"CMakeFiles/cmTryCompileExec.dir/testCCompiler.c.o" -o cmTryCompileExec
-rdynamic
arm-none-eabi-gcc.exe: error: unrecognized option '-rdynamic'
make.exe[1]: *** [cmTryCompileExec] Error 1
Using Yagatdo 4.6.* cross-compilation toolchain
How can I skip this tests or fix -rdynamic error that I am getting?
You can set CMAKE_<LANG>_COMPILER_WORKS to true to suppress further compiler checks for that language.
set(CMAKE_C_COMPILER_WORKS 1)
You can skip the compiler checks by adding NONE to your project call:
project(<projectname> NONE)
but this can have pretty far-reaching effects. For full details, run
cmake --help-command project
I'm not familiar with ARM, so this is probably not your best option here. I guess you'd be better to see if there's a way to fix the -rdynamic flag.
EDIT:
It looks like this was identified as a bug which is effectively still unresolved. The comments in the bug report mention adding the following lines as a workaround (presumably before your project call):
set(CMAKE_SHARED_LIBRARY_LINK_C_FLAGS "")
set(CMAKE_SHARED_LIBRARY_LINK_CXX_FLAGS "")
It seems you target actually something else than Linux, so you should tell cmake that you are cross-compiling for the generic case:
SET(CMAKE_SYSTEM_NAME Generic)
Followed by (optionally, but nice to specify):
SET(CMAKE_SYSTEM_PROCESSOR arm)
SET(CMAKE_CROSSCOMPILING 1)
However, if you specify (which you likely did because this is stated in a lot of examples online):
SET(CMAKE_SYSTEM_NAME Linux)
Then cmake will load the configuration files from (suppose version 2.8) the file:
/usr/share/cmake-2.8/Modules/Platform/Linux.cmake
from which it is likely to load:
/usr/share/cmake-2.8/Modules/Platform/Linux-GNU.cmake
Here the -rdynamic flag is set for historical reasons:
macro(__linux_compiler_gnu lang)
# We pass this for historical reasons. Projects may have
# executables that use dlopen but do not set ENABLE_EXPORTS.
set(CMAKE_SHARED_LIBRARY_LINK_${lang}_FLAGS "-rdynamic")
endmacro()
Rather than disabling the tests as indeed is done by specifying NONE as the PROJECT argument, it seems setting the CMAKE_SYSTEM_NAME (to something else than Linux, for instance Generic) is what you actually want to do.
If you're just compiling a static library and you want to avoid having CMake test that the compiler can generate binaries, you can set the variable CMAKE_TRY_COMPILE_TARGET_TYPE.
set(CMAKE_TRY_COMPILE_TARGET_TYPE STATIC_LIBRARY)
When cross compiling for Windows, where there is no -rdynamic option, you can use
-DCMAKE_SYSTEM_NAME="Windows"
with cmake. Then Cmake will skip the test with -rdynamic.

Undefined Symbols when linking against a mixed C and Fortran in OS X 10.6.4

I'm trying to compile a code (not mine) that consists of mixed Fortran and C source files, which are compiled into a library. This library can either be linked against directly, or (more usefully) driven from a python class. I have previously successfully built the code as 32-bit with g77 and gcc, but I've encountered a situation in which the code uses big chunks of memory, and needs to be 64-bit.
I've attempted to build as both 64-bit only, or as a universal binary, with gfortran 4.2.3 (binary dist from the AT&T R project) and the system gcc (4.2). The source files build correctly, but when I attempt to link against the library, I get many "Undefined Symbols" errors for a number of the Fortran functions. An nm on the library shows that the symbols appear to exist, but obviously the linker isn't finding them.
Here are two (of many) of the compile commands (which produce no errors):
/usr/local/bin/gfortran -arch ppc -arch i386 -arch x86_64 -fPIC -fno-strength-reduce -fno-common -ff2c -Wall -c lsame.f
gcc -c -I/Users/keriksen/Research/atomic_data/fac -I/Users/keriksen/Research/atomic_data/fac/faclib -O2 -fPIC -fno-strength-reduce -fno-common pmalloc.c
And the link step, which bombs:
gcc -o sfac sfac.c stoken.c -I/Users/keriksen/Research/atomic_data/fac -I/Users/keriksen/Research/atomic_data/fac/faclib -O2 -fPIC -fno-strength-reduce -fno-common -L/Users/keriksen/Research/atomic_data/fac -lfac -lm -lgfortran -lgcc
A sample Undefined Symbol:
"_acofz1", referenced from:
_HydrogenicDipole in libfac.a(coulomb.o)
_HydrogenicDipole in libfac.a(coulomb.o)
and the corresponding nm that shows that symbol exists:
niobe:atomic_data/fac[14] nm libfac.a | grep acof
0000000000000000 T _acofz1_
0000000000002548 S _acofz1_.eh
U _acofz1
Am I doing something stupid, like not including a necessary switch to the linker, or is something more subtle going on here?
Per Yuji's suggestion:
The cfortran.h header file (available on the Web, and apparently fairly widely used) that handles the C/Fortran compatibility issues does not handle gfortran out of the box. I hacked it (incorrectly) to ignore this fact, and paid for my insolence.
The specific issue is that gfortran emits object code containing symbols with a trailing underscore, gcc does not.
The correct thing to do was to set the environment variable CPPFLAGS to -Df2cFortran. Once this macro is set, cfortran.h adds the necessary underscore to the symbols in the calling C functions' object code, and the linker is happy.
The other surprising thing in this particular instance was the configure script looks at the F77 environment variable for the name of the fortran compiler. Once I set F77 to "/usr/local/bin/gfortran -arch x86_64" the generated Makefile was correct, and it produced 64-bit only object code. I'm not sure if this is standard configure behavior, or if it a peculiarity of this particular script.
The upshot is that I now have a 64-bit shared library which plays nicely with a 64-bit python I downloaded. I'm half-considering going back and trying to produce a universal library that will work with the system python, but I'm not sure I want to tempt fate.

Resources