savi
savi

Reputation: 537

CMake does not build an executable with add_executable

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?

Upvotes: 7

Views: 8294

Answers (3)

Mygod
Mygod

Reputation: 2180

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 ...)

Upvotes: 4

kwiqsilver
kwiqsilver

Reputation: 1027

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.

Upvotes: 0

skypjack
skypjack

Reputation: 50550

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

Upvotes: 0

Related Questions