Updating cross compilation toolchain from 2.7 to 2.8

I’m updating our cross compilation of Ceres 1.11.0 from 2.7 to 2.8. Here’s the process we are using:

Set Path

PATH=/usr/local/oecore-x86_64/sysroots/x86_64-angstromsdk-linux/usr/bin:/usr/local/oecore-x86_64/sysroots/x86_64-angstromsdk-linux/usr/bin/arm-angstrom-linux-gnueabi:$PATH

Download Ceres####

mkdir ceres
cd ceres
wget http://ceres-solver.org/ceres-solver-1.11.0.tar.gz
tar xf ceres-solver-1.11.0.tar.gz

Disable some Ceres options

  • Open the file ceres-solver-1.11.0/CMakeLists.txt

    vi ceres-solver-1.11.0/CMakeLists.txt

  • Change the following options to OFF

    • option(GFLAGS "Enable Google Flags."OFF)
    • option(SUITESPARSE “Enable SuiteSparse.” OFF)
    • option(CXSPARSE “Enable CXSparse.” OFF)
    • option(LAPACK “Enable use of LAPACK.” OFF)
    • option(OPENMP “Enable threaded solving in Ceres (requires OpenMP)” OFF)

I updated our toolchain.cmake file to reflect the new SDK locations in 2.8.
toolchain.cmake

Now, build using cmake and the new toolchain file:

mkdir build
cd build
cmake -DCMAKE_TOOLCHAIN_FILE=../toolchain.cmake -DCMAKE_INSTALL_PREFIX=/usr/local/oecore-x86_64/sysroots/armv7at2hf-neon-angstrom-linux-gnueabi/usr ../ceres-solver-1.11.0

From the output, it looks like cmake is finding the various components correctly:

-- Found Eigen version 3.2.8: /usr/local/oecore-x86_64/sysroots/armv7at2hf-neon-angstrom-linux-gnueabi/usr/include/eigen3

   ===============================================================
   Disabling the use of Eigen as a sparse linear algebra library.
   This does not affect the covariance estimation algorithm
   which can still use the EIGEN_SPARSE_QR algorithm.
   ===============================================================

-- Building without LAPACK.
-- Building without SuiteSparse.
-- Building without CXSparse.
   ===============================================================
   Compiling without any sparse library: SuiteSparse, CXSparse
   & Eigen (Sparse) are all disabled or unavailable.  No sparse
   linear solvers (SPARSE_NORMAL_CHOLESKY & SPARSE_SCHUR)
   will be available when Ceres is used.
   ===============================================================
-- Google Flags disabled; no tests or tools will be built!
-- Found Google Log header in: /usr/local/oecore-x86_64/sysroots/armv7at2hf-neon-angstrom-linux-gnueabi/usr/include
-- Building without OpenMP (disabling multithreading).
-- Looking for C++ include unordered_map
-- Looking for C++ include unordered_map - found
-- Performing Test HAVE_UNORDERED_MAP_IN_STD_NAMESPACE
-- Performing Test HAVE_UNORDERED_MAP_IN_STD_NAMESPACE - Success
-- Found unordered_map/set in std namespace.
-- Looking for C++ include memory
-- Looking for C++ include memory - found
-- Performing Test HAVE_SHARED_PTR_IN_STD_NAMESPACE
-- Performing Test HAVE_SHARED_PTR_IN_STD_NAMESPACE - Success
-- Found shared_ptr in std namespace using <memory> header.
-- Building Ceres as a static library.
-- Enabling CERES_NO_LAPACK in Ceres config.h
-- Enabling CERES_NO_SUITESPARSE in Ceres config.h
-- Enabling CERES_NO_CXSPARSE in Ceres config.h
-- Enabling CERES_NO_THREADS in Ceres config.h
-- Enabling CERES_STD_UNORDERED_MAP in Ceres config.h
-- Build the examples.
-- Configuring done
-- Generating done
CMake Warning:
  Manually-specified variables were not used by the project:
CMAKE_TOOLCHAIN_FILE
-- Build files have been written to: /home/philmass/ceres/build

####Now, compile

make -j 4 > buildoutput.txt

Ceres compilation fails about 75% of the way through, and I get a number of errors that look like:

In file included from /usr/local/oecore-x86_64/sysroots/armv7at2hf-neon-angstrom-linux-gnueabi/usr/include/c++/7.3.0/vector:69:0,
                 from /home/philmass/ceres/ceres-solver-1.11.0/internal/ceres/compressed_row_sparse_matrix.h:34,
                 from /home/philmass/ceres/ceres-solver-1.11.0/internal/ceres/compressed_row_sparse_matrix.cc:31:
/usr/local/oecore-x86_64/sysroots/armv7at2hf-neon-angstrom-linux-gnueabi/usr/include/c++/7.3.0/bits/vector.tcc: In member function ‘void std::vector<_Tp, _Alloc>::_M_fill_insert(std::vector<_Tp, _Alloc>::iterator, std::vector<_Tp, _Alloc>::size_type, const value_type&) [with _Tp = double; _Alloc = std::allocator]’:
/usr/local/oecore-x86_64/sysroots/armv7at2hf-neon-angstrom-linux-gnueabi/usr/include/c++/7.3.0/bits/vector.tcc:458:5: note: parameter passing for argument of type ‘std::vector::iterator {aka __gnu_cxx::__normal_iterator >}’ changed in GCC 7.1
     vector<_Tp, _Alloc>::
     ^~~~~~~~~~~~~~~~~~~

The buildoutput.txt file is attached. link text

2 questions:

  1. Is there some additional setting I need to add for the 2.8 build vs the 2.7 build to make Ceres compilation work?

  2. Is there a better way to cross compile Ceres with the new SDK setup in 2.8, as opposed to the toolchain.cmake file? It’s moderately cumbersome to re-edit all of the SDK paths in that file and try to get them right.

Thanks,

hi @emack

Are you just try to compile the ceres-solver library or an application which is using ceres-solver. If you just need the library then you can include this to your local.conf and the library will be included in the image. Thus if you create a SDK for this image, the library will be included also in the SDK. This SDK can then be used for Cross Compilation.

Best regards, Jaski

Hi Jaski,

OK: I started fresh, and downloaded the current 2.8 oe-core build.

I added this to the end of ~/oe-core/build/conf/local.conf for OpenCV and ceres-solver:
IMAGE_INSTALL_append = " opencv ceres-solver"

I added the following to the end of the opencv recipe at ~/oe-core/layers/meta-openembedded/meta-oe/recipes-support/opencv/opencv_3.3.bb to tell the assembler to use thumb instructions:
CXXFLAGS += " -Wa,-mimplicit-it=thumb"

I ran bitbake, and this worked. I then populated the SDK with the default /usr/local/oecore-x86_64 location.

When I compile my application, however, I get an error that the compiler can’t find ceres/ceres.h.

I looked at the SDK sysroots in /usr/local/oecore-x86_64/sysroots, and recursively searched for ceres*, but didn’t find anything.

When I search in oe-core I can see it at:
./tmp-glibc/work/armv7at2hf-vfp-angstrom-linux-gnueabi/ceres-solver/1.13-r0/image/usr/include/ceres
./tmp-glibc/work/armv7at2hf-vfp-angstrom-linux-gnueabi/ceres-solver/1.13-r0/image/usr/include/ceres/ceres.h

Do I need to do something else to populate ceres into the SDK when built this way?

Hi Eliot

And you did, after your changes to the local conf, rebuild and then reinstall the SDK.

e.g. ‘I ran bitbake’ above means:

MACHINE=apalis-tk1 bitbake image-name -c populate_sdk
deploy/sdk/sdk-name.sh

Is ceres-solver part of the target manifest?

grep ceres deploy/sdk/*manifest

Max