解決Android bp build error: dependency "..." of "..." missing variant

Android O上開始谷歌加大力度推廣使用新的soong編譯,隨之而來的影響就是原先在Android.mk文件需要轉換為Android.bp文件做編譯配置。

使用soong提供的androidmk命令可以把Android.mk文件轉換為Android.bp文件,但是對于一些復雜的mk語法,轉換的結果往往不能像原先的Android.mk那樣可以正常編譯出想要的結果。這就需要將轉換出的Android.bp做進一步的修改,以符合原來的編譯需求。

androidmk Android.mk > Android.bp

下面來說說我所遇到的dependency "..." of "..." missing variant 錯誤的解決過程:

1.Android.mk轉換成Android.bp:

原先的Android.mk中有如下配置,目的是需要將編譯出兩個版本的tinyalsa, Android版和Host版,且名稱相同。以下是Android.mk中tinyalsa的兩個版本的配置:

include $(CLEAR_VARS)

LOCAL_C_INCLUDES:= external/tinyalsa/include

LOCAL_SRC_FILES:= mixer.c pcm.c

LOCAL_MODULE := libtinyalsa

LOCAL_SHARED_LIBRARIES:= libcutils libutils liblog

LOCAL_MODULE_TAGS := optional

LOCAL_CFLAGS += -Werror

ifeq ($(strip $(NXP_SMARTPA_SUPPORT)),tfa9895)

LOCAL_CFLAGS += -DNXP_TFA9895_SUPPORT

LOCAL_C_INCLUDES+= device/vendor/msm8937/TFA9895/app/exTfa98xx/inc

LOCAL_SHARED_LIBRARIES+= libtfa9895

endif

include $(BUILD_SHARED_LIBRARY)

ifeq ($(HOST_OS), linux)

include $(CLEAR_VARS)

LOCAL_C_INCLUDES:= external/tinyalsa/include

LOCAL_SRC_FILES:= mixer.c pcm.c

LOCAL_MODULE := libtinyalsa

LOCAL_STATIC_LIBRARIES:= libcutils libutils liblog

LOCAL_CFLAGS += -Werror

include $(BUILD_HOST_STATIC_LIBRARY)

endif


原android版tinyalsa是shared_library, host版tinyalsa是static_library, 用androidmk命令轉換成bp文件后內容如下:

cc_library_shared {

include_dirs: ["external/tinyalsa/include"] + ["device/vendor/msm8937/TFA9895/app/exTfa98xx/inc"] + ["device/vendor/msm8937/TFA9891/app/exTfa98xx/inc"],

// ANDROIDMK TRANSLATION ERROR: unsupported conditional

// ifeq ($(strip $(NXP_SMARTPA_SUPPORT)),tfa9895)

// ANDROIDMK TRANSLATION ERROR: endif from unsupported contitional

// endif

// ANDROIDMK TRANSLATION ERROR: endif from unsupported contitional

// endif

// ANDROIDMK TRANSLATION ERROR: unsupported conditional

// ifeq ($(strip $(NXP_SMARTPA_SUPPORT)),tfa9895)

srcs: [

"mixer.c",

"pcm.c",

],

name: "libtinyalsa",

shared_libs: [

"libcutils",

"libutils",

],

cflags: ["-Werror"] + ["-DNXP_TFA9895_SUPPORT"] + ["-DNXP_TFA9895_SUPPORT"],

shared_libs: ["libtfa9895"],

// ANDROIDMK TRANSLATION ERROR: endif from unsupported contitional

// endif

// ANDROIDMK TRANSLATION ERROR: endif from unsupported contitional

// endif

}

cc_library_host_static {

include_dirs: ["external/tinyalsa/include"],

srcs: [

"mixer.c",

"pcm.c",

],

name: "libtinyalsa",

static_libs: [

"libcutils",

"libutils",

],

cflags:["-Werror"],

target:{

not_linux:{

enabled:false,

},

},

}

轉換后有兩個名字相同的libtinyalsa module。

因為項目需求,在libtinyalsa Android版中添加了共享庫依賴:libtfa9895:

所以現在的庫依賴關系變為:

Android:? libtinyalsa -> libcutils, libutils,libtfa9895

Host: libtinyalsa -> libcutils, libutils

2. Android.mk轉為Android.bp之后,手動修改,刪除名字相同的多余module.

bp文件定義的一個規則是,可以定義很多種很多個module,每個module必須有一個名字,且名字必須唯一不重復。這是因為bp文件沒有判斷邏輯,不能像mk中那樣根據不同的編譯選項選擇不同的版本。

在原Android.mk中定義了兩個名字相同的tinyalsa, 一個是Android版,一個是Host版。轉成bp后,出現了兩個名字相同的tinyalsa module,一個是cc_library_shared, 一個是cc_library_host_static。而根據bp的module名字不重復規則,這種情況是不允許的,所以我們做的第一個修改是將兩個module合并為一個,然后通過**host_supported: true**使其支持host;

又因為原來的兩個module,一個為shared,一個為static,所以第二個修改是合并后的module類型為cc_library, 這樣才能同時包含shared與static兩種不同的屬性類型。

修改后的Android.bp:

cc_library {

include_dirs: ["device/vendor/msm8937/TFA9895/app/exTfa98xx/inc"],

name: "libtinyalsa",

host_supported: true,

vendor_available: true,

srcs: [

"mixer.c",

"pcm.c",

],

shared_libs: [

"libcutils",

"libutils",

"libtfa9895",

],

cflags: ["-Werror", "-Wno-macro-redefined"]+ ["-DNXP_TFA9895_SUPPORT"],

export_include_dirs: ["include"],

local_include_dirs: ["include"],

target: {

darwin: {

enabled: false,

},

},

}

下面要說的編譯錯誤就是因為在tinyplay和tinyalsa中添加了host_supported引起的:

error: external/tinyalsa/Android.bp:1:1: dependency "libtfa9895" of "libtinyalsa" missing variant:

arch:linux_x86_64, link:shared

available variants:

arch:android_arm64_armv8-a, link:shared, image:core

arch:android_arm_armv7-a-neon_cortex-a53, link:shared, image:core

從出錯信息來看,是由于libtfa9895中不支持linux_x86_64平臺的編譯。

以下是libtfa9895轉換為Android.bp后的配置:

cc_library_shared {

local_include_dirs: [

"srv/inc",

"tfa/inc",

"utl/inc",

"hal/inc",

"hal/src",

"hal/src/lxScribo",

"srv/src/iniFile",

"app/exTfa98xx/inc",

],

export_include_dirs: [

"srv/inc",

"tfa/inc",

"utl/inc",

"hal/inc",

"hal/src",

"hal/src/lxScribo",

"srv/src/iniFile",

"app/exTfa98xx/inc",

],

srcs: ["app/exTfa98xx/src/main_container.c"],

name: "libtfa9895",

shared_libs: [

"libcutils",

],

static_libs: [

"libsrv",

"libtfa",

"libhal",

],

}

?3. 除錯過程:

libtinyalsa依賴庫有三個,libcutils, libutils, libtfa9895,

而log中只提供libtfa9895有錯,查看libcutils和libutils的配置發現,這兩個庫里的配置信息都有添加host_supported,而libtfa9895沒有,所以嘗試在libtfa9895中添加host_supported配置后重新編譯,

然后出現了相同的錯誤提示,只不過這次提示libtfa9895依賴的三個庫(libsrv/libtfa/libhal)不支持host。看來在有host_supported配置的庫中,其依賴庫也必須是host_supported的。

在libsrv/libtfa/libhal中分別添加host_supported配置后,再次提示這三個庫依賴的libutils不支持host.

查看libutils的配置發現libutils有添加host_supported,這里怎么回事呢?

cc_library {

name: "libutils",

vendor_available: true,

host_supported: true,

srcs: [

....

],

cflags: ["-Werror"],

include_dirs: ["external/safe-iop/include"],

header_libs: [

"libutils_headers",

],

export_header_lib_headers: [

"libutils_headers",

],

arch: {

mips: {

cflags: ["-DALIGN_DOUBLE"],

},

},

target: {

android: {

srcs: [

"Looper.cpp",

"ProcessCallStack.cpp",

"Trace.cpp",

],

cflags: ["-fvisibility=protected"],

shared_libs: [

"libbacktrace",

"libcutils",

"libdl",

"liblog",

"libvndksupport",

],

sanitize: {

misc_undefined: ["integer"],

},

},

host: {

cflags: ["-DLIBUTILS_NATIVE=1"],

shared: {

enabled: false,

},

},

linux: {

srcs: [

"Looper.cpp",

"ProcessCallStack.cpp",

],

},

linux_bionic: {

enabled: true,

srcs: [

"Looper.cpp",

"ProcessCallStack.cpp",

],

},

darwin: {

cflags: ["-Wno-unused-parameter"],

},

// Under MinGW, ctype.h doesn't need multi-byte support

windows: {

cflags: ["-DMB_CUR_MAX=1"],

enabled: true,

},

},

clang: true,

}

仔細分析libutils中的配置,發現原來在target:下的host配置,將shared屬性設置成了false,就是說在編譯Android版時,libutils可以作為shared lib引用,但是在host版中,只能做為static lib引用。

host: {

cflags: ["-DLIBUTILS_NATIVE=1"],

shared: {

enabled: false,

},

},

所以對引用libutils的module中,做了如下修改,首先刪除libutils的引用,然后添加如下配置:

target: {

android: {

cflags: ["-DAndroid"],

shared_libs: [

"libutils",

],

},

host: {

static_libs: ["libutils"],

},

},

android版以shared lib引用libutils, host版以static lib引用。

修改后的完整的libtfa9895的配置信息如下:

cc_library_shared {

local_include_dirs: [

"srv/inc",

"tfa/inc",

"utl/inc",

"hal/inc",

"hal/src",

"hal/src/lxScribo",

"srv/src/iniFile",

"app/exTfa98xx/inc",

],

export_include_dirs: [

"srv/inc",

"tfa/inc",

"utl/inc",

"hal/inc",

"hal/src",

"hal/src/lxScribo",

"srv/src/iniFile",

"app/exTfa98xx/inc",

],

srcs: ["app/exTfa98xx/src/main_container.c"],

name: "libtfa9895",

host_supported: true,

shared_libs: [

"libcutils",

],

static_libs: [

"libsrv",

"libtfa",

"libhal",

],

target: {

android: {

cflags: ["-DAndroid"],

shared_libs: [

"libutils",

],

},

host: {

static_libs: ["libutils"],

},

},

}

所以修改完成后,編譯通過。

?4. 進一步完善

回到前面我們libtinyalsa的定義,在原mk中android版 libtinyalsa是shared library, host版是static library,而轉成bp后,libtinyalsa合并成了一個cc_library,但是并未對android版與host版區分其shared/static屬性。

參考libutils中的方法,可以對libtinyalsa? target為android與host兩個版本的shared屬性設置為不同的值。

target: {

android:{

shared:{

enabled: true,

},

},

host:{

cflags: ["-DLIBUTILS_NATIVE=1"],

shared: {

enabled: false,

},},

},
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容