Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

CMake doesn't find Boost libraries while using android-cmake toolchain file

I am trying to make a CMake project for code that uses Boost libraries. I want to build it for Android, and I am using this project as a reference: https://code.google.com/p/android-cmake/.

I want to use Boost static libraries that I previously built for android and not make them part of the project to compile.

This is my CMakeLists.txt for the project part that uses Boost

#BOOST

set(BOOST_ROOT /home/neb/workspace/SDLActivityCMAKE/jni/boost)

set(Boost_INCLUDE_DIR /home/neb/workspace/SDLActivityCMAKE/jni/boost/include/boost-1_53)
set(BOOST_INCLUDEDIR /home/neb/workspace/SDLActivityCMAKE/jni/boost/include/boost-1_53)
set(Boost_LIBRARY_DIR /home/neb/workspace/SDLActivityCMAKE/jni/boost/lib)
set(BOOST_LIBRARYDIR /home/neb/workspace/SDLActivityCMAKE/jni/boost/lib)

set(Boost_USE_STATIC_LIBS ON)
set(USE_STATIC_BOOST ON)
set(Boost_USE_STATIC_RUNTIME ON)
set(BOOST_COMPILER gcc)

find_package(Boost COMPONENTS "thread-gcc-mt-1_53" "date_time-gcc-mt-1_53" REQUIRED)

include_directories(${Boost_INCLUDE_DIR})
link_directories(${Boost_LIBRARY_DIR})
#BOOSTEND

add_executable(main main.cpp)
target_link_libraries( main ${Boost_LIBRARIES} )

When I run regular cmake command (cmake .. from subdir of the jni folder in android project) there is no problem, cmake finds libraries. When I am making cmake to use android.toolchain.cmake provided by the project mentioned above I get this (I am using -DBoost_DEBUG option).

-- [ /usr/share/cmake-2.8/Modules/FindBoost.cmake:566 ] _boost_TEST_VERSIONS = 1.56.0;1.56;1.55.0;1.55;1.54.0;1.54;1.53.0;1.53;1.52.0;1.52;1.51.0;1.51;1.50.0;1.50;1.49.0;1.49;1.48.0;1.48;1.47.0;1.47;1.46.1;1.46.0;1.46;1.45.0;1.45;1.44.0;1.44;1.43.0;1.43;1.42.0;1.42;1.41.0;1.41;1.40.0;1.40;1.39.0;1.39;1.38.0;1.38;1.37.0;1.37;1.36.1;1.36.0;1.36;1.35.1;1.35.0;1.35;1.34.1;1.34.0;1.34;1.33.1;1.33.0;1.33
-- [ /usr/share/cmake-2.8/Modules/FindBoost.cmake:568 ] Boost_USE_MULTITHREADED = TRUE
-- [ /usr/share/cmake-2.8/Modules/FindBoost.cmake:570 ] Boost_USE_STATIC_LIBS = ON
-- [ /usr/share/cmake-2.8/Modules/FindBoost.cmake:572 ] Boost_USE_STATIC_RUNTIME = ON
-- [ /usr/share/cmake-2.8/Modules/FindBoost.cmake:574 ] Boost_ADDITIONAL_VERSIONS = 
-- [ /usr/share/cmake-2.8/Modules/FindBoost.cmake:576 ] Boost_NO_SYSTEM_PATHS = 
-- [ /usr/share/cmake-2.8/Modules/FindBoost.cmake:644 ] Declared as CMake or Environmental Variables:
-- [ /usr/share/cmake-2.8/Modules/FindBoost.cmake:646 ]   BOOST_ROOT = /home/neb/workspace/SDLActivityCMAKE/jni/boost
-- [ /usr/share/cmake-2.8/Modules/FindBoost.cmake:648 ]   BOOST_INCLUDEDIR = /home/neb/workspace/SDLActivityCMAKE/jni/boost/include/boost-1_53
-- [ /usr/share/cmake-2.8/Modules/FindBoost.cmake:650 ]   BOOST_LIBRARYDIR = /home/neb/workspace/SDLActivityCMAKE/jni/boost/lib
-- [ /usr/share/cmake-2.8/Modules/FindBoost.cmake:652 ] _boost_TEST_VERSIONS = 1.56.0;1.56;1.55.0;1.55;1.54.0;1.54;1.53.0;1.53;1.52.0;1.52;1.51.0;1.51;1.50.0;1.50;1.49.0;1.49;1.48.0;1.48;1.47.0;1.47;1.46.1;1.46.0;1.46;1.45.0;1.45;1.44.0;1.44;1.43.0;1.43;1.42.0;1.42;1.41.0;1.41;1.40.0;1.40;1.39.0;1.39;1.38.0;1.38;1.37.0;1.37;1.36.1;1.36.0;1.36;1.35.1;1.35.0;1.35;1.34.1;1.34.0;1.34;1.33.1;1.33.0;1.33
-- [ /usr/share/cmake-2.8/Modules/FindBoost.cmake:734 ] location of version.hpp: /home/neb/workspace/SDLActivityCMAKE/jni/boost/include/boost-1_53/boost/version.hpp
-- [ /usr/share/cmake-2.8/Modules/FindBoost.cmake:754 ] version.hpp reveals boost 1.53.0
-- [ /usr/share/cmake-2.8/Modules/FindBoost.cmake:786 ] guessed _boost_COMPILER = -gcc46
-- [ /usr/share/cmake-2.8/Modules/FindBoost.cmake:796 ] _boost_MULTITHREADED = -mt
-- [ /usr/share/cmake-2.8/Modules/FindBoost.cmake:839 ] _boost_RELEASE_ABI_TAG = -s
-- [ /usr/share/cmake-2.8/Modules/FindBoost.cmake:841 ] _boost_DEBUG_ABI_TAG = -sd
-- [ /usr/share/cmake-2.8/Modules/FindBoost.cmake:884 ] _boost_LIBRARY_SEARCH_DIRS = /home/neb/workspace/SDLActivityCMAKE/jni/boost/lib;/home/neb/workspace/SDLActivityCMAKE/jni/boost/lib;/home/neb/workspace/SDLActivityCMAKE/jni/boost/stage/lib;/home/neb/workspace/SDLActivityCMAKE/jni/boost/include/boost-1_53/lib;/home/neb/workspace/SDLActivityCMAKE/jni/boost/include/boost-1_53/../lib;/home/neb/workspace/SDLActivityCMAKE/jni/boost/include/boost-1_53/stage/lib;C:/boost/lib;C:/boost;/boost/boost_1_53_0/lib;/boost/boost_1_53/lib;/boost/lib;/boost;/sw/local/lib
-- [ /usr/share/cmake-2.8/Modules/FindBoost.cmake:962 ] Searching for THREAD-GCC-MT-1_53_LIBRARY_RELEASE: boost_thread-gcc-mt-1_53-gcc46-mt-s-1_53;boost_thread-gcc-mt-1_53-gcc46-mt-s;boost_thread-gcc-mt-1_53-mt-s-1_53;boost_thread-gcc-mt-1_53-mt-s;boost_thread-gcc-mt-1_53
-- [ /usr/share/cmake-2.8/Modules/FindBoost.cmake:994 ] Searching for THREAD-GCC-MT-1_53_LIBRARY_DEBUG: boost_thread-gcc-mt-1_53-gcc46-mt-sd-1_53;boost_thread-gcc-mt-1_53-gcc46-mt-sd;boost_thread-gcc-mt-1_53-mt-sd-1_53;boost_thread-gcc-mt-1_53-mt-sd;boost_thread-gcc-mt-1_53-mt;boost_thread-gcc-mt-1_53
-- [ /usr/share/cmake-2.8/Modules/FindBoost.cmake:962 ] Searching for DATE_TIME-GCC-MT-1_53_LIBRARY_RELEASE: boost_date_time-gcc-mt-1_53-gcc46-mt-s-1_53;boost_date_time-gcc-mt-1_53-gcc46-mt-s;boost_date_time-gcc-mt-1_53-mt-s-1_53;boost_date_time-gcc-mt-1_53-mt-s;boost_date_time-gcc-mt-1_53
-- [ /usr/share/cmake-2.8/Modules/FindBoost.cmake:994 ] Searching for DATE_TIME-GCC-MT-1_53_LIBRARY_DEBUG: boost_date_time-gcc-mt-1_53-gcc46-mt-sd-1_53;boost_date_time-gcc-mt-1_53-gcc46-mt-sd;boost_date_time-gcc-mt-1_53-mt-sd-1_53;boost_date_time-gcc-mt-1_53-mt-sd;boost_date_time-gcc-mt-1_53-mt;boost_date_time-gcc-mt-1_53
-- [ /usr/share/cmake-2.8/Modules/FindBoost.cmake:1108 ] Boost_FOUND = FALSE
CMake Error at /usr/share/cmake-2.8/Modules/FindBoost.cmake:1195 (message):
  Unable to find the requested Boost libraries.

  Boost version: 1.53.0

  Boost include path:
  /home/neb/workspace/SDLActivityCMAKE/jni/boost/include/boost-1_53

  The following Boost libraries could not be found:

          boost_thread-gcc-mt-1_53
          boost_date_time-gcc-mt-1_53

  No Boost libraries were found.  You may need to set BOOST_LIBRARYDIR to the
  directory containing Boost libraries or BOOST_ROOT to the location of
  Boost.
Call Stack (most recent call first):
  src/CMakeLists.txt:15 (find_package)


-- Configuring incomplete, errors occurred!

So I see that CMake is searching for libraries in this exact directory: /home/neb/workspace/SDLActivityCMAKE/jni/boost/lib In which there are compiled static libraries:

neb@neb-VirtualBox:~/workspace/SDLActivityCMAKE/jni/boost/lib$ ls -l
total 24440
-rwxrwxrwx 1 neb neb   557190 sie 27 12:36 libboost_date_time-gcc-mt-1_53.a
-rwxrwxrwx 1 neb neb  1348474 sie 27 12:36 libboost_filesystem-gcc-mt-1_53.a
-rwxrwxrwx 1 neb neb   827216 sie 27 12:36 libboost_iostreams-gcc-mt-1_53.a
-rwxrwxrwx 1 neb neb  6813972 sie 27 12:36 libboost_program_options-gcc-mt-1_53.a
-rwxrwxrwx 1 neb neb 12927086 sie 27 12:37 libboost_regex-gcc-mt-1_53.a
-rwxrwxrwx 1 neb neb  1197696 sie 27 12:37 libboost_signals-gcc-mt-1_53.a
-rwxrwxrwx 1 neb neb   159462 sie 27 12:36 libboost_system-gcc-mt-1_53.a
-rwxrwxrwx 1 neb neb  1177994 sie 27 12:37 libboost_thread-gcc-mt-1_53.a`

I set all variables pointing to BOOST directories I could find, I set variables saying that Boost libraries should be static, but it still doesn't find them. What else can I do?

like image 421
Nebril Avatar asked Sep 10 '13 09:09

Nebril


3 Answers

Finding Boost using CMake

Let me start by saying getting CMake to find Boost can be difficult because the automagic in FindBoost.cmake will bite you and KitWare the makers of CMake have some of the worst documentation of any popular project I've ever encountered. You'll have to walk through the source of FindBoost.cmake to debug it if it fails.

Cross-compiled Boost

The directory you installed cross-compiled boost looks like this assuming 1.62.0

boost-arm-build/include
boost-arm-build/include/boost-1_62
boost-arm-build/lib

The call to CMake from Project-Build directory

cmake \
   -DBoost_NO_SYSTEM_PATHS=TRUE \
   -DBoost_ADDITIONAL_VERSIONS="1.62" \
   -DCMAKE_TOOLCHAIN_FILE=../android.toolchain \
   -DBOOST_ROOT="../boost-arm-build" \
   ../Project/

-DBoost_ADDITIONAL_VERSIONS - CMake looks for Boost using a hardcoded list of strings, if your CMake is older than the Boost version you're building it won't know where to look in the include directory so you'll need to pass it along. Although the version is actually 1.62.0, boost put the includes in boost-1_62 so I use 1.62 instead. In FindBoost.cmake you'll find each version is added twice, as in "1.62.0" "1.62" for this very reason.

You should also inspect the file names of the libraries you built, for my example let's look at system:

libboost_system-gcc-mt-1_62.a
libboost_system-gcc-mt-1_62.so    # Symbolic link to libboost_system-gcc-mt-1_62.so.1.62.0
libboost_system-gcc-mt-1_62.so.1.62.0
libboost_system-gcc-mt-d-1_62.a
libboost_system-gcc-mt-d-1_62.so  # Symbolic link to libboost_system-gcc-mt-d-1_62.so.1.62.0
libboost_system-gcc-mt-d-1_62.so.1.62.0
  • gcc - the compiler used
  • mt - multithreaded
  • d - debug
  • 1_62 - the version of boost, obviously

If you see libboost_system.a instead it means you failed to build boost with --with-layout=versioned and should probably check out my SO Answer on building boost using the NDK. If you see clang instead of gcc it's great you've built boost with clang, but you'll probably need to inform CMake that clang exists using the Boost_COMPILER flag.

-DBoost_COMPILER="-clang"

android.toolchain file

set(CMAKE_SYSTEM_NAME Android)

set(CROSS_COMPILER_DIR /opt/ndk-R13-standalone)
set(CMAKE_C_COMPILER ${CROSS_COMPILER_DIR}/bin/arm-linux-androideabi-gcc)
set(CMAKE_CXX_COMPILER ${CROSS_COMPILER_DIR}/bin/arm-linux-androideabi-g++)

set(ANDROID_NATIVE_API_LEVEL android-19)
set(ANDROID_ABI armeabi-v7a)
set(ANDROID_STL gnustl_static)

set(CMAKE_SYSROOT ${CROSS_COMPILER_DIR}/sysroot)
set(CMAKE_FIND_ROOT_PATH ${CMAKE_SYSROOT})

# search for programs in the build host directories
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
like image 149
Cameron Lowell Palmer Avatar answered Nov 02 '22 13:11

Cameron Lowell Palmer


I had the very same issue. Using find_host_package(Boost COMPONENTS ..) instead of find_package(Boost COMPONENTS ..) solved the problem for me.

(Found here: http://code.google.com/p/android-cmake/issues/detail?id=16)

like image 35
ketza Avatar answered Nov 02 '22 12:11

ketza


There are a few issues here.

It looks like your boost libraries have been built without runtime-link=static ie they aren't linked statically to the C++ Standard Library. If they had been, their names' postfixes should contain an s (see the boost docs on library naming)

Another issue is that CMake's FindBoost module expects the COMPONENTS arguments to be of the form "date_time", "thread" rather than the full name as you have provided.

Another more minor point is that you shouldn't need to set Boost_INCLUDE_DIR or Boost_LIBRARY_DIR; these are set by the CMake module if successful. Setting them shouldn't cause any problems however, it's just unnecessary clutter.

Also, for BOOST_ROOT, BOOST_INCLUDEDIR, and BOOST_LIBRARYDIR, these would normally be set via the command line using the -D option, or set as environment variables in order to avoid hard-coding paths specific to your machine into the CMakeLists.txt.

The final point is that you should remove the link_directories call. Its own documentation discourages its use, and it's not needed since you're already passing the full paths to the boost libs in the target_link_libraries call.

So, the final version should be more like:

#BOOST
set(Boost_USE_STATIC_LIBS ON)
set(USE_STATIC_BOOST ON)  # Not sure if you really need this later.  If not, delete.
set(Boost_USE_STATIC_RUNTIME OFF)
set(Boost_COMPILER -gcc)

find_package(Boost COMPONENTS thread date_time REQUIRED)

include_directories(${Boost_INCLUDE_DIRS})
#BOOSTEND

add_executable(main main.cpp)
target_link_libraries(main ${Boost_LIBRARIES})

and you can invoke CMake like this:

cmake . -DBOOST_ROOT=<path to root> -DBOOST_INCLUDEDIR=... -DBOOST_LIBRARYDIR=...
like image 2
Fraser Avatar answered Nov 02 '22 14:11

Fraser