diff --git a/rules/framework.bzl b/rules/framework.bzl index 93160f9b3..8f73760dd 100644 --- a/rules/framework.bzl +++ b/rules/framework.bzl @@ -46,6 +46,39 @@ def _find_framework_dir(outputs): return prefix + ".framework" return None +def _framework_packaging_symlink_headers(ctx, inputs, outputs): + inputs_by_basename = {input.basename: input for input in inputs} + + # If this check is true it means that multiple inputs have the same 'basename', + # an additional check is done to see if that was caused by 'action_inputs' containing + # two different paths to the same file + # + # In that case fails with a msg listing the differences found + if len(inputs_by_basename) < len(inputs): + inputs_by_basename_paths = [x.path for x in inputs_by_basename.values()] + inputs_with_duplicated_basename = [x for x in inputs if not x.path in inputs_by_basename_paths] + if len(inputs_with_duplicated_basename) > 0: + fail(""" + [Error] Multiple files with the same name exists.\n + See below for the list of paths found for each basename:\n + {} + """.format({x.basename: (x.path, inputs_by_basename[x.basename].path) for x in inputs_with_duplicated_basename})) + + # If no error occurs create symlinks for each output with + # each input as 'target_file' + output_input_dict = {output: inputs_by_basename[output.basename] for output in outputs} + for (output, input) in output_input_dict.items(): + ctx.actions.symlink(output = output, target_file = input) + +def _framework_packaging_symlink_modulemap(ctx, inputs, outputs): + if len(inputs) != 1 or len(outputs) != 1: + fail(""" + Multiple .modulemap files found, double check expected inputs and outputs:\n + inputs: {}\n + outputs: {} + """.format([x.path for x in inputs], [x.path for x in outputs])) + ctx.actions.symlink(output = outputs[0], target_file = inputs[0]) + def _framework_packaging(ctx, action, inputs, outputs, manifest = None): if not inputs: return [] @@ -63,13 +96,20 @@ def _framework_packaging(ctx, action, inputs, outputs, manifest = None): args.add("--action", action) args.add_all("--inputs", inputs) args.add_all("--outputs", outputs) - ctx.actions.run( - executable = ctx.executable._framework_packaging, - arguments = [args], - inputs = action_inputs, - outputs = outputs, - mnemonic = "PackagingFramework%s" % action.title().replace("_", ""), - ) + + if action in ["header", "private_header"]: + _framework_packaging_symlink_headers(ctx, inputs, outputs) + elif action == "modulemap": + _framework_packaging_symlink_modulemap(ctx, inputs, outputs) + else: + ctx.actions.run( + executable = ctx.executable._framework_packaging, + arguments = [args], + inputs = action_inputs, + outputs = outputs, + mnemonic = "PackagingFramework%s" % action.title().replace("_", ""), + ) + return outputs def _add_to_dict_if_present(dict, key, value): diff --git a/rules/framework/framework_packaging.py b/rules/framework/framework_packaging.py index 1bee806d4..011ae6096 100644 --- a/rules/framework/framework_packaging.py +++ b/rules/framework/framework_packaging.py @@ -18,37 +18,6 @@ def _mkdir(path): def _cp(src, dest): shutil.copyfile(src, dest) - -def _copy_private_headers(framework_root, header_paths): - _copy_headers(framework_root, header_paths, "PrivateHeaders") - -def _copy_headers(framework_root, header_paths, dir = "Headers"): - """Copy header from source to framework/Header folder. - - Args: - framework_root: root path of the framework - header_paths: a list of paths of headers - """ - if not header_paths: return - - header_folder = os.path.join(framework_root, dir) - _mkdir(header_folder) - basenames = {} - for path in header_paths: - basename = os.path.basename(path) - if basename in basenames and path != basenames[basename]: - print( - "Error: Multiple files with the same name {} exists\n" - "New path: {}\n Existing path: {}\n" - "in the same module. Please double " - "check".format(basename, path, basenames[basename])) - sys.exit(1) - else: - basenames[basename] = path - dest = os.path.join(header_folder, basename) - _cp(path, dest) - - def _merge_binaries(framework_root, framework_name, binary_in): """Process built binaries. @@ -73,18 +42,6 @@ def _merge_binaries(framework_root, framework_name, binary_in): ] + binary_in subprocess.check_call(commands) - -def _copy_modulemap(framework_root, modulemap_path): - """Copy modulemaps to its destination. - - Args: - framework_root: root folder of the framework - modulemap_path: path of the original modulemap - """ - dest = os.path.join(framework_root, "Modules", "module.modulemap") - _mkdir(os.path.dirname(dest)) - _cp(modulemap_path, dest) - def _clean(framework_root, manifest_file, output_manifest_file): """Remove stale files from the framework root. @@ -135,14 +92,8 @@ def output(self): def main(): """Main function.""" actions = { - "header": - lambda args: _copy_headers(args.framework_root, args.inputs), - "private_header": - lambda args: _copy_private_headers(args.framework_root, args.inputs), "binary": lambda args: _merge_binaries(args.framework_root, args.framework_name, args.inputs), - "modulemap": - lambda args: _copy_modulemap(args.framework_root, args.input()), "swiftmodule": lambda args: _cp(args.input(), args.output()), "swiftdoc":