Skip to content

Commit 1f3397a

Browse files
authored
Merge pull request #62492 from DougGregor/recursive-lipo-better
Remove --copy-subdirs from recursive-lipo.
2 parents 77b5e13 + 73e2757 commit 1f3397a

File tree

2 files changed

+60
-62
lines changed

2 files changed

+60
-62
lines changed

utils/build-script-impl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3579,7 +3579,7 @@ if [[ ${#LIPO_SRC_DIRS[@]} -gt 0 ]]; then
35793579
else
35803580
LIPO_PATH="${HOST_LIPO}"
35813581
fi
3582-
call "${SWIFT_SOURCE_DIR}"/utils/recursive-lipo --lipo=${LIPO_PATH} --copy-subdirs="$(get_host_install_prefix ${host})lib/swift $(get_host_install_prefix ${host})lib/swift_static" --explicit-src-files="$(get_host_install_prefix ${host})lib/swift/${host%%-*}/lib_InternalSwiftScan.dylib" --destination="$(get_host_install_destdir ${mergedHost})" ${LIPO_SRC_DIRS[@]}
3582+
call "${SWIFT_SOURCE_DIR}"/utils/recursive-lipo --lipo=${LIPO_PATH} --destination="$(get_host_install_destdir ${mergedHost})" ${LIPO_SRC_DIRS[@]}
35833583

35843584
if [[ $(should_execute_action "${mergedHost}-lipo") ]]; then
35853585
# Build and test the lipo-ed package.

utils/recursive-lipo

Lines changed: 59 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,10 @@ import shutil
99
from swift_build_support.swift_build_support import shell
1010

1111

12-
def merge_file_lists(src_root_dirs, explicit_src_files, skip_files,
13-
skip_subpaths):
12+
def merge_file_lists(src_root_dirs, skip_files):
1413
"""Merges the file lists recursively from all src_root_dirs supplied,
1514
returning the union of all file paths found.
1615
Files matching skip_files are ignored and skipped.
17-
Subpaths matching skip_subpaths are not recursed into.
1816
"""
1917
file_list = []
2018
for src_root_dir in src_root_dirs:
@@ -25,20 +23,39 @@ def merge_file_lists(src_root_dirs, explicit_src_files, skip_files,
2523
if file not in skip_files]
2624
file_list.extend(
2725
filter(lambda file: file not in file_list, rel_files))
28-
dirs[:] = filter(
29-
lambda dir: os.path.join(rel_dir, dir)
30-
not in skip_subpaths, dirs)
31-
32-
for file in explicit_src_files:
33-
# If this is an absolute installation path, e.g. /Applications/Xcode/...,
34-
# treat it as being relative to a built toolchain
35-
relative_path = file[1:] if file.startswith("/") else file
36-
file_list.append(relative_path) if relative_path not in file_list else file_list
26+
3727
return file_list
3828

3929

40-
def merge_lipo_files(src_root_dirs, file_list, copy_verbatim_subpaths,
41-
dest_root_dir, verbose=False, lipo_executable="lipo"):
30+
# Determine if the file paths contain any overlapping architectures.
31+
def overlapping_lipo_architectures(file_paths, lipo_executable):
32+
lipo_cmd = [lipo_executable, "-archs"]
33+
34+
known_archs = []
35+
for file in file_paths:
36+
archs = shell.capture(lipo_cmd + [file], echo=False).split(' ')
37+
for arch in archs:
38+
arch = arch.strip()
39+
if arch in known_archs:
40+
return True
41+
known_archs.append(arch)
42+
return False
43+
44+
45+
# Determine the path to the first file and where it should be installed.
46+
def get_first_file_and_dest_path(file, src_root_dirs, dest_root_dir):
47+
for dir in src_root_dirs:
48+
orig_file = os.path.join(dir, file)
49+
if os.path.exists(orig_file):
50+
dest_path = os.path.join(
51+
dest_root_dir, os.path.relpath(orig_file, dir))
52+
return (orig_file, dest_path)
53+
54+
return None
55+
56+
57+
def merge_lipo_files(src_root_dirs, file_list, dest_root_dir, verbose=False,
58+
lipo_executable="lipo"):
4259
"""Recursively merges and runs lipo on all files from file_list in
4360
src_root_dirs to destRoorDir.
4461
@@ -48,9 +65,7 @@ def merge_lipo_files(src_root_dirs, file_list, copy_verbatim_subpaths,
4865
it's lipo'ed together from all src_root_dirs into a fat binary.
4966
5067
Any path in file_list that's a directory in src_root_dirs results in a
51-
corresponding subdirectory in dest_root_dir. If the subdirectory path
52-
matches copy_verbatim_subpaths, the whole subdirectory is recursively
53-
copied verbatim.
68+
corresponding subdirectory in dest_root_dir.
5469
"""
5570
lipo_cmd = [lipo_executable, "-create"]
5671

@@ -62,8 +77,10 @@ def merge_lipo_files(src_root_dirs, file_list, copy_verbatim_subpaths,
6277
print("-- Warning: Can't locate source file %s" % file)
6378
continue
6479

65-
dest_path = os.path.join(
66-
dest_root_dir, os.path.relpath(file_paths[0], src_root_dirs[0]))
80+
first_file_and_dest = get_first_file_and_dest_path(
81+
file, src_root_dirs, dest_root_dir)
82+
orig_file = first_file_and_dest[0]
83+
dest_path = first_file_and_dest[1]
6784

6885
if all([os.path.islink(item) for item in file_paths]):
6986
# It's a symlink in all found instances, copy the link.
@@ -73,32 +90,34 @@ def merge_lipo_files(src_root_dirs, file_list, copy_verbatim_subpaths,
7390
os.remove(dest_path)
7491
os.symlink(os.readlink(file_paths[0]), dest_path)
7592
elif all([os.path.isdir(item) for item in file_paths]):
76-
# It's a subdir in all found instances.
77-
# See if we should copy verbatim or create the destination subdir.
78-
if file in copy_verbatim_subpaths:
79-
print("-- Copying subdir verbatim %s" % dest_path)
80-
if os.path.isdir(dest_path):
81-
shutil.rmtree(dest_path)
82-
shutil.copytree(file_paths[0], dest_path, symlinks=True)
83-
else:
84-
print("-- Creating subdir %s" % dest_path)
85-
if not os.path.isdir(dest_path):
86-
os.makedirs(dest_path)
93+
# It's a subdir in all found instances. Create the destination
94+
# subdir.
95+
print("-- Creating subdir %s" % dest_path)
96+
if not os.path.isdir(dest_path):
97+
os.makedirs(dest_path)
8798
elif all([os.path.isfile(item) for item in file_paths]):
8899
# It's a regular file in all found instances, see if they're
89100
# identical.
90101
if all([filecmp.cmp(item, file_paths[0]) for item in file_paths]):
91102
# All instances are identical, just copy the unique file.
92103
print("-- Copying file %s" % dest_path)
93-
shutil.copy2(file_paths[0], dest_path)
104+
shutil.copy2(orig_file, dest_path)
94105
elif all([os.access(item, os.X_OK) for item in file_paths]):
95-
# Multiple instances are different and executable, try lipo.
96-
if verbose:
97-
print("-- Running lipo %s to %s" % (file_paths, dest_path))
106+
if overlapping_lipo_architectures(file_paths, lipo_executable):
107+
# lipo will fail due to overlapping architectures, so
108+
# copy the file directly.
109+
print("-- Copying file verbatim %s" % dest_path)
110+
shutil.copy2(orig_file, dest_path)
98111
else:
99-
print("-- Running lipo %s" % dest_path)
100-
shell.call(lipo_cmd + ["-output", dest_path] + file_paths,
101-
echo=verbose)
112+
# Multiple instances are different and executable, try lipo.
113+
if verbose:
114+
print("-- Running lipo %s to %s" %
115+
(file_paths, dest_path))
116+
else:
117+
print("-- Running lipo %s" % dest_path)
118+
shell.call((lipo_cmd + ["-output", dest_path] +
119+
file_paths),
120+
echo=verbose)
102121
else:
103122
# Multiple instances are different, and they're not executable.
104123
print(
@@ -119,10 +138,6 @@ If all the copies of the file in the source directories are the same,
119138
the file is copied directly to the destination. If there are different
120139
files in different directories, but the files are executable,
121140
lipo is run to merge the files together. Otherwise, a warning is produced.
122-
123-
Use --copy-subdirs to override normal logic and copy certain sub directory
124-
paths verbatim. This is useful if some subdirectories already contain fat
125-
binaries.
126141
""")
127142

128143
parser.add_argument("-v", "--verbose", action='store_true',
@@ -134,19 +149,6 @@ binaries.
134149
default=".DS_Store",
135150
help="Files to ignore and skip merge/copy, default " +
136151
"is \".DS_Store\"")
137-
# A list of files which this script will ensure are merged using lipo.
138-
# The intent is to allow for exceptions to binaries located under
139-
# `copy-subdirs` that are not built fat. However, if more such exceptions
140-
# are added, it would be better to re-think our approach to a more-general
141-
# solution.
142-
parser.add_argument("--explicit-src-files", metavar="<explicit-source-files>",
143-
default="",
144-
help="Optional list of files which should be merged to " +
145-
"be installed")
146-
parser.add_argument("--copy-subdirs", metavar="<subdirs-to-copy-verbatim>",
147-
default="",
148-
help="Optional list of subdirectory paths that " +
149-
"should be copied verbatim")
150152

151153
required_group = parser.add_argument_group("required arguments")
152154
required_group.add_argument("--destination", metavar="<dest-path>",
@@ -159,19 +161,15 @@ binaries.
159161
args = parser.parse_args()
160162

161163
skip_files = args.skip_files.split()
162-
explicit_sources = args.explicit_src_files.split()
163-
copy_verbatim_subpaths = [
164-
subdir.strip('/') for subdir in args.copy_subdirs.split()]
165164

166-
file_list = merge_file_lists(args.src_root_dirs, explicit_sources,
167-
skip_files, copy_verbatim_subpaths)
165+
file_list = merge_file_lists(args.src_root_dirs, skip_files)
168166

169167
if args.verbose:
170168
print("Discovered files and dirs: %s" % file_list)
171169

172170
merge_lipo_files(
173-
args.src_root_dirs, file_list, copy_verbatim_subpaths,
174-
args.destination, args.verbose, args.lipo)
171+
args.src_root_dirs, file_list, args.destination, args.verbose,
172+
args.lipo)
175173

176174
return 0
177175

0 commit comments

Comments
 (0)