[英]How to prevent from C++ to recompile all files in Android NDK?
Hello, 你好,
I'm using the Android Studio with NDK and JNI in a project with a large amount of C++ files. 我在带有大量C ++文件的项目中使用带有NDK和JNI的Android Studio。 When I make changes in a single C++ file it won't apply in the code unless I rebuild the whole project and refresh the entire C++ files so they have to recompile.
当我在单个C ++文件中进行更改时, 除非重新构建整个项目并刷新整个C ++文件, 否则它们将不会应用在代码中,因此必须重新编译它们。 The compilation process takes more than 3 minutes for every small change, make it 20 times a day and you have lost an hour.
每次小的更改,编译过程都会花费3分钟以上的时间,每天进行20次,而您却损失了一个小时。
According to today, after I make a change to a file I go to 根据今天,在我更改文件后,我转到
Build >> Refresh Linked C++ Projects, 构建>>刷新链接的C ++项目,
and then run the project, resulting in a full, redundant compilation of all files. 然后运行该项目,从而对所有文件进行完整的冗余编译。
I'm looking for way for the compiler to refresh only the changed file, and as a result shorten the build process. 我正在寻找编译器仅刷新更改的文件的方法,因此缩短了构建过程。
NOTE: This problem only occurs in windows, when I run Android Studio on a Mac, the compiler recompiles only the relevant files. 注意:此问题仅出现在Windows中,当我在Mac上运行Android Studio时,编译器仅重新编译相关文件。
This is my CMakeLists.txt file: 这是我的CMakeLists.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)
And my gradle.build file: 和我的gradle.build文件:
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'
}
Thanks in advance! 提前致谢!
I think this has been a problem for a long time (judging by the complaints) in Android Studio (more specifically the NDK
build system). 我认为这在Android Studio(更具体而言是
NDK
构建系统)中已经存在很长时间了 (根据投诉来判断)。 Now, in the latest version, it is finally ready and working (hopefully). 现在,在最新版本中,它终于可以使用了(希望如此)。
Note: gradlew
builds are significantly faster than using the Android Studio IDE
, and can be built using a batch file script ( .bat
). 注意:
gradlew
构建要比使用Android Studio IDE
快得多,并且可以使用批处理文件脚本( .bat
)构建。
(P1) Android Studio
rebuilds everything every time if multiple ABIs are supported See this SO Q/A . (P1)如果支持多个ABI,
Android Studio
每次都会重新构建所有内容。请参阅此SO Q / A。
(C1) Build variants all had the same output directory for the .o files. (C1)构建变体的.o文件都具有相同的输出目录。
(S1) You need to split out the build directory into release/debug and into the different ABIs. (S1)您需要将构建目录拆分为release / debug和不同的ABI。
Android Studio 3.1
, NDK release 10
, gradle
version 4.4 (plugin 3.1.0) Android Studio 3.1
, NDK release 10
, gradle
版本4.4(插件3.1.0)
I have 2 libraies to build ( libhello_world.so
with 1 c++ file, and libjni_photoeditor.so
with 24 c++ files). 我有2个libraies构建(
libhello_world.so
用1个C ++文件,和libjni_photoeditor.so
24个C ++文件)。
I am using externalNativeBuild
-> ndkBuild
to build my native code (you could use CMake
also, I have not tested that). 我正在使用
externalNativeBuild
> ndkBuild
来构建我的本机代码(您也可以使用CMake
,但我尚未对此进行测试)。
app level build.gradle
: 应用程序级别
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
: Application.mk
:
APP_ABI := armeabi-v7a
APP_PLATFORM := android-19
APP_STL := stlport_static
Android.mk
: 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)
Build -> Build APK(s)
build Build -> Build APK(s)
build (A) Modify one of my projects 24 C++
files ( quantize.cpp
) and rebuild. (A) 修改我的项目之一的24个
C++
文件( quantize.cpp
)并重建。
(B) Build -> Build APK(s)
(B)
Build -> Build APK(s)
(C) Only the C:\\Android\\PhotoRend1\\app\\build\\intermediates\\ndkBuild\\debug\\obj\\local\\armeabi-v7a\\objs-debug\\jni_photoeditor\\quantize.o timestamp changed (and the library). (C)仅更改了C:\\ Android \\ PhotoRend1 \\ app \\ build \\ intermediates \\ ndkBuild \\ debug \\ obj \\ local \\ armeabi-v7a \\ objs-debug \\ jni_photoeditor \\ quantize.o时间戳(和库)。
gradlew
terminal window (command line) build gradlew
终端窗口(命令行)构建 From the project root I use gradlew
in a terminal window
to assemble
my apk
. 从项目根目录,我在
terminal window
使用gradlew
assemble
我的apk
。
(1) Every thing is up-to-date build: (1)每件事都是最新的版本:
C:\\Android\\PhotoRend1>gradlew assembleDebug
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) Modify one of my projects 24 C++
files (quantize.cpp) and re-assemble. (2) 修改我的项目之一24个
C++
文件(quantize.cpp)并重新组装。
(3) One file changes is up-to-date build: (3)一个文件更改是最新版本:
C:\\Android\\PhotoRend1>gradlew assembleDebug
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) As you can see it did an incremental build. (4)如您所见,它进行了增量构建。
Structure (with abiFilters 'x86', 'armeabi-v7a'
): 结构(使用
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
Some links: Manual NDK
updates 一些链接: 手动
NDK
更新
Finally I have found the cause to the problem. 最后,我找到了问题的原因。
In my project I have worked with symlink C++ files. 在我的项目中,我使用了symlink C ++文件。 The NDK cannot immediately apply the changes made in these files and they won't be expressed in your app unless you rebuild the whole project.
NDK无法立即应用对这些文件所做的更改,除非您重建整个项目,否则它们不会在您的应用程序中表示出来。
The solution is to work with hard copy files. 解决方案是使用硬拷贝文件。
If I find some way to work correctly with symlink files it would be better for my needs. 如果我找到一些正确使用symlink文件的方法,则对我的需求会更好。 Until then I can at least edit single or multiple files without recompiling the whole project.
在此之前,我至少可以编辑一个或多个文件,而无需重新编译整个项目。
This is a relatively esoteric situation but might be helpful for someone in the future. 这是一个相对深奥的情况,但将来可能对某人有所帮助。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.