如果我为一个ABI构建我的AndroidStudio,它会按预期工作。
如果我支持两个ABI,比如">armeabi-v7a"和"arm64-v8a",那么Android Studio每次都会重建每个文件,即使没有任何变化。
我使用 CMake 外部构建来用于应用的本机部分。
我的成绩档案:
android {
compileSdkVersion 26
buildToolsVersion '26.0.2'
defaultConfig {
applicationId "com.steenriver.biplane"
minSdkVersion 19
targetSdkVersion 19
versionCode 115
versionName "1.15"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
ndk {
//abiFilters 'x86', 'x86_64', 'armeabi', 'armeabi-v7a', 'arm64-v8a'
abiFilters 'armeabi-v7a', 'arm64-v8a'
//abiFilters 'arm64-v8a'
//abiFilters 'armeabi-v7a'
}
externalNativeBuild {
cmake {
//ldFlags "-Wl,-fuse-ld=gold"
cppFlags "-std=c++11 -DANDROID=1 -DPLAY=1 -DUSEES3=1 -DLOGTAG=biplane"
arguments "-DCMAKE_VERBOSE_MAKEFILE=1", "-DANDROID_TOOLCHAIN=clang", "-DANDROID_ARM_NEON=TRUE", "-DANDROID_ARM_MODE=arm"
}
}
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
debug {
externalNativeBuild {
cmake {
cppFlags += "-DDEBUG -DSHOWGRAPHS"
}
}
}
}
externalNativeBuild {
cmake {
path '../jni/CMakeLists.txt'
}
}
}
还有我的顶级CMakeList.txt:
cmake_minimum_required(VERSION 3.4.1)
# dependency: dblunt
set( dblunt_src_DIR $ENV{HOME}/src/dutch-blunt/src )
set( dblunt_build_DIR $ENV{HOME}/src/dutch-blunt/src/output )
file(MAKE_DIRECTORY ${dblunt_build_DIR})
add_subdirectory( ${dblunt_src_DIR} ${dblunt_build_DIR} )
# dependency: GBase
set( gbase_src_DIR $ENV{HOME}/apps/GBase/src )
set( gbase_build_DIR $ENV{HOME}/apps/GBase/src/output )
file(MAKE_DIRECTORY ${gbase_build_DIR})
add_subdirectory( ${gbase_src_DIR} ${gbase_build_DIR} )
# dependency: PI
set( pi_src_DIR ../../PI )
set( pi_build_DIR ../../PI/output )
file(MAKE_DIRECTORY ${pi_build_DIR})
add_subdirectory( ${pi_src_DIR} ${pi_build_DIR} )
# dependency uif
set( uif_src_DIR ../../../uif )
set( uif_build_DIR ../../../uif/output )
file(MAKE_DIRECTORY ${uif_build_DIR})
add_subdirectory( ${uif_src_DIR} ${uif_build_DIR} )
# dependency gpgoap
set( gpgoap_src_DIR $ENV{HOME}/src/GPGOAP )
set( gpgoap_build_DIR $ENV{HOME}/src/GPGOAP/output )
file(MAKE_DIRECTORY ${gpgoap_build_DIR})
add_subdirectory( ${gpgoap_src_DIR} ${gpgoap_build_DIR} )
# dependency: OpenDE
set( opende_src_DIR $ENV{HOME}/src/opende )
set( opende_build_DIR $ENV{HOME}/src/opende/output )
file(MAKE_DIRECTORY ${opende_build_DIR})
add_subdirectory( ${opende_src_DIR} ${opende_build_DIR} )
# dependency: OpenAL
set( openal_src_DIR $ENV{HOME}/src/openal-soft/jni )
set( openal_build_DIR $ENV{HOME}/src/openal-soft/jni/output )
file(MAKE_DIRECTORY ${openal_build_DIR})
add_subdirectory( ${openal_src_DIR} ${openal_build_DIR} )
# dependency: freealut
set( freealut_src_DIR $ENV{HOME}/src/freealut/src )
set( freealut_build_DIR $ENV{HOME}/src/freealut/src/output )
file(MAKE_DIRECTORY ${freealut_build_DIR})
add_subdirectory( ${freealut_src_DIR} ${freealut_build_DIR} )
# depencency: gpg (prebuilt, provided by Google)
add_library( gpg
STATIC
IMPORTED
)
set_target_properties( gpg
PROPERTIES IMPORTED_LOCATION
$ENV{HOME}/src/gpg-cpp-sdk/android/lib/gnustl/${ANDROID_ABI}/libgpg.a )
set ( CMAKE_SHARED_LINKER_FLAGS "-fuse-ld=gold ${CMAKE_SHARED_LINKER_FLAGS}" )
# now build app's shared lib
add_library(biplane SHARED
main.cpp
StateManager.cpp
scorekeeper.cpp
)
target_include_directories(biplane PRIVATE
$ENV{HOME}/src/gpg-cpp-sdk/android/include
$ENV{HOME}/apps/GBase/src
$ENV{HOME}/apps/GBase/src/Android
$ENV{HOME}/src/stb
../../PI
.
)
# add lib dependencies
target_link_libraries(biplane
gpg
pi
uif
gbase
dblunt
gpgoap
opende
freealut
openal
EGL
GLESv3
OpenSLES
android
log
z
m
)
如何说服 Android Studio 仅重新编译已更改的文件?
这是由于构建变体都具有相同的 .o 文件输出目录这一事实造成的。
您需要将构建目录拆分为发布/调试和不同的 ABI。
执行此操作的方法是使用 CMAKE_CURRENT_BINARY_DIR 宏,如下所示:
set( gpgoap_src_DIR $ENV{HOME}/src/GPGOAP )
add_subdirectory( ${gpgoap_src_DIR} ${CMAKE_CURRENT_BINARY_DIR}/gpgoap )
如果这样做,则 arm7 调试对象文件将最终位于: app/.externalNativeBuild/cmake/debug/armeabi-v7a
这样他们就不会与其他 ABI 发生冲突。
请注意,您不能重复使用输出目录,因此您需要为每个 add_subdirectory(( 后缀它们。
最后一点:cmake 文档说输出目录对于 add_subdirectory(( 是可选的,但我发现情况并非如此。您需要至少提供两个参数。