Patch ios-usb-dependencies binaries with relative paths
This CL does:
1) uses regex to detect paths that need to be updated
2) patches paths for iproxy, libcrypto.3.dylib, idevicescreenshot, idevicesyslog
3) also uploads libimobiledeviceglue lib to GCS
Led run: https://ci.chromium.org/raw/build/logs.chromium.org/flutter/led/keyonghan_google.com/ab1258510096a02701ed9fcdc3bdb8fc0df0f1e9e1dab127587204cfd6960014/+/build.proto?server=chromium-swarm.appspot.com
Change-Id: I4c1b7157bc9a39e611fcd3eec5e5e1fada1f8458
Bug: https://github.com/flutter/flutter/issues/36019
Reviewed-on: https://flutter-review.googlesource.com/c/recipes/+/34240
Commit-Queue: Keyong Han <keyonghan@google.com>
Reviewed-by: Jenn Magder <magder@google.com>
diff --git a/recipes/ios_usb_dependencies/ios-usb-dependencies.expected/basic.json b/recipes/ios_usb_dependencies/ios-usb-dependencies.expected/basic.json
index 3b5b3f8..43ea546 100644
--- a/recipes/ios_usb_dependencies/ios-usb-dependencies.expected/basic.json
+++ b/recipes/ios_usb_dependencies/ios-usb-dependencies.expected/basic.json
@@ -470,6 +470,32 @@
},
{
"cmd": [
+ "python",
+ "RECIPE_MODULE[flutter::zip]/resources/zip.py"
+ ],
+ "name": "zipping libimobiledeviceglue dir",
+ "stdin": "{\"entries\": [{\"path\": \"[START_DIR]/src/libimobiledeviceglue_output\", \"type\": \"dir\"}], \"output\": \"[START_DIR]/libimobiledeviceglue.zip\", \"root\": \"[START_DIR]/src/libimobiledeviceglue_output\"}"
+ },
+ {
+ "cmd": [
+ "python3",
+ "-u",
+ "RECIPE_MODULE[depot_tools::gsutil]/resources/gsutil_smart_retry.py",
+ "--",
+ "RECIPE_REPO[depot_tools]/gsutil.py",
+ "----",
+ "cp",
+ "[START_DIR]/libimobiledeviceglue.zip",
+ "gs://flutter_infra_release/ios-usb-dependencies/unsigned/libimobiledeviceglue/None/libimobiledeviceglue.zip"
+ ],
+ "infra_step": true,
+ "name": "gsutil upload of libimobiledeviceglue.zip",
+ "~followup_annotations": [
+ "@@@STEP_LINK@libimobiledeviceglue.zip@https://storage.cloud.google.com/flutter_infra_release/ios-usb-dependencies/unsigned/libimobiledeviceglue/None/libimobiledeviceglue.zip@@@"
+ ]
+ },
+ {
+ "cmd": [
"vpython3",
"-u",
"RECIPE_MODULE[recipe_engine::file]/resources/fileutil.py",
@@ -549,6 +575,32 @@
},
{
"cmd": [
+ "otool",
+ "-L",
+ "[START_DIR]/src/libusbmuxd_output/iproxy"
+ ],
+ "name": "Get linked paths from iproxy before patch"
+ },
+ {
+ "cmd": [
+ "install_name_tool",
+ "-change",
+ "/opt/s/w/ir/x/w/src/libusbmuxd_install/lib/libusbmuxd-2.0.6.dylib",
+ "@loader_path/../libusbmuxd-2.0.6.dylib",
+ "[START_DIR]/src/libusbmuxd_output/iproxy"
+ ],
+ "name": "Patch [START_DIR]/src/libusbmuxd_output/iproxy with install_name_tool"
+ },
+ {
+ "cmd": [
+ "otool",
+ "-L",
+ "[START_DIR]/src/libusbmuxd_output/iproxy"
+ ],
+ "name": "Get linked paths from [START_DIR]/src/libusbmuxd_output/iproxy after patch"
+ },
+ {
+ "cmd": [
"python",
"RECIPE_MODULE[flutter::zip]/resources/zip.py"
],
@@ -656,6 +708,22 @@
},
{
"cmd": [
+ "otool",
+ "-L",
+ "[START_DIR]/src/openssl_output/libcrypto.3.dylib"
+ ],
+ "name": "Get linked paths from libcrypto.3.dylib before patch"
+ },
+ {
+ "cmd": [
+ "otool",
+ "-L",
+ "[START_DIR]/src/openssl_output/libcrypto.3.dylib"
+ ],
+ "name": "Get linked paths from [START_DIR]/src/openssl_output/libcrypto.3.dylib after patch"
+ },
+ {
+ "cmd": [
"python",
"RECIPE_MODULE[flutter::zip]/resources/zip.py"
],
@@ -766,6 +834,38 @@
},
{
"cmd": [
+ "otool",
+ "-L",
+ "[START_DIR]/src/libimobiledevice_output/idevicescreenshot"
+ ],
+ "name": "Get linked paths from idevicescreenshot before patch"
+ },
+ {
+ "cmd": [
+ "otool",
+ "-L",
+ "[START_DIR]/src/libimobiledevice_output/idevicescreenshot"
+ ],
+ "name": "Get linked paths from [START_DIR]/src/libimobiledevice_output/idevicescreenshot after patch"
+ },
+ {
+ "cmd": [
+ "otool",
+ "-L",
+ "[START_DIR]/src/libimobiledevice_output/idevicesyslog"
+ ],
+ "name": "Get linked paths from idevicesyslog before patch"
+ },
+ {
+ "cmd": [
+ "otool",
+ "-L",
+ "[START_DIR]/src/libimobiledevice_output/idevicesyslog"
+ ],
+ "name": "Get linked paths from [START_DIR]/src/libimobiledevice_output/idevicesyslog after patch"
+ },
+ {
+ "cmd": [
"python",
"RECIPE_MODULE[flutter::zip]/resources/zip.py"
],
diff --git a/recipes/ios_usb_dependencies/ios-usb-dependencies.py b/recipes/ios_usb_dependencies/ios-usb-dependencies.py
index 848f01c..d74a87b 100644
--- a/recipes/ios_usb_dependencies/ios-usb-dependencies.py
+++ b/recipes/ios_usb_dependencies/ios-usb-dependencies.py
@@ -3,6 +3,7 @@
# found in the LICENSE file.
from contextlib import contextmanager
+import re
DEPS = [
'depot_tools/gsutil',
@@ -11,12 +12,71 @@
'recipe_engine/context',
'recipe_engine/file',
'recipe_engine/path',
+ 'recipe_engine/raw_io',
'recipe_engine/runtime',
'recipe_engine/step',
]
BUCKET_NAME = 'flutter_infra_release'
+# These regex are used to detect lib paths that need to be patched.
+LIBUSBMUXD_PATTERN = r'^\t(\/.*(libusbmuxd.*\.dylib)).*'
+LIBPLIST_PATTERN = r'^\t(\/.*(libplist.*\.dylib)).*'
+LIBSSL_PATTERN = r'^\t(\/.*(libssl.*\.dylib)).*'
+LIBCRYPTO_PATTERN = r'^\t(\/.*(libcrypto.*\.dylib)).*'
+LIBIMOBILEDEVICE_PATTERN = r'^\t(\/.*(libimobiledevice.*\.dylib)).*'
+LIBIMOBILEDEVICEGLUE_PATTERN = r'^\t(\/.*(libimobiledevice-glue.*\.dylib)).*'
+
+DIRNAME_PATTERN_TUPLES = [
+ ('libusbmuxd', LIBUSBMUXD_PATTERN),
+ ('libplist', LIBPLIST_PATTERN),
+ ('lisbssl', LIBSSL_PATTERN),
+ ('libcrypto', LIBCRYPTO_PATTERN),
+ ('libimobiledevice', LIBIMOBILEDEVICE_PATTERN),
+ ('libimobiledevice-glue', LIBIMOBILEDEVICEGLUE_PATTERN)
+ ]
+
+# Map between package and its artifacts that need path patch.
+BIANRY_ARTIFACT_MAP = {
+ 'libusbmuxd': ['iproxy'],
+ 'openssl': ['libcrypto.3.dylib'],
+ 'libimobiledevice': ['idevicescreenshot', 'idevicesyslog']
+}
+
+def ParseOtoolPath(input_string):
+ '''Parse paths that need to be patched to relative paths via otool.'''
+ input_lines = input_string.split('\n')
+ output = {}
+ for input_line in input_lines:
+ for dirname, pattern in DIRNAME_PATTERN_TUPLES:
+ # re.match searches from beginning of string
+ match = re.match(pattern, input_line)
+ if match:
+ old_path = match.group(1)
+ new_path = '@loader_path/../%s' % match.group(2)
+ output[old_path] = new_path
+ return output
+
+def PatchLoadPath(api, ouput_path, package_name):
+ '''Update dynamically linked paths in a binary'''
+ if package_name not in BIANRY_ARTIFACT_MAP:
+ return
+ artifacts = BIANRY_ARTIFACT_MAP[package_name]
+ for artifact in artifacts:
+ artifact_path = ouput_path.join(artifact)
+ otool_step_data = api.step(
+ 'Get linked paths from %s before patch' % artifact,
+ ['otool', '-L', artifact_path], stdout=api.raw_io.output_text())
+ old_paths_to_new_paths = ParseOtoolPath(otool_step_data.stdout.rstrip())
+ for old_path in old_paths_to_new_paths:
+ new_path = old_paths_to_new_paths[old_path]
+ api.step(
+ 'Patch %s with install_name_tool' % artifact_path,
+ ['install_name_tool', '-change', old_path, new_path, artifact_path],
+ )
+ api.step(
+ 'Get linked paths from %s after patch' % artifact_path,
+ ['otool', '-L', artifact_path])
def GetCloudPath(api, package_name, commit_sha):
"""Location of cloud bucket for unsigned binaries"""
@@ -137,6 +197,7 @@
api, env, env_prefixes, package_name, package_install_dir, update_path,
update_library_path, update_pkg_config_path
)
+ PatchLoadPath(api, package_out_dir, package_name)
UploadPackage(
api, package_name, work_dir, package_out_dir, upload, commit_sha
)
@@ -158,6 +219,7 @@
env,
env_prefixes,
'libimobiledeviceglue',
+ upload=True,
update_library_path=True,
update_pkg_config_path=True
)
@@ -190,4 +252,8 @@
api.path['start_dir'].join('src').join('ios-deploy'
).join('commit_sha.txt'),
),
+ api.step_data(
+ 'Get linked paths from iproxy before patch',
+ stdout=api.raw_io.output_text('\t/opt/s/w/ir/x/w/src/libusbmuxd_install/lib/libusbmuxd-2.0.6.dylib (compatibility version 7.0.0, current version 7.0.0)'),
+ retcode=0)
)
diff --git a/recipes/ios_usb_dependencies/ios-usb-dependencies.resources/libimobiledeviceglue.sh b/recipes/ios_usb_dependencies/ios-usb-dependencies.resources/libimobiledeviceglue.sh
index c7bd4f6..9a9890c 100755
--- a/recipes/ios_usb_dependencies/ios-usb-dependencies.resources/libimobiledeviceglue.sh
+++ b/recipes/ios_usb_dependencies/ios-usb-dependencies.resources/libimobiledeviceglue.sh
@@ -23,3 +23,5 @@
"$SRC_DIR"/configure --prefix="$INSTALL_DIR"
make install
+
+cp "$INSTALL_DIR"/lib/libimobiledevice-glue-1.0.0.dylib "$OUTPUT_DIR"