Skip to content

Commit 55b67af

Browse files
authored
Merge pull request #205 from bazel-ios/thiago/symlink-headers-instead-of-copy-in-frameworks
Symlink headers and modulemap instead of copy in framework_packaging
2 parents 8d8b1fa + 4137cda commit 55b67af

File tree

2 files changed

+47
-56
lines changed

2 files changed

+47
-56
lines changed

rules/framework.bzl

Lines changed: 47 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,39 @@ def _find_framework_dir(outputs):
4646
return prefix + ".framework"
4747
return None
4848

49+
def _framework_packaging_symlink_headers(ctx, inputs, outputs):
50+
inputs_by_basename = {input.basename: input for input in inputs}
51+
52+
# If this check is true it means that multiple inputs have the same 'basename',
53+
# an additional check is done to see if that was caused by 'action_inputs' containing
54+
# two different paths to the same file
55+
#
56+
# In that case fails with a msg listing the differences found
57+
if len(inputs_by_basename) < len(inputs):
58+
inputs_by_basename_paths = [x.path for x in inputs_by_basename.values()]
59+
inputs_with_duplicated_basename = [x for x in inputs if not x.path in inputs_by_basename_paths]
60+
if len(inputs_with_duplicated_basename) > 0:
61+
fail("""
62+
[Error] Multiple files with the same name exists.\n
63+
See below for the list of paths found for each basename:\n
64+
{}
65+
""".format({x.basename: (x.path, inputs_by_basename[x.basename].path) for x in inputs_with_duplicated_basename}))
66+
67+
# If no error occurs create symlinks for each output with
68+
# each input as 'target_file'
69+
output_input_dict = {output: inputs_by_basename[output.basename] for output in outputs}
70+
for (output, input) in output_input_dict.items():
71+
ctx.actions.symlink(output = output, target_file = input)
72+
73+
def _framework_packaging_symlink_modulemap(ctx, inputs, outputs):
74+
if len(inputs) != 1 or len(outputs) != 1:
75+
fail("""
76+
Multiple .modulemap files found, double check expected inputs and outputs:\n
77+
inputs: {}\n
78+
outputs: {}
79+
""".format([x.path for x in inputs], [x.path for x in outputs]))
80+
ctx.actions.symlink(output = outputs[0], target_file = inputs[0])
81+
4982
def _framework_packaging(ctx, action, inputs, outputs, manifest = None):
5083
if not inputs:
5184
return []
@@ -63,13 +96,20 @@ def _framework_packaging(ctx, action, inputs, outputs, manifest = None):
6396
args.add("--action", action)
6497
args.add_all("--inputs", inputs)
6598
args.add_all("--outputs", outputs)
66-
ctx.actions.run(
67-
executable = ctx.executable._framework_packaging,
68-
arguments = [args],
69-
inputs = action_inputs,
70-
outputs = outputs,
71-
mnemonic = "PackagingFramework%s" % action.title().replace("_", ""),
72-
)
99+
100+
if action in ["header", "private_header"]:
101+
_framework_packaging_symlink_headers(ctx, inputs, outputs)
102+
elif action == "modulemap":
103+
_framework_packaging_symlink_modulemap(ctx, inputs, outputs)
104+
else:
105+
ctx.actions.run(
106+
executable = ctx.executable._framework_packaging,
107+
arguments = [args],
108+
inputs = action_inputs,
109+
outputs = outputs,
110+
mnemonic = "PackagingFramework%s" % action.title().replace("_", ""),
111+
)
112+
73113
return outputs
74114

75115
def _add_to_dict_if_present(dict, key, value):

rules/framework/framework_packaging.py

Lines changed: 0 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -18,37 +18,6 @@ def _mkdir(path):
1818
def _cp(src, dest):
1919
shutil.copyfile(src, dest)
2020

21-
22-
def _copy_private_headers(framework_root, header_paths):
23-
_copy_headers(framework_root, header_paths, "PrivateHeaders")
24-
25-
def _copy_headers(framework_root, header_paths, dir = "Headers"):
26-
"""Copy header from source to framework/Header folder.
27-
28-
Args:
29-
framework_root: root path of the framework
30-
header_paths: a list of paths of headers
31-
"""
32-
if not header_paths: return
33-
34-
header_folder = os.path.join(framework_root, dir)
35-
_mkdir(header_folder)
36-
basenames = {}
37-
for path in header_paths:
38-
basename = os.path.basename(path)
39-
if basename in basenames and path != basenames[basename]:
40-
print(
41-
"Error: Multiple files with the same name {} exists\n"
42-
"New path: {}\n Existing path: {}\n"
43-
"in the same module. Please double "
44-
"check".format(basename, path, basenames[basename]))
45-
sys.exit(1)
46-
else:
47-
basenames[basename] = path
48-
dest = os.path.join(header_folder, basename)
49-
_cp(path, dest)
50-
51-
5221
def _merge_binaries(framework_root, framework_name, binary_in):
5322
"""Process built binaries.
5423
@@ -73,18 +42,6 @@ def _merge_binaries(framework_root, framework_name, binary_in):
7342
] + binary_in
7443
subprocess.check_call(commands)
7544

76-
77-
def _copy_modulemap(framework_root, modulemap_path):
78-
"""Copy modulemaps to its destination.
79-
80-
Args:
81-
framework_root: root folder of the framework
82-
modulemap_path: path of the original modulemap
83-
"""
84-
dest = os.path.join(framework_root, "Modules", "module.modulemap")
85-
_mkdir(os.path.dirname(dest))
86-
_cp(modulemap_path, dest)
87-
8845
def _clean(framework_root, manifest_file, output_manifest_file):
8946
"""Remove stale files from the framework root.
9047
@@ -135,14 +92,8 @@ def output(self):
13592
def main():
13693
"""Main function."""
13794
actions = {
138-
"header":
139-
lambda args: _copy_headers(args.framework_root, args.inputs),
140-
"private_header":
141-
lambda args: _copy_private_headers(args.framework_root, args.inputs),
14295
"binary":
14396
lambda args: _merge_binaries(args.framework_root, args.framework_name, args.inputs),
144-
"modulemap":
145-
lambda args: _copy_modulemap(args.framework_root, args.input()),
14697
"swiftmodule":
14798
lambda args: _cp(args.input(), args.output()),
14899
"swiftdoc":

0 commit comments

Comments
 (0)