6

I am new to CMake and I have problem creating an executable using CMake. I am trying to build an executable and a shared library from a single CMakeLists.txt file. My CMakeLists.txt is as follows:

cmake_minimum_required(VERSION 3.4.1)
project (TestService)

include_directories(
    src/main/cpp/
    libs/zlib/include/
)

add_library(libz SHARED IMPORTED)

set_target_properties(libz PROPERTIES IMPORTED_LOCATION ${PROJECT_SOURCE_DIR}/libs/zlib/libs/${ANDROID_ABI}/libz.so)

find_library(log-lib log)

add_executable(
    test_utility
    src/main/cpp/test_utility.cpp
    src/main/cpp/storage.cpp
)

target_link_libraries(test_utility ${log-lib} libz)

add_library(
    processor
    SHARED
    src/main/cpp/com_example_testservice.cpp
    src/main/cpp/storage.cpp
)

target_link_libraries(processor libz ${log-lib})

However when I build my project using android studio/gradlew from command line, I only see the processor.so library getting created, test_utility executable is never created. What is incorrect in my CMakeLists.txt?

savi
  • 497
  • 2
  • 12
  • 27
  • processor and test_utility are not related, they only share storage.cpp file. I want to create an executable test_utility and a shared library processor.so. Where do I run make test_utility? – savi Jun 09 '17 at 22:46
  • [Building executables for Android shell](https://stackoverflow.com/a/35275134/3290339) – Onik Sep 16 '17 at 00:50

3 Answers3

4

The answer is: it builds, it's just not packaged into apk because only files matching pattern lib*.so will be copied. Therefore the fix is easy:

add_executable(libnativebinaryname.so ...)
Mygod
  • 2,077
  • 1
  • 19
  • 43
  • Note: You should probably also use `android:installLocation="internalOnly"` if you are executing the binaries directly. – Mygod Sep 18 '18 at 09:47
0

It's hard to say what's happening under the hood without seeing the actual command.
That being said, probably you are using make processor that explicitly builds processor target only. From your CMakeLists.txt you can see that processor target has not test_utility target as a dependency.

To compile the latter you can:

  • either use make, to make all the targets
  • or run make test_utility, to build it explicitly
skypjack
  • 49,335
  • 19
  • 95
  • 187
  • processor and test_utility are not related, they only share storage.cpp file. I want to create an executable test_utility and a shared library processor.so. Where do I run make test_utility? – savi Jun 09 '17 at 22:48
  • From the command line or by adding it as a target to your gradle file. It's up to you. To be sure that's the problem, I would try to run it from the command line first. – skypjack Jun 09 '17 at 22:50
  • It says "make: *** No rule to make target `license_storage_utility'. Stop.", then how is processor.so getting created? – savi Jun 09 '17 at 22:51
  • I am using gradlew clean build to generate my apk and .so files. I do not understand where to specify the target. Can you please explain where the target for test_utility needs to be mentioned? Is it in build.gradle? – savi Jun 09 '17 at 23:00
0

You need to specify your executable as a build target. Android Studio builds .so files by default, but will not build executables unless you specify them. Here's the documentation on the topic (search for "targets").

Basically, add something like this to your module's build.gradle file:

defaultConfig {
    externalNativeBuild {
        cmake {
            targets "executable_target"
        }
    }
}

You can also place it under a product flavor like this:

productFlavors {
    chocolate {
        externalNativeBuild {
            cmake {
                targets "executable_target"
            }
        }
    }
}

If you add any explicit build target, it will no longer build all shared objects by default, only those that are dependents of the explicit target(s). You can specify more than one target to build all your executables and shared objects. This bug covers improving that.

kwiqsilver
  • 1,017
  • 2
  • 11
  • 24