From 2692ed37bbb852f2254361555732dbc4789a366c Mon Sep 17 00:00:00 2001 From: Soim Kim Date: Tue, 29 Sep 2026 11:54:15 +0900 Subject: [PATCH 1/2] fix(binary): search soong static libs when obj path is gone Skip find on missing product directories and read target .a files from out/soong when obj/STATIC_LIBRARIES does not exist. --- .../android_binary_analysis.py | 66 ++++++++++++++----- 1 file changed, 51 insertions(+), 15 deletions(-) diff --git a/src/fosslight_android/android_binary_analysis.py b/src/fosslight_android/android_binary_analysis.py index 3dfe2f1..59d0ab9 100755 --- a/src/fosslight_android/android_binary_analysis.py +++ b/src/fosslight_android/android_binary_analysis.py @@ -342,6 +342,19 @@ def set_env_variables_from_result_log(android_src_path): read_module_info_from_build_output_file() +def _add_find_cmd(cmd_list, directory, cmd): + if os.path.isdir(directory): + cmd_list.append(cmd) + return + logger.info("Skip missing binary search path: %s", directory) + + +def _soong_intermediates_path(product_out): + # out/target/product/ -> out/soong/.intermediates + out_dir = os.path.dirname(os.path.dirname(os.path.dirname(product_out))) + return os.path.join(out_dir, "soong", ".intermediates") + + def find_binaries_from_out_dir(): global build_out_path @@ -353,23 +366,45 @@ def find_binaries_from_out_dir(): root_path = os.path.join(build_out_path, "root") obj_static_lib = os.path.join(build_out_path, "obj/STATIC_LIBRARIES") font_path = os.path.join(build_out_path, "system/fonts") - cmd_list = [ + cmd_list = [] + _add_find_cmd( + cmd_list, system_path, "find " + system_path + " -type f -exec file \"{}\" \\; | " "egrep \"ELF\\ |ARM,|\\.jar|\\.apk\" | grep -v \"\\.o:\" | " - "grep -v \"\\.odex:\" | awk -F\":\" \'{print $1}\'", + "grep -v \"\\.odex:\" | awk -F\":\" \'{print $1}\'") + _add_find_cmd( + cmd_list, root_path, "find " + root_path + " -type f -exec file \"{}\" \\; | " - "egrep \"ELF\\ |ARM,|\\.jar|\\.apk\" | grep -v \"\\.o:\" | awk -F\":\" \'{print $1}\' ", + "egrep \"ELF\\ |ARM,|\\.jar|\\.apk\" | grep -v \"\\.o:\" | awk -F\":\" \'{print $1}\' ") + _add_find_cmd( + cmd_list, build_out_path, "find " + build_out_path + " -maxdepth 1 -type f -exec file \"{}\" \\; | grep data$ |" - " grep -v .img | awk -F\":\" \'{print $1}\' ", - "find " + obj_static_lib + " -type f -exec file \"{}\" \\; | egrep \"ar archive\" | awk -F\":\" \'{print $1}\' ", - f"find {build_out_path} ! \\( \\( -type d -path {system_path}" - f" -o -path {root_path} -o -path \'{build_out_path}" - f"/obj*\' -o -path {build_out_path}/symbols -o -path \'" - f"{build_out_path}/factory_*\' -o -path {build_out_path}" - "/dex_bootjars \\) -prune \\) -type f -exec file \"{}\" \\; | egrep \"ELF\\ |ARM,|\\.jar|\\.apk\" | " - "grep -v \"\\.o:\" | grep -v \"\\.odex:\" | awk -F\":\" \'{print $1}\' ", - "find " + font_path + " -type f -exec file \"{}\" \\; | egrep \"font\" | awk -F\":\" \'{print $1}\'" - ] + " grep -v .img | awk -F\":\" \'{print $1}\' ") + if os.path.isdir(obj_static_lib): + _add_find_cmd( + cmd_list, obj_static_lib, + "find " + obj_static_lib + " -type f -exec file \"{}\" \\; | " + "egrep \"ar archive\" | awk -F\":\" \'{print $1}\' ") + else: + # Android 17 drops Make obj/STATIC_LIBRARIES. Target .a files live in Soong. + # Plain android_*_static only: skip cfi, apex, and afdo variant copies. + soong_intermediates = _soong_intermediates_path(build_out_path) + logger.info("STATIC_LIBRARIES not found. Search Soong static libs: %s", soong_intermediates) + _add_find_cmd( + cmd_list, soong_intermediates, + "find " + soong_intermediates + " -regextype posix-extended -type f " + "-regex '.*/android_[^/]*_static/[^/]*\\.a$'") + if os.path.isdir(build_out_path): + cmd_list.append( + f"find {build_out_path} ! \\( \\( -type d -path {system_path}" + f" -o -path {root_path} -o -path \'{build_out_path}" + f"/obj*\' -o -path {build_out_path}/symbols -o -path \'" + f"{build_out_path}/factory_*\' -o -path {build_out_path}" + "/dex_bootjars \\) -prune \\) -type f -exec file \"{}\" \\; | egrep \"ELF\\ |ARM,|\\.jar|\\.apk\" | " + "grep -v \"\\.o:\" | grep -v \"\\.odex:\" | awk -F\":\" \'{print $1}\' ") + _add_find_cmd( + cmd_list, font_path, + "find " + font_path + " -type f -exec file \"{}\" \\; | egrep \"font\" | awk -F\":\" \'{print $1}\'") return_list = do_multi_process(find_binary, cmd_list) tmp_files = [] @@ -507,8 +542,9 @@ def map_binary_module_name_and_path(installed_file_list): for out_binary in installed_file_list: file_name_with_relative_path = out_binary.replace(build_out_path + "/", "") - if "obj/STATIC_LIBRARIES/" in file_name_with_relative_path: - file_name_with_relative_path = os.path.basename(file_name_with_relative_path) + if ("obj/STATIC_LIBRARIES/" in file_name_with_relative_path + or ("/soong/.intermediates/" in out_binary and out_binary.endswith(".a"))): + file_name_with_relative_path = os.path.basename(out_binary) file_name = os.path.basename(file_name_with_relative_path) index_of_dot = file_name.rfind('.') if index_of_dot > -1: From ef7ddb2bbbc580e46719eb8edcffd5f4598246c1 Mon Sep 17 00:00:00 2001 From: Soim Kim Date: Tue, 29 Sep 2026 14:21:17 +0900 Subject: [PATCH 2/2] fix(binary): drop intermediate static library search Linked .so and executables are already collected from system and apex. Static .a files are not installed on the target. --- .../android_binary_analysis.py | 24 ------------------- 1 file changed, 24 deletions(-) diff --git a/src/fosslight_android/android_binary_analysis.py b/src/fosslight_android/android_binary_analysis.py index 59d0ab9..267f7a4 100755 --- a/src/fosslight_android/android_binary_analysis.py +++ b/src/fosslight_android/android_binary_analysis.py @@ -349,12 +349,6 @@ def _add_find_cmd(cmd_list, directory, cmd): logger.info("Skip missing binary search path: %s", directory) -def _soong_intermediates_path(product_out): - # out/target/product/ -> out/soong/.intermediates - out_dir = os.path.dirname(os.path.dirname(os.path.dirname(product_out))) - return os.path.join(out_dir, "soong", ".intermediates") - - def find_binaries_from_out_dir(): global build_out_path @@ -364,7 +358,6 @@ def find_binaries_from_out_dir(): system_path = os.path.join(build_out_path, "system") root_path = os.path.join(build_out_path, "root") - obj_static_lib = os.path.join(build_out_path, "obj/STATIC_LIBRARIES") font_path = os.path.join(build_out_path, "system/fonts") cmd_list = [] _add_find_cmd( @@ -380,20 +373,6 @@ def find_binaries_from_out_dir(): cmd_list, build_out_path, "find " + build_out_path + " -maxdepth 1 -type f -exec file \"{}\" \\; | grep data$ |" " grep -v .img | awk -F\":\" \'{print $1}\' ") - if os.path.isdir(obj_static_lib): - _add_find_cmd( - cmd_list, obj_static_lib, - "find " + obj_static_lib + " -type f -exec file \"{}\" \\; | " - "egrep \"ar archive\" | awk -F\":\" \'{print $1}\' ") - else: - # Android 17 drops Make obj/STATIC_LIBRARIES. Target .a files live in Soong. - # Plain android_*_static only: skip cfi, apex, and afdo variant copies. - soong_intermediates = _soong_intermediates_path(build_out_path) - logger.info("STATIC_LIBRARIES not found. Search Soong static libs: %s", soong_intermediates) - _add_find_cmd( - cmd_list, soong_intermediates, - "find " + soong_intermediates + " -regextype posix-extended -type f " - "-regex '.*/android_[^/]*_static/[^/]*\\.a$'") if os.path.isdir(build_out_path): cmd_list.append( f"find {build_out_path} ! \\( \\( -type d -path {system_path}" @@ -542,9 +521,6 @@ def map_binary_module_name_and_path(installed_file_list): for out_binary in installed_file_list: file_name_with_relative_path = out_binary.replace(build_out_path + "/", "") - if ("obj/STATIC_LIBRARIES/" in file_name_with_relative_path - or ("/soong/.intermediates/" in out_binary and out_binary.endswith(".a"))): - file_name_with_relative_path = os.path.basename(out_binary) file_name = os.path.basename(file_name_with_relative_path) index_of_dot = file_name.rfind('.') if index_of_dot > -1: