Android Ndk-build compiling a static library libxx.a
Requirements Scenario:
Currently there are two of the Android coded now OpenSSL. A, we need to invoke the function of OpenSSL and then encapsulate the function. A;
In this case, in the Android Studio JNI Project CMake, you need to refer to the. A of OpenSSL before referencing the. A in the above package.
If so, then directly in the CPP of the Android Studio JNI project to call the method of OpenSSL, to provide the JNI Java interface, packaging into so can;
First, pack your libxx.a with Ndk-build and refer to the static library of OpenSSL when you pack. A
1. First, prepare a coded OpenSSL static library in the current directory, as shown in the Android platform
2. Test the source file used, I am here in. H declares a encapsulated method Ssl_sha, and in the. C implementation, invokes the SHA256 interface of OpenSSL;
Adding #ifdef __cplusplus is to make an undefined error in CPP when the JNI call occurs, as follows SSL_HASH.H
#ifndef Ssl_hash_h #define ssl_hash_h# ifdef __cplusplusextern"C" { #endif<stdio.h>/**/int ssl_sha256 ( Const Char *in_data,int in_len,Char *out_hash); # ifdef __cplusplus}# endif #endif /* ssl_hash_h */
The following SSL_HASH.C implementation file
#include"ssl_hash.h"#include"openssl/sha.h"intSSL_SHA256 (Const Char*in_data,intIn_len,Char*Out_hash) { if(!in_data) { return- -; } if(! SHA256 ((ConstUnsignedChar*) In_data, In_len, (unsignedChar*) (Out_hash)) {return-1001; } return 1;}
The same two files are also placed in the same directory as the. Mk;
3. Start writing android.mk,application.mk, as shown in the following example
#Android. mk file Local_path:= $ (call my-dir) include $ (clear_vars) #编码后生成的. A's name Local_module := Sslhash #要编码的源文件c或cppLOCAL_SRC_FILES:= ssl_hash.c# dependent static Library. A, to use a dynamic library, use the local_shared_libraries. Solocal_ Static_libraries:= libs/${target_arch_abi}/lib/libssl.a libs/${target_arch_abi}/lib/libcrypto.a# Dependent static Library header file Local_c_includes:= libs/${target_arch_abi}/include# Last generated static library include $ (build_static_library)
#Application. MK is tested here, compiling only x86 App_abi:= x86
4. When all the files are ready, as shown below:
5. Call Ndk-build to start compiling
~/library/android/sdk/ndk-bundle/ndk-build ndk_project_path=./ndk_libs_out=./APP_BUILD_SCRIPT=./Android.mk NDK_ Application_mk=./application.mk
6. After success, the obj directory is generated under the current directory, which contains the generated static library libxx.a
7. After compiling, the following needs to be tested in Android studio; Create a JNI project with as;
8. Add Libs directory (Android view) in Project Build.gradle (Module:app)
Externalnativebuild { cmake { "CMakeLists.txt" } } Sourcesets { main { = ['libs'] } }
and only compile x86 in the specified test
Externalnativebuild { cmake { "" "x86" } } ndk{ "x86" }
9. Copy all the OpenSSL libraries from the previous Libs directory to the Project Jnilibs catalog (Android view)
And put the generated libsslhash.a under the X86/lib.
And put the SSL_HASH.H head file under the X86/include.
Wherever you go, you need to specify a reference in the CMake.
10. Open CmakeList.txt To configure the reference for the OpenSSL static library, and configure the reference generated LIBSSLHASH.A
The following perfect cmakelist
Cmake_minimum_required (VERSION3.4.1)Set(Cmake_cxx_flags"${cmake_cxx_flags}-std=gnu++11") #这里配置指定目录libsSet(Openssl_dir ${cmake_source_dir}/Libs) # Creates and names a library, sets it aseither static# or SHARED, and provides the relative paths to it source code.# you can define multiple libraries, an D CMake builds them foryou.# Gradle automatically packages GKFX libraries with your APK. #这里引用三个静态. A, Ssl,sslhash,cryptoadd_library ( Crypto static imported) Add_library (SSL static imported) Add_library (Sslhash static imported) # Load here and find the appropriate libxxx.aset_ Target_properties (# Specifies the target library. Crypto # Specifies the parameter you want to define. PROPERTIES Imported_location # provides the path to the library of your want to import. ${openssl_dir}/${android_abi}/lib/libcrypto.a) set_target_properties (# Specifies the target library. SSL # Specifies the parameter you want to define. PROPERTIES Imported_location # provides the path to the library of your want to import. ${openssl_dir}/${android_abi}/lib/libssl.a) set_target_properties (# Specifies the target library. Sslhash # Specifies the parameter you want to define. PROPERTIES Imported_location # provides the path to the library of your want to import. ${openssl_dir}/${android_abi}/lib/libsslhash.a) Add_library (# Sets the name of the library. Native-Lib # sets the library asa shared library. SHARED # provides a relative path to your source file (s). SRC/main/cpp/native-lib.cpp) # searches forA specified prebuilt library and stores the path asa# variable. Because CMake includes system librariesinchThe search path by#defaultNeed to specify the name of the PublicNDK library# you want to add. CMake verifies that the library exists before# completing its build.find_library (# sets the name of the path variable. Log-Lib # Specifies the name of the NDK library that # you want CMake to locate. LOG) # Specifies libraries CMake should link to your target library. you# can link multiple libraries, such asLibraries you defineinch This# Build script, prebuilt third-Party libraries, or system libraries. #这里openssl需要 Zlib Library, loading the system's Find_library (Z-Lib Z) #这里指定一下咱的头文件目录, OpenSSL header file, and our encapsulated SSL_HASH.H header file Include_directories (${openssl_dir}/${android_abi}/include ${openssl_dir}/${android_abi}/#最后一步连接, note here, be sure to put sslhash, we encapsulated this. A put it in front of ssl,crypto, otherwise the error said method is undefined, perhaps because Sslhash quoted the thing of OpenSSL, target_link_ Libraries (# Specifies the target library. Native-Lib # Links the target library to the Log Library # includedinchThe NDK. Sslhash SSL Crypto ${log-Lib} ${z-lib})
11. The configuration is complete, if the compilation is not a problem, you can write the JNI call test;
In Mainactitity.java, add the Jni method
Public native String Stringfromjni (); // Add a test method Public int Sslsha (byte[] indata,int inlen,byte[] outhash);
12. Implement the Jni method in Native-lib.cpp
#include"ssl_hash.h"extern "C"jniexport jint Jnicalljava_androidapp_cocoajin_com_tjni_mainactivity_sslsha (jnienv*Env, jobject instance, Jbytearray Indata_, Jint Inlen, Jbytearray outhash_) {jbyte*indata = env->getbytearrayelements (Indata_, NULL); Jbyte*outhash = env->getbytearrayelements (Outhash_, NULL); intret = ssl_sha256 ((Const Char*) Indata,inlen, (Char*) Outhash); Env->releasebytearrayelements (Indata_, Indata,0); Env->releasebytearrayelements (Outhash_, Outhash,0); returnret;}//of the default systemextern "C"jniexport jstring jnicalljava_androidapp_cocoajin_com_tjni_mainactivity_stringfromjni (JNIEnv*Env, Jobject/* This*/) {std::stringHello ="Hello from C + +"; returnEnv->Newstringutf (Hello.c_str ());}
13. Last call, here byte[] turned into hexstring displayed on the app
// Example of a call to a native method TextView TV = (TextView) Findviewbyid (r.id.sample_text); " Hello " ; byte New byte [+]; Sslsha (He.getbytes (), He.length (), habb); Tv.settext (bytehexutil.bytestohexstring (Habb));
14. Execution results, and validation results
15: References and Engineering downloads
Android Ndk-build compiling static library libxx.a and Android studio OpenSSL static library configuration (CMake)