1

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:

Canato
  • 3,598
  • 5
  • 33
  • 57
  • The message "is not able to compile a simple test program." isn't the *main* message (at least, it is not the only "main" one). It should be a line (like in the first question reference) "It fails with the following output:", after which you will found exact reason, why the compilation fails. – Tsyvarev Sep 18 '18 at 16:54
  • @Tsyvarev thanks for the help. I just edited with the message that you ask, but looks like the same message before, thanks for any ideas – Canato Sep 19 '18 at 07:17
  • 1
    Hm, no, the message `No such file or directory` is new in your log. And the message `Make command was: "" "cmTC_27ba1"` looks suspicious: instead of empty quoted string it should be `ninja` (or absolute path to it). Note, that setting `set(CMAKE_MAKE_PROGRAM <...>/ninja)` is **wrong**: you need to set *CACHE* variable instead: `set(CMAKE_MAKE_PROGRAM <...>/ninja CACHE FILEPATH "")`. If you want to resolve other problems, you need to post your *full* toolchain file. You list two compilers, set another one in `CMakeLists.txt`, but CMake uses other one, probably, because of the toolchain. – Tsyvarev Sep 19 '18 at 08:00
  • @Tsyvarev this is my full toolchain file right now. I putted later what more I had insert, but they made no difference, so I removed. My `CMakeList.txt` has none compiler, it will work as Cross Compiler. What path I should put in CACHE FILEPATH? Ninja? just the same? – Canato Sep 19 '18 at 09:41
  • `<...>/ninja` is a replacement for your path. As for the last `""` parameter, it denotes documentation string and may be leaved empty (but it cannot be omitted). "My `CMakeList.txt` has none compiler" - the line `set(CMAKE_CXX_COMPILER "/usr/bin/g++")` is intended to set a compiler... (Anyway, it does it wrong: the line should be issued after the `project()` call). – Tsyvarev Sep 19 '18 at 09:50
  • @Tsyvarev thanks, worked like a charm. If you wanna, put this as answer. Now I have another problem `ld: library not found for -lc++`will research a little. – Canato Sep 19 '18 at 11:40
  • I wonder what is `Android.cmake` file in your post? Googling for the file with this exact name finds nothing useful. Judging the file's content, as most of its `set` calls suggest, that this is a *toolchain* file. But setting `CMAKE_TOOLCHAIN_FILE` variable in the toolchain is *useless* - CMake uses the variable to find the toolchain file itself. The setting `set(CMAKE_BUILD_TYPE Debug)` isn't for toolchain too. In your first version of the post, you name this file as "CMake", so I suggested that it was `CMakeLists.txt`. Please, clarify meaning of this file. – Tsyvarev Sep 19 '18 at 12:26
  • 1
    @Tsyvarev you is right, `Android.cmake` is used in build script as toolchain file. (Line 5 buildscript.py). I'm not setting `CMAKE_TOOLCHAIN_FILE` and `CMAKE_BUILD_TYPE`, you looked at "What I already Tried" session. This is not the file now, when I created this post the file only has two "SET's" – Canato Sep 19 '18 at 12:38
  • Not sure what do you mean by "It is asking for LD library.", but the error is about missed `c++` library. As far as I know, `clang` uses *external* (which is not part of llvm) linker `ld`. If your host `ld` is actually picked, than it is a problem by itself: the host linker can only process `x86-64` and related arch'es, not the `arm`. I cannot tell how to check that (probably, by running `which ld` from the conan's toolchain). Also, `--sysroot=/usr/bin` looks weird: normally, the directory `/usr/bin` contains only *executables*, but sysroot implies *libraries*, *headers*, and so on. – Tsyvarev Sep 19 '18 at 14:14
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/180361/discussion-between-canato-and-tsyvarev). – Canato Sep 19 '18 at 14:31

1 Answers1

1

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

Community
  • 1
  • 1
Tsyvarev
  • 60,011
  • 17
  • 110
  • 153
  • Sorry to remove the right tick, I thought that the problem was in another place, but still in the same. But now I put more informations after your right shot about the `CACHE FILEPATH` – Canato Sep 19 '18 at 13:34