【安卓實踐】apex導致的安卓編譯失敗原因調查

背景

在實現(xiàn)功能的時候,我把我的功能邏輯實現(xiàn)在libmeminfo.so庫當中。
由于我的功能需要調用libmemtrack.so庫中的一些函數(shù),我就在libmeminfo的Androidbp中將libmemtrack.so動態(tài)連接過來了。如下:

cc_library {
    name: "libmeminfo",
    defaults: ["libmeminfo_defaults"],
    export_include_dirs: ["include"],
    export_shared_lib_headers: ["libbase"],
    srcs: [
        "pageacct.cpp",
        "procmeminfo.cpp",
        "sysmeminfo.cpp",
    ],
    //ADD START: {
    shared_libs: [
        "libmemtrack",
    ],
    //END}
}

這樣增加之后無論是在 其他so庫中調用我提供的方法,還是單獨編譯libmeminfo都可以編譯通過,并且功能驗證不會有問題。
但是當我?guī)atch編譯整個rom包的時候,卻報了以下錯誤:

[ 99% 111787/112588] //art/build/apex:art-check-debug-apex-gen generate art-check-debug-apex-gen.dummy
FAILED: out/soong/.intermediates/art/build/apex/art-check-debug-apex-gen/gen/art-check-debug-apex-gen.dummy
rm -rf out/soong/.intermediates/art/build/apex/art-check-debug-apex-gen/gen && out/soong/host/linux-x86/bin/sbox --sandbox-path out/soong/.temp --output-root out/soong/.intermediates/art/build/apex/art-check-debug-apex-gen/gen -c 'out/soong/host/linux-x86/bin/art-apex-tester --debugfs out/soong/host/linux-x86/bin/debugfs --tmpdir __SBOX_OUT_DIR__ --debug out/soong/.intermediates/art/build/apex/com.android.runtime.debug/android_common_com.android.runtime.debug/com.android.runtime.debug.apex && touch __SBOX_OUT_FILES__'  __SBOX_OUT_DIR__/art-check-debug-apex-gen.dummy
--bitness=auto, trying to autodetect. This may be incorrect!
  Detected multilib
Unexpected file 'lib64/libcutils.so'
Unexpected file 'lib64/libutils.so'
Unexpected file 'lib64/libhwbinder.so'
Unexpected file 'lib64/libhidlbase.so'
Unexpected file 'lib64/libbinderthreadstate.so'
Unexpected file 'lib64/libhidltransport.so'
Unexpected file 'lib64/libprocessgroup.so'
Unexpected file 'lib64/libhardware.so'
Unexpected file 'lib64/libmemtrack.so'
Unexpected file 'lib64/android.hardware.memtrack@1.0.so'
No superfluous libraries checker FAILED

拿到這個錯誤的時候,由于這個錯誤最多是“Unexpected file 'lib64/libmemtrack.so'”這一行與我的修改有關系,
所以我一度覺得不是我的問題。后來調查了兩個小時我才發(fā)現(xiàn)編譯錯誤的原因。

原因

確實我的修改不會導致問題,但是在安卓編譯的過程中編譯com.android.runtime.debug時,編譯腳本會檢查/apex/com.android.runtime.debug/目錄下多個目錄lib/lib64/bin/以及l(fā)ib/bionic等路徑下是否包含非法的so庫。
如果包含非法的so庫,就會在編譯腳本中報錯,導致rom包的編譯失敗。

art/build/apex/art_apex_test.py
  def check_no_superfluous_files(self, dir_path):
    paths = []
    for name in sorted(self._provider.read_dir(dir_path).keys()):
      if name not in ('.', '..'):
        paths.append(os.path.join(dir_path, name))
    expected_paths = set()
    dir_prefix = dir_path + '/'
    for path_glob in self._expected_file_globs:
      expected_paths |= set(fnmatch.filter(paths, path_glob))
      # If there are globs in subdirectories of dir_path we want to match their
      # path segments at this directory level.
      if path_glob.startswith(dir_prefix):
        subpath = path_glob[len(dir_prefix):]
        subpath_first_segment, _, _ = subpath.partition('/')
        expected_paths |= set(fnmatch.filter(paths, dir_prefix + subpath_first_segment))
    for unexpected_path in set(paths) - expected_paths:
      self.fail('Unexpected file \'%s\'', unexpected_path)

修改編譯腳本,執(zhí)行“make art-check-debug-apex-gen -j16”打印expected_paths如下:

expected_paths '{'lib64/libziparchive.so', 'lib64/libz.so', 'lib64/libmeminfo.so', 'lib64/libprofile.so', 'lib64/libnpt.so', 'lib64/libart-compiler.so', 'lib64/libvixl.so', 'lib64/libc_malloc_debug.so', 'lib64/libopenjdkjvmd.so', 'lib64/libprofiled.so', 'lib64/libcrypto.so', 'lib64/libjavacore.so', 'lib64/libartd.so', 'lib64/libartbase.so', 'lib64/libartd-dexlayout.so', 'lib64/libprocinfo.so', 'lib64/libart-dexlayout.so', 'lib64/libc_malloc_hooks.so', 'lib64/libnativeloader.so', 'lib64/bionic', 'lib64/libc++.so', 'lib64/libexpat.so', 'lib64/libbase.so', 'lib64/liblzma.so', 'lib64/libunwindstack.so', 'lib64/libpac.so', 'lib64/libdt_fd_forward.so', 'lib64/libopenjdkd.so', 'lib64/libopenjdkjvmtid.so', 'lib64/libnativehelper.so', 'lib64/libicui18n.so', 'lib64/libadbconnection.so', 'lib64/libsigchain.so', 'lib64/libdexfile_support.so', 'lib64/libopenjdkjvmti.so', 'lib64/libopenjdkjvm.so', 'lib64/libartpalette.so', 'lib64/libvixld.so', 'lib64/libdexfile.so', 'lib64/libdexfile_external.so', 'lib64/libdt_socket.so', 'lib64/libopenjdk.so', 'lib64/libartd-disassembler.so', 'lib64/libandroidicu.so', 'lib64/libjdwp.so', 'lib64/libbacktrace.so', 'lib64/libart-disassembler.so', 'lib64/libartd-compiler.so', 'lib64/libnativebridge.so', 'lib64/libicuuc.so', 'lib64/libadbconnectiond.so', 'lib64/libdexfiled.so', 'lib64/libartbased.so', 'lib64/libart.so', 'lib64/libandroidio.so'}'

可以看到libmeminfo.so包含在這些庫當中。
這意味著,如果我在libmeminfo.so中想要動態(tài)連接其他非expected_paths中的so庫,如libmemtrack,就會在編譯的時候把libmemtrack放在apex/com.anroid.runtime.debug/lib64/路徑下。
而編譯腳本會檢查此路徑下的庫是否都是expected_paths中所包含的庫,如果不是,就會報錯。
而這次報錯中之所以會有其他庫如libhwbinder.so,原因是libmemtrack動態(tài)連接了這些庫。
至此,問題原因調查完畢。
那只能換一種方式實現(xiàn)我的功能了,至少不能放在libmeminfo.so中去實現(xiàn)。

?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

友情鏈接更多精彩內容