2016-10-20 2 views
2

기존 빌드 환경에서 Android.mk 파일을 자동 생성하려고합니다. 이 환경은 많은 라이브러리를 서로 연결하고 제 3 자 라이브러리 (예 : 부스트)에 링크 할 수도 있습니다.Android.mk : 모듈이 이미 존재하는지 확인하는 방법

부스트를 사용하여 libA이 있다고 가정 해 봅니다. 목표는 libB 폴더에서 ndk-build를 실행하여 libAlibB을 빌드하는 것입니다.

그래서 나는 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) 

가 지금은 boostlibA을 모두 사용하여 libB 있습니다. 내가 libB을 할 때

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

, 나는이보고되고있어 :

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. 

인가 나는 다음과 같이 libA 파일의 가져 오기가 추가 된 것을 제외하고 libB의의 Android.mklibA 매우 유사하다 '의 거기에 boost_atomic (예 : if (exists boost_atomic))이 이미 정의되어 있는지 한 번만 정의되었는지 확인하는 방법이 있습니까? 또는 충돌을 막기 위해 모든 이름 끝에 접미사 (boost_system_for_libAboost_system_for_libB)를 사용해야합니까? 또는 다른 대안?

알렉스 콘이 언급 한 바와 같이
+0

* 모듈 정의가 중복되는 것을 피할 수는 있지만, 경우에 따라 부스트를 위해'LOCAL_LDLIBS + = .. /dev/libcpp/boost/1.60.1/lib/libboost_atomic '을 추가하는 것이 더 쉽습니다. a'를 LOCAL_STATIC_LIBRARIES로 추가하는 대신 –

+0

@AlexCohn : 좋은 해결책이 될 것입니다. 내일 한번 해봐. 공유 라이브러리에서도 동일한 작업을 수행 할 수 있습니까? 왜냐하면'libB'와'libA'를 사용하여'libC '를 사용하면 같은 문제가 발생할 것이기 때문에'libA'는 컴파일 할 때'libB'와'libC'에 의해 두 번 정의 될 것입니다. 'libC'. – jpo38

+0

아니요, 사전 빌드되지 않은 libs에서는 작동하지 않으며 LDLIBS에서는 공유 라이브러리를 지정하지 않아야합니다. 그러나 일반적으로 하위 디렉토리의 계층 구조에 따라 Android.mk 파일을 포함시키는 것은 쉽습니다. 이렇게하면 중복을 피할 수 있습니다. –

답변

2

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.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))) 

제 3 자 홍보에 대한 중복 정의를 선호하지 않습니다. boost와 같은 ebuilt 라이브러리가 아니라 각각 Android.mk 정의를 사용하고 필요하면 언제든지 include 정의를 사용합니다. 이렇게하면 외부 라이브러리가 업데이트되면 변경할 수있는 한 곳이 있습니다.

업데이트 : 당신이 $(if …) 구문을 좋아하지 않는 경우, 대신

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

를 사용할 수 있습니다.

+1

니스, 저는 중복 정의를 추적하기 위해 자체 변수를 설정했지만 코드가 복잡해집니다 (http://stackoverflow.com/questions/40173692/android-makefiles-how-to 참조). -early-return). 나는 당신의 해결책을 시도 할 것이지만, 단지 몇 주 안에 (휴가에서 돌아올 때). – jpo38

+0

작동하지 않았습니다. 나는'include $ (PREBUILT_STATIC_LIBRARY)'를 실행 한 직후에'ifndef $ (modules_get_list). $ (LOCAL_MODULE)'을 호출하려고했는데 이것은'true'로 평가됩니다. 내가 뭐 놓친 거 없니? – jpo38

+0

사과, 이건'$ (modules-get-list)'입니다. 업데이트 된 답변을 참조하십시오. –

1

, 하나는 대체하여 그것을 해결할 수 :

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 

:

  • 가 컴파일 경고를 소개 :

    경고 NG : /Users/jwalton/Android-CryptoPP/jni/Android.mk : prng : 링커 플래그가 아닌 시스템 라이브러리 : -lcryptopp -lstlport_shared
    잘못된 빌드가 발생할 가능성이 있습니다. 현재 모듈의 라이브러리 의존성을 나열하는 대신 LOCAL_STATIC_LIBRARIES
    또는 LOCAL_SHARED_LIBRARIES를 사용해보십시오

  • 공유 제 3의 라이브러리 작동하지 않습니다 는

그래서 나는 마침내 내 새로운 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 지금이 : 그래서 boost을 가져 오지 않고 libA를 가져 오는 것을

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

(도 정의 0에서의 Android.mk).

경고가 없으면 부드럽게 컴파일됩니다.

1

기존 빌드 환경에서 Android.mk 파일을 자동 생성하려고합니다. 이 환경은 각각 에 링크되어 있고 제 3 자 라이브러리 (예 : 부스트)에 링크되어있는 라이브러리가 많이 있습니다.

Android.mk 파일로 고통스러운 대처 대신 standalone NDK toolchains을 사용하지 않으시겠습니까? 독립형 툴 체인과 같은 사운드는 사용자 상황에 이상적입니다.

+0

@ jpo38 예. 그렇습니다. _... 기존 빌드 환경의 경우 ... _ - 이미 일부 makefile/빌드 스크립트가있는 것처럼 보입니까? – Sergio

+0

예, Visual Studio를 사용하고 있습니다. 그것은 또한 기본적으로 안드로이드 타겟을 지원하지만 프로페셔널 에디션만을 지원합니다. 익스프레스 에디션을 사용하고 있습니다. – jpo38

+0

@ jpo38 Visual Studio는 제 차가 아니지만 어쨌든 익스프레스 에디션이라도 어떻게 든 사용자 정의 툴체인을 사용할 수 있다고 믿습니다. 어쩌면 [이 답변] (http://stackoverflow.com/a/14819449/2878070) 아이디어를 줄 것입니다. – Sergio

관련 문제