Introduction to JNI & NDK in Android (4) Use CMake to compile NDK

1 Introduction

We made an introduction to JNK / NDK in the previous articles, which used the local configuration of Android.mk and Application.mk for NDK development. But in fact, after Android Studio 2.2, the CMake method was added to compile the NDK code.

2 CMake

CMake is a cross-platform installation (compilation) tool that can describe the installation (compilation process) of all platforms with simple statements. He can output various makefiles or project files, and can test the C ++ features supported by the compiler, similar to automake under UNIX. Google uses NDK and CMake to compile C and C ++ code into native libraries from Android Studio 2.2 and higher. Among them, Gradle can easily encapsulate SO libraries into APKs.

3 Hello world

If you are using CMake for the first time, you should install the NDK as before, check the CMake item on the SDK management page in Android Studio to download, the operation is as shown below:

After the installation is complete, you can create a Native C ++ project. In the [File] – [New Project] pop-up window, tick the [Include C ++ support] item, as shown below:

After the project is created, we can see that there are several differences from the ordinary Android project, as shown below:

1. There is an additional .externalNativeBuidl directory under the app directory.

2. There is an additional cpp directory under the main directory, where there is a native-lib.cpp file, which is where the C / C ++ code is placed.

3. There are two more items in the content of buile.gradle in the app directory. It can be seen that the first item is the C ++ version we selected when creating a new project and the -fexceptions and -frtti items on the tick. They are exception support (-fexceptions) and runtime type information support (-frtti); The second item is to specify the CMakeLists.txt file.

4. There is an additional CMakeLists.txt file in the app directory, whose contents are as follows:

 

3.1 CMakeLists.txt解说

Let's look back at the content of the CMakeLists.txt file above. There are 4 lines of valid code left in the comments. Let's take a look at their meaning.

cmake_minimum_required(VERSION major[.minor[.patch[.tweak]]][FATAL_ERROR])

Set the minimum CMake version required by the project. For example, the minimum version above is 3.4.1.

add_library(<name> [STATIC | SHARED | MODULE] [EXCLUDE_FROM_ALL] source1 source2 ... sourceN)

Add a library . As mentioned above: compile a dynamic library native-lib, the source file is only src / main / cpp / native-lib.cpp. Parameter Description:

<name> means to add a library file with the specified name.

[STATIC | SHARED | MODULE] Specifies the type of library to be created, the static library corresponding to STATIC (.a file, required for compilation, equivalent to the lib file in Windows), and the shared dynamic library corresponding to SHARED (.so file, runtime Required, equivalent to the dll file in Windows), MODULE corresponds to the module in the project.

[EXCLUDE_FROM_ALL] If this attribute is specified, some corresponding attributes will be set when the directory is created, please refer to the corresponding documentation for details.

source1 source2 ... sourceN specifies the source file.

find_library(<VAR> name1 [path1 path2 ...])

Find a library file . As above: look for the pre-compiled library log_lib.

target_link_libraries(<name> lib1 lib2 lib3)

Link the given library to a target . As mentioned above: find the pre-compiled library log_lib and link to the dynamic library native-lib.

3.2 Code explanation

native-lib.cpp

#include <jni.h>
#include <string>

extern "C" JNIEXPORT jstring JNICALL
Java_com_zyx_cmakedemo_MainActivity_stringFromJNI(JNIEnv *env, jobject /* this */) {
    std::string hello = "Hello from C++";
    return env->NewStringUTF(hello.c_str());
}

MainActivity.java

public class MainActivity extends AppCompatActivity {

    // Used to load the 'native-lib' library on application startup.
    static {
        System.loadLibrary("native-lib");
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // Example of a call to a native method
        TextView tv = findViewById(R.id.sample_text);
        tv.setText(stringFromJNI());
    }

    /**
     * A native method that is implemented by the 'native-lib' native library,
     * which is packaged with this application.
     */
    public native String stringFromJNI();
}

Very simple code, load libnative-lib.so in a static block in MainActivity, and then define a native method stringFromJNI. Then implement the stringFromJNI method in native-lib.cpp, the function name also follows the rules: Java_package name_class name_method name.

3.3 Operation

Compile and run, then the corresponding so file will be generated in the app \ build \ intermediates \ cmake \ debug \ obj directory. Then run the program on the phone and you will see that Java successfully called the C ++ code and returned the result.

 

4 Reference to external so library

In the actual development process, the C ++ project is often separated from the Android project, or the Android project directly references the externally provided ready-made so library file. Now let's simulate this happening.

First copy the above compiled so file to app \ src \ main \ jniLibs, as shown below:

Then modify the content of CMakeLists.txt as follows:

cmake_minimum_required(VERSION 3.4.1)

add_library(native-lib SHARED IMPORTED)

set_target_properties(native-lib PROPERTIES IMPORTED_LOCATION ${CMAKE_SOURCE_DIR}/src/main/jniLibs/${ANDROID_ABI}/libnative-lib.so)

The following two lines of code mean: add a dynamic library, and then set the path of the so library, where $ {CMAKE_SOURCE_DIR} is the path where CMakeLists.txt is located, and $ {ANDROID_ABI} is the cup type.

Recompile and run after the modification, the display result is the same as the above source code integration.

5 More information

For more information about NDK and CMake, please refer to:

https://developer.android.com/ndk/guides/index.html

https://developer.android.com/ndk/guides/cmake.html.

https://www.zybuluo.com/khan-lau/note/254724

https://github.com/googlesamples/android-ndk

https://cmake.org/cmake-tutorial/

 

 

 

Published 106 original articles · praised 37 · 80,000 views

Guess you like

Origin blog.csdn.net/lyz_zyx/article/details/88324547