I'm trying to cross compile to an ARM with linux from my x86 with a linux.
The issue appears to be that when including some standard library headers like iostream or string, even if those are included from the path where the cross compiler is, and its standard library, some of the dependencies of those headers seems to be included from my local standard library.
The headers from my local standard library have some x86 specific type definitions which do not exist on ARM hence the compilation fails.
The error shown is:
[01m[K/usr/include/bits/floatn.h:87:9:[m[K [01;31m[Kerror: [m[K?[01m[K__float128[m[K? does not name a type; did you mean ?[01m[K__cfloat128[m[K??
87 | typedef [01;31m[K__float128[m[K _Float128;
| [01;31m[K^~~~~~~~~~[m[K
| [32m[K__cfloat128[m[K
In file included from [01m[K/opt/fslc-wayland/3.1/sysroots/aarch64-fslc-linux/usr/include/c++/9.3.0/cwchar:44[m[K,
from [01m[K/opt/fslc-wayland/3.1/sysroots/aarch64-fslc-linux/usr/include/c++/9.3.0/bits/postypes.h:40[m[K,
from [01m[K/opt/fslc-wayland/3.1/sysroots/aarch64-fslc-linux/usr/include/c++/9.3.0/iosfwd:40[m[K,
from [01m[K/opt/fslc-wayland/3.1/sysroots/aarch64-fslc-linux/usr/include/c++/9.3.0/ios:38[m[K,
from [01m[K/opt/fslc-wayland/3.1/sysroots/aarch64-fslc-linux/usr/include/c++/9.3.0/ostream:38[m[K,
from [01m[K/opt/fslc-wayland/3.1/sysroots/aarch64-fslc-linux/usr/include/c++/9.3.0/iostream:39[m[K,
from [01m[K/home/lorandpetok/cross_ws/src/rvc_robot/rvc_ui/include/ConsoleMenu.h:5[m[K,
from [01m[K/home/lorandpetok/cross_ws/src/rvc_robot/rvc_ui/src/ConsoleMenu.cpp:1[m[K:<
Here you can see that I include iostream, the includes cascade down to cwchar which in turn includes floatn.h from my local x86 library.
The compiler used for cross compilation is gcc 9.3.0
My cmake toolchain file used:
set(ARTHERO_SYSROOTS "/opt/fslc-wayland/3.1/sysroots")
set(CMAKE_SYSTEM_NAME Linux)
set(CMAKE_SYSTEM_PROCESSOR armv8-a)
set(TOOLCHAIN_PREFIX ${ARTHERO_SYSROOTS}/x86_64-fslcsdk-linux/usr/bin/aarch64-fslc-linux/aarch64-fslc-linux-)
set(CMAKE_C_COMPILER ${TOOLCHAIN_PREFIX}gcc)
set(CMAKE_CXX_COMPILER ${TOOLCHAIN_PREFIX}g++)
set(CMAKE_SYSROOT ${ARTHERO_SYSROOTS}/aarch64-fslc-linux)
set(CMAKE_PREFIX_PATH ${CMAKE_SYSROOT}/usr/lib/cmake ${CMAKE_SYSROOT}/opt/ros/melodic/share)
set(CMAKE_FIND_ROOT_PATH ${CMAKE_SYSROOT} ${CATKIN_DEVEL_PREFIX})
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)
set(CMAKE_MODULE_PATH ${CMAKE_SYSROOT}/opt/ros/melodic/share)
set(LD_LIBRARY_PATH ${CMAKE_SYSROOT}/opt/ros/melodic/lib)
set(COMPILER_FLAGS " -march=armv8-a -mtune=cortex-a53")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${COMPILER_FLAGS}" CACHE STRING "" FORCE)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${COMPILER_FLAGS}" CACHE STRING "" FORCE)
include_directories(/opt/fslc-wayland/3.1/sysroots/aarch64-fslc-linux/opt/ros/melodic/include/)
What could make the compiler or cmake to include the header from my local standard library and how should i tell it to look in the correct path?
Related
On my host system (Ubuntu, 64Bit) I use gcc/g++ compilers to crosscompile my library for my Android app (arm64-v8a). On calling functions from my App I receive messages that libraries like libc.so.6 or libstdc++.so.6 cannot be found.
Within my /usr directory I have an aarch64-linux-gnu folder containing bin, include and lib folders.
CMakeLists.txt:
cmake_minimum_required(VERSION 3.6.0)
set(CMAKE_TOOLCHAIN_FILE android.toolchain.cmake)
project(testlibrary)
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STYANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)
# find header & source
file(GLOB_RECURSE SOURCE_CPP "src/*.cpp")
file(GLOB_RECURSE HEADER "src/*.h")
add_library(${PROJECT_NAME} SHARED
${SOURCE_CPP}
${HEADER}
)
source_group("Header include" FILES ${HEADER})
source_group("Source src" FILES ${SOURCE_CPP})
android.toolchain.cmake:
cmake_minimum_required(VERSION 3.6.0)
set(CMAKE_SYSTEM_NAME Android)
set(CMAKE_SYSTEM_VERSION 1)
set(CMAKE_SYSTEM_PROCESSOR aarch64)
set(CMAKE_ANDROID_ARCH_ABI arm64-v8a)
set(CMAKE_C_COMPILER "aarch64-linux-gnu-gcc")
set(CMAKE_CXX_COMPILER "aarch64-linux-gnu-g++")
set(CMAKE_ANDROID_NDK /home/ubuntu/Android/Sdk/ndk/21.4.7075529)
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)
The error messages are the following:
dlopen failed: library "libc.so.6" not found: needed by /my/lib/path/testlib.so in namespace classloader-namespace
or
dlopen failed: library "libstdc++.so.6" not found: needed by /my/lib/path/testlib.so in namespace classloader-namespace
Do I have to set a Sysroot or other paths so my libraries are found within my toolchain file and which path(s) do I use?
EDIT1: Adding the aarch64-linux-gnu folder to my build directory and explicitly including
target_link_libraries($PROJECT_NAME} PUBLIC ${CMAKE_CURRENT_LIST_DIR}/aarch64-linux-gnu/lib/libstdc++.so.6)
# also any other lib, e.g. libstdc++.so, libc.so and libc.so.6 don't work
still results in the mentioned error message.
I made a minimal example of the error using the .cpp and .hpp files below which results in this case in libc.so.6 not found. Removing the malloc line also removes the error messages. Calling the testFunc also return the correct value to my App which I can display.
src_file.cpp
#include "header_file.hpp"
#include <stdlib.h> // for malloc
int testFunc_(){
char* buffer;
buffer = (char *) malloc (10);
return 42;
}
header_file.hpp
extern "C" int testFunc_();
I also added the following lines to my android.toolchain.cmake file (I copied the folder from /usr/aarch64/linux-gnu/ to my build dir)
set(CMAKE_SKIP_BUILD_RPATH FALSE)
set(CMAKE_BUILD_WITH_INSTALL_RPATH FALSE)
set(CMAKE_INSTALL_RPATH "")
set(CMAKE_INSTALL_RPATH_USE_LINK_PATH FALSE)
set(LDFLAGS="-Wl,-rpath,../aarch64-linux-gnu/lib")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${LDFLAGS}" CACHE INTERNAL "" FORCE)
set(CMAKE_C_LINK_FLAGS "${CMAKE_C_LINK_FLAGS} ${LDFLAGS}" CACHE INTERNAL "" FORCE)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${LDFLAGS}" CACHE INTERNAL "" FORCE)
set(CMAKE_CXX_LINK_FLAGS "${CMAKE_CXX_LINK_FLAGS} ${LDFLAGS}" CACHE INTERNAL "" FORCE)
EDIT2:
On running readelf -d 'path/to/lib' I get the following (necessary I suppose) entries
Tag Type Name/Value
0x000...1 (NEEDED) Shared library: [libc.so.6]
0x000..1d (RUNPATH) Library runpath: [/home/username/Desktop/projectfolder/aarch64-linux-gnu/lib]
Adding the following line to my CMakeLists.txt (after removing the RPATH related stuff from my toolchain file or changing them also to ./) should allow me to add the libraries right next to my library.so in the build folder (arm64-v8a).
set_target_properties(${PROJECT_NAME} PROPERTIES LINK_FLAGS "-Wl,-rpath,./")
There is no RPATH tag. The RUNPATH entry is the location of my .so.6 and .so files I copied from the /usr/aarch64-linux-gnu folder. I think my main problem is bundling the necessary libraries correctly within my application as David Grayson implicated.
EDIT3:
Running file libc.so.6 also shows its an ELF 64-bit LSB shared object with ARM aarch64 architecture dynamically linked for GNU/Linux 3.7.0, interpreter /lib/ld-linux-aarch64.so.1, stripped
EDIT4:
Within my app/build.gradle I have the following lines
if(isNewArchitectureEnabled()) {
externalNativeBuild {
ndkBuild {
arguments "APP_PLATFORM=android-12",
"APP_STL=c_++shared",
"NDK_TOOLCHAIN_VERSION=gcc", // was clang before
"GENERATED_SRC_DIR=$buildDir/generated/source",
"PROJECT_BUILD_DIR=$buildDir",
"REACT_ANDROID_DIR=${reactNativeRoot}/ReactAndroid",
"REACT_ANDROID_BUILD_DIR=${reactNativeRoot}/ReactAndroid/build",
"NODE_MODULES_DIR=$rootDir/../node_modules"
cflags "-Wall", "-Werror", "-fexceptions", "-frtti", "-DWITH_INSPECTOR=1"
cppFlags "-std=c++17", //maybe 11 here(?) tried out both my App and .so to 11 but also no success
targets "myapp_appmodules"
}
}
}
and also
packagingOptions {
pickFirst 'lib/arm64-v8a/libc++_shared.so'
pickFirst 'lib/arm64-v8a/libm.so'
pickFirst 'lib/arm64-v8a/libm.so.6'
pickFirst 'lib/arm64-v8a/libstdc++.so'
pickFirst 'lib/arm64-v8a/libstdc++.so.6'
pickFirst 'lib/arm64-v8a/libc.so'
pickFirst 'lib/arm64-v8a/libc.so.6'
}
Am I probably using a wrong compiler/give the standalone toolchain within my ndk folder a try!
You either need to link those libraries statically into your executable (-static at link time might work) or you need to ship them with your executable and put them somewhere the executable will find them, like in the same directory.
I'm not very familiar with Android but there might also be a way to have the target Android system provide those libraries at run time, since they are very common and used widely.
I solved it changing my compilers (CMAKE_C_COMPILER and CMAKE_CXX_COMPILER ) within the toolchain file and leaving my CMakeLists.txt as it was in the first place.
cmake_minimum_required(VERSION 3.6.0)
set(CMAKE_SYSTEM_NAME Android)
set(CMAKE_SYSTEM_VERSION 21)
set(CMAKE_SYSTEM_PROCESSOR aarch64)
set(CMAKE_ANDROID_ARCH_ABI arm64-v8a)
set(CMAKE_C_COMPILER /home/username/path/to/ndk/toolchains/llvm/prebuilt/linux-x86_64/bin/aarch64-linux-android21-clang)
set(CMAKE_CXX_COMPILER /home/username/path/to/ndk/toolchains/llvm/prebuilt/linux-x86_64/bin/aarch64-linux-android21-clang++)
set(CMAKE_ANDROID_NDK /home/username/path/to/ndk)
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)
using Android API level 21.
I have been trying to make a program for Windows with C++ and Linux. I imported some libraries and wrote the code. Now this is the config for CMakeLists.txt
cmake_minimum_required(VERSION 3.10)
set(CMAKE_BUILD_TYPE Release)
set(CMAKE_C_COMPILER gcc)
set(CMAKE_C_FLAGS -m32)
set(CMAKE_CXX_COMPILER g++)
set(CMAKE_CXX_FLAGS "-std=c++14 -DCMAKE_BUILD_TYPE=release64 -m32")
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
project(qpsm)
add_executable(
a.exe
main.cpp
)
add_executable(
a.run
main.cpp
)
I know it's not very efficent, but it does the job for Linux. When it compiles for Windows and I try to open it on a Windows Machine it gives me the error with the title Not supported 16 Bit-Application that a feature called "\??\C:\Users\kroyz\Downloads\a.exe" cannot be run due to a incompatibility with 64-Bit Versions.
I know I am very bad at trying to explain things and errors so let me know if I did something wrong
Regards,
Alex
I am trying to compile a simple program made in C++ from windows to my raspberry pi 4 B.
For that I use Cmake but I don't know what to use to compile the program. Visual Studio it seems can compile Arm and Arm64 but according to the documentation, the Rp4 is in ArmV8 and when I do uname -m on the Rp4 I get armv71. I don't know what to indicate in CMakeLists.txt
cmake_minimum_required(VERSION 3.14)
set(CMAKE_SYSTEM_NAME Linux)
set(CMAKE_SYSTEM_PROCESSOR aarch64)
set(CMAKE_SYSROOT /home/devel/rasp-pi-rootfs)
set(CMAKE_STAGING_PREFIX /home/devel/stage)
set(tools /home/devel/gcc-4.7-linaro-rpi-gnueabihf)
set(CMAKE_C_COMPILER ${tools}/bin/arm-linux-gnueabihf-gcc)
set(CMAKE_CXX_COMPILER ${tools}/bin/arm-linux-gnueabihf-g++)
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)
project(SCWWS CXX)
#=================== INCLUSION OF Project Files ====================#
set(FORMS_DIR "${CMAKE_SOURCE_DIR}/forms")
set(INCLUDE_DIR "${CMAKE_SOURCE_DIR}/include")
set(SOURCE_DIR "${CMAKE_SOURCE_DIR}/src")
include_directories(${FORMS_DIR})
include_directories(${INCLUDE_DIR})
include_directories(${SOURCE_DIR})
file(GLOB_RECURSE SOURCES
"${INCLUDE_DIR}/*.h"
"${SOURCE_DIR}/*.cpp"
)
#=================== SETUP EXECTUABLE ====================#
# Add the executable
add_executable(SCWWS ${SOURCES})
# Add the target includes for SCWWS
target_include_directories(SCWWS PRIVATE ${FORMS_DIR})
target_include_directories(SCWWS PRIVATE ${INCLUDE_DIR})
target_include_directories(SCWWS PRIVATE ${SOURCE_DIR})
When I run my program on the Rp4 I get this error:
-bash: ./SCWWS: cannot execute binary file: Exec format error
For now, here is the cpp code that I am compiling:
#include <iostream>
using namespace std;
int main(){
cout << "Hello World !";
return 0;
}
For later, I would like to make a Qt application, will there be anything else to do?
I'm trying to cross compile from Ubuntu to Windows, using CMake. I have everything configured (Installed both mingw32 and mingw64), and I have the relevant toolchain files for both. The problem is that a variable that I set in one toolchain file, after it is used, persists in the second run with the other toolchain file one as well.
These are my toolchain files:
Windows 64 bit: (Toolchain-Ubuntu-mingw64.cmake)
set(CMAKE_SYSTEM_NAME Windows)
unset(PROCESSOR_ARCHITECTURE CACHE)
set(PROCESSOR_ARCHITECTURE x64)
message("===Processor architecture: " ${PROCESSOR_ARCHITECTURE})
set(TOOLCHAIN_PREFIX x86_64-w64-mingw32)
set(CMAKE_C_COMPILER ${TOOLCHAIN_PREFIX}-gcc)
set(CMAKE_CXX_COMPILER ${TOOLCHAIN_PREFIX}-g++)
set(CMAKE_RC_COMPILER ${TOOLCHAIN_PREFIX}-windres)
set(CMAKE_FIND_ROOT_PATH /usr/${TOOLCHAIN_PREFIX})
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
Windows 32 bit: (Toolchain-Ubuntu-mingw32.cmake)
set(CMAKE_SYSTEM_NAME Windows)
unset(PROCESSOR_ARCHITECTURE CACHE)
set(PROCESSOR_ARCHITECTURE x86)
message("===Processor architecture: " ${PROCESSOR_ARCHITECTURE})
set(TOOLCHAIN_PREFIX i686-w64-mingw32)
set(CMAKE_C_COMPILER ${TOOLCHAIN_PREFIX}-gcc)
set(CMAKE_CXX_COMPILER ${TOOLCHAIN_PREFIX}-g++)
set(CMAKE_RC_COMPILER ${TOOLCHAIN_PREFIX}-windres)
set(CMAKE_FIND_ROOT_PATH /usr/${TOOLCHAIN_PREFIX})
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
And this is the top of my CMakeLists.txt file:
cmake_minimum_required(VERSION 2.8)
project("project")
set(SOURCE_FILE_LIST main.c)
set(ARCH_PROJECT_NAME ${PROJECT_NAME}${PROCESSOR_ARCHITECTURE})
message("Project - " ${ARCH_PROJECT_NAME})
...
When I run
cmake -DCMAKE_TOOLCHAIN_FILE=../cmake-toolchains/Toolchain-Ubuntu-mingw64.cmake ../src/
The output starts with:
===Processor architecture: x64
Project - projectx64
The unexpected part comes when I run:
cmake -DCMAKE_TOOLCHAIN_FILE=../cmake-toolchains/Toolchain-Ubuntu-mingw32.cmake ../src/
and the output still starts with
===Processor architecture: x64
Project - projectx64
What can I do to fix this behaviour?
CMake will cache many of the values it finds during the setup process. Frustratingly it does this to the point that attempting to recreate the projects with a new option specified on the command line simply doesn't work. The only solution I've found is to either delete the entire build directory, or the specific cache file in the build directory, called CMakeCache.txt I believe.
I am trying to make a cross-compilation toolchain script for my BeagleBoard XM, but it doesn't work : the basic c++ includes (<algorithm>, etc...) aren't found when compiling.
Here is my toolchain file, made by following these two tutorials:
http://clang.llvm.org/docs/CrossCompilation.html
http://www.cmake.org/Wiki/CMake_Cross_Compiling#The_toolchain_file
The file:
set(CMAKE_SYSTEM_NAME Linux)
set(CMAKE_SYSTEM_VERSION 1)
set(CMAKE_SYSTEM_PROCESSOR arm)
set(FLOAT_ABI_SUFFIX "")
set(CMAKE_C_COMPILER clang)
set(CMAKE_CXX_COMPILER clang++)
set(CMAKE_CXX_FLAGS "-target armv7a-unknown-eabi -mfloat-abi=hard -mcpu=cortex-a8 --sysroot=/mnt/beagle/")
# where is the target environment
SET(CMAKE_FIND_ROOT_PATH /mnt/beagle /mnt/beagle/usr)
# search for programs in the build host directories
SET(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
# for libraries and headers in the target directories
SET(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
SET(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
/mnt/beagle is a SD Card with a copy of the system in my BeagleBoard, with all the necessary development packages, etc. installed.
Both the host and the guest are under Debian Jessie.
As a side question, I also have the android SDK & NDK installed. Is it possible to use them as a cross-compile environment, since it's ARMv7, or does the android NDK bring significant changes ?