在Eclipse中更改构建配置时,是否有办法强制Android NDK重建特定库?
我正在使用Android NDK构建一个Android项目来构建C ++库。我正在使用Eclipse和Sequoyah插件。一切都已建立并运作良好。
但是,我遇到了构建配置的问题。您可以通过右键单击project->属性来管理构建配置,然后转到C / C ++ Build部分。这允许您创建大多数C ++库以某种方式依赖的传统Debug和Release构建。
以下是我的“调试”配置示例:
V=1 NDK_DEBUG=1 NDK_APPLICATION_MK=config/debug/Application.mk
这些工作很好,除了当我在配置之间来回切换时,它不会触发我正在构建的库的重建。对于像Visual Studio这样的东西,每个构建配置转储到不同的目录,但是在Eclipse中,所有东西都被转储到同一目录。我被迫实际更改相关的源文件以触发重建。所以最终发生的事情是我最终在Debug配置中运行(例如),但链接到Release中构建的库。
所以我的问题是:有没有办法在更改配置时强制NDK重建库?我知道我可以添加的-B命令,但是重建了所有内容,每次。如果我可以只为一个特定的库(在本例中为libBootInfo)做这件事,我每次都可以重建。
以下是我的根Android.mk文件的样子:
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := game$(MY_BUILD_CONFIG_EXTENSION)
# Include files are relative to the NDK root directly (fix by prepending with $(LOCAL_PATH))
# Source files are relative $(LOCAL_PATH)
#LOCAL_LDLIBS := -landroid
# Add all source file names to be included in lib separated by a whitespace
LOCAL_SRC_FILES := ../../../../../../engine/code/main/mainandroid.cpp
# Module dependencies are expressed with LOCAL_STATIC_LIBRARIES and LOCAL_SHARED_LIBRARIES.
# we're building the "main" entry point, so it doesn't depend on much
LOCAL_STATIC_LIBRARIES := libDebug$(MY_BUILD_CONFIG_EXTENSION) libCore$(MY_BUILD_CONFIG_EXTENSION)
include $(BUILD_SHARED_LIBRARY)
$(call import-module,libBdCore)
$(call import-module,libDebug)
##################################################################
## In addition to the core game library, we also build another
## *.so file here: "libBootInfo". This very small library is used
## by Java to find out which version of game to load based on
## the current build configuration.
##
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := libBootInfo
# Add all source file names to be included in lib separated by a whitespace
# TODO: This path is relative to "android-ndk\build\core" which seems
# different from the LOCAL_SRC_FILES in game above. It seems like
# the build process leaves us in a different directory than we started.
# We make need to look into a way to make sure that this path always
# works regardless of what came before it.
#
LOCAL_SRC_FILES := ../../../../engine/code/main/bootinfo.cpp
include $(BUILD_SHARED_LIBRARY)
答案 0 :(得分:2)
NDK构建始终会刷新lib/armeabi
中的 .so 库。另一方面,obj
目录包含用于每个模块的调试和发布版本的单独树。
不幸的是,如果你的Android.mk
做了tge框架不支持的事情,那么很容易搞砸这个设置。
例如,在您的情况下,cpp文件(../../../..
)的长路径可能是一个坏主意。我建议为每个模块设置LOCAL_PATH
,并避免../
中的LOCAL_SRC_FILES
。
以下是我对Android.mk建议的更改:
ANDROID_MK_PATH := $(call my-dir)
LOCAL_PATH := $(ANDROID_MK_PATH)/../../../engine/code/main
include $(CLEAR_VARS)
LOCAL_MODULE := game$(MY_BUILD_CONFIG_EXTENSION)
LOCAL_SRC_FILES := mainandroid.cpp
LOCAL_STATIC_LIBRARIES := libDebug$(MY_BUILD_CONFIG_EXTENSION) libCore$(MY_BUILD_CONFIG_EXTENSION)
include $(BUILD_SHARED_LIBRARY)
##################################################################
## In addition to the core game library, we also build another
## *.so file here: "libBootInfo". This very small library is used
## by Java to find out which version of game to load based on
## the current build configuration.
##
include $(CLEAR_VARS)
LOCAL_MODULE := libBootInfo
LOCAL_SRC_FILES := bootinfo.cpp
include $(BUILD_SHARED_LIBRARY)
$(call import-module,libBdCore)
$(call import-module,libDebug)
UPDATE :实际上,在我看来,使用模块名称后缀来分隔构建配置是最佳解决方案。此方法允许您一次构建和部署多个配置。例如,当我必须优化Tegra(没有Neon)或Snapdragon(使用Neon)时,我会使用它:直到最近,在Play商店中放置两个单独的APK并不容易,因此我打包了两个libv-neon.so
和libv-tegra.so
lib/armeabi-v7a
。
我不知道你的 BootInfo 库包含什么逻辑,但是如果你只是部署一个库,你可以避免在Java类静态构造函数中使用以下代码的所有麻烦:
static {
boolean loaded = false;
while (!loaded) {
try {
System.loadLibrary("game" + nextExtensionAttempt);
loaded = true;
}
catch (Exception ex) {
}
}
}
另一种方法是覆盖输出目录./obj
。为此,您可以将以下行添加到Application.mk
文件中:
NDK_APP_OUT := obj$(MY_BUILD_EXTENSION)
这样,所有.obj
,.a
和.so
个文件(在安装到libs/armeabi
之前)都将放入每个配置单独的目录。更简单的是,您可以在NDK_OUT
命令行上提供ndk-build
参数,例如
ndk-build V=1 NDK_OUT=obj${MY_BUILD_EXTENSION}
如果您使用Eclipse来维护和选择配置,这非常容易。这使得Java可以轻松加载模块,因为它始终具有相同的名称。但是您一次只能部署单个配置。
答案 1 :(得分:0)
我从来没能把这个工作做得很好。最后我刚刚创建了一个批处理文件,它写出了一个空的源文件。该批处理文件作为Eclipse中构建步骤的一部分执行。然后我将源文件包含在我的库中。由于每次构建时都会更改时间戳,因此每次都会强制ndk重建该库。我确保库保持很小,大多数代码都存在于其他库中,这使得构建时间非常短。