Android.如何检查一个模块是否已经存在

Android.mk: How to check if a module already exists

本文关键字:存在 模块 是否 一个 何检查 检查 Android      更新时间:2023-10-16

我正在尝试生成Android。Mk文件自动用于现有的构建环境。这个环境有许多库相互链接,也可能链接到第三方库(如boost)。

假设我有libA使用boost。我的目标是通过从libB文件夹运行ndk-build来构建libAlibB

生成这个Android。mk for libA:

LOCAL_PATH := $(call my-dir)
# Import boost
include $(CLEAR_VARS)
LOCAL_MODULE    := boost_atomic
LOCAL_SRC_FILES := ../dev/libcpp/boost/1.60.1/lib/libboost_atomic.a
include $(PREBUILT_STATIC_LIBRARY)
# libA:
include $(CLEAR_VARS)
LOCAL_MODULE    := libA
LOCAL_SRC_FILES := libA.cpp
LOCAL_C_INCLUDES := ../dev/libcpp/boost/1.60.1
# boost import:
LOCAL_CPPFLAGS += -DHAVE_CONFIG_H -fexceptions -frtti
LOCAL_STATIC_LIBRARIES += boost_atomic
# build libA:
include $(BUILD_SHARED_LIBRARY)

现在我有libB使用boostlibAlibBAndroid.mklibA的非常相似,只是我增加了libA文件的导入,如下所示:

# Import libA
include $(CLEAR_VARS)
LOCAL_MODULE := libA
include ../../libA/jni/Android.mk

当我尝试制作libB时,我被报告:

Android NDK: Trying to define local module 'boost_atomic' in ../../libA/jni/Android.mk.
Android NDK: But this module was already defined by ../../libA/jni/Android.mk.
B:/Android/android-ndk-r11b/build//../build/core/build-module.mk:34: *** Android
 NDK: Aborting.    .  Stop.

我是否有办法检查boost_atomic是否已经定义(如if (exists boost_atomic)),以确保它只定义一次?或者我是否应该为所有名称加上后缀(以boost_system_for_libAboost_system_for_libB结尾)以防止冲突?或者有其他选择吗?

您有一个NDK函数$(modules_get_list)。依靠它,你的libA/jni/Android。mk文件可能如下所示:

LOCAL_PATH := $(call my-dir)
include ../../boost/Android.mk
# libA:
include $(CLEAR_VARS)
LOCAL_MODULE    := libA
LOCAL_SRC_FILES := libA.cpp
# boost import:
LOCAL_STATIC_LIBRARIES += boost_atomic
# build libA:
$(if $(call set_is_member,$(modules-get-list),$(LOCAL_MODULE)),
    ,$(eval include $(BUILD_SHARED_LIBRARY)))

增加/Android。可文件:

LOCAL_PATH := $(call my-dir)
# Import boost
include $(CLEAR_VARS)
LOCAL_MODULE    := boost_atomic
LOCAL_SRC_FILES := ../dev/libcpp/boost/1.60.1/lib/libboost_atomic.a
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/../dev/libcpp/boost/1.60.1
LOCAL_EXPORT_CPPFLAGS += -DHAVE_CONFIG_H -fexceptions -frtti
$(if $(call set_is_member,$(modules-get-list),$(LOCAL_MODULE)),
    ,$(eval include $(PREBUILT_STATIC_LIBRARY))
最后,

libB/jni Android.mk :

LOCAL_PATH := $(call my-dir)
include ../../boost/Android.mk
include ../../libA/jni/Android.mk
# libB:
include $(CLEAR_VARS)
LOCAL_MODULE    := libB
LOCAL_SRC_FILES := libB.cpp
# boost import:
LOCAL_STATIC_LIBRARIES += boost_atomic
# build libA:
$(if $(call set_is_member,$(modules-get-list),$(LOCAL_MODULE)),
    ,$(eval include $(BUILD_SHARED_LIBRARY)))

我不喜欢第三方预构建库的重复定义,比如boost,而是使用单独的Android。mk定义,并在必要时使用include。这样,如果外部库更新了,我就有一个地方可以更改。

更新:如果你不喜欢$(if …)语法,你可以使用

ifeq ($(filter $(modules-get-list),$(LOCAL_MODULE)),)
    include $(BUILD_…_LIBRARY)
endif

正如Alex Cohn所提到的,可以通过替换:

include $(CLEAR_VARS)
LOCAL_MODULE    := boost_atomic
LOCAL_SRC_FILES := ../dev/libcpp/boost/1.60.1/lib/libboost_atomic.a
include $(PREBUILT_STATIC_LIBRARY)
...
# boost import:
LOCAL_CPPFLAGS += -DHAVE_CONFIG_H -fexceptions -frtti
LOCAL_STATIC_LIBRARIES += boost_atomic
由简单:

LOCAL_LDLIBS += ../dev/libcpp/boost/1.60.1/lib/libboost_atomic.a

可以,但是:

  • 引入编译警告:

    警告:/用户/jwalton/Android-CryptoPP/jni/Android.mk: prng:链接器标志中的非系统库:-lcryptopp -lstlport_shared
    这很可能导致不正确的构建。尝试使用LOCAL_STATIC_LIBRARIES
    类的库依赖项当前模块

  • 不能用于共享第三方库

所以我终于解决了这个问题,我添加了一个新的mk文件特定于libA, libB:

libAAndroid.mk现在:

LOCAL_PATH := $(call my-dir)
# Import boost
include $(CLEAR_VARS)
LOCAL_MODULE    := boost_atomic
LOCAL_SRC_FILES := ../dev/libcpp/boost/1.60.1/lib/libboost_atomic.a
include $(PREBUILT_STATIC_LIBRARY)
include libA.mk

libAlibA.mk是现在:

LOCAL_PATH := $(call my-dir)
# libA:
include $(CLEAR_VARS)
LOCAL_MODULE    := libA
LOCAL_SRC_FILES := libA.cpp
LOCAL_C_INCLUDES := ../dev/libcpp/boost/1.60.1
# boost link:
LOCAL_CPPFLAGS += -DHAVE_CONFIG_H -fexceptions -frtti
LOCAL_STATIC_LIBRARIES += boost_atomic
# build libA:
include $(BUILD_SHARED_LIBRARY)

libBlibB.mk现在有:

# Import libA
include $(CLEAR_VARS)
LOCAL_MODULE := libA
include ../../libA/jni/libA.mk

使其导入libA而不导入boost(也在libBAndroid.mk中定义)。

我正在尝试生成Android。Mk文件自动为已存在的构建环境。这个环境有许多库链接到每个库其他也可能链接到第三方库(如boost)。

为什么不使用独立的NDK工具链,而不是痛苦地处理Android.mk文件?听起来独立的工具链非常适合您的情况。