2017-06-18 36 views
1

Android NDKを使用して実行可能ファイルをビルドしようとしています。これを行うために、私は "Android Library"プロジェクトを作成し、自分のすべてのネイティブコード(cpp)ファイルを "src/main/cpp"というディレクトリの下に含めました。Androidで実行可能なビルドNDK

CMakeLists.txtファイルに、次のものを追加しました。私はビルドを実行すると

cmake_minimum_required(VERSION 3.4.1) 

set (TEST_SRC 
    src/test/cpp/test.cpp 
) 

add_library (test-lib SHARED ${TEST_SRC}) 
add_executable(test-exec ${TEST_SRC}) 

、私は図書館が私のビルド出力ディレクトリ(libtest-lib.so)で正しく作成されていることがわかり、しかし、実行ファイルが生成されていません。

コマンドライン(./gradlew clean build --info --debug)でプロジェクトをビルドし、次のログメッセージが見つかりました。

externalNativeBuildRelease: not building target test-exec because no 
targets are specified and library build output file extension isn't 
'so'. 

アンドロイドNDKは、意図的に構築されてからの私の実行を無効にされているようです:(これを回避する方法はありますか私は間違って

答えて

2

UPDATE何かを指定しました:?私はこの答えを掲載するので?を私はより洗練された解決策を見つけました。Android.mkファイル内の何かを変更する必要はありません。app/build.gradleの関連部分です(元のgradleスクリプトはsyncopoli projectに属しています。このbuild.gradleスクリプトhere

android { 

    defaultConfig { 
     // ... 

     externalNativeBuild { 
      ndkBuild { 
       // I only want the following targets to be built 
       targets 'rsync', 'ssh' 
      } 
     } 

     ndk { 
      // add whatever ABIs you want here 
      abiFilters 'armeabi' 
     } 
    } 

    externalNativeBuild { 
     ndkBuild { 
      // all my external sources are under src/main/jni 
      path 'src/main/jni/Android.mk' 
     } 
    } 
} 

// this is the meat. It copies the binaries to appropriate location 
// after externalNativeBuildRelease task is finished. 
// you can change the paths to match where your binaries live and where 
// you want them to go 
gradle.taskGraph.afterTask { task -> 
    if (task.name == "externalNativeBuildRelease") { 
     def src = rootProject.file('app/build/intermediates/ndkBuild/release/obj/local/') 
     def dst = rootProject.file('app/src/main/assets/') 

     copy { 
      from(src) { 
       // the objs directory has all the .o files I don't care about 
       exclude "**/objs" 
      } 

      into dst 

      // this is purely for debugging purposes. it might come in handy 
      eachFile { 
       println "file = " + it.getPath() 
      } 
     } 

    } 
} 

src/main/jni/Android.mkあり、以下の内容:

include $(call all-subdir-makefiles) 

前の回答

私はこの問題をヒットし、手動ndk-buildや設定を呼び出すのGradleで余分なタスクを作成することによって、その周りに働いていますこれらのタスクに依存するプロジェクト。

これはapp/build.gradleの関連する部分である:

import org.apache.tools.ant.taskdefs.condition.Os 

Properties properties = new Properties() 
properties.load(project.rootProject.file('local.properties').newDataInputStream()) 

task ndkBuild(type: Exec) { 
    def ndkDirProperty = properties.getProperty('ndk.dir') 
    def ndkDirPrefix = ndkDirProperty != null ? ndkDirProperty + '/' : '' 

    def ndkBuildExt = Os.isFamily(Os.FAMILY_WINDOWS) ? ".cmd" : "" 

    commandLine "${ndkDirPrefix}ndk-build${ndkBuildExt}", '-C', file('src/main').absolutePath, 
      '-j', Runtime.runtime.availableProcessors() 
} 

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

// Cleanup task to remove previously generated binaries 
task ndkClean(type: Exec) { 
    def ndkDirProperty = properties.getProperty('ndk.dir') 
    def ndkDirPrefix = ndkDirProperty != null ? ndkDirProperty + '/' : '' 

    def ndkBuildExt = Os.isFamily(Os.FAMILY_WINDOWS) ? ".cmd" : "" 

    commandLine "${ndkDirPrefix}ndk-build${ndkBuildExt}", '-C', file('src/main').absolutePath, 'clean' 
} 

tasks.withType(Delete) { 
    cleanTask -> cleanTask.dependsOn ndkClean 
} 

最終実行可能ファイルはassets/<target_arch_abi>/<executableで終わるので、私はさらに実行可能ファイルのAndroid.mkファイルを変更しました。今

SAVED_NDK_APP_DST_DIR := $(NDK_APP_DST_DIR) 
NDK_APP_DST_DIR := assets/$(TARGET_ARCH_ABI) 
...LOCAL_MODULE/LOCAL_CFLAGS/LOCAL_etc... 
include $(BUILD_EXECUTABLE) 
NDK_APP_DST_DIR := $(SAVED_NDK_APP_DST_DIR) 

gradlew buildを実行すると、残りの部分と一緒に実行ファイルを作成します。

これが役に立ちます。

関連する問題