Cross-compiling to Raspberry Pi, using Qt and opencv - c++

There are various ways to cross-compile to Raspberry Pi, and there are also solutions posted for cross-compiling Qt or opencv.
However, I couldn't find any solution to cross-compile a program with Qt which also uses opencv.
I tried the following, using debian on a 64-bit PC:
I compiled and set up Qt as a cross-compiler to ARM7, using this tutorial. It didn't work without issues though, here is an answer I posted which solved it for me. I can now run my Qt programs with graphical GUI on the Raspberry Pi (although only full-screen, but that's a completely different issue)
I followed the guide on the official opencv website to build opencv. It failed with No CMAKE_CXX_COMPILER could be found.
Knowing from experience (I used Qt with opencv both on Windows and Linux) that Qt and opencv work together only if both are compiled with the same compiler, I tried to use the same cross-compiler for opencv which I used successfully to compile Qt: gcc-4.7-linaro-rpi-gnueabihf
I specified the gnueabihf I previously used to compile Qt, as the compiler:
I created the directory ~/opt/opencv_build_arm7/ and in it, I tried:
sudo cmake -DCMAKE_CXX_COMPILER=/home/<user>/opt/gcc-4.7-linaro-rpi-gnueabihf/bin/arm-linux-gnueabihf-g++ -DCMAKE_C_COMPILER=/home/<user>/opt/gcc-4.7-linaro-rpi-gnueabihf/bin/arm-linux-gnueabihf-gcc -DCMAKE_TOOLCHAIN_FILE=/usr/dev/opencv/platforms/linux/arm-gnueabi.toolchain.cmake /usr/dev/opencv/
(Where the downloaded opencv sources were in /usr/dev/opencv/ which I recently used successfully to compile opencv for an x64 platform, using the g++ compiler which came with my Qt installation.) Note, that <user> is the username for the current session, in case other beginners might try these methods in the future.
This failed with the following error (where <user> is my username)
CMake Error at
/usr/share/cmake-3.0/Modules/CMakeTestCXXCompiler.cmake:54 (message):
The C++ compiler
"/home//opt/gcc-4.7-linaro-rpi-gnueabihf/bin/arm-linux-gnueabihf-g++"
is not able to compile a simple test program.
It fails with the following output :
Change Dir: /home//temp/CMakeFiles/CMakeTmp
Run Build Command:"/usr/bin/make" "cmTryCompileExec117178613/fast"
/usr/bin/make -f CMakeFiles/cmTryCompileExec117178613.dir/build.make
CMakeFiles/cmTryCompileExec117178613.dir/build
make1: Entering directory '/home//temp/CMakeFiles/CMakeTmp'
/usr/bin/cmake -E cmake_progress_report
/home//temp/CMakeFiles/CMakeTmp/CMakeFiles 1
Building CXX object
CMakeFiles/cmTryCompileExec117178613.dir/testCXXCompiler.cxx.o
/home//opt/gcc-4.7-linaro-rpi-gnueabihf/bin/arm-linux-gnueabihf-g++
-mthumb -fdata-sections -Wa,--noexecstack -fsigned-char -Wno-psabi -mthumb -fdata-sections -Wa,--noexecstack -fsigned-char -Wno-psabi -o CMakeFiles/cmTryCompileExec117178613.dir/testCXXCompiler.cxx.o -c /home//temp/CMakeFiles/CMakeTmp/testCXXCompiler.cxx
/home//temp/CMakeFiles/CMakeTmp/testCXXCompiler.cxx: In
function ‘int main()’:
/home//temp/CMakeFiles/CMakeTmp/testCXXCompiler.cxx:4:10:
sorry, unimplemented: Thumb-1 hard-float VFP ABI
CMakeFiles/cmTryCompileExec117178613.dir/build.make:57: recipe for
target
'CMakeFiles/cmTryCompileExec117178613.dir/testCXXCompiler.cxx.o'
failed
make1: ***
[CMakeFiles/cmTryCompileExec117178613.dir/testCXXCompiler.cxx.o] Error
1
make1: Leaving directory '/home//temp/CMakeFiles/CMakeTmp'
Makefile:118: recipe for target 'cmTryCompileExec117178613/fast'
failed
make: *** [cmTryCompileExec117178613/fast] Error 2
I specified an absolute path for the compiler, but even if I don't specify it, and just add it to my $PATH, it still has the same problem.
export PATH=$PATH:/home/<user>/opt/gcc-4.7-linaro-rpi-gnueabihf/bin/
sudo cmake -DCMAKE_TOOLCHAIN_FILE=/usr/dev/opencv/platforms/linux/arm-gnueabi.toolchain.cmake /usr/dev/opencv/
The compiler itself is found correctly, if I type
arm-linux-gnueabihf-g++ -v
it is found successfully:
Using built-in specs. COLLECT_GCC=./arm-linux-gnueabihf-c++
COLLECT_LTO_WRAPPER=/home/vszabi/opt/gcc-4.7-linaro-rpi-gnueabihf/bin/../libexec/gcc/arm-linux-gnueabihf/4.7.2/lto-wrapper
Target: arm-linux-gnueabihf Configured with:
/opt/dev/src/crosstool-ng/crosstool-ng-linaro-1.13.1-2012.07-20120720/builds/arm-linux-gnueabihf-linux/.build/src/gcc-linaro-4.7-2012.07/configure
--build=i686-build_pc-linux-gnu --host=i686-build_pc-linux-gnu --target=arm-linux-gnueabihf --prefix=/opt/dev/src/crosstool-ng/crosstool-ng-linaro-1.13.1-2012.07-20120720/builds/arm-linux-gnueabihf-linux/install
--with-sysroot=/opt/dev/src/crosstool-ng/crosstool-ng-linaro-1.13.1-2012.07-20120720/builds/arm-linux-gnueabihf-linux/install/arm-linux-gnueabihf/libc
--enable-languages=c,c++,fortran --enable-multilib --with-arch=armv6zk --with-tune=arm1176jzf-s --with-fpu=vfp --with-float=hard --with-pkgversion='crosstool-NG linaro-1.13.1-2012.07-20120720 - Linaro GCC 2012.07'
--with-bugurl=https://bugs.launchpad.net/gcc-linaro --enable-__cxa_atexit --enable-libmudflap --enable-libgomp --enable-libssp --with-gmp=/opt/dev/src/crosstool-ng/crosstool-ng-linaro-1.13.1-2012.07-20120720/builds/arm-linux-gnueabihf-linux/.build/arm-linux-gnueabihf/build/static
--with-mpfr=/opt/dev/src/crosstool-ng/crosstool-ng-linaro-1.13.1-2012.07-20120720/builds/arm-linux-gnueabihf-linux/.build/arm-linux-gnueabihf/build/static
--with-mpc=/opt/dev/src/crosstool-ng/crosstool-ng-linaro-1.13.1-2012.07-20120720/builds/arm-linux-gnueabihf-linux/.build/arm-linux-gnueabihf/build/static
--with-ppl=/opt/dev/src/crosstool-ng/crosstool-ng-linaro-1.13.1-2012.07-20120720/builds/arm-linux-gnueabihf-linux/.build/arm-linux-gnueabihf/build/static
--with-cloog=/opt/dev/src/crosstool-ng/crosstool-ng-linaro-1.13.1-2012.07-20120720/builds/arm-linux-gnueabihf-linux/.build/arm-linux-gnueabihf/build/static
--with-libelf=/opt/dev/src/crosstool-ng/crosstool-ng-linaro-1.13.1-2012.07-20120720/builds/arm-linux-gnueabihf-linux/.build/arm-linux-gnueabihf/build/static
--with-host-libstdcxx='-L/opt/dev/src/crosstool-ng/crosstool-ng-linaro-1.13.1-2012.07-20120720/builds/arm-linux-gnueabihf-linux/.build/arm-linux-gnueabihf/build/static/lib
-lpwl' --enable-threads=posix --disable-libstdcxx-pch --enable-linker-build-id --enable-gold --with-local-prefix=/opt/dev/src/crosstool-ng/crosstool-ng-linaro-1.13.1-2012.07-20120720/builds/arm-linux-gnueabihf-linux/install/arm-linux-gnueabihf/libc
--enable-c99 --enable-long-long Thread model: posix gcc version 4.7.2 20120701 (prerelease) (crosstool-NG linaro-1.13.1-2012.07-20120720 -
Linaro GCC 2012.07)
What could I try next? Opening the gui version of cmake with opencv/platforms/linux/arm-gnueabi.toolchain.cmake shows very few options (only ARM_LINUX_SYSROOT, CMAKE_BUILD_TYPE, CMAKE_CONFIGURATION_TYPES, CMAKE_INSTALL_PREFIX, GCC_COMPILER_VERSION and LIBRARY_OUTPUT_PATH_ROOT, but none of the BUILD_opencv_xyz with which I can disable individual packages), much fewer than the case when I built opencv for an x86 or x64 platform.
I'm afraid that searching for a different compiler might cause issues with Qt, because as far as I know, for opencv to work within Qt, it has to be compiled with the same compiler as what is used both to build the Qt libraries and build my program. Whenever I tried it in the past without being careful that these 3 things (Qt libs, opencv, my program) need to be compiled with the same compiler, I always experienced weird crashes either as soon as I included any opencv header, or whenever I called any function from opencv.

The tutorial at http://docs.opencv.org/doc/tutorials/introduction/crosscompilation/arm_crosscompile_with_cmake.html seems to be either wrong or out of date.
Downloading the source of opencv 3.0, the opencv/platforms/linux/arm-gnueabi.toolchain.cmake seems to be insufficiently configured for the Raspberry Pi.
Configure
Visiting the workgroup page of the creators of the arm-linux-gnueabihf toolchain, it seems that for the ARM7 in the Raspberry Pi to be supported, the following options have to be passed to the compiler: -mcpu=cortex-a7 -mfloat-abi=hard -mfpu=vfpv4
So, we have to edit the opencv/platforms/linux/arm-gnueabi.toolchain.cmake file and change
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mthumb -fdata-sections -Wa,--noexecstack -fsigned-char -Wno-psabi")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -mthumb -fdata-sections -Wa,--noexecstack -fsigned-char -Wno-psabi")
to
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mthumb -fdata-sections -Wa,--noexecstack -fsigned-char -Wno-psabi -mcpu=cortex-a7 -mfloat-abi=hard -mfpu=vfpv4")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -mthumb -fdata-sections -Wa,--noexecstack -fsigned-char -Wno-psabi -mcpu=cortex-a7 -mfloat-abi=hard -mfpu=vfpv4")
running cmake again, the configuration was successfully completed!
Make
During the building process, if the following error appears
CMakeFiles/opencv_core.dir/src/rand.cpp.o: relocation
R_ARM_THM_MOVW_ABS_NC against `a local symbol' can not be used when
making a shared object; recompile with -fPIC
CMakeFiles/opencv_core.dir/src/rand.cpp.o: could not read symbols: Bad
value
just add the -fPIC flag to the CMAKE_C_FLAGS and CMAKE_CXX_FLAGS in the cmake file and run make again.
Deployement
Using Qt Creator to deploy, just set up the headers and libraries in your .pro file, for example:
INCLUDEPATH += <your build dir>/install/include/opencv2/
INCLUDEPATH += <your build dir>/install/include/
LIBS += -L "<your build dir>/install/lib/"
LIBS += -lopencv_calib3d
LIBS += -lopencv_core
#... and so on
You also have to copy the compiled libraries (found in <your build dir>/install/lib/) to the Raspberry Pi. Using a USB stick might mess up the symlinks, so I would recommend using scp to copy the files.
If you are relatively new to Linux (just as myself), don't forget that executables don't automatically look into their own folders for dynamic libraries as they did in Windows.
Therefore you should either copy the libraries to a place which is usually searched for them (like /usr/local/bin) or update your LD_LIBRARY_PATH accordingly.
For a quick and dirty test, to see if everything works, you might copy the libraries into the same folder where your executable is deployed, and run it by using
$ LD_LIBRARY_PATH=. ./your_program
Testing
Opencv should work now in your Qt program on the Raspberry Pi.
Unless my google-fu is very weak, this might be the first documented case of running a Qt GUI application on a Raspberry Pi with opencv working in it. :)
However, note that there might still be some issues with window management.
Trying to open an opencv window, for example, cv::namedWindow("image"); might fail with the following error:
OpenCV Error: Unspecified error (The function is not implemented.
Rebuild the library with Windows, GTK+ 2.x or Carbon support. If you
are on Ubuntu or Debian, install libgtk2.0-dev and pkg-config, then
re-run cmake or configure script) in cvNamedWindow, file
/usr/dev/opencv/modules/highgui/src/window.cpp, line 516 terminate
called after throwing an instance of 'cv::Exception' what():
/usr/dev/opencv/modules/highgui/src/window.cpp:516: error: (-2) The
function is not implemented. Rebuild the library with Windows, GTK+
2.x or Carbon support. If you are on Ubuntu or Debian, install libgtk2.0-dev and pkg-config, then re-run cmake or configure script in
function cvNamedWindow
I guess we should do as it says, but cvNamedWindow is not very useful in a Qt GUI application, as it's usually only required for debugging. Therefore if the image has to be shown in your application, converting it to QImage might be better anyway than opening up an independent window.
However, everything else seems to work, I managed to successfully run complicated image matching algorithms on the Raspberry Pi.
(... will update if I find a good solution for running the Qt application in a window and using cvNamedWindow)

Related

What's the right cmake command to cross-compile for Raspberry Pi from M1 Mac?

My title seems general but I need to compile a project for my Raspberry Pi 3b. I want to use Telegram's Bot API server on it, but it takes a lot of time to compile, so I'm looking for faster ways to compile it. I heard about cross compiling, and I tried to compile the project from a Debian VM using UTM on my M1 Mac, but obviously arm64 isn't the same as armhf.
The main commands I need to perform are (from the project's page, selecting Debian 10+):
cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX:PATH=.. ..
cmake --build . --target install
from build folder.
I'm not an expert with compilation commands, and I've looked over a bunch of potential answer over the internet, but it's or too complicated, or not for cmake, or not for M1 Mac...
Anyway, I found what seems to be a pretty decent solution, however once again it's for clang++ and not cmake.
So my question is straightforward, what cmake arguments/commands can I use to easily build the binary for my (slow) Raspberry from my (fast) M1 Mac?
EDIT 1:
According to the answer of #sweenish, it's possible to pass directly arguments to the cmake command, which I did, wrapping them all into -DCMAKE_CXX_FLAGS.
My current command is:
cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX:PATH=.. -DCMAKE_CXX_FLAGS="--target=arm-linux-gnueabihf --sysroot $HOME/sysroot -isysroot $HOME/sysroot -isystem $HOME/sysroot/usr/include/c++/10 -isystem $HOME/sysroot/usr/include/arm-linux-gnueabihf/c++/10 -L$HOME/sysroot/usr/lib/gcc/arm-linux-gnueabihf/10 -B$HOME/sysroot/usr/lib/gcc/arm-linux-gnueabihf/10 --gcc-toolchain=$(brew --prefix arm-linux-gnueabihf-binutils)" ..
However, as the output shows, it seems like macOS/Xcode is natively appending 'default' arguments at the end of my command:
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/c++ --target=arm-linux-gnueabihf --sysroot /Users/antoine/sysroot -isysroot /Users/antoine/sysroot -isystem /Users/antoine/sysroot/usr/include/c++/10 -isystem /Users/antoine/sysroot/usr/include/arm-linux-gnueabihf/c++/10 -L/Users/antoine/sysroot/usr/lib/gcc/arm-linux-gnueabihf/10 -B/Users/antoine/sysroot/usr/lib/gcc/arm-linux-gnueabihf/10 --gcc-toolchain=/opt/homebrew/opt/arm-linux-gnueabihf-binutils -arch arm64 -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX12.3.sdk -Wl,-search_paths_first -Wl,-headerpad_max_install_names CMakeFiles/cmTC_42ace.dir/testCXXCompiler.cxx.o -o cmTC_42ace
(notice the additional space after the end of my args and the beginning of uncontrolled args)
This leads to 3 main errors:
-L$HOME... is not used
-arch arm64, which I didn't choose to append, is unused too
Error: unable to disambiguate: -search_paths_first (did you mean --search_paths_first ?), again in the appended args
So to sum up, 'disabling' system args should solve 2/3 of my problems, and removing the -L one should be enough to be finally able to compile. How do I get rid of these final appended arguments?

CMake: Clang-based cross-compile for Linux uses wrong target platform

I'm attempting to build a library for Linux using CMake and Clang on Windows 10. Because this library needs to be compatible with a specific version of the Unreal Engine, I'm using the recommended cross-compilation toolchain for Unreal Engine 4.26, which is labelled v17_clang-10.0.1-centos7.
I've not made a toolchain file yet, but have been experimenting with CMake options on the command line to find a setup that works. My current configuration is:
CC environment variable points to v17_clang-10.0.1-centos7\x86_64-unknown-linux-gnu\bin\clang.exe
CXX environment variable points to v17_clang-10.0.1-centos7\x86_64-unknown-linux-gnu\bin\clang++.exe
-DCMAKE_TRY_COMPILE_TARGET_TYPE=STATIC_LIBRARY: According to this answer, this must be set to STATIC_LIBRARY or the compiler checks will fail (and did when I first ran them) when they try to link.
-DCMAKE_C_COMPILER_TARGET=x86_64-unknown-linux-gnu and -DCMAKE_CXX_COMPILER_TARGET=x86_64-unknown-linux-gnu are set to match the Clang distribution I'm using.
For good measure, -DCMAKE_SYSTEM_NAME=linux and -DCMAKE_SYSTEM_PROCESSOR=x86_64 are also set.
This configuration is generated correctly (I'm using Ninja as the generator), but when building it appears that the target is still Windows and not Linux. I get lots of errors like the following:
[14/106] Building CXX object core/thirdParty/cppfs-1.2.0/cppfs-1.2.0/source/cppfs/CMakeFiles/cppfs.dir/source/Diff.cpp.obj
FAILED: core/thirdParty/cppfs-1.2.0/cppfs-1.2.0/source/cppfs/CMakeFiles/cppfs.dir/source/Diff.cpp.obj
C:\UnrealToolchains\v17_clang-10.0.1-centos7\x86_64-unknown-linux-gnu\bin\clang++.exe -DCLIENT_VERSION_MAJOR=-1
-DCLIENT_VERSION_MINOR=-1 -DCLIENT_VERSION_PATCH=-1 -DCPPFS_STATIC_DEFINE -DFACEIT_CORELIB_BUILD_PRODUCER
-DHAVE_OPENSSL -DSERVER_VERSION_MAJOR=-1 -DSERVER_VERSION_MINOR=-1 -DSERVER_VERSION_PATCH=-1 -DSYSTEM_WINDOWS
-Icore/thirdParty/cppfs-1.2.0/cppfs-1.2.0/source/include
-I../core/thirdParty/cppfs-1.2.0/cppfs-1.2.0/source/cppfs/3rdparty
-I../core/thirdParty/cppfs-1.2.0/cppfs-1.2.0/source/cppfs/include
-Icore/thirdParty/cppfs-1.2.0/cppfs-1.2.0/source/cppfs/include -g -Xclang -gcodeview -O0 -D_DEBUG -D_DLL -D_MT
-Xclang --dependent-lib=msvcrtd -Wall -Wextra -pedantic -Werror -Wl,--fatal-warnings -fPIC -Wno-unused-parameter
-std=gnu++14 -MD -MT core/thirdParty/cppfs-1.2.0/cppfs-1.2.0/source/cppfs/CMakeFiles/cppfs.dir/source/Diff.cpp.obj
-MF core\thirdParty\cppfs-1.2.0\cppfs-1.2.0\source\cppfs\CMakeFiles\cppfs.dir\source\Diff.cpp.obj.d
-o core/thirdParty/cppfs-1.2.0/cppfs-1.2.0/source/cppfs/CMakeFiles/cppfs.dir/source/Diff.cpp.obj
-c ../core/thirdParty/cppfs-1.2.0/cppfs-1.2.0/source/cppfs/source/Diff.cpp
clang++: error: -Wl,--fatal-warnings: 'linker' input unused [-Werror,-Wunused-command-line-argument]
clang++: error: unsupported option '-fPIC' for target 'x86_64-pc-windows-msvc'
It seems that the target is x86_64-pc-windows-msvc, and PLATFORM_WINDOWS is defined, so my input settings have been ignored. What am I missing here? Do I need an actual toolchain file after all?
EDIT: After recommendations in the comments, I have created a toolchain file which looks like this:
if("$ENV{LINUX_MULTIARCH_ROOT}" STREQUAL "")
message(FATAL_ERROR "Provide the path to the Clang toolchain in the LINUX_MULTIARCH_ROOT environment variable.")
endif()
# Clang target triple
set(TARGET_TRIPLE x86_64-unknown-linux-gnu)
# Clean path separators
file(TO_CMAKE_PATH $ENV{LINUX_MULTIARCH_ROOT}/${TARGET_TRIPLE} TOOLCHAIN_ROOT)
list(APPEND CMAKE_PROGRAM_PATH ${TOOLCHAIN_ROOT}/bin)
set(CMAKE_CROSSCOMPILING TRUE)
set(CMAKE_SYSTEM_NAME Linux)
set(CMAKE_SYSTEM_PROCESSOR x86_64)
# specify the cross compiler
set(CMAKE_C_COMPILER_TARGET ${TARGET_TRIPLE})
set(CMAKE_C_COMPILER clang)
set(CMAKE_CXX_COMPILER_TARGET ${TARGET_TRIPLE})
set(CMAKE_CXX_COMPILER clang++)
set(CMAKE_ASM_COMPILER_TARGET ${TARGET_TRIPLE})
set(CMAKE_ASM_COMPILER clang)
# C/C++ toolchain
set(CMAKE_C_COMPILER_EXTERNAL_TOOLCHAIN ${TOOLCHAIN_ROOT})
set(CMAKE_CXX_COMPILER_EXTERNAL_TOOLCHAIN ${TOOLCHAIN_ROOT})
# This must be set or compiler checks fail when linking
set(CMAKE_TRY_COMPILE_TARGET_TYPE STATIC_LIBRARY)
set(CMAKE_FIND_ROOT_PATH ${TOOLCHAIN_ROOT})
set(CMAKE_SYSROOT ${TOOLCHAIN_ROOT})
After starting from a clean environment it seems the target is now detected correctly, but instead I get a configuring error saying Could NOT find Threads (missing: Threads_FOUND). I'm assuming this is because the Threads package is not being found in the toolchain, although I can verify that the libraries are present in Windows explorer.
Another edit: I'm beginning to wonder whether the package cannot be found because CMake is attempting to look for a package description file rather than the libraries themselves? Is there a way I can fix that for this particular case of cross-compilation?

Compiling freetype library on I386 (simulator) for iPhone

I'm trying to compile FreeType2 2.5.3 as a static library on I386 arch,
then use it on an iPhone OpenGL application.
I'm building the .a it with this script:
./configure '--without-bzip2' '--without-zlib' 'CFLAGS=-arch i386'
make clean
make
cp objs/.libs/libfreetype.a /Users/vlzvl/Desktop/libfreetype-i386.a
I'm not entirely sure but iPhone Simulator can run I386 arch library? should i build it on other arch instead (running Mountain Lion 10.8.2) on Virtualbox with iOS 6.0 SDK and XCode 4.5 ?
Anyway, i'm then loading the library on XCode through Build Phase -> Link Binary With Libraries and use the Other option to locate it.
My app crashes on first freetype function, the FT_Init_FreeType with a Signal SIGABRT error.
I finally succeeded compiling my static freetype library for i386 arch using the following script (with a help of some SO answers and some folder changes eg. /iPhonesimulator instead of /iPhoneOS)
./configure '--without-bzip2' '--without-zlib' '--without-png' '--host=arm-apple-darwin' '--enable-static=yes' '--enable-shared=no' 'CC=/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/gcc' 'CFLAGS=-arch i386 -pipe -std=c99 -Wno-trigraphs -fpascal-strings -O2 -Wreturn-type -Wunused-variable -fmessage-length=0 -fvisibility=hidden -miphoneos-version-min=6.0 -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator6.0.sdk/'
make clean
make
cp objs/.libs/libfreetype.a /Users/vlzvl/Desktop/libfreetype-i386.a

Linking error when compiling Crypto++ for ARMHF

I'm trying to compile the crypto++ library to run for the armhf architecture. I'm following the method provided in this answer. I tweaked the setenv-embed.sh to match my system's configuration. The output of running . ./setenv-embed.sh is
CPP: /usr/bin/arm-linux-gnueabihf-cpp
CXX: /usr/bin/arm-linux-gnueabihf-g++
AR: /usr/bin/arm-linux-gnueabihf-ar
LD: /usr/bin/arm-linux-gnueabihf-ld
RANLIB: /usr/bin/arm-linux-gnueabihf-gcc-ranlib-4.8
ARM_EMBEDDED_TOOLCHAIN: /usr/bin
ARM_EMBEDDED_CXX_HEADERS: /usr/arm-linux-gnueabihf/include/c++/4.8.2
ARM_EMBEDDED_FLAGS: -march=armv7-a mfloat-abi=hard -mfpu=neon -I/usr/arm-linux-gnueabihf/include/c++/4.8.2 -I/usr/arm-linux-gnueabihf/include/c++/4.8.2/arm-linux-gnueabihf
ARM_EMBEDDED_SYSROOT: /usr/arm-linux-gnueabihf
which indicates that the correct compilers have been found. However, when I build the library using make I run into the following error
/usr/lib/gcc-cross/arm-linux-gnueabihf/4.8/../../../../arm-linux-gnueabihf/bin/‌​ld: cannot find /usr/arm-linux-gnueabihf/lib/libc.so.6 inside /usr/arm-linux-gnueabihf
/usr/lib/gcc-cross/arm-linux-gnueabihf/4.8/../../../../arm-linux-gnueabihf/bin/‌​ld: cannot find /usr/arm-linux-gnueabihf/lib/libc_nonshared.a inside /usr/arm-linux-gnueabihf
/usr/lib/gcc-cross/arm-linux-gnueabihf/4.8/../../../../arm-linux-gnueabihf/bin/‌​ld: cannot find /usr/arm-linux-gnueabihf/lib/ld-linux-armhf.so.3 inside /usr/arm-linux-gnueabihf
But when I open the location /usr/arm-linux-gnueabihf/lib I can find all the three error files mentioned above ie libc.so.6, libc_nonshared.a and ld-linux-armhf.so.3
I'm trying to compile the library for Beaglebone, if that helps.
Update 1:
The results of running make -f GNUmakefile-cross system after doing a fresh git pull
hassan#hassan-Inspiron-7537:~/cryptopp-armhf$ make -f GNUmakefile-cross system
CXX: /usr/bin/arm-linux-gnueabihf-g++
CXXFLAGS: -DNDEBUG -g2 -Os -Wall -Wextra -DCRYPTOPP_DISABLE_ASM -march=armv7-a -mfloat-abi=hard -mfpu=neon -mthumb -I/usr/arm-linux-gnueabihf/include/c++/4.8.2 -I/usr/arm-linux-gnueabihf/include/c++/4.8.2/arm-linux-gnueabihf --sysroot=/usr/arm-linux-gnueabihf -Wno-type-limits -Wno-unknown-pragmas
LDLIBS:
GCC_COMPILER: 1
CLANG_COMPILER: 0
INTEL_COMPILER: 0
UNALIGNED_ACCESS:
UNAME: Linux hassan-Inspiron-7537 3.13.0-35-generic #62-Ubuntu SMP Fri Aug 15 01:58:42 UTC 2014 x86_64 x86_64 x86_64 GNU/Linux
MACHINE:
SYSTEM:
RELEASE:
make: Nothing to be done for `system'.
The problem is simple. It is in the --sysroot option. The value of this option is /usr/arm-linux-gnueabihf/ and it is used by the linker and the resulting library folder becomes
/usr/arm-linux-gnueabihf/usr/arm-linux-gnueabihf/lib/
I removed the --sysroot option from line 68 in the file GNUmakefile-cross and everything compiled and linked OK.
However, I couldn't run the example on my BeagleBone Black because of mismatch of some shared libraries versions. But this wasn't a real problem for me, because in my application I link crypto++ statically, not dynamically.
Based on Crosswalking's research I think I can explain what is going on. I don't think I agree with the assessment "The problem is simple. It is in the --sysroot option" since the Crypto++ environment script and makefile are doing things as expected.
I think Crosswalking's answer could be how to work around it; but see open questions below. The following is from Crypto++ Issue 134: setenv-embedded.sh and GNUmakefile-cross:
I think this another distro problem, similar to g++-arm-linux-gnueabi
cannot compile a C++ program with
--sysroot.
It might be a Ubuntu problem or a Debian problem if it is coming from
upstream.
When cross-compiling, we expect the following (using ARMHF):
SYSROOT is /usr/arm-linux-gnueabihf
INCLUDEDIR is /usr/arm-linux-gnueabihf/include
LIBDIR is /usr/arm-linux-gnueabihf/lib
BINDIR is /usr/arm-linux-gnueabihf/bin
How LIBDIR morphed into into
/usr/arm-linux-gnueabihf/usr/arm-linux-gnueabihf/lib/ (i.e.,
$SYSROOT/$SYSROOT/lib) is a mystery. But in all fairness, building
GCC is not a trivial task.
You should probably file a bug report with Debian or Ubuntu (or
whomever provides the toolchain).
The open question for me is, since $SYSROOT/lib is messed up, then is $SYSROOT/include messed up, too?
If the include directory is also messed up, then the cross compile is using the host's include files, and not the target include files. That will create hard to diagnose problems later.
If both $SYSROOT/include and $SYSROOT/lib are messed up, then its not enough to simply remove --sysroot. Effectively, this is what has to be done:
# Exported by setenv-embedded
export=ARM_EMBEDDED_SYSROOT=/usr/arm-linux-gnueabihf
# Used by the makefile
-I $ARM_EMBEDDED_SYSROOT/$ARM_EMBEDDED_SYSROOT/include
-L $ARM_EMBEDDED_SYSROOT/$ARM_EMBEDDED_SYSROOT/lib
Which means we should be able to do the following:
# Exported by setenv-embedded
export=ARM_EMBEDDED_SYSROOT=/usr/arm-linux-gnueabihf/usr/arm-linux-gnueabihf
# Used by the makefile
--sysroot="$ARM_EMBEDDED_SYSROOT"
Finally, this looks a lot like Ubuntu's Bug 1375071: g++-arm-linux-gnueabi cannot compile a C++ program with --sysroot. The bug report specifically calls out ... the built-in paths use an extra "/usr/arm-linux-gnueabi".
We need the paths:
A) /usr/arm-linux-gnueabi/include/c++/4.7.3 B)
/usr/arm-linux-gnueabi/include/c++/4.7.3/arm-linux-gnueabi
But the built-in paths tries to use:
C) /usr/arm-linux-gnueabi/usr/arm-linux-gnueabi/include/c++/4.7.3
D)
/usr/arm-linux-gnueabi/usr/arm-linux-gnueabi/include/c++/4.7.3/arm-linux-gnueabi/sf
E)
/usr/arm-linux-gnueabi/usr/arm-linux-gnueabi/include/c++/4.7.3/backward
Notice the built-in paths use an extra "/usr/arm-linux-gnueabi"

Did upgrading to Ubuntu 14.04 break the c++ linker?

I have a Linux-based application, running under Ubuntu 12.04 LTS, that compiled, linked, and ran with no problem.
I recently upgraded my Ubuntu to 14.04 LTS and encountered problems compiling and linking the app.
The compilation problems were solved by manually modifying my local copy of Boost 1.48 in two files (include/boost/config/stdlib/libstdcpp3.hpp and include/boost/thread/xtime.hpp). At this point the app compiled successfully.
The problem I have is that the linkage fails with the error message:
c++: error: unrecognized command line option ‘-Wl’
I use CMake to enable compiling the app on multiple platforms. Here is the linker script generated by CMake. Note that the "-Wl" options are now inexplicably unrecognized by /usr/bin/c++:
/usr/bin/c++
-fno-stack-protector
-g
-Wl
CMakeFiles/Project.dir/main.cpp.o
CMakeFiles/Project.dir/TestCallback.cpp.o
CMakeFiles/Project.dir/utils.cpp.o
CMakeFiles/Project.dir/Request1.cpp.o
CMakeFiles/Project.dir/Response1.cpp.o
CMakeFiles/Project.dir/TextChatRequest.cpp.o
CMakeFiles/Project.dir/TextChatResponse.cpp.o
-o
/home/user/private/Project/Project_Release_1_2_Codename/Build/bin/Debug/Project
-L/home/user/Libraries/Ubuntu32_12.04/boost_1.48/lib
-L/home/user/Libraries/Ubuntu32_12.04/SqlLite_3.6/lib
-L/home/user/Libraries/Ubuntu32_12.04/taglib_1.7/lib
-L/home/user/Libraries/Ubuntu32_12.04/JSON_1.0/lib/Debug
-L/home/user/private/Project/Project_Release_1_2_Codename/Build/../lib/libUbuntu32/Debug
-rdynamic
/home/user/private/Project/Project_Release_1_2_Codename/lib/libUbuntu32/Debug/libAPI.a
/home/user/private/Project/Project_Release_1_2_Codename/lib/libUbuntu32/Debug/libInternals.a
-lboost_thread
-lboost_system
-lboost_filesystem
-lboost_program_options
-ltaglib
-lJSON
-lpthread
-Wl,-Bstatic
-lsqlite3
-Wl,-Bdynamic
-ldl
-Wl,-rpath,/home/user/Libraries/Ubuntu32_12.04/boost_1.48/lib:/home/user/Libraries/Ubuntu32_12.04/SqlLite_3.6/lib:/home/user/Libraries/Ubuntu32_12.04/taglib_1.7/lib:/home/user/Libraries/Ubuntu32_12.04/JSON_1.0/lib/Debug:/home/user/private/Project/Project_Release_1_2_Codename/Build/../lib/libUbuntu32/Debug
Here is version information for the software I'm using:
Ubuntu:
14.04.1 LTS (trusty)
c++ compiler/linker:
(Ubuntu 4.8.2-19ubuntu1) 4.8.2
CMake:
Version 2.8.12.2
Why doesn't the linker recognize "-Wl" commands? Did my upgrade to 14.04 LTS modify the linker software libraries? How can I get my app back up and linking?
On line 4 of the command you have -Wl without any actual linker options.
https://gcc.gnu.org/gcc-4.7/porting_to.html
Right at the top of this page is the following:
Earlier releases did not warn or error about completely invalid
options on gcc/g++/gfortran etc. command lines, if nothing was
compiled, but only linking was performed. This is no longer the case.
For example,
gcc -Wl -o foo foo.o -mflat_namespace
Now produces the following error
error: unrecognized command line option ‘-Wl’
error: unrecognized command line option ‘-mflat_namespace’
Invalid options need to be removed from the command line or replaced by something that is valid.
12.04 LTS packaged GCC 4.6, you've now jumped to 4.8 and -Wl on its own is no longer a valid option (or rather it never was, GCC is just more pedantic now).
As mentioned by others previously, it indeed turned out that my CMake script was injecting a lone, solitary, seemingly unnecessary "-Wl" via the CMAKE_EXE_LINKER_FLAGS setting:
if(LINUX)
set(THIRDPARTY_LIBS boost_thread boost_system boost_filesystem boost_program_options taglib JSON)
set(OS_LIBS pthread sqlite3.a dl)
set(CMAKE_EXE_LINKER_FLAGS "-Wl")
set(PREPROCESSOR_DEFINITIONS ${PREPROCESSOR_DEFINITIONS};/DTAGLIB_STATIC)
endif(LINUX)
When I removed this setting, the build succeeded. This oversight has been around a while, with the earlier version of gcc not minding. The latest gcc, however, is more pedantic and flagged it as an error.