Linking error when compiling Crypto++ for ARMHF

2019-07-09 20:48发布

问题:

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'.

回答1:

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.



回答2:

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"