1

I am trying to use an existing native library as part of an android project. I followed instructions about adding C and C++ Code to a project for android studio. I got to the point where I have a functioning CMakeLists.txt file (tested independently) and I've instructed gradle to use it to compile the native code.

The library I'm using uses make so I use ExternalProject_Add to instruct cmake how to compile it. Here is the relevant code:

ExternalProject_Add(foo
    SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../libfoo
    CONFIGURE_COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/../libfoo/configure
        --host=arm-linux-androideabi
    BUILD_COMMAND ${MAKE}
    INSTALL_COMMAND true)

This is the relevant part of the build.gradle for the module:

externalNativeBuild {
    cmake {
        path '../cpp/CMakeLists.txt'
    }
}

When I run ./gradlew assembleDebug, the external project is not compiled. After adding an executable (named bar) that depends on foo in cmake, the configure step runs but the build step doesn't. I modified the code of the library so that compilation would fail, but gradle returns success anyway).

Here are the last lines of the output of ./gradlew assembleDebug after these changes.

configure: creating ./config.status
config.status: creating Makefile
config.status: executing depfiles commands
[6/10] Performing build step for 'foo'
[7/10] Performing install step for 'foo'
[8/10] Completed 'foo'
[9/10] Building C object CMakeFiles/bar.dir/bar.c.o
[10/10] Linking C executable bar

BUILD SUCCESSFUL in 18s

Any ideas what is happening? What am I doing wrong?

I'm using gradle 4.1 and cmake 3.6.

martinkunev
  • 1,364
  • 18
  • 39
  • Can you add `LOG_BUILD ON` to your ExternalProject_Add ? also did you wrap in an imported target the result of the build to consume it in `bar` ? – Mizux Jan 05 '18 at 09:55

2 Answers2

1

you should use BUILD_IN_SOURCE ON otherwise your BINARY_DIR is somewhere else so make do nothing IMHO.

Mizux
  • 8,222
  • 7
  • 32
  • 48
  • Thanks, this was the reason nothing happened while building. However I still need the fictional executable `bar` to make gradle do the steps for the external target. – martinkunev Jan 06 '18 at 01:23
0

See https://stackoverflow.com/a/47636956/192373. You don't need fictional executables. You do need two separate targets, though.

add_library(foolib SHARED IMPORTED)
add_dependencies(foolib foo)
set_target_properties(foolib IMPORTED_LOCATION ${CMAKE_CURRENT_SOURCE_DIR}/../libfoo/…/libfoo.so)

You don't necessarily need BUILD_IN_SOURCE ON, better set BINARY_DIR somewhere in build/intermediates, and pass the same to make.

Alex Cohn
  • 56,089
  • 9
  • 113
  • 307
  • I know it's been a while, but I'm struggling here. So "foo" here comes from `ExternalProject_Add(foo ...`, correct? In my case, this is still not running the build (the configure step is fine though). However, my configure step writes files in `.cxx` and not in `build/intermediates`. Is that relevant? It does set `-DCMAKE_RUNTIME_OUTPUT_DIRECTORY` to `build/intermediates`, though. – JonasVautherin Dec 28 '22 at 15:21
  • I guess I'm confused as to why the configure step is fine, but then gradle somehow does not run `ninja -C path_to_builddir` – JonasVautherin Dec 28 '22 at 15:26
  • I don't understand what files your configuration step writes in `.cxx`. The bottom line of my approach is that the external build (`make` in the case of original question) is not used *as is* by CMake that is coordinated with Gradle, but an extra `IMPORTED` step is introduced which takes care of all dependencies. As for your continuation, why should Gradle run `ninja`? – Alex Cohn Dec 29 '22 at 10:50
  • That's what it does automatically. I am building for Android, and it sets stuff like the toolchain etc. And `-GNinja`. – JonasVautherin Dec 29 '22 at 11:11
  • I didn't express myself well. What I tried to say, if Gradle and CMake find that the build is not necessary, they won't start `ninja`. – Alex Cohn Dec 29 '22 at 14:55
  • Right. I'm guessing that Gradle would run `cmake --build [...]` (which runs ninja), and when I run `cmake --build [...]` manually, it works (even without your additional target "foolib"). So it feels like Gradle does not run it somehow (even when I add your foolib target)... But I don't understand why and I don't know how to see it. – JonasVautherin Dec 30 '22 at 00:03
  • Most likely your **foolib** is not correctly wired into the setup. – Alex Cohn Jan 01 '23 at 08:34
  • Hmm I opened a new question here: https://stackoverflow.com/questions/75115285/cmake-imported-library-not-included-in-gradle-output – JonasVautherin Jan 14 '23 at 02:03