pptang
pptang

Reputation: 1921

How to compile my C++ library in pure Android Studio way (without specifying any .mk file on our own)

At the beginning, I have to say I already searched around as many possible answers as I can to my answer. Some of them are really helpful, but not in Android Studio way. Also, I can get my JNI worked with the well-known example "getStringFromNative()", so please don't give me this kind of links. What I have tried so far :

1. structure of my directory

app 
 |- src
     |- main
         |- java
         |- jni
             |- libs
                 |- libcrypto.a
                 |- libssl.a
             |- openssl
                 |- xxxxx.h
                 |...... -> those .h file of openssl
             |- com_ais_ndksample_MainActivity.h
             |- CipherModule.cpp
             |- CipherModule.h

2. build.gradle

apply plugin: 'com.android.application'

android {
    compileSdkVersion 22
    buildToolsVersion "23.0.0 rc3"

    defaultConfig {
        applicationId "com.ais.ndksample"
        minSdkVersion 16
        targetSdkVersion 22
        versionCode 1
        versionName "1.0"

        ndk {

            moduleName "JniDemo"

        }
    }

    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-  android.txt'), 'proguard-rules.pro'
        }
    }
    sourceSets {
        main {

          jni.srcDirs = ['src/main/jni']

          jniLibs.srcDirs = ['src/main/jni/libs']

        }
    }
}

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    compile 'com.android.support:appcompat-v7:22.2.1'

}
  1. The errors occurred in my CipherModule.cpp, I have several statement on the top as below:

    #include "CipherModule.h"
    #include <openssl/aes.h>
    #include <stdio.h>
    #include <iostream>
    

and the #include shows warning that Unused import statement, but I did use that. When I built, I got the error message indicated as followed:

undefined reference to `AES_set_encrypt_key`
undefined reference to `AES_cbc_encrypt`

As a result, I doubted that I didn't make my openssl library right, but I did specify it in my build.gradle. I had made so much efforts on this and got no luck. Any clue or thought would be appreciated!!!!

Upvotes: 3

Views: 2652

Answers (1)

pptang
pptang

Reputation: 1921

Finally I found out the root cause of this. The error messages I got as below:

undefined reference to `AES_set_encrypt_key`
undefined reference to `AES_cbc_encrypt`

are due to the fact that my libcrypto.a and libssl.a library are not built for android-armv7 based devices. I solved this issue by "cross-compile" my openssl for armv7. The script is shown as follow:

export CC=/your_path_to_sdk/ndk-bundle/toolchains/arm-linux-androideabi-4.8/prebuilt/darwin-x86_64/bin/arm-linux-androideabi-gcc

export AR=/your_path_to_sdk/ndk-bundle/toolchains/arm-linux-androideabi-4.8/prebuilt/darwin-x86_64/bin/arm-linux-androideabi-ar

export RANLIB=/your_path_to_sdk/toolchains/arm-linux-androideabi-4.8/prebuilt/darwin-x86_64/bin/arm-linux-androideabi-gcc-ranlib

./Configure android-armv7

export ANDROID_DEV=/your_path_to_sdk/ndk-bundle/platforms/android-15/arch-arm/usr

make

You can run this script inside your openssl folder downloaded from official website and your will get your libcrypto.a and libssl.a inside openssl folder. Those are compiled for android this time. If you guys still encounter similar issues, feel free to ask me!

Upvotes: 1

Related Questions