Search code examples
androidc++opencvcmakendk-build

On OpenCV. C++ Compiler is not able to compile a simple test program. Using Clang++


Goal: Compile a external Library for Android using Cross Compile Build Script with Conan and OpenCV.

My Environment today:

  • OS: MacOS High Sierra 10.13.6;
  • Conan: 1.7.3 ../Cellar/conan/1.6.1/bin/conan
  • Python: 2.7.10 /usr/bin/python (Tried with 3 too)
  • GCC/C++: 8.2.0 /opt/local/bin/gcc-mp-8 || /opt/local/bin/g++-mp-8 (Cited because clang use c++)
  • Clang/Clang++: 9.1.0 /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin (This is not the one the program is using)
  • CMake: 3.12.2 /Applications/CMake.app/Contents/bin/cmake
  • NDK used: 17

Problem: The Open CV don't Compiler C++. The main message is

-- The CXX compiler identification is Clang 6.0.2
-- The C compiler identification is Clang 6.0.2
-- Check for working CXX compiler: /Users/<user>/Library/Android/sdk/ndk-bundle/toolchains/llvm/prebuilt/darwin-x86_64/bin/clang++
-- Check for working CXX compiler: /Users/<user>/Library/Android/sdk/ndk-bundle/toolchains/llvm/prebuilt/darwin-x86_64/bin/clang++ -- broken
CMake Error at /Applications/CMake.app/Contents/share/cmake-3.12/Modules/CMakeTestCXXCompiler.cmake:45 (message):
The C++ compiler

"/Users/<user>/Library/Android/sdk/ndk-bundle/toolchains/llvm/prebuilt/darwin-x86_64/bin/clang++"

is not able to compile a simple test program.

It fails with the following output:

Change Dir: /Users/<user>/.conan/data/OpenCV/3.4.1/ins/stable/build/4492059a128c69658616e0cf3d3f007e2ce6603c/CMakeFiles/CMakeTmp

Run Build Command:"/Users/<user>/Library/Android/sdk/cmake/3.6.4111459/bin/ninja" "cmTC_4338c"
[1/2] Building CXX object CMakeFiles/cmTC_4338c.dir/testCXXCompiler.cxx.o
[2/2] Linking CXX executable cmTC_4338c
FAILED: : && /Users/<user>/Library/Android/sdk/ndk-bundle/toolchains/llvm/prebuilt/darwin-x86_64/bin/clang++ --sysroot=/Users/<user>/Library/Android/sdk/ndk-bundle/sysroot   -Wl,-search_paths_first -Wl,-headerpad_max_install_names  CMakeFiles/cmTC_4338c.dir/testCXXCompiler.cxx.o  -o cmTC_4338c   && :
ld: library not found for -lc++
clang++: error: linker command failed with exit code 1 (use -v to see invocation)
ninja: build stopped: subcommand failed.

CMake will not be able to correctly generate this project.
  • CMakeTmp is a folder, empty.
  • CMakeError has the same message after "..fail with the following output"

It is asking for LD library. But on LLVM folder don't have LLVM-LD, it was remove on 4.0 if I'm not wrong. I'm using 10.0. This is what has in my folder

enter image description here

  • Obs: As you can see I don't know how to set up the Flag in the right way and don't know if this would change something.

Code:

Buildscript.py

build_dir = "build_Android_Debug"
conan_install_arguments = "-s compiler=clang -s compiler.version=6.0 -s compiler.libcxx=libc++ -s os=Android -s os.api_level=26 -s arch=armv8 -s build_type=Debug"

android_cmake_toolchain_path = current_dir_absolute_path + "/cmake-toolchains/Android.cmake"
conan_install_arguments += " --env CONAN_CMAKE_TOOLCHAIN_FILE=\"%s\"" % android_cmake_toolchain_path

conan_install_arguments += " --env CONAN_CMAKE_FIND_ROOT_PATH=/Users/<user>/Library/Android/sdk/ndk-bundle/sysroot"
conan_install_arguments += " --env PATH=[/Users/<user>/Library/Android/sdk/ndk-bundle/toolchains/llvm/prebuilt/darwin-x86_64/bin]"
conan_install_arguments += " --env AR=llvm-ar"
conan_install_arguments += " --env AS=llvm-as"
conan_install_arguments += " --env CC=clang"
conan_install_arguments += " --env CXX=clang++"

conan_install_command = "cd %s && conan install .. %s" % (build_dir, conan_install_arguments)

os.system(conan_install_command)

Android.cmake

set(CMAKE_MAKE_PROGRAM /Users/vcanato/Library/Android/sdk/cmake/3.6.4111459/bin/ninja)
set(CMAKE_ANDROID_NDK /Users/vcanato/Library/Android/sdk/ndk-bundle/)

What I already Tried

On Buildscript

compiler=clang
compiler.version=5.0
compiler.libcxx=libc++
os=Android
os.api_level=21
arch=armv7

Obs: Gcc in deprecated, so would be good a solution without, but still didn't work.

compiler=gcc
compiler.version=4.9
compiler.libcxx=libstdc++
os=Android
os.api_level=21
arch=armv7
build_type=Release

On Android.cmake:

cmake_minimum_required(VERSION 3.4 FATAL_ERROR)
include_directories("/usr/local/Cellar/gcc/8.2.0/include/c++/8.2.0")
include_directories( "/usr/local/Cellar/gcc/8.2.0/include/c++/8.2.0/x86_64-apple-darwin17.7.0/bits")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -I /usr/local/include/c++/8.2.0/")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -X /usr/include/c++/4.2.1/")
set(CMAKE_CXX_STANDARD 11)
set(CXX_STANDARD_REQUIRED)
set(CMAKE_CXX_COMPILER "/usr/bin/g++")
set(CMAKE_CXX_COMPILER "/Users/vcanato/Library/Android/sdk/ndk-bundle/toolchains/llvm/prebuilt/darwin-x86_64/bin/clang++")
set(CMAKE_C_COMPILER "/usr/bin/gcc")
set(ANDROID_ABI arm64-v8a)
set(CMAKE_ANDROID_API android-21)
set(CMAKE_BUILD_TYPE Debug)
set(CMAKE_TOOLCHAIN_FILE /Users/<user>/Library/Android/sdk/ndk-bundle/build/cmake/android.toolchain.cmake)

set(CMAKE_ANDROID_NDK /Users/<user>/Library/Android/sdk/ndk-bundle/ CACHE FILEPATH "")

On CmakeList.txt

set(CMAKE_CXX_COMPILER "/Users/vcanato/Library/Android/sdk/ndk-bundle/toolchains/llvm/prebuilt/darwin-x86_64/bin/clang++")
set(CMAKE_CXX_COMPILER "/usr/bin/g++")

Before and after project()

Toolchains:

/Users/vcanato/Library/Android/sdk/ndk-bundle/toolchains/arm-linux-androideabi-4.9
/Users/vcanato/Library/Android/sdk/ndk-bundle/toolchains/x86_64-4.9

I even try to build my own standalone toolchain and use Conan cross building guide to Android

Similar Question On Stack and GitHub:


Solution

  • Proper way for specify CMAKE_MAKE_COMMAND in the toolchain is setting CACHE variable:

    set(CMAKE_MAKE_PROGRAM /Users/vcanato/Library/Android/sdk/cmake/3.6.4111459/bin/ninja
        CACHE FILEPATH "")
    

    This is implied both by documentation (if the variable is set by a generator, CACHE version is set), and in this CMake mailing.

    More explanations

    Emptiness of the first string in the message

    Make command was: "" "cmTC_27ba1"
    

    should be the first signal of "something goes wrong". Instead of the empty string it should be an executable corresponded to the CMake generator (or an absolute path to the executable). In you case the generator's executable is ninja.

    Usually, CMake signals about the problem in more descriptive way:

    CMAKE_MAKE_PROGRAM is not set