Android.mk:如何检查模块是否已经存在
我正在尝试为现有构建环境自动生成Android.mk文件。这个环境中有许多库相互链接,也可能链接到第三方lib(如boost) 假设我有Android.mk:如何检查模块是否已经存在,android,c++,android-ndk,Android,C++,Android Ndk,我正在尝试为现有构建环境自动生成Android.mk文件。这个环境中有许多库相互链接,也可能链接到第三方lib(如boost) 假设我有libA使用boost。 我的目标是通过从libB文件夹运行ndk build来构建libA和libB 因此,我为libA生成了这个Android.mk: LOCAL_PATH := $(call my-dir) # Import boost include $(CLEAR_VARS) LOCAL_MODULE := boost_atomic LOCAL
libA
使用boost。
我的目标是通过从libB文件夹运行ndk build来构建libA
和libB
因此,我为libA
生成了这个Android.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)
# 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)
现在,我使用了boost
和libA
,实现了libB
libB
的Android.mk与libA
非常相似,只是我添加了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\u-atomic
(比如if(exists-boost\u-atomic)
),以确保只定义一次?或者我应该为所有的名字加后缀(最后是boost\u system\u表示_libA
和boost\u system\u表示_libB
),以防止冲突?或任何其他替代方案?正如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
这是可行的,但:
- 引入编译警告:
警告:/Users/jwalton/Android CryptoPP/jni/Android.mk:prng:
链接器标志中的非系统库:-lcryptopp-lstlport\u共享
这可能会导致不正确的生成。尝试使用本地\u静态\u库
或本地共享库,以列出 电流模块 - 不适用于共享的第三方库
libA
,libB
:
libA
的Android.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
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)
# Import libA
include $(CLEAR_VARS)
LOCAL_MODULE := libA
include ../../libA/jni/libA.mk
libA
的libA.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
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)
# Import libA
include $(CLEAR_VARS)
LOCAL_MODULE := libA
include ../../libA/jni/libA.mk
libB
的libB.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
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)
# Import libA
include $(CLEAR_VARS)
LOCAL_MODULE := libA
include ../../libA/jni/libA.mk
因此,它导入libA
,而不导入boost
(也在libB
的Android.mk
中定义)
然后,没有任何警告,它可以顺利编译
我正在尝试为现有的应用程序自动生成Android.mk文件
构建环境。此环境有许多库链接到每个库
其他,也可能链接到第三方LIB(如boost)
为什么不使用,而不是痛苦地处理
Android.mk
文件?听起来独立的工具链非常适合您的情况。您有一个NDK函数$(模块获取列表)
。依靠它,您的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)))
和boost/Android.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
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)))
我不希望对第三方预构建的lib(如boost)有重复的定义,而是希望对每个lib使用单独的Android.mk定义,并在必要时包含它。这样,如果外部库被更新,我就有一个地方可以更改
更新:如果您不喜欢$(如果…
语法,您可以使用
ifeq ($(filter $(modules-get-list),$(LOCAL_MODULE)),)
include $(BUILD_…_LIBRARY)
endif
相反。可以避免模块的重复定义,但在您的情况下,对于boost,只需添加
LOCAL\u LDLIBS+=../dev/libcpp/boost/1.60.1/lib/libboost\u atomic.a
而不是将其添加为LOCAL\u STATIC_LIBRARIES@AlexCohn:这将是一个很好的解决办法。我明天试试。我可以对共享库执行同样的操作吗?因为我想如果使用libB
和libA
使用libC
我也会遇到同样的问题,libA
将在编译libC
时被定义两次(由libB
和libC
导入)。不,这不适用于非预构建的libs,无论如何,不应在LDLIBS中指定共享LIB。但通常很容易根据子目录的层次结构包含您的Android.mk文件。这避免了重复。@AlexCohn:谢谢,LOCAL\u LDLIBS+=../dev/libcpp/boost/1.60.1/lib/libboost\u atomic。a
将在链接器中发出非系统库的警告。如何摆脱这个警告?(仅尝试了LOCAL_STATIC_LIBRARIES+=../dev/libcpp/boost/1.60.1/lib/libboost_atomic.a
,但无效)。您可以忽略此警告。它只与共享LIB相关。@jpo38是的,它们是。。。对于现有生成环境…-看起来您已经有了一些makefiles/构建脚本,不是吗?是的,我正在使用Visual Studio。它本身也支持Android target,但只支持专业版,我使用的是Express edition…@jpo38 Visual Studio不是我喜欢的,但无论如何,我相信即使是Express edition也能让你以某种方式使用自定义工具链。也许会给你一个主意,我去看看。但是,老实说,从CMake手动生成makefile并不是什么大事。我只编写了100行CMake代码就可以工作了(不久前,我已经这样做了,以便从CMake生成QtCreator项目文件,因为在QtCreator中导入CMake对我来说并不正常)。我完全控制发生的事情……很好,我设置了自己的变量来跟踪重复的定义,但这会使代码变得复杂(请参阅)。我会试试你的解决方案,但只在几周后(度假回来的时候)。不起作用。我尝试调用ifndef$(modules\u get\u list)。$(LOCAL\u MODULE)
就在我执行include$(预构建的静态库)
之后,这被评估为true
。我错过了什么吗?很抱歉,这是$(模块获取列表)
。请查看更新的答案。谢谢Alex。如何将其放入常规if语句中ifeq($(调用集\是\成员,$(模块获取列表),$(本地\模块)),true)
失败,因为$(调用集\是\成员,$(模块获取列表),$(本地\模块))
被计算为T
不是true
(对不起,我不是很熟悉)