Error executing libqi cross compiled for 32-bit ARM

0

I'm attempting to cross-compile libqi to run on an ARMv7 chip. Libqi has some dependencies on boost and openssl, so I cross compile those libraries before I cross compile libqi. The host machine where I am compiling this code is a 64 bit Redhat machine.

I am able to cross compile with no errors, but when I run an executable that uses libqi on the target ARM I get an error. As a side note I am able execute libqi libraries compiled for the host machine on the host machine just fine.

Here is the error I see when running a cross-compiled executable on the ARM:

    $ ./video_stream --qi-url=196.168.3.2
[E] 1496944759.281001 8415 qimessaging.messagesocket: 0x96b2d8: Ill-formed capabilities message: Type b not deserializable
[W] 1496944759.282350 8414 qitype.genericvalue: Conversion from X(int) to X(long long) failed 
[W] 1496944759.286159 8413 qi.FutureSync: Error in future on destruction: 'disconnected' - continuing stack unwinding...
terminate called after throwing an instance of 'qi::FutureUserException'
  what():  disconnected
Aborted

Here is the code for video_stream:

#include <iostream>
#include <qi/applicationsession.hpp>
#include <qi/vision_definitions.h>
#include <qi/anyvalue.hpp>
#include <qi/jsoncodec.hpp>

using namespace std;

int main(int argc, char** argv)
{
    qi::ApplicationSession app(argc, argv);
    app.startSession();
    qi::SessionPtr session = app.session();
    qi::AnyObject video_service = session->service("ALVideoDevice");

    /* Subscribe a client image requiring 320*240 and BGR colorspace.*/
    auto subscriberId = video_service.call<std::string>("subscribe", "test",      kQVGA, kBGRColorSpace, 30);

    auto results = video_service.call<qi::AnyValue>("getImageRemote", subscriberId);
    std::cout << "image " << qi::encodeJSON(results) << std::endl;
    auto imageAsValue = results[6];
    auto buffer = imageAsValue.content().asRaw();
    std::cout << "buffer size: " << buffer.second << std::endl;

    video_service.call<void>("releaseImage", subscriberId);
    video_service.call<void>("unsubscribe", subscriberId);
}

Here are some properties of the executable:

$ file video_stream 
video_stream: ELF 32-bit LSB  executable, ARM, EABI5 version 1 (GNU/Linux),     dynamically linked (uses shared libs), for GNU/Linux 2.6.32, not stripped

$ objdump -f video_stream 
video_stream:     file format elf32-littlearm
architecture: arm, flags 0x00000112:
EXEC_P, HAS_SYMS, D_PAGED
start address 0x001c2bb0

$ objdump -j .interp -s ./video_stream
./video_stream:     file format elf32-littlearm

Contents of section .interp:
8134 2f6c6962 2f6c642d 6c696e75 782e736f  /lib/ld-linux.so
8144 2e3300                               .3.    

Here are the first few lines of the build processs which let me know that cmake has picked up the cross-toolchain:

-- The C compiler identification is GNU 4.9.2
-- The CXX compiler identification is GNU 4.9.2
-- Check for working C compiler: /<path>/arm-xilinx-linux-gnueabi-gcc
-- Check for working C compiler: /<path>/arm-xilinx-linux-gnueabi-gcc -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working CXX compiler: /<path>/arm-xilinx-linux-gnueabi-g++
-- Check for working CXX compiler: /<path>/arm-xilinx-linux-gnueabi-g++ -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Using qibuild 3.11.14

Another sidenote. I am able to execute a cross compiled simple project on the ARM. Here's the code for that:

#include <iostream>
int main()
{
  std::cout << "Hello, world" << std::endl;
  return 0;
}

Output:

$ ./temp
Hello, world

Here are the steps I take to cross compile: OpenSSL:

cd <openssl source directory>
./Configure linux-armv4 --cross-compile-prefix=arm-xilinx-linux-gnueabi- --prefix=/<path>/libqi-team-platform-dev --openssldir=/<path>/libqi-team-platform-dev/openssl no-shared
make
make install

Boost:

echo "using gcc : arm : arm-xilinx-linux-gnueabi-gcc ;" > ~/user-config.jam
./bootstrap.sh --prefix=/<path>/libqi-team-platform-dev
./b2 --prefix=/<path>/libqi-team-platform-dev link=static install

LibQI: To compile libqi, I edit libqi's CMakeLists.txt so that the Boost and OpenSSL libraries are are included. I also add a compiler flag to enable GDB debugging. Finally I tell cmake to compile the projects libraries as STATIC. Below is the CMAKE code that does what I just described.

CMakeLists.txt


set(Boost_NO_SYSTEM_PATHS TRUE) 
if (Boost_NO_SYSTEM_PATHS)
  set(BOOST_ROOT "${CMAKE_CURRENT_SOURCE_DIR}/include")
  set(BOOST_INCLUDE_DIRS "${CMAKE_CURRENT_SOURCE_DIR}/include/boost")
  set(BOOST_LIBRARY_DIRS "${CMAKE_CURRENT_SOURCE_DIR}/lib")
endif (Boost_NO_SYSTEM_PATHS)
find_package(Boost REQUIRED atomic date_time thread chrono filesystem locale regex program_options)
include_directories(${BOOST_INCLUDE_DIRS})

set(OPENSSL_NO_SYSTEM_PATHS TRUE) 
if (OPENSSL_NO_SYSTEM_PATHS)
  set(OPENSSL_ROOT "${CMAKE_CURRENT_SOURCE_DIR}")
  set(OPENSSL_INCLUDE_DIRS "${CMAKE_CURRENT_SOURCE_DIR}/include")
  set(OPENSSL_LIBRARY_DIRS "${CMAKE_CURRENT_SOURCE_DIR}/lib")
endif (OPENSSL_NO_SYSTEM_PATHS)
include_directories(${OPENSSL_INCLUDE_DIRS})
link_directories(${OPENSSL_LIBRARY_DIRS})


#### Set compilation flags {{{
if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang" OR "${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
  set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra")
  set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=gnu++11")
  set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g")
endif()


qi_create_lib(qi STATIC
                 ${QI_H}     ${QI_C}
                 ${QITYPE_H} ${QITYPE_C}
                 ${QIM_H}    ${QIM_C}
                 ${QIPERF_H} ${QIPERF_C}
              DEPENDS ASSUME_SYSTEM_INCLUDE BOOST BOOST_ATOMIC BOOST_DATE_TIME BOOST_THREAD BOOST_CHRONO BOOST_FILESYSTEM BOOST_LOCALE BOOST_REGEX BOOST_PROGRAM_OPTIONS 
              SUBMODULE ${_tp_qi})


target_link_libraries(qi ${Boost_LIBRARIES} ${OPENSSL_LIBRARIES}) 

Finally I compile libqi using the following commands

export PATH=/<cross compiler path>/bin:$PATH
export CROSS_COMPILE=arm-xilinx-linux-gnueabi-
mkdir BUILD_CROSS && cd BUILD_CROSS
cmake .. -DCMAKE_TOOLCHAIN_FILE=zynq7-linux.cmake -DQI_WITH_TESTS=OFF -DBUILD_VIDEOSTREAM=ON 
make -j8 
make -j8 install DESTDIR=./output

contents of zynq7-linux.cmake

set (CMAKE_SYSTEM_PROCESSOR "arm"                       CACHE STRING "")
set (CROSS_PREFIX           "arm-xilinx-linux-gnueabi-" CACHE STRING "")
include ("/<path>/cross-linux-gcc.cmake")

contents of cross-linux-gcc.cmake

set (CMAKE_SYSTEM_NAME  "Linux"              CACHE STRING "")
set (CMAKE_C_COMPILER   "${CROSS_PREFIX}gcc" CACHE STRING "")
set (CMAKE_CXX_COMPILER "${CROSS_PREFIX}g++" CACHE STRING "")
set (CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER CACHE STRING "")
set (CMAKE_FIND_ROOT_PATH_MODE_LIBRARY NEVER CACHE STRING "")
set (CMAKE_FIND_ROOT_PATH_MODE_INCLUDE NEVER CACHE STRING "")
boost
openssl
arm
cross-compiling
nao-robot
asked on Stack Overflow Sep 7, 2017 by user2852381 • edited Sep 9, 2017 by jww

0 Answers

Nobody has answered this question yet.


User contributions licensed under CC BY-SA 3.0