Issue
I'm trying to generate Android.mk files automatically for an existing build environment. This environment has many libraries linking to each other and also possibly linking to 3rd party libs (like boost).
Let's say I have libA
using boost.
My goal being to build both libA
and libB
by running ndk-build from libB folder.
So I generate this 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)
Now I have libB
using both boost
and libA
. libB
's Android.mk
is very similar to libA
's except I added the import of libA
file as below:
# Import libA
include $(CLEAR_VARS)
LOCAL_MODULE := libA
include ../../libA/jni/Android.mk
When I try to make libB
, I'm being reported:
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.
Is there a way for me to check if boost_atomic
is already defined (like if (exists boost_atomic)
) to make sure it gets defined once only? Or should I suffix all the names (ending up with boost_system_for_libA
and boost_system_for_libB
) to prevent the conflict? Or any other alternative?
Solution
You have an NDK function $(modules_get_list)
. Relying on it, your libA/jni/Android.mk file may look as follows:
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)))
and boost/Android.mk file:
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))
Finally, 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)))
I prefer not to have duplicate definitions for 3rd party prebuilt libs, like boost, but rather to use a separate Android.mk definition for each, and include
it whenever necessary. This way, I have one place to change if the external library is updated.
Update: if you don't like $(if …)
syntax, you may use
ifeq ($(filter $(modules-get-list),$(LOCAL_MODULE)),)
include $(BUILD_…_LIBRARY)
endif
instead.
Answered By - Alex Cohn
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.