3
votes

I have a problem with linking boost library into my cross-compiled c++ program. The code I write is cross-compiled with CodeSourcery under Ubuntu 12.04 for an arm-target (Pandaboard, also Ubuntu 12.04). Compiling simple test-programs without library works fine, even OpenCV with static libraries works fine.

But here is the problem when linking boost 1.52.0 libraries:

When crosscompiled WITH linking boost libraries (-lboost_thread -lboost_system) the program compiles without errors, but when executing it on target, nothing happens.

Program finishes without error as if it would have never been executed.

When crosscompiled with CodeSourcery WITHOUT linking boost libraries: everything works fine on target. Compiled locally with g++: everything fine as well.

For testing purposes i stripped down my code to the following few lines: (error even appears when no chrono-function is used. just linking makes the difference)

main.cpp

#include <iostream>
using namespace std;

#include<boost/chrono.hpp>

int main(int argc, char* argv[]) {

    cout << "!!!this test worked!!!" << endl;

    return 0;
}

Linker command is (out of eclipse):

arm-none-linux-gnueabi-g++ -L/home/xy/arm-none-linux-gnueabi/lib -o "testARM" ./src/main.o -lpthread -lboost_thread -lboost_system

The boost-libraries were cross-compiled with CodeSourcery arm-none-linux-gnueabi-g++ following this guide. I copied them all to the target into /usr/lib folder and added /usr/lib to PATH and to LD_LIBRARY_PATH.

I tried remote debugging with eclipse and its the same: starting program.. program terminated with 1. But nothing happend.

It doesnt even print an error or complain about something missing. So by now I cant think of anything more I could google that I havent tried...

Could you give me any hints what I could try to fix this?

Many thanks in advance!


Update:

When running my test program with strace, the log contains following info:


    $ vi strace-testARM.log
    22:23:56.511385 execve("./testARM", ["./testARM"], [/* 17 vars */]) = 0
    22:23:56.512789 brk(0)                  = 0xfae000
    22:23:56.512972 uname({sys="Linux", node="panda", ...}) = 0
    22:23:56.514010 access("/etc/ld.so.nohwcap", F_OK) = -1 ENOENT (No such file or directory)
    22:23:56.514315 mmap2(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb6f9b000
    22:23:56.514498 access("/etc/ld.so.preload", R_OK) = -1 ENOENT (No such file or directory)
    22:23:56.514742 open("/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3
    22:23:56.514986 fstat64(3, {st_mode=S_IFREG|0644, st_size=52288, ...}) = 0
    22:23:56.515353 mmap2(NULL, 52288, PROT_READ, MAP_PRIVATE, 3, 0) = 0xb6f72000
    22:23:56.515536 close(3)                = 0
    22:23:56.515688 access("/etc/ld.so.nohwcap", F_OK) = -1 ENOENT (No such file or directory)
    22:23:56.515902 open("/lib/arm-linux-gnueabihf/libpthread.so.0", O_RDONLY|O_CLOEXEC) = 3
    22:23:56.516207 read(3, "\177ELF\1\1\1\0\0\0\0\0\0\0\0\0\3\0(\0\1\0\0\0\5P\0\0004\0\0\0"..., 512) = 512
    22:23:56.516451 lseek(3, 66332, SEEK_SET) = 66332
    22:23:56.516573 read(3, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 1400) = 1400
    22:23:56.516787 lseek(3, 65924, SEEK_SET) = 65924
    22:23:56.516909 read(3, "A6\0\0\0aeabi\0\1,\0\0\0\0057-A\0\6\n\7A\10\1\t\2\n\4\22"..., 55) = 55
    22:23:56.517153 fstat64(3, {st_mode=S_IFREG|0755, st_size=100802, ...}) = 0
    22:23:56.517519 mmap2(NULL, 107024, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0xb6f57000
    22:23:56.517642 mprotect(0xb6f67000, 28672, PROT_NONE) = 0
    22:23:56.517794 mmap2(0xb6f6e000, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0xf) = 0xb6f6e000
    22:23:56.517977 mmap2(0xb6f70000, 4624, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0xb6f70000
    22:23:56.518160 close(3)                = 0
    22:23:56.518313 access("/etc/ld.so.nohwcap", F_OK) = -1 ENOENT (No such file or directory)
    22:23:56.518557 open("/lib/arm-linux-gnueabihf/tls/v7l/neon/vfp/libboost_thread.so.1.52.0", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
    22:23:56.518832 stat64("/lib/arm-linux-gnueabihf/tls/v7l/neon/vfp", 0xbea34ea8) = -1 ENOENT (No such file or directory)
    22:23:56.519076 open("/lib/arm-linux-gnueabihf/tls/v7l/neon/libboost_thread.so.1.52.0", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file 
... [ lots of other directories with file not found ] ...
    22:23:56.545382 stat64("/usr/lib/neon/vfp", 0xbea34ea8) = -1 ENOENT (No such file or directory)
    22:23:56.545565 open("/usr/lib/neon/libboost_thread.so.1.52.0", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
    22:23:56.545748 stat64("/usr/lib/neon", 0xbea34ea8) = -1 ENOENT (No such file or directory)
    22:23:56.545932 open("/usr/lib/vfp/libboost_thread.so.1.52.0", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
    22:23:56.546115 stat64("/usr/lib/vfp", 0xbea34ea8) = -1 ENOENT (No such file or directory)
    22:23:56.546298 open("/usr/lib/libboost_thread.so.1.52.0", O_RDONLY|O_CLOEXEC) = 3
    22:23:56.546481 read(3, "\177ELF\1\1\1\0\0\0\0\0\0\0\0\0\3\0(\0\1\0\0\0\324\331\0\0004\0\0\0"..., 512) = 512
    22:23:56.546755 lseek(3, 121020, SEEK_SET) = 121020
    22:23:56.546878 read(3, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 1200) = 1200
    22:23:56.547091 lseek(3, 119052, SEEK_SET) = 119052
    22:23:56.547213 read(3, "A(\0\0\0aeabi\0\1\36\0\0\0\0055TE\0\6\4\10\1\t\1\22\4\24\1\25"..., 41) = 41
    22:23:56.547396 exit_group(1)           = ?


Update 2:

I am compiling my program on an Ubuntu Host, transfer the file onto the Pandaboard and issue the following commands as suggested by @ShaunMarko:

`ldd testARM` =>  `not a dynamic executable`

`file testARM` => `testARM: ELF 32-bit LSB executable, ARM, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.16, not stripped`

`file libboost_thread.so.1.52.0` => `libboost_thread.so.1.52.0: ELF 32-bit LSB shared object, ARM, version 1 (SYSV), dynamically linked, not stripped`

Adding -v -H to the compiling g++ expression I receive:

... /xy/CodeSourcery/bin/../lib/gcc/arm-none-linux-gnueabi/4.7.2/../../../../arm-none-linux-gnueabi/include/boost/utility/result_of.hpp

COLLECT_GCC_OPTIONS='-O0' '-g3' '-Wall' '-c' '-fmessage-length=0' '-v' '-H' '-MMD' '-MP' '-MF' 'main.d' '-MT' 'main.d' '-o' 'main.o' '-shared-libgcc' '-march=armv5te' '-mtls-dialect=gnu' '-funwind-tables' '-D' '__CS_SOURCERYGXX_MAJ__=2012' '-D' '__CS_SOURCERYGXX_MIN__=9' '-D' '__CS_SOURCERYGXX_REV__=64'
 /xy/CodeSourcery/bin/../lib/gcc/arm-none-linux-gnueabi/4.7.2/../../../../arm-none-linux-gnueabi/bin/as -v -march=armv5te -meabi=5 -o main.o /tmp/cceTwLmn.s
GNU assembler version 2.23.51 (arm-none-linux-gnueabi) using BFD version (Sourcery CodeBench Lite 2012.09-64) 2.23.51.20120829
COMPILER_PATH=/xy/CodeSourcery/bin/../libexec/gcc/arm-none-linux-gnueabi/4.7.2/:/xy/CodeSourcery/bin/../libexec/gcc/:/xy/CodeSourcery/bin/../lib/gcc/arm-none-linux-gnueabi/4.7.2/../../../../arm-none-linux-gnueabi/bin/
LIBRARY_PATH=/xy/CodeSourcery/bin/../lib/gcc/arm-none-linux-gnueabi/4.7.2/:/xy/CodeSourcery/bin/../lib/gcc/:/xy/CodeSourcery/bin/../lib/gcc/arm-none-linux-gnueabi/4.7.2/../../../../arm-none-linux-gnueabi/lib/:/xy/CodeSourcery/bin/../arm-none-linux-gnueabi/libc/lib/:/xy/CodeSourcery/bin/../arm-none-linux-gnueabi/libc/usr/lib/
COLLECT_GCC_OPTIONS='-O0' '-g3' '-Wall' '-c' '-fmessage-length=0' '-v' '-H' '-MMD' '-MP' '-MF' 'main.d' '-MT' 'main.d' '-o' 'main.o' '-shared-libgcc' '-march=armv5te' '-mtls-dialect=gnu' '-funwind-tables' '-D' '__CS_SOURCERYGXX_MAJ__=2012' '-D' '__CS_SOURCERYGXX_MIN__=9' '-D' '__CS_SOURCERYGXX_REV__=64'

**** Build Finished ****

(This is the last part, above that there are listed tons of included headers. The xy-Path is where CodeSourcery is installed in my home directory)

1
Can you run your program on the target with strace (wiki.ubuntu.com/Strace)?Shaun Marko
Thanks for your answer. I posted the strace-log above. Can you derive any useful information from it?Felix
You can issue "ldd testARM" on the target to ensure all the references are resolved.Slava Zhuyko
When typing "ldd testARM" it says "not a dynamic executable"Felix
Just to be clear, you are running ldd testARM on the ARM target, correct? Also run file on your test program and the libboost_thread library in question.Shaun Marko

1 Answers

3
votes

General rule for building ARM applications (in fact it must be true for any platform)

You must compile your entire program with the same ABI, and link with a compatible set of libraries.

In your case last item looks like /usr/lib/libboost_thread.so.1.52.0 and since it is also related to your usage, be sure that libboost_thread matches the one on the host that you are cross compiling.

22:23:56.546298 open("/usr/lib/libboost_thread.so.1.52.0", O_RDONLY|O_CLOEXEC) = 3
22:23:56.546481 read(3, "\177ELF\1\1\1\0\0\0\0\0\0\0\0\0\3\0(\0\1\0\0\0\324\331\0\0004\0\0\0"..., 512) = 512
22:23:56.546755 lseek(3, 121020, SEEK_SET) = 121020
22:23:56.546878 read(3, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 1200) = 1200
22:23:56.547091 lseek(3, 119052, SEEK_SET) = 119052
22:23:56.547213 read(3, "A(\0\0\0aeabi\0\1\36\0\0\0\0055TE\0\6\4\10\1\t\1\22\4\24\1\25"..., 41) = 41
22:23:56.547396 exit_group(1)           = ?

With ARM systems you can have many variants of a library like different ABIs or VFP/NEON support and getting an off the shelf toolchain might not match what you target by default just because it is for ARM.

update

If you check a previous log

22:23:56.515902 open("/lib/arm-linux-gnueabihf/libpthread.so.0", O_RDONLY|O_CLOEXEC) = 3
22:23:56.516207 read(3, "\177ELF\1\1\1\0\0\0\0\0\0\0\0\0\3\0(\0\1\0\0\0\5P\0\0004\0\0\0"..., 512) = 512
22:23:56.516451 lseek(3, 66332, SEEK_SET) = 66332
22:23:56.516573 read(3, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 1400) = 1400
22:23:56.516787 lseek(3, 65924, SEEK_SET) = 65924
22:23:56.516909 read(3, "A6\0\0\0aeabi\0\1,\0\0\0\0057-A\0\6\n\7A\10\1\t\2\n\4\22"..., 55) = 55

You see two things, first your system is hf from the path. In the read data we also see 7-A, which probably means ARMv7-A compared to 5TE which probably means ARMv5TE from your libboost_thread library. You should use readelf from your toolchain to get information about elf files instead of file utility.

I would try to compile boost with -march=armv7-a -mfpu=vfpv3-d16 -mfloat-abi=hard and put the resulting binary under `/usr/lib/vfp.

I think reading vfp stuff from Debian site can help you greatly and you should make small exercises yourself, instead of dealing with compilation process of boost to understand the situation.