From 0bc3826129d55ff717dde7ebf715c13132886c2e Mon Sep 17 00:00:00 2001 From: Mark Mentovai Date: Wed, 2 Sep 2020 16:42:59 -0400 Subject: [PATCH] mac-arm64: Allow target_cpu = "mac_universal" to create universal builds MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When building for macOS and configured with target_cpu = "mac_universal", bi-architecture x86_64/arm64 output will be produced. mac_universal is, so far, a “Crashpad special” that will only work with mini_chromium and the standalone Crashpad build, and not the in-Chromium build. It exists to support Keystone, which intends to ship as x86_64/arm64 universal. Includes: Update mini_chromium to e0008f2714a76c7f2a3854fa75774427a886d6b9 e0008f2714a7 mac-arm64: Allow target_cpu = "mac_universal" to create universal builds Bug: crashpad:345 Change-Id: I5ff2dce5ffae58186e33757aa94587f8eca20b99 Reviewed-on: https://chromium-review.googlesource.com/c/crashpad/crashpad/+/2387410 Commit-Queue: Mark Mentovai Reviewed-by: Robert Sesek --- DEPS | 2 +- snapshot/BUILD.gn | 3 +- snapshot/x86/cpuid_reader.cc | 5 ++- snapshot/x86/cpuid_reader.h | 6 +++ util/BUILD.gn | 9 ++++ util/mach/mig.py | 80 ++++++++++++++++++++++++++++++++---- util/mach/mig_gen.py | 22 ++++++---- 7 files changed, 110 insertions(+), 17 deletions(-) diff --git a/DEPS b/DEPS index 66c24df3..3ecc47d6 100644 --- a/DEPS +++ b/DEPS @@ -42,7 +42,7 @@ deps = { '7bde79cc274d06451bf65ae82c012a5d3e476b5a', 'crashpad/third_party/mini_chromium/mini_chromium': Var('chromium_git') + '/chromium/mini_chromium@' + - 'f3cfec80ca521881c97629adf6fcdf21158d635d', + 'e0008f2714a76c7f2a3854fa75774427a886d6b9', 'crashpad/third_party/libfuzzer/src': Var('chromium_git') + '/chromium/llvm-project/compiler-rt/lib/fuzzer.git@' + 'fda403cf93ecb8792cb1d061564d89a6553ca020', diff --git a/snapshot/BUILD.gn b/snapshot/BUILD.gn index 8da697d8..0b452ca5 100644 --- a/snapshot/BUILD.gn +++ b/snapshot/BUILD.gn @@ -232,7 +232,8 @@ static_library("snapshot") { ] } - if (current_cpu == "x86" || current_cpu == "x64") { + if (current_cpu == "x86" || current_cpu == "x64" || + (crashpad_is_mac && current_cpu == "mac_universal")) { sources += [ "x86/cpuid_reader.cc", "x86/cpuid_reader.h", diff --git a/snapshot/x86/cpuid_reader.cc b/snapshot/x86/cpuid_reader.cc index e600141f..58340584 100644 --- a/snapshot/x86/cpuid_reader.cc +++ b/snapshot/x86/cpuid_reader.cc @@ -16,7 +16,6 @@ #include -#include "build/build_config.h" #include "snapshot/cpu_context.h" #if defined(OS_WIN) @@ -24,6 +23,8 @@ #include #endif // OS_WIN +#if defined(ARCH_CPU_X86_FAMILY) + namespace crashpad { namespace internal { @@ -132,3 +133,5 @@ void CpuidReader::Cpuid(uint32_t cpuinfo[4], uint32_t leaf) const { } // namespace internal } // namespace crashpad + +#endif // ARCH_CPU_X86_FAMILY diff --git a/snapshot/x86/cpuid_reader.h b/snapshot/x86/cpuid_reader.h index b6782afb..39a1ca84 100644 --- a/snapshot/x86/cpuid_reader.h +++ b/snapshot/x86/cpuid_reader.h @@ -19,6 +19,10 @@ #include +#include "build/build_config.h" + +#if defined(ARCH_CPU_X86_FAMILY) + namespace crashpad { namespace internal { @@ -65,4 +69,6 @@ class CpuidReader { } // namespace internal } // namespace crashpad +#endif // ARCH_CPU_X86_FAMILY + #endif // CRASHPAD_SNAPSHOT_X86_CPUID_READER_H_ diff --git a/util/BUILD.gn b/util/BUILD.gn index 57bcd5c3..2585caae 100644 --- a/util/BUILD.gn +++ b/util/BUILD.gn @@ -131,6 +131,15 @@ if (crashpad_is_mac || crashpad_is_ios) { "--arch", "arm64", ] + } else if (crashpad_is_mac && current_cpu == "mac_universal") { + args += [ + "--arch", + "x86_64", + "--arch", + "arm64", + ] + } else { + assert(false, "Unsupported architecture") } } diff --git a/util/mach/mig.py b/util/mach/mig.py index fa35e006..53a7a5bd 100755 --- a/util/mach/mig.py +++ b/util/mach/mig.py @@ -14,22 +14,88 @@ # See the License for the specific language governing permissions and # limitations under the License. +import os +import shutil import sys +import tempfile import mig_fix import mig_gen -def main(args): - parsed = mig_gen.parse_args(args) +def _try_remove(*paths): + for path in paths: + try: + os.remove(path) + except OSError: + pass - interface = mig_gen.MigInterface(parsed.user_c, parsed.server_c, - parsed.user_h, parsed.server_h) - mig_gen.generate_interface(parsed.defs, interface, parsed.include, - parsed.sdk, parsed.clang_path, parsed.mig_path, - parsed.migcom_path, parsed.arch) + +def _generate_and_fix(user_c, server_c, user_h, server_h, defs, include, sdk, + clang_path, mig_path, migcom_path, arch): + interface = mig_gen.MigInterface(user_c, server_c, user_h, server_h) + mig_gen.generate_interface(defs, interface, include, sdk, clang_path, + mig_path, migcom_path, arch) mig_fix.fix_interface(interface) +def _wrap_arch_guards(file, arch): + contents = '#if defined(__%s__)\n' % arch + contents += open(file, 'r').read() + contents += '\n#endif /* __%s__ */\n' % arch + return contents + + +def _write_file(path, data): + with open(path, 'w') as file: + file.write(data) + + +def main(args): + parsed = mig_gen.parse_args(args, multiple_arch=True) + + _try_remove(parsed.user_c, parsed.server_c, parsed.user_h, parsed.server_h) + + if len(parsed.arch) <= 1: + _generate_and_fix(parsed.user_c, parsed.server_c, parsed.user_h, + parsed.server_h, parsed.defs, parsed.include, + parsed.sdk, parsed.clang_path, parsed.mig_path, + parsed.migcom_path, + parsed.arch[0] if len(parsed.arch) >= 1 else None) + return 0 + + # Run mig once per architecture, and smush everything together, wrapped in + # in architecture-specific #if guards. + + user_c_data = '' + server_c_data = '' + user_h_data = '' + server_h_data = '' + + for arch in parsed.arch: + # Python 3: use tempfile.TempDirectory instead + temp_dir = tempfile.mkdtemp(prefix=os.path.basename(sys.argv[0]) + '_') + try: + user_c = os.path.join(temp_dir, os.path.basename(parsed.user_c)) + server_c = os.path.join(temp_dir, os.path.basename(parsed.server_c)) + user_h = os.path.join(temp_dir, os.path.basename(parsed.user_h)) + server_h = os.path.join(temp_dir, os.path.basename(parsed.server_h)) + _generate_and_fix(user_c, server_c, user_h, server_h, parsed.defs, + parsed.include, parsed.sdk, parsed.clang_path, + parsed.mig_path, parsed.migcom_path, arch) + + user_c_data += _wrap_arch_guards(user_c, arch) + server_c_data += _wrap_arch_guards(server_c, arch) + user_h_data += _wrap_arch_guards(user_h, arch) + server_h_data += _wrap_arch_guards(server_h, arch) + finally: + shutil.rmtree(temp_dir) + + _write_file(parsed.user_c, user_c_data) + _write_file(parsed.server_c, server_c_data) + _write_file(parsed.user_h, user_h_data) + _write_file(parsed.server_h, server_h_data) + + if __name__ == '__main__': sys.exit(main(sys.argv[1:])) diff --git a/util/mach/mig_gen.py b/util/mach/mig_gen.py index dcbf8296..99b4f7ec 100755 --- a/util/mach/mig_gen.py +++ b/util/mach/mig_gen.py @@ -59,17 +59,25 @@ def generate_interface(defs, subprocess.check_call(command) -def parse_args(args): +def parse_args(args, multiple_arch=False): parser = argparse.ArgumentParser() - parser.add_argument('--clang-path', help='Path to Clang') + parser.add_argument('--clang-path', help='Path to clang') parser.add_argument('--mig-path', help='Path to mig') parser.add_argument('--migcom-path', help='Path to migcom') - parser.add_argument('--arch', help='Target architecture') + if not multiple_arch: + parser.add_argument('--arch', help='Target architecture') + else: + parser.add_argument( + '--arch', + default=[], + action='append', + help='Target architecture (may appear multiple times)') parser.add_argument('--sdk', help='Path to SDK') - parser.add_argument('--include', - default=[], - action='append', - help='Additional include directory') + parser.add_argument( + '--include', + default=[], + action='append', + help='Additional include directory (may appear multiple times)') parser.add_argument('defs') parser.add_argument('user_c') parser.add_argument('server_c')