代码之家  ›  专栏  ›  技术社区  ›  Ariel Mann

如何防止C++在Android NDK中重新编译所有文件?

  •  11
  • Ariel Mann  · 技术社区  · 7 年前

    你好

    我正在一个包含大量C++文件的项目中使用Android Studio与NDK和JNI。当我在单个C++文件中进行更改时 除非我重建整个项目,否则它不会应用于代码中 并刷新整个 C++文件,因此它们必须重新编译。每做一个小改动,编译过程就需要3分钟以上,每天修改20次,这样你就浪费了一个小时。

    根据today,在我更改文件后

    构建(>)&燃气轮机;刷新链接的C++项目,

    然后运行项目,从而对所有文件进行完整、冗余的编译。

    我正在寻找编译器只刷新更改的文件的方法,从而缩短构建过程。

    注: 这个问题只发生在windows中,当我在Mac上运行Android Studio时,编译器只重新编译相关文件。

    这是我的简历。txt文件:

    cmake_minimum_required(VERSION 3.4.1)
    
    FILE(GLOB CPP_SRC
         "src/main/cpp/*.c"
         "src/main/cpp/*.h"
         "src/main/cpp/*.cpp"
         "src/main/cpp/*.hpp"
     )
    
    
    add_library(MyLib
    
                 SHARED
                 ${CPP_SRC} )
    
    find_library(
                  log-lib
                  log )
    
    target_link_libraries(
                           MyLib
    
                           ${log-lib} )
    
    target_link_libraries(MyLib
                          android
                          log
                          EGL
                          GLESv2)
    

    还有我的格拉德尔。生成文件:

    apply plugin: 'com.android.library'
    
    android {
        signingConfigs {
            config {
                keyAlias '*****'
                keyPassword '*****'
                storeFile file(*****)
                storePassword '*****'
            }
        }
        compileSdkVersion 27
        buildToolsVersion '27.0.3'
        defaultConfig {
    
        minSdkVersion 16
        targetSdkVersion 27
        versionCode 1
    
        versionName "1.0"
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
    
        externalNativeBuild {
            cmake {
    
                arguments "-DANDROID_ARM_NEON=TRUE", "-DANDROID_TOOLCHAIN=clang", "-DANDROID_STL=c++_shared", "-DCMAKE_BUILD_TYPE=Release", "-DANDROID_CPP_FEATURES=rtti exceptions"
                cppFlags "-D__STDC_FORMAT_MACROS", '-Ofast', '-fsigned-char', "-std=c++14", "-frtti", "-fexceptions", "-mtune=arm7", "-mfpu=vfpv3-d16", "-mfloat-abi=softfp", "-Wall",
                        "-DCOMPILE_EUROPE_ID_AND_FACE_OCR_MANAGER",
                        "-DCOMPILE_FRENCH_PASSPORT_SIGNATURE",
                        "-DCOMPILE_FRENCH_ID_BACK_OCR",
                        "-DCOMPILE_FRENCH_PASSPORT_SIGNATURE_MANAGER",
                        "-DCOMPILE_PASSPORT_AND_FACE_OCR_MANAGER",
                        "-DCOMPILE_MRZ_OCR",
                        "-DCOMPILE_FRENCH_ID_BACK_OCR_MANAGER"
            }
    
            ndk {
                abiFilters 'x86', 'armeabi-v7a'
            }
        }
    
        splits {
            abi {
                enable true
                reset()
                include 'x86', 'armeabi-v7a'
                universalApk true
            }
        }
    }
        buildTypes {
           release {
                minifyEnabled false
                proguardFiles getDefaultProguardFile('proguard-android.txt'), 
               'proguard-rules.pro'
                signingConfig signingConfigs.config
        }
    }
        externalNativeBuild {
            cmake {
                path "CMakeLists.txt"
            }
        }
    
        libraryVariants.all { variant -> variant.outputs.all { output -> 
        outputFileName = "${"libScanovateImaging"}.aar" }
            }
        }
    
        allprojects {
                repositories {
                jcenter()
                maven {
                    url "https://maven.google.com"
                }
            }    
        }
        dependencies {
            implementation 'com.google.android.gms:play-services-vision:15.0.0'
            implementation 'com.android.support:recyclerview-v7:27.1.1'
            implementation fileTree(dir: 'libs', include: ['*.jar'])
            implementation 'com.android.support.constraint:constraint-layout:1.1.0-beta6'
            implementation 'com.android.support:appcompat-v7:27.1.1'
            implementation 'com.android.support:design:27.1.1'
    
    }
    

    提前感谢!

    2 回复  |  直到 7 年前
        1
  •  3
  •   Jon Goodwin    7 年前

    介绍

    我认为这是一个问题 长时间 (根据投诉判断)在Android Studio(更具体地说 NDK 构建系统)。现在,在最新版本中,它终于准备好并开始工作了(希望如此)。

    注: gradlew 构建速度明显快于使用 Android Studio IDE ,并且可以使用批处理文件脚本生成( .bat ).

    C制造可能的问题(P=问题,C=原因,S=解决方案)

    (P1) Android Studio 如果支持多个ABI,则每次都会重建所有内容请参见 this SO Q/A .
    (C1)构建变体都具有相同的输出目录。o文件。
    (S1)您需要将构建目录拆分为release/debug和不同的abi。

    我的设置(ndkBuild)

    Android Studio 3.1 , NDK release 10 , gradle 版本4.4(插件3.1.0)

    我有两个图书馆要建( libhello_world.so 使用1个c++文件 libjni_photoeditor.so 有24个c++文件)。

    我正在使用 externalNativeBuild -&燃气轮机; ndkBuild build 我的本机代码(您 能够 使用 CMake 此外,我还没有对此进行测试)。

    应用程序级别 build.gradle :

    apply plugin: 'com.android.application'
            android {
                compileSdkVersion 25
    
                defaultConfig {
                    applicationId "xxxxxxxxxxxxxxxxxxxxx"
                    minSdkVersion 16
                    targetSdkVersion 16
                    versionCode 1
                    versionName "1.0"
                    ndk {
                             abiFilters 'armeabi-v7a' //,'x86'
                    }//ndk
                }//defaultConfig
    
                buildTypes {
                    release {
                        minifyEnabled true
                        proguardFiles.add(file('proguard-android-optimize.txt'))
                        proguardFiles.add(file('proguard-rules.pro'))
                    }//release
                    debug {
                        minifyEnabled false
                        jniDebuggable true
                        renderscriptDebuggable true
                    }//debug
                }//buildTypes
    
                externalNativeBuild {
                    // Encapsulates your CMake build configurations.
    //              cmake {
    //                // Provides a relative path to your CMake build script.
    //                path "src/main/cpp/CMakeLists.txt"
    //              }
                    ndkBuild {
                    //****this is the working build****
                        path 'src/main/cpp/Android.mk'
                    }//ndkBuild
                }//externalNativeBuild
            }//android
    
            dependencies {
            }//dependencies
    

    Application.mk :

    APP_ABI := armeabi-v7a
    APP_PLATFORM := android-19
    APP_STL := stlport_static
    

    Android.mk :

    #================================================
    LOCAL_PATH := $(call my-dir) #only call it ONCE !
    #================================================
    include $(CLEAR_VARS)
    LOCAL_MODULE      := hello_world
    LOCAL_MULTILIB := 32
    LOCAL_SRC_FILES :=  hello_world.cpp
    include $(BUILD_SHARED_LIBRARY)
    #================================================
    include $(CLEAR_VARS)
    LOCAL_MODULE      := libjni_photoeditor
    LOCAL_MODULE_TAGS := optional
    LOCAL_SHARED_LIBRARIES := libm liblog libjnigraphics
    LOCAL_LDLIBS := -lm -llog -ljnigraphics -lbcc
    LOCAL_LDLIBS := -lm -llog -ljnigraphics
    LOCAL_SRC_FILES := _jni.cpp utils.cpp quantize.cpp #etc.. 24 files
    LOCAL_CFLAGS := -Werror \
        -I$(OUT)/../../../../frameworks/compile/libbcc/include
    LOCAL_LDFLAGS := -L$(OUT)/system/lib
    include $(BUILD_SHARED_LIBRARY)
    

    测试1。Android Studio Build -> Build APK(s) 建筑

    (A) 修改 我的一个项目24 C++ 文件( quantize.cpp )和重建。

    (B) 构建->生成APK

    (C) 只有C:\Android\PhotoRend1\app\build\intermediates\ndkBuild\debug\obj\local\armeabi-v7a\objs debug\jni\u photoeditor\quantize。o时间戳已更改(和库)。

    测试2。 格拉德勒 终端窗口(命令行)生成

    从我使用的项目根目录 格拉德勒 在一个 terminal window assemble 我的 apk .

    (1) 一切都是最新版本:

    C: \Android\PhotoRend1>gradlew assembleDebug

    Starting a Gradle Daemon, 1 busy and 1 incompatible and 1 stopped Daemons could not be reused, use --status for details
    > Configure project :app
    > Task :app:externalNativeBuildDebug
    Build hello_world armeabi-v7a
    make.exe: `C:/Android/PhotoRend1/app/build/intermediates/ndkBuild/debug/obj/local/armeabi-v7a/libhello_world.so' is up to date.
    Build jni_photoeditor armeabi-v7a
    make.exe: `C:/Android/PhotoRend1/app/build/intermediates/ndkBuild/debug/obj/local/armeabi-v7a/libjni_photoeditor.so' is up to date.
    BUILD SUCCESSFUL in 3m 46s
    

    (2) 修改 我的一个项目24 C++ 文件(quantize.cpp)并重新组装。

    (3) 一个文件更改是最新版本:

    C: \Android\PhotoRend1>gradlew assembleDebug

    > Configure project :app
    > Task :app:externalNativeBuildDebug
    Build hello_world armeabi-v7a
    make.exe: `C:/Android/PhotoRend1/app/build/intermediates/ndkBuild/debug/obj/local/armeabi-v7a/libhello_world.so' is up to date.
    Build jni_photoeditor armeabi-v7a
    [armeabi-v7a] Compile++ thumb: jni_photoeditor <= quantize.cpp
    [armeabi-v7a] SharedLibrary  : libjni_photoeditor.so
    BUILD SUCCESSFUL in 59s
    

    (4) 正如您所看到的,它进行了增量构建。

    结构(带 abiFilters 'x86', 'armeabi-v7a' ):

    C:\Android\PhotoRend1\app\build\intermediates\ndkBuild
    |
    V
    └───debug
        └───obj
            └───local
                ├───armeabi-v7a
                │   └───objs-debug
                │       ├───hello_world
                │       └───jni_photoeditor
                └───x86
                    └───objs-debug
                        ├───hello_world
                        └───jni_photoeditor
    

    一些链接: Manual NDK updates

        2
  •  0
  •   Ariel Mann    6 年前

    我终于找到了问题的原因。

    在我的项目中,我与 symlink C++文件。 NDK无法立即应用在这些文件中所做的更改 除非重建整个项目,否则不会在应用程序中表达。

    解决方案是使用硬拷贝文件。

    如果我能找到一些方法来正确处理符号链接文件,那会更好 满足我的需要。在此之前,我至少可以编辑单个或多个文件,而无需重新编译整个项目。

    这是一个相对深奥的情况,但可能有助于 未来的某个人。