1. 程式人生 > >Gradle快速構建(二)gradle構建NDK編譯環境

Gradle快速構建(二)gradle構建NDK編譯環境

在我的文章如何使用AndroidStudio-Cmake中有說過在gradle配置jni環境,本章主要更加細緻的介紹如何配置一些自定義的選項,比如選擇ndk版本編譯,編譯不同的庫,cmake編譯下配置引用不同的C++ libd等。

文章目錄


具體的一些語法請參照我的Groovy語法學習兩章

一 mk編譯下自定義ndk編譯指令

在釋出我們的lib庫時,想給別人,但是可能考慮到人家沒有配置ndk全域性環境變數怎麼辦,我們可以通過從local.properties中獲取,當前AS NDK的配置路徑,去手動指定ndk編譯器編譯j’ni庫,當然,這是基於Android.mk編譯jni的情況下

注意配置NDK許可,這個在新版本被去除了,改成了通過externalNativeBuild 宣告,老版本是在gradle.properties新增:

android.useDeprecatedNdk=true

1. 獲取NDK路徑

  • 在gradle根目錄下新增

      String getNdkBuildPath() {
      	Properties properties = new Properties()
      	properties.load(project.rootProject.file('local.properties').newDataInputStream())
      	def ndkBuildingDir = properties.getProperty("ndk.dir")
      	def ndkBuildPath = ndkBuildingDir
      	if (Os.isFamily(Os.FAMILY_WINDOWS)) {//需要判斷系統版本
      		ndkBuildPath = ndkBuildingDir + '/ndk-build.cmd'
      	} else {
      		ndkBuildPath = ndkBuildingDir + '/ndk-build'
      	}
      	return ndkBuildPath
      }
    

2. 執行ndk編譯指令

task ndkBuild(type: Exec, description: 'Compile JNI source') {
	println('executing ndkBuild')
	def ndkBuildPath = getNdkBuildPath();
	commandLine ndkBuildPath, '-j8', '-C', file('src/main').absolutePath
}

tasks.withType(JavaCompile) {
	compileTask -> compileTask.dependsOn ndkBuild
}

task ndkClean(type: Exec, description: 'clean JNI libraries') {
	println('executing ndkBuild clean')
	def ndkBuildPath = getNdkBuildPath();
	commandLine ndkBuildPath, 'clean', '-C', file('src/main').absolutePath
}

clean.dependsOn 'ndkClean'

3. 指定靜態庫的引用路徑

通過上述任務執行編譯,基於.mk的編譯指令碼,通過執行ndk庫編譯,它生成的靜態庫檔案也位於mian/src/libs,我們知道AS的預設引用路徑在jniLibs,所以我們還需要指定.so的引用路徑。以及去除AS對jni的自動編譯選項

sourceSets.main {
	jniLibs.srcDir 'src/main/libs'
	jni.srcDirs = [] //disable automatic ndk-build call
}

二 cmake編譯選項配置

cmake用起來感覺比mk指令碼方便一點,在某些大型jni專案時,更具靈活性,我們在編譯jni程式碼時,可以在CMakeLists.txt中配置幾乎所有引數,當然,也可以選擇將一部分配置放到gradle中配置,這樣可以更直觀的看到我們配置引數,並且修改起來也更加方便。

1.配置AS編譯方式

  • 選擇CMakeLists.txt編譯方式

      android {
      	externalNativeBuild {
      	  cmake {
      	      path "CMakeLists.txt"
      	  }
      	} 
      }
    
  • android.mk編譯方式

      externalNativeBuild {
          ndkBuild {
              path 'src/main/jni/Android.mk'  //你的android.mk目錄
              path 'src/main/jni/Application.mk'  //Application.mk目錄
          }
      }
    

2.配置C++編譯引數

指定一些編譯巨集引數和格式,指定編譯的平臺版本

android {
	defaultConfig {    
		// This block is different from the one you use to link Gradle
		// to your CMake or ndk-build script.
		externalNativeBuild {
			// For ndk-build, instead use ndkBuild {}
			cmake {
			  // Cmake可選引數
			  arguments "-DANDROID_ARM_NEON=TRUE", "-DANDROID_TOOLCHAIN=clang"
			
			  // 選擇C編譯的標記,選一個即可
			  cFlags "-D_EXAMPLE_C_FLAG1", "-D_EXAMPLE_C_FLAG2"
			
			  // C ++巨集常量格式
			  cppFlags "-D__STDC_FORMAT_MACROS"
			}
		}
	ndk {
		// 指定編譯的ABI,選擇你專案需要的abi即可
		abiFilters 'x86', 'x86_64', 'armeabi', 'armeabi-v7a',
	         'arm64-v8a'
	}
}

3.JNI分包打包配置

gradle android根目錄

//分包打包,可指定不同的編譯版本
productFlavors {   
  one {
    externalNativeBuild {
      cmake {
        targets "native-lib-1"
      }
    }
  }
  two {     
    externalNativeBuild {
      cmake {        
        targets "native-lib-2"
      }
    }
  }
}