# Copyright 2015 The Crashpad Authors
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

import("../build/crashpad_buildconfig.gni")
import("net/tls.gni")

if (crashpad_is_in_chromium) {
  import("//build/config/sanitizers/sanitizers.gni")
}

if (crashpad_is_apple && !crashpad_is_tvos) {
  if (crashpad_is_in_chromium || crashpad_is_in_fuchsia) {
    import("//build/config/sysroot.gni")
  } else {
    import("$mini_chromium_import_root/build/sysroot.gni")
  }

  action_foreach("mig") {
    script = "mach/mig.py"
    inputs = [
      "mach/mig_fix.py",
      "mach/mig_gen.py",
    ]

    if (crashpad_is_mac) {
      sources = [
        "$sysroot/usr/include/mach/exc.defs",
        "$sysroot/usr/include/mach/mach_exc.defs",
        "$sysroot/usr/include/mach/notify.defs",
        "mach/child_port.defs",
      ]
    } else if (crashpad_is_ios) {
      sources = [
        # The iOS SDK doesn’t have any .defs files. Get them directly from xnu.
        "../third_party/xnu/osfmk/mach/exc.defs",
        "../third_party/xnu/osfmk/mach/mach_exc.defs",
      ]
    }

    outputs = [
      "$target_gen_dir/mach/{{source_name_part}}User.c",
      "$target_gen_dir/mach/{{source_name_part}}Server.c",
      "$target_gen_dir/mach/{{source_name_part}}.h",
      "$target_gen_dir/mach/{{source_name_part}}Server.h",
    ]

    args = [ "{{source}}" ]
    args += rebase_path(outputs, root_build_dir)
    if (crashpad_is_in_chromium) {
      if (!use_system_xcode) {
        import("//build/config/clang/clang.gni")
        import("//build/config/mac/mac_sdk.gni")
        clang_path =
            rebase_path("$clang_base_path/bin/", root_build_dir) + "clang"
        mig_path = "$mac_bin_path" + "mig"
        migcom_path = "$mac_bin_path" + "../libexec/migcom"

        args += [
          "--clang-path",
          clang_path,
          "--mig-path",
          mig_path,
          "--migcom-path",
          migcom_path,
        ]
      }
      if (crashpad_is_mac) {
        deps = [ "//build/config/mac:sdk_inputs" ]
      }
    }
    if (sysroot != "") {
      if (crashpad_is_in_chromium) {
        # Chromium often brings along its own SDK and wants to keep paths
        # relative…
        args += [
          "--sdk",
          rebase_path(sysroot, root_build_dir),
        ]
      } else {
        # …but that’s not an option in the standalone Crashpad build, where the
        # SDK is installed on the system and is absolute. (But use rebase_path
        # just to be sure.)
        args += [
          "--sdk",
          rebase_path(sysroot, ""),
        ]
      }
    }
    args += [
      "--include",
      rebase_path("..", root_build_dir),
      "--include",
      rebase_path("../compat/mac", root_build_dir),
    ]
    if (crashpad_is_ios) {
      args += [
        "--include",
        rebase_path("../compat/ios", root_build_dir),
      ]
    }
    if (current_cpu == "x86") {
      args += [
        "--arch",
        "i386",
      ]
    } else if (current_cpu == "x64") {
      args += [
        "--arch",
        "x86_64",
      ]
    } else if (current_cpu == "arm") {
      args += [
        "--arch",
        "armv7",
      ]
    } else if (current_cpu == "arm64") {
      args += [
        "--arch",
        "arm64",
      ]
    } else if (crashpad_is_mac && current_cpu == "mac_universal") {
      args += [
        "--arch",
        "x86_64",
        "--arch",
        "arm64",
      ]
    } else {
      assert(false, "Unsupported architecture")
    }
  }

  static_library("mig_output") {
    deps = [ ":mig" ]
    sources = get_target_outputs(":mig")
    if (crashpad_is_in_chromium) {
      # mig output contains unreachable code, which irks -Wunreachable-code.
      configs -= [ "//build/config/compiler:chromium_code" ]
      configs += [ "//build/config/compiler:no_chromium_code" ]
    }
    public_configs = [ "..:crashpad_config" ]
  }
}

# Used by crashpad_wer_handler to avoid linking all of :util.
if (crashpad_is_win) {
  source_set("util_registration_protocol") {
    sources = [
      "misc/address_types.h",
      "win/address_types.h",
      "win/registration_protocol_win_structs.h",
    ]
    public_deps = [ "../third_party/mini_chromium:build" ]
    public_configs = [ "..:crashpad_config" ]
  }
}

crashpad_static_library("util") {
  sources = [
    "file/delimited_file_reader.cc",
    "file/delimited_file_reader.h",
    "file/directory_reader.h",
    "file/file_helper.cc",
    "file/file_helper.h",
    "file/file_io.cc",
    "file/file_io.h",
    "file/file_reader.cc",
    "file/file_reader.h",
    "file/file_seeker.cc",
    "file/file_seeker.h",
    "file/file_writer.cc",
    "file/file_writer.h",
    "file/filesystem.h",
    "file/output_stream_file_writer.cc",
    "file/output_stream_file_writer.h",
    "file/scoped_remove_file.cc",
    "file/scoped_remove_file.h",
    "file/string_file.cc",
    "file/string_file.h",
    "misc/address_sanitizer.h",
    "misc/address_types.h",
    "misc/arraysize.h",
    "misc/as_underlying_type.h",
    "misc/capture_context.h",
    "misc/clock.h",
    "misc/elf_note_types.h",
    "misc/from_pointer_cast.h",
    "misc/implicit_cast.h",
    "misc/initialization_state.h",
    "misc/initialization_state_dcheck.cc",
    "misc/initialization_state_dcheck.h",
    "misc/lexing.cc",
    "misc/lexing.h",
    "misc/memory_sanitizer.h",
    "misc/metrics.cc",
    "misc/metrics.h",
    "misc/paths.h",
    "misc/pdb_structures.cc",
    "misc/pdb_structures.h",
    "misc/random_string.cc",
    "misc/random_string.h",
    "misc/range_set.cc",
    "misc/range_set.h",
    "misc/reinterpret_bytes.cc",
    "misc/reinterpret_bytes.h",
    "misc/scoped_forbid_return.cc",
    "misc/scoped_forbid_return.h",
    "misc/symbolic_constants_common.h",
    "misc/time.cc",
    "misc/time.h",
    "misc/tri_state.h",
    "misc/uuid.cc",
    "misc/uuid.h",
    "misc/zlib.cc",
    "misc/zlib.h",
    "numeric/checked_address_range.cc",
    "numeric/checked_address_range.h",
    "numeric/checked_range.h",
    "numeric/checked_vm_address_range.h",
    "numeric/in_range_cast.h",
    "numeric/int128.h",
    "numeric/safe_assignment.h",
    "process/process_id.h",
    "process/process_memory.cc",
    "process/process_memory.h",
    "process/process_memory_native.h",
    "process/process_memory_range.cc",
    "process/process_memory_range.h",
    "stdlib/aligned_allocator.cc",
    "stdlib/aligned_allocator.h",
    "stdlib/map_insert.h",
    "stdlib/objc.h",
    "stdlib/string_number_conversion.cc",
    "stdlib/string_number_conversion.h",
    "stdlib/strlcpy.cc",
    "stdlib/strlcpy.h",
    "stdlib/strnlen.cc",
    "stdlib/strnlen.h",
    "stdlib/thread_safe_vector.h",
    "stream/base94_output_stream.cc",
    "stream/base94_output_stream.h",
    "stream/file_encoder.cc",
    "stream/file_encoder.h",
    "stream/file_output_stream.cc",
    "stream/file_output_stream.h",
    "stream/log_output_stream.cc",
    "stream/log_output_stream.h",
    "stream/output_stream_interface.h",
    "stream/zlib_output_stream.cc",
    "stream/zlib_output_stream.h",
    "string/split_string.cc",
    "string/split_string.h",
    "synchronization/scoped_spin_guard.h",
    "synchronization/semaphore.h",
    "thread/stoppable.h",
    "thread/thread.cc",
    "thread/thread.h",
    "thread/thread_log_messages.cc",
    "thread/thread_log_messages.h",
    "thread/worker_thread.cc",
    "thread/worker_thread.h",
  ]

  defines = [ "ZLIB_CONST" ]

  if (crashpad_is_posix || crashpad_is_fuchsia) {
    sources += [
      "file/directory_reader_posix.cc",
      "file/file_io_posix.cc",
      "file/filesystem_posix.cc",
      "misc/clock_posix.cc",
      "posix/close_stdio.cc",
      "posix/close_stdio.h",
      "posix/scoped_dir.cc",
      "posix/scoped_dir.h",
      "posix/scoped_mmap.cc",
      "posix/scoped_mmap.h",
      "posix/signals.cc",
      "posix/signals.h",
      "synchronization/semaphore_posix.cc",
      "thread/thread_posix.cc",
    ]

    if (!crashpad_is_fuchsia) {
      sources += [
        "posix/close_multiple.cc",
        "posix/close_multiple.h",
        "posix/drop_privileges.cc",
        "posix/drop_privileges.h",
        "posix/process_info.h",

        # These map signals to and from strings. While Fuchsia defines some of
        # the common SIGx defines, signals are never raised on Fuchsia, so
        # there's need to include this mapping code.
        "posix/symbolic_constants_posix.cc",
        "posix/symbolic_constants_posix.h",
      ]

      if (crashpad_is_android || crashpad_is_linux || crashpad_is_mac) {
        sources += [
          "posix/spawn_subprocess.cc",
          "posix/spawn_subprocess.h",
        ]
      }
    }
  }

  if (crashpad_is_apple) {
    sources += [
      "mac/sysctl.cc",
      "mac/sysctl.h",
      "mac/xattr.cc",
      "mac/xattr.h",
      "mach/mach_extensions.cc",
      "mach/mach_extensions.h",
      "misc/capture_context_mac.S",
      "misc/clock_mac.cc",
      "misc/paths_mac.cc",
      "synchronization/semaphore_mac.cc",
    ]

    # Exclude files related to Mach exceptions when building for tvOS. Mach
    # messaging APIs are not available to third-party applications on tvOS so
    # crashes are handled via POSIX signals.
    if (!crashpad_is_tvos) {
      sources += [
        "mach/composite_mach_message_server.cc",
        "mach/composite_mach_message_server.h",
        "mach/exc_client_variants.cc",
        "mach/exc_client_variants.h",
        "mach/exc_server_variants.cc",
        "mach/exc_server_variants.h",
        "mach/exception_behaviors.cc",
        "mach/exception_behaviors.h",
        "mach/exception_ports.cc",
        "mach/exception_ports.h",
        "mach/mach_message.cc",
        "mach/mach_message.h",
        "mach/mach_message_server.cc",
        "mach/mach_message_server.h",
        "mach/symbolic_constants_mach.cc",
        "mach/symbolic_constants_mach.h",
      ]
    }
  }

  if (crashpad_is_mac && !crashpad_is_in_fuchsia) {
    sources += [
      "mac/checked_mach_address_range.h",
      "mac/launchd.h",
      "mac/launchd.mm",
      "mac/mac_util.cc",
      "mac/mac_util.h",
      "mac/service_management.cc",
      "mac/service_management.h",
      "mach/bootstrap.cc",
      "mach/bootstrap.h",
      "mach/child_port_handshake.cc",
      "mach/child_port_handshake.h",
      "mach/child_port_server.cc",
      "mach/child_port_server.h",
      "mach/child_port_types.h",
      "mach/exception_types.cc",
      "mach/exception_types.h",
      "mach/notify_server.cc",
      "mach/notify_server.h",
      "mach/scoped_task_suspend.cc",
      "mach/scoped_task_suspend.h",
      "mach/task_for_pid.cc",
      "mach/task_for_pid.h",
      "posix/process_info_mac.cc",
      "process/process_memory_mac.cc",
      "process/process_memory_mac.h",
    ]
  }

  if (crashpad_is_ios) {
    sources += [
      "ios/ios_intermediate_dump_data.cc",
      "ios/ios_intermediate_dump_data.h",
      "ios/ios_intermediate_dump_format.h",
      "ios/ios_intermediate_dump_interface.cc",
      "ios/ios_intermediate_dump_interface.h",
      "ios/ios_intermediate_dump_list.cc",
      "ios/ios_intermediate_dump_list.h",
      "ios/ios_intermediate_dump_map.cc",
      "ios/ios_intermediate_dump_map.h",
      "ios/ios_intermediate_dump_object.cc",
      "ios/ios_intermediate_dump_object.h",
      "ios/ios_intermediate_dump_reader.cc",
      "ios/ios_intermediate_dump_reader.h",
      "ios/ios_intermediate_dump_writer.cc",
      "ios/ios_intermediate_dump_writer.h",
      "ios/ios_system_data_collector.h",
      "ios/ios_system_data_collector.mm",
      "ios/raw_logging.cc",
      "ios/raw_logging.h",
      "ios/scoped_background_task.h",
      "ios/scoped_background_task.mm",
      "ios/scoped_vm_map.cc",
      "ios/scoped_vm_map.h",
      "ios/scoped_vm_read.cc",
      "ios/scoped_vm_read.h",
    ]
  }

  deps = []

  if (crashpad_is_android) {
    sources += [
      "linux/initial_signal_dispositions.cc",
      "linux/initial_signal_dispositions.h",
    ]
  }

  if (crashpad_is_linux || crashpad_is_android) {
    sources += [
      "linux/address_types.h",
      "linux/auxiliary_vector.cc",
      "linux/auxiliary_vector.h",
      "linux/checked_linux_address_range.h",
      "linux/direct_ptrace_connection.cc",
      "linux/direct_ptrace_connection.h",
      "linux/exception_handler_client.cc",
      "linux/exception_handler_client.h",
      "linux/exception_handler_protocol.cc",
      "linux/exception_handler_protocol.h",
      "linux/exception_information.h",
      "linux/memory_map.cc",
      "linux/memory_map.h",
      "linux/pac_helper.cc",
      "linux/pac_helper.h",
      "linux/proc_stat_reader.cc",
      "linux/proc_stat_reader.h",
      "linux/proc_task_reader.cc",
      "linux/proc_task_reader.h",
      "linux/ptrace_broker.cc",
      "linux/ptrace_broker.h",
      "linux/ptrace_client.cc",
      "linux/ptrace_client.h",
      "linux/ptrace_connection.h",
      "linux/ptracer.cc",
      "linux/ptracer.h",
      "linux/scoped_pr_set_dumpable.cc",
      "linux/scoped_pr_set_dumpable.h",
      "linux/scoped_pr_set_ptracer.cc",
      "linux/scoped_pr_set_ptracer.h",
      "linux/scoped_ptrace_attach.cc",
      "linux/scoped_ptrace_attach.h",
      "linux/socket.cc",
      "linux/socket.h",
      "linux/thread_info.cc",
      "linux/thread_info.h",
      "linux/traits.h",
      "misc/capture_context_linux.S",
      "misc/paths_linux.cc",
      "misc/time_linux.cc",
      "posix/process_info_linux.cc",
      "process/process_memory_linux.cc",
      "process/process_memory_linux.h",
      "process/process_memory_sanitized.cc",
      "process/process_memory_sanitized.h",
    ]
  }

  if (crashpad_is_win) {
    sources += [
      "file/directory_reader_win.cc",
      "file/file_io_win.cc",
      "file/filesystem_win.cc",
      "misc/clock_win.cc",
      "misc/paths_win.cc",
      "misc/time_win.cc",
      "process/process_memory_win.cc",
      "process/process_memory_win.h",
      "synchronization/semaphore_win.cc",
      "thread/thread_win.cc",
      "win/address_types.h",
      "win/checked_win_address_range.h",
      "win/command_line.cc",
      "win/command_line.h",
      "win/context_wrappers.h",
      "win/critical_section_with_debug_info.cc",
      "win/critical_section_with_debug_info.h",
      "win/exception_codes.h",
      "win/exception_handler_server.cc",
      "win/exception_handler_server.h",
      "win/get_function.cc",
      "win/get_function.h",
      "win/get_module_information.cc",
      "win/get_module_information.h",
      "win/handle.cc",
      "win/handle.h",
      "win/initial_client_data.cc",
      "win/initial_client_data.h",
      "win/loader_lock.cc",
      "win/loader_lock.h",
      "win/module_version.cc",
      "win/module_version.h",
      "win/nt_internals.cc",
      "win/nt_internals.h",
      "win/ntstatus_logging.cc",
      "win/ntstatus_logging.h",
      "win/process_info.cc",
      "win/process_info.h",
      "win/process_structs.h",
      "win/registration_protocol_win.cc",
      "win/registration_protocol_win.h",
      "win/registration_protocol_win_structs.h",
      "win/safe_terminate_process.h",
      "win/scoped_handle.cc",
      "win/scoped_handle.h",
      "win/scoped_local_alloc.cc",
      "win/scoped_local_alloc.h",
      "win/scoped_process_suspend.cc",
      "win/scoped_process_suspend.h",
      "win/scoped_registry_key.h",
      "win/scoped_set_event.cc",
      "win/scoped_set_event.h",
      "win/session_end_watcher.cc",
      "win/session_end_watcher.h",
      "win/termination_codes.h",
      "win/traits.h",
      "win/xp_compat.h",
    ]

    if (current_cpu != "arm64") {
      sources += [
        "misc/capture_context_win.asm",
        "win/safe_terminate_process.asm",
      ]
    } else {
      # When building with clang, clang-cl is used as the assembler. Since
      # clang-cl recognizes a different assembly dialect than Microsoft’s
      # armasm64 macro assembler, the same .asm file can’t be used for each. As
      # a workaround, use a prebuilt .obj file when the Microsoft-dialect
      # assembler isn’t available.
      if (crashpad_is_clang) {
        sources += [ "misc/capture_context_win_arm64.obj" ]
      } else {
        sources += [ "misc/capture_context_win_arm64.asm" ]
      }
    }
  }

  if (crashpad_is_fuchsia) {
    sources += [
      "fuchsia/koid_utilities.cc",
      "fuchsia/koid_utilities.h",
      "fuchsia/scoped_task_suspend.cc",
      "fuchsia/scoped_task_suspend.h",
      "fuchsia/traits.h",
      "misc/paths_fuchsia.cc",
      "process/process_memory_fuchsia.cc",
      "process/process_memory_fuchsia.h",
    ]

    sources -= [ "misc/capture_context.h" ]
  }

  public_configs = [ "..:crashpad_config" ]

  # Include generated files starting with "util".
  if (crashpad_is_in_fuchsia) {
    include_dirs =
        [ "$root_gen_dir/" + rebase_path(fuchsia_crashpad_root, "//") ]
  } else {
    include_dirs = [ "$root_gen_dir/third_party/crashpad/crashpad" ]
  }

  public_deps = [
    ":no_cfi_icall",
    "../compat",
    "../third_party/zlib",
  ]

  deps = [ "$mini_chromium_source_parent:base" ]

  configs = [ "../build:flock_always_supported_defines" ]

  if (crashpad_is_apple) {
    include_dirs += [ "$root_gen_dir" ]
    deps += [ "../build:apple_enable_arc" ]

    if (!crashpad_is_tvos) {
      deps += [ ":mig_output" ]
    }
  }

  if (crashpad_is_mac && !crashpad_is_in_fuchsia) {
    libs = [ "bsm" ]
    frameworks = [
      "CoreFoundation.framework",
      "Foundation.framework",
      "IOKit.framework",
    ]
  }

  if (crashpad_is_ios) {
    configs += [ "../build:crashpad_is_ios_app_extension" ]
  }

  if (crashpad_is_win) {
    libs = [
      "user32.lib",

      # TODO(jperaza): version.lib is needed for Windows 7 compatibility.
      # mincore.lib may be linked against instead when targeting Windows 8+.
      "version.lib",

      "winhttp.lib",
    ]

    cflags = [ "/wd4201" ]  # nonstandard extension used: nameless struct/union.

    if (current_cpu == "x86") {
      asmflags = [ "/safeseh" ]
    }
  }

  if (crashpad_is_fuchsia) {
    public_deps += [ "../third_party/fuchsia" ]
  }

  if (crashpad_is_android || crashpad_is_linux) {
    deps += [ "../third_party/lss" ]
  }
}

# net is split into a separate target from util so that client code does
# not have to depend on it.
crashpad_static_library("net") {
  sources = [
    "net/http_body.cc",
    "net/http_body.h",
    "net/http_body_gzip.cc",
    "net/http_body_gzip.h",
    "net/http_headers.h",
    "net/http_multipart_builder.cc",
    "net/http_multipart_builder.h",
    "net/http_transport.cc",
    "net/http_transport.h",
    "net/url.cc",
    "net/url.h",
  ]

  deps = [
    ":util",
    "$mini_chromium_source_parent:base",
  ]

  if (crashpad_is_apple) {
    deps += [ "../build:apple_enable_arc" ]
  }

  if (crashpad_is_mac && !crashpad_is_in_fuchsia) {
    sources += [ "net/http_transport_mac.mm" ]
  }

  if (crashpad_is_ios) {
    sources += [ "net/http_transport_mac.mm" ]
  }

  if (crashpad_is_win) {
    sources += [ "net/http_transport_win.cc" ]
  }

  if (crashpad_http_transport_impl == "socket") {
    sources += [ "net/http_transport_socket.cc" ]
    if (crashpad_use_boringssl_for_http_transport_socket) {
      defines = [ "CRASHPAD_USE_BORINGSSL" ]

      if (crashpad_is_in_chromium || crashpad_is_in_fuchsia) {
        deps += [ "//third_party/boringssl" ]
      } else {
        libs = [
          "crypto",
          "ssl",
        ]
      }
    }
  } else if (crashpad_http_transport_impl == "libcurl") {
    sources += [ "net/http_transport_libcurl.cc" ]
  }
}

if (!crashpad_is_android && !crashpad_is_ios) {
  crashpad_executable("http_transport_test_server") {
    testonly = true
    sources = [ "net/http_transport_test_server.cc" ]

    deps = [
      ":net",
      ":util",
      "$mini_chromium_source_parent:base",
      "../third_party/cpp-httplib",
      "../third_party/zlib",
      "../tools:tool_support",
    ]

    # TODO(b/189353575): make these relocatable using $mini_chromium_ variables
    if (crashpad_is_standalone) {
      remove_configs = [ "//third_party/mini_chromium/mini_chromium/build/config:Wexit_time_destructors" ]
    } else if (crashpad_is_external) {
      remove_configs = [ "//../../mini_chromium/mini_chromium/build/config:Wexit_time_destructors" ]
    }

    if (crashpad_is_win) {
      libs = [ "ws2_32.lib" ]
    }

    if (crashpad_use_boringssl_for_http_transport_socket) {
      defines = [ "CRASHPAD_USE_BORINGSSL" ]

      if (crashpad_is_in_chromium || crashpad_is_in_fuchsia) {
        deps += [ "//third_party/boringssl" ]
      } else {
        libs = [
          "crypto",
          "ssl",
        ]
      }
    }
  }
}

# This exists as a separate target from util so that compat may depend on it
# without cycles.
source_set("no_cfi_icall") {
  sources = [ "misc/no_cfi_icall.h" ]
  public_configs = [ "..:crashpad_config" ]
  public_deps = [
    "$mini_chromium_source_parent:base",
    "$mini_chromium_source_parent:build",
  ]
}

source_set("util_test") {
  testonly = true

  sources = [
    "file/delimited_file_reader_test.cc",
    "file/directory_reader_test.cc",
    "file/file_io_test.cc",
    "file/file_reader_test.cc",
    "file/filesystem_test.cc",
    "file/string_file_test.cc",
    "misc/arraysize_test.cc",
    "misc/capture_context_test.cc",
    "misc/capture_context_test_util.h",
    "misc/clock_test.cc",
    "misc/from_pointer_cast_test.cc",
    "misc/initialization_state_dcheck_test.cc",
    "misc/initialization_state_test.cc",
    "misc/no_cfi_icall_test.cc",
    "misc/paths_test.cc",
    "misc/random_string_test.cc",
    "misc/range_set_test.cc",
    "misc/reinterpret_bytes_test.cc",
    "misc/scoped_forbid_return_test.cc",
    "misc/time_test.cc",
    "misc/uuid_test.cc",
    "net/http_body_gzip_test.cc",
    "net/http_body_test.cc",
    "net/http_body_test_util.cc",
    "net/http_body_test_util.h",
    "net/http_multipart_builder_test.cc",
    "net/url_test.cc",
    "numeric/checked_address_range_test.cc",
    "numeric/checked_range_test.cc",
    "numeric/in_range_cast_test.cc",
    "numeric/int128_test.cc",
    "process/process_memory_range_test.cc",
    "process/process_memory_test.cc",
    "stdlib/aligned_allocator_test.cc",
    "stdlib/map_insert_test.cc",
    "stdlib/string_number_conversion_test.cc",
    "stdlib/strlcpy_test.cc",
    "stdlib/strnlen_test.cc",
    "stdlib/thread_safe_vector_test.cc",
    "stream/base94_output_stream_test.cc",
    "stream/file_encoder_test.cc",
    "stream/log_output_stream_test.cc",
    "stream/test_output_stream.cc",
    "stream/test_output_stream.h",
    "stream/zlib_output_stream_test.cc",
    "string/split_string_test.cc",
    "synchronization/scoped_spin_guard_test.cc",
    "synchronization/semaphore_test.cc",
    "thread/thread_log_messages_test.cc",
    "thread/thread_test.cc",
    "thread/worker_thread_test.cc",
  ]

  if (!crashpad_is_android && !crashpad_is_ios) {
    # Android requires an HTTPTransport implementation.
    sources += [ "net/http_transport_test.cc" ]
  }

  if (crashpad_is_posix || crashpad_is_fuchsia) {
    if (!crashpad_is_fuchsia && !crashpad_is_ios) {
      sources += [
        "posix/process_info_test.cc",
        "posix/signals_test.cc",
        "posix/symbolic_constants_posix_test.cc",
      ]
    }
    sources += [ "posix/scoped_mmap_test.cc" ]
  }

  if (crashpad_is_apple) {
    sources += [
      "mac/xattr_test.cc",
      "misc/capture_context_test_util_mac.cc",
    ]

    if (!crashpad_is_tvos) {
      sources += [
        "mach/composite_mach_message_server_test.cc",
        "mach/exc_server_variants_test.cc",
        "mach/exception_behaviors_test.cc",
        "mach/mach_extensions_test.cc",
        "mach/mach_message_test.cc",
        "mach/symbolic_constants_mach_test.cc",
      ]
    }
  }

  if (crashpad_is_mac) {
    sources += [
      "mac/launchd_test.mm",
      "mac/mac_util_test.mm",
      "mac/service_management_test.mm",
      "mac/sysctl_test.cc",
      "mach/bootstrap_test.cc",
      "mach/child_port_handshake_test.cc",
      "mach/child_port_server_test.cc",
      "mach/exc_client_variants_test.cc",
      "mach/exception_ports_test.cc",
      "mach/exception_types_test.cc",
      "mach/mach_message_server_test.cc",
      "mach/notify_server_test.cc",
      "mach/scoped_task_suspend_test.cc",
      "process/process_memory_mac_test.cc",
    ]
  }

  if (crashpad_is_ios) {
    sources += [
      "ios/ios_intermediate_dump_reader_test.cc",
      "ios/ios_intermediate_dump_writer_test.cc",
      "ios/scoped_vm_map_test.cc",
      "ios/scoped_vm_read_test.cc",
    ]

    sources -= [
      "process/process_memory_range_test.cc",
      "process/process_memory_test.cc",
    ]
  }

  if (crashpad_is_linux || crashpad_is_android) {
    sources += [
      "linux/auxiliary_vector_test.cc",
      "linux/memory_map_test.cc",
      "linux/proc_stat_reader_test.cc",
      "linux/proc_task_reader_test.cc",
      "linux/ptrace_broker_test.cc",
      "linux/ptracer_test.cc",
      "linux/scoped_ptrace_attach_test.cc",
      "linux/socket_test.cc",
      "misc/capture_context_test_util_linux.cc",
      "process/process_memory_sanitized_test.cc",
    ]
  }

  if (crashpad_is_fuchsia) {
    sources -= [
      "misc/capture_context_test.cc",
      "misc/capture_context_test_util.h",
    ]
  }

  if (crashpad_is_win) {
    sources += [
      "misc/capture_context_test_util_win.cc",
      "win/command_line_test.cc",
      "win/critical_section_with_debug_info_test.cc",
      "win/exception_handler_server_test.cc",
      "win/get_function_test.cc",
      "win/handle_test.cc",
      "win/initial_client_data_test.cc",
      "win/loader_lock_test.cc",
      "win/process_info_test.cc",
      "win/registration_protocol_win_test.cc",
      "win/safe_terminate_process_test.cc",
      "win/scoped_process_suspend_test.cc",
      "win/session_end_watcher_test.cc",
    ]

    if (crashpad_is_in_chromium && is_asan && is_component_build) {
      # TODO(crbug.com/856174): Re-enable these once Windows ASan is fixed.
      sources -= [ "stdlib/string_number_conversion_test.cc" ]
    }
  }

  data = [
    "net/testdata/ascii_http_body.txt",
    "net/testdata/binary_http_body.dat",
    "net/testdata/crashpad_util_test_cert.pem",
    "net/testdata/crashpad_util_test_key.pem",
  ]

  deps = [
    ":net",
    ":util",
    "$mini_chromium_source_parent:base",
    "../client",
    "../compat",
    "../test",
    "../third_party/googletest",
    "../third_party/googletest:googlemock",
    "../third_party/zlib",
  ]

  if (!crashpad_is_android && !crashpad_is_ios) {
    data_deps = [ ":http_transport_test_server" ]

    if (crashpad_use_boringssl_for_http_transport_socket) {
      defines = [ "CRASHPAD_USE_BORINGSSL" ]
    }
  }

  if (crashpad_is_apple) {
    deps += [ "../build:apple_enable_arc" ]
  }

  if (crashpad_is_mac) {
    frameworks = [ "Foundation.framework" ]
  }

  if (crashpad_is_ios) {
    deps += [ ":util_test_bundle_data" ]
  }

  if (crashpad_is_android || crashpad_is_linux) {
    deps += [ "../third_party/lss" ]
  }

  if (crashpad_is_win) {
    libs = [
      "rpcrt4.lib",
      "dbghelp.lib",
    ]
    data_deps += [
      ":crashpad_util_test_loader_lock_test",
      ":crashpad_util_test_process_info_test_child",
      ":crashpad_util_test_safe_terminate_process_test_child",
    ]
  }
}

if (crashpad_is_ios) {
  bundle_data("util_test_bundle_data") {
    testonly = true

    sources = [
      "net/testdata/ascii_http_body.txt",
      "net/testdata/binary_http_body.dat",
    ]

    outputs = [ "{{bundle_resources_dir}}/crashpad_test_data/" +
                "{{source_root_relative_dir}}/{{source_file_part}}" ]
  }
}

if (crashpad_is_win) {
  crashpad_executable("crashpad_util_test_process_info_test_child") {
    testonly = true
    sources = [ "win/process_info_test_child.cc" ]
  }

  crashpad_executable("crashpad_util_test_safe_terminate_process_test_child") {
    testonly = true
    sources = [ "win/safe_terminate_process_test_child.cc" ]
  }

  crashpad_loadable_module("crashpad_util_test_loader_lock_test") {
    testonly = true
    sources = [ "win/loader_lock_test_dll.cc" ]
    deps = [ ":util" ]
  }
}
