# Copyright (c) 2021 Huawei Device Co., Ltd.
# 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.

if (defined(ohos_lite)) {
  import("//build/lite/config/component/lite_component.gni")
} else {
  import("//build/ohos.gni")
}
import("//third_party/libunwind/libunwind.gni")
common_source = [
  "libunwind/src/dwarf/Gexpr.c",
  "libunwind/src/dwarf/Gfde.c",
  "libunwind/src/dwarf/Gfind_proc_info-lsb.c",
  "libunwind/src/dwarf/Gfind_unwind_table.c",
  "libunwind/src/dwarf/global.c",
  "libunwind/src/dwarf/Gparser.c",
  "libunwind/src/dwarf/Gpe.c",
  "libunwind/src/dwarf/Lexpr.c",
  "libunwind/src/dwarf/Lfde.c",
  "libunwind/src/dwarf/Lfind_proc_info-lsb.c",
  "libunwind/src/dwarf/Lfind_unwind_table.c",
  "libunwind/src/dwarf/Lparser.c",
  "libunwind/src/dwarf/Lpe.c",
  "libunwind/src/mi/backtrace.c",
  "libunwind/src/mi/dyn-cancel.c",
  "libunwind/src/mi/dyn-info-list.c",
  "libunwind/src/mi/dyn-register.c",
  "libunwind/src/mi/flush_cache.c",
  "libunwind/src/mi/Gdestroy_addr_space.c",
  "libunwind/src/mi/Gdyn-extract.c",
  "libunwind/src/mi/Gdyn-remote.c",
  "libunwind/src/mi/Gfind_dynamic_proc_info.c",
  "libunwind/src/mi/Gget_accessors.c",
  "libunwind/src/mi/Gget_fpreg.c",
  "libunwind/src/mi/Gget_proc_info_by_ip.c",
  "libunwind/src/mi/Gget_proc_name.c",
  "libunwind/src/mi/Gget_reg.c",
  "libunwind/src/mi/Gput_dynamic_unwind_info.c",
  "libunwind/src/mi/Gset_cache_size.c",
  "libunwind/src/mi/Gset_caching_policy.c",
  "libunwind/src/mi/Gset_fpreg.c",
  "libunwind/src/mi/Gset_reg.c",
  "libunwind/src/mi/init.c",
  "libunwind/src/mi/Ldestroy_addr_space.c",
  "libunwind/src/mi/Ldyn-extract.c",
  "libunwind/src/mi/Lfind_dynamic_proc_info.c",
  "libunwind/src/mi/Lget_fpreg.c",
  "libunwind/src/mi/Lget_proc_info_by_ip.c",
  "libunwind/src/mi/Lget_proc_name.c",
  "libunwind/src/mi/Lget_reg.c",
  "libunwind/src/mi/Lput_dynamic_unwind_info.c",
  "libunwind/src/mi/Lset_cache_size.c",
  "libunwind/src/mi/Lset_caching_policy.c",
  "libunwind/src/mi/Lset_fpreg.c",
  "libunwind/src/mi/Lset_reg.c",
  "libunwind/src/mi/mempool.c",
  "libunwind/src/mi/strerror.c",
  "libunwind/src/os-linux.c",
  "libunwind/src/ptrace/_UPT_access_fpreg.c",
  "libunwind/src/ptrace/_UPT_access_mem.c",
  "libunwind/src/ptrace/_UPT_access_reg.c",
  "libunwind/src/ptrace/_UPT_accessors.c",
  "libunwind/src/ptrace/_UPT_create.c",
  "libunwind/src/ptrace/_UPT_destroy.c",
  "libunwind/src/ptrace/_UPT_find_proc_info.c",
  "libunwind/src/ptrace/_UPT_get_dyn_info_list_addr.c",
  "libunwind/src/ptrace/_UPT_get_proc_name.c",
  "libunwind/src/ptrace/_UPT_put_unwind_info.c",
  "libunwind/src/ptrace/_UPT_reg_offset.c",
  "libunwind/src/ptrace/_UPT_resume.c",
]

# as libc++ is static linked with libunwind.a
# we remove the Gstep.c for duplicated symbol violation
arm_source = [
  "libunwind/src/arm/Gapply_reg_state.c",
  "libunwind/src/arm/Gcreate_addr_space.c",
  "libunwind/src/arm/Gex_tables.c",
  "libunwind/src/arm/Gget_proc_info.c",
  "libunwind/src/arm/Gget_save_loc.c",
  "libunwind/src/arm/Gglobal.c",
  "libunwind/src/arm/Ginit.c",
  "libunwind/src/arm/Ginit_local.c",
  "libunwind/src/arm/Ginit_remote.c",
  "libunwind/src/arm/Gos-linux.c",
  "libunwind/src/arm/Greg_states_iterate.c",
  "libunwind/src/arm/Gregs.c",
  "libunwind/src/arm/Gresume.c",
  "libunwind/src/arm/Gstash_frame.c",
  "libunwind/src/arm/Gstep.c",
  "libunwind/src/arm/Gtrace.c",
  "libunwind/src/arm/Lcreate_addr_space.c",
  "libunwind/src/arm/Lex_tables.c",
  "libunwind/src/arm/Lget_proc_info.c",
  "libunwind/src/arm/Lget_save_loc.c",
  "libunwind/src/arm/Lglobal.c",
  "libunwind/src/arm/Linit.c",
  "libunwind/src/arm/Linit_local.c",
  "libunwind/src/arm/Linit_remote.c",
  "libunwind/src/arm/Los-linux.c",
  "libunwind/src/arm/Lregs.c",
  "libunwind/src/arm/Lresume.c",
  "libunwind/src/arm/Lstash_frame.c",
  "libunwind/src/arm/Lstep.c",
  "libunwind/src/arm/Ltrace.c",
  "libunwind/src/arm/getcontext.S",
  "libunwind/src/arm/is_fpreg.c",
  "libunwind/src/arm/regname.c",
  "libunwind/src/arm/siglongjmp.S",
  "libunwind/src/elf32.c",
]

arm64_source = [
  "libunwind/src/aarch64/Gcreate_addr_space.c",
  "libunwind/src/aarch64/Gget_proc_info.c",
  "libunwind/src/aarch64/Gget_save_loc.c",
  "libunwind/src/aarch64/Gglobal.c",
  "libunwind/src/aarch64/Ginit.c",
  "libunwind/src/aarch64/Ginit_local.c",
  "libunwind/src/aarch64/Ginit_remote.c",
  "libunwind/src/aarch64/Gis_signal_frame.c",
  "libunwind/src/aarch64/Gregs.c",
  "libunwind/src/aarch64/Gresume.c",
  "libunwind/src/aarch64/Gstash_frame.c",
  "libunwind/src/aarch64/Gstep.c",
  "libunwind/src/aarch64/Gtrace.c",
  "libunwind/src/aarch64/Lcreate_addr_space.c",
  "libunwind/src/aarch64/Lget_proc_info.c",
  "libunwind/src/aarch64/Lget_save_loc.c",
  "libunwind/src/aarch64/Lglobal.c",
  "libunwind/src/aarch64/Linit.c",
  "libunwind/src/aarch64/Linit_local.c",
  "libunwind/src/aarch64/Linit_remote.c",
  "libunwind/src/aarch64/Lis_signal_frame.c",
  "libunwind/src/aarch64/Lregs.c",
  "libunwind/src/aarch64/Lresume.c",
  "libunwind/src/aarch64/Lstash_frame.c",
  "libunwind/src/aarch64/Lstep.c",
  "libunwind/src/aarch64/Ltrace.c",
  "libunwind/src/aarch64/getcontext.S",
  "libunwind/src/aarch64/is_fpreg.c",
  "libunwind/src/aarch64/regname.c",
  "libunwind/src/elf64.c",
]

x64_source = [
  "libunwind/src/elf64.c",
  "libunwind/src/x86_64/Gcreate_addr_space.c",
  "libunwind/src/x86_64/Gget_proc_info.c",
  "libunwind/src/x86_64/Gget_save_loc.c",
  "libunwind/src/x86_64/Gglobal.c",
  "libunwind/src/x86_64/Ginit.c",
  "libunwind/src/x86_64/Ginit_local.c",
  "libunwind/src/x86_64/Ginit_remote.c",
  "libunwind/src/x86_64/Gos-linux.c",
  "libunwind/src/x86_64/Gregs.c",
  "libunwind/src/x86_64/Gresume.c",
  "libunwind/src/x86_64/Gstash_frame.c",
  "libunwind/src/x86_64/Gstep.c",
  "libunwind/src/x86_64/Gtrace.c",
  "libunwind/src/x86_64/Lcreate_addr_space.c",
  "libunwind/src/x86_64/Lget_proc_info.c",
  "libunwind/src/x86_64/Lget_save_loc.c",
  "libunwind/src/x86_64/Lglobal.c",
  "libunwind/src/x86_64/Linit.c",
  "libunwind/src/x86_64/Linit_local.c",
  "libunwind/src/x86_64/Linit_remote.c",
  "libunwind/src/x86_64/Los-linux.c",
  "libunwind/src/x86_64/Lregs.c",
  "libunwind/src/x86_64/Lresume.c",
  "libunwind/src/x86_64/Lstash_frame.c",
  "libunwind/src/x86_64/Lstep.c",
  "libunwind/src/x86_64/Ltrace.c",
  "libunwind/src/x86_64/getcontext.S",
  "libunwind/src/x86_64/is_fpreg.c",
  "libunwind/src/x86_64/regname.c",
  "libunwind/src/x86_64/setcontext.S",
]

riscv64_source = [
  "libunwind/src/elf64.c",
  "libunwind/src/riscv/Gapply_reg_state.c",
  "libunwind/src/riscv/Gcreate_addr_space.c",
  "libunwind/src/riscv/getcontext.S",
  "libunwind/src/riscv/Gget_proc_info.c",
  "libunwind/src/riscv/Gget_save_loc.c",
  "libunwind/src/riscv/Gglobal.c",
  "libunwind/src/riscv/Ginit.c",
  "libunwind/src/riscv/Ginit_local.c",
  "libunwind/src/riscv/Ginit_remote.c",
  "libunwind/src/riscv/Gis_signal_frame.c",
  "libunwind/src/riscv/Gregs.c",
  "libunwind/src/riscv/Greg_states_iterate.c",
  "libunwind/src/riscv/Gresume.c",
  "libunwind/src/riscv/Gstep.c",
  "libunwind/src/riscv/is_fpreg.c",
  "libunwind/src/riscv/Lcreate_addr_space.c",
  "libunwind/src/riscv/Lget_proc_info.c",
  "libunwind/src/riscv/Lget_save_loc.c",
  "libunwind/src/riscv/Lglobal.c",
  "libunwind/src/riscv/Linit.c",
  "libunwind/src/riscv/Linit_local.c",
  "libunwind/src/riscv/Linit_remote.c",
  "libunwind/src/riscv/Lis_signal_frame.c",
  "libunwind/src/riscv/Lregs.c",
  "libunwind/src/riscv/Lreg_states_iterate.c",
  "libunwind/src/riscv/Lresume.c",
  "libunwind/src/riscv/Lstep.c",
  "libunwind/src/riscv/offsets.h",
  "libunwind/src/riscv/regname.c",
  "libunwind/src/riscv/setcontext.S",
  "libunwind/src/riscv/siglongjmp.S",
]

remove_sources = []

ptrace_sources = [
  "libunwind/src/ptrace/_UPT_access_fpreg.c",
  "libunwind/src/ptrace/_UPT_access_mem.c",
  "libunwind/src/ptrace/_UPT_access_reg.c",
  "libunwind/src/ptrace/_UPT_accessors.c",
  "libunwind/src/ptrace/_UPT_create.c",
  "libunwind/src/ptrace/_UPT_destroy.c",
  "libunwind/src/ptrace/_UPT_find_proc_info.c",
  "libunwind/src/ptrace/_UPT_get_dyn_info_list_addr.c",
  "libunwind/src/ptrace/_UPT_get_proc_name.c",
  "libunwind/src/ptrace/_UPT_put_unwind_info.c",
  "libunwind/src/ptrace/_UPT_reg_offset.c",
  "libunwind/src/ptrace/_UPT_resume.c",
]

libunwind_la_SOURCES_local_nounwind = [
  "libunwind/src/mi/backtrace.c",
  "libunwind/src/mi/dyn-cancel.c",
  "libunwind/src/mi/dyn-info-list.c",
  "libunwind/src/mi/dyn-register.c",
  "libunwind/src/mi/Ldyn-extract.c",
  "libunwind/src/mi/Lfind_dynamic_proc_info.c",

  # "libunwind/src/mi/Lget_accessors.c", # miss
  "libunwind/src/mi/Lget_proc_info_by_ip.c",
  "libunwind/src/mi/Lget_proc_name.c",
  "libunwind/src/mi/Lput_dynamic_unwind_info.c",
  "libunwind/src/mi/Ldestroy_addr_space.c",
  "libunwind/src/mi/Lget_reg.c",
  "libunwind/src/mi/Lset_reg.c",
  "libunwind/src/mi/Lget_fpreg.c",
  "libunwind/src/mi/Lset_fpreg.c",
  "libunwind/src/mi/Lset_caching_policy.c",
  "libunwind/src/mi/Lset_cache_size.c",
]

libunwind_dwarf_local_la_SOURCES = [
  "libunwind/src/dwarf/Lexpr.c",
  "libunwind/src/dwarf/Lfde.c",
  "libunwind/src/dwarf/Lparser.c",
  "libunwind/src/dwarf/Lpe.c",
  "libunwind/src/dwarf/Lfind_proc_info-lsb.c",
  "libunwind/src/dwarf/Lfind_unwind_table.c",
]

# remove local file
remove_sources += libunwind_la_SOURCES_local_nounwind
remove_sources += libunwind_dwarf_local_la_SOURCES
remove_sources += ptrace_sources

config("unwind_config_public") {
  include_dirs = [
    "libunwind/src",
    "libunwind/include",
  ]

  cflags = [
    "-D_GNU_SOURCE",
    "-DHAVE_CONFIG_H",
    "-DNDEBUG",
    "-DCC_IS_CLANG",
    "-fcommon",
    "-Wno-absolute-value",
    "-Wno-header-guard",
    "-Wno-unused-parameter",
    "-Wno-unused-variable",
    "-Wno-int-to-pointer-cast",
    "-Wno-pointer-to-int-cast",
    "-Wno-error",
  ]

  if (defined(ohos_lite)) {
    cflags += [ "-fPIC" ]
  }

  if (target_cpu == "arm") {
    include_dirs += [ "libunwind/include/tdep-arm" ]
    cflags += [
      "-Wno-inline-asm",
      "-Wno-shift-count-overflow",
      "-Wno-tautological-constant-out-of-range-compare",
      "-Wno-unused-function",
    ]
  } else if (target_cpu == "riscv64") {
    include_dirs += [ "libunwind/include/tdep-riscv" ]
    cflags += [ "-Wno-implicit-function-declaration" ]
  } else if (target_cpu == "arm64") {
    include_dirs += [ "libunwind/include/tdep-aarch64" ]
    cflags += [ "-Wno-incompatible-pointer-types" ]
  } else if (target_cpu == "x64" || target_cpu == "x86_64") {
    include_dirs += [ "libunwind/include/tdep-x86_64" ]
  } else if (target_cpu == "mipsel") {
    include_dirs += [ "libunwind/include/tdep-mips" ]
  }
}

config("unwind_config_remote") {
  cflags =
      [ "-Wno-format" ]  # some debug feature will warning in host x64 build
}

config("unwind_config_local_only") {
  defines = [ "UNW_LOCAL_ONLY" ]
}

config("unwind_config_remote_public") {
  cflags = []
  include_dirs = []
  defines = []

  # this is a host tools build
  # what means host use remote mode to unwind
  # with dwarf from stack or coredump or something not real target
  # There is an exception, we can support local unwind for linux.
  cflags += [ "-DUNW_REMOTE_ONLY" ]

  cflags += [ "-DBUILD_REMOTE" ]

  cflags += [ "-Wno-sometimes-uninitialized" ]  # some value not initialized in
                                                # host x64 build
  cflags += [ "-Wno-int-to-void-pointer-cast" ]

  if (is_linux) {
    cflags += [ "-g" ]  # we need debug info when it crash.
  }

  defines += [ "build_remote=1" ]
  defines += [ "target_cpu=${target_cpu}" ]
  defines += [ "host_toolchain=${host_toolchain}" ]
  defines += [ "current_toolchain=${current_toolchain}" ]
  defines += [ "default_toolchain=${default_toolchain}" ]
}

config("unwind_config_arm") {
  defines = [ "UNW_TARGET_ARM" ]
}

config("unwind_config_arm64") {
  defines = [ "UNW_TARGET_ARM64" ]
}

config("unwind_config_arm64_opt") {
  defines = [ "ONLY_RECOVER_GENERAL_REGS" ]
}

config("unwind_config_x64") {
  defines = [ "UNW_TARGET_X86_64" ]
  defines += [ "UNW_TARGET_X86_64_LINUX" ]
}

config("unwind_config_x86_64") {
  defines = [ "UNW_TARGET_X86_64" ]
  defines += [ "UNW_TARGET_X86_64_LINUX" ]
}

config("unwind_config_riscv64") {
  defines = [ "UNW_TARGET_RISCV" ]
}

if (defined(ohos_lite)) {
  source_set("unwind_source_arm") {
    configs += [ ":unwind_config_remote" ]
    public_configs = [
      ":unwind_config_public",
      ":unwind_config_remote_public",
      ":unwind_config_arm",
    ]
    sources = common_source

    # no jump lib
    arm_source -= [
      "libunwind/src/arm/getcontext.S",
      "libunwind/src/arm/siglongjmp.S",
    ]
    sources += arm_source
    sources -= remove_sources
  }

  source_set("unwind_source_arm64") {
    configs += [ ":unwind_config_remote" ]
    public_configs = [
      ":unwind_config_public",
      ":unwind_config_remote_public",
      ":unwind_config_arm64",
    ]
    sources = common_source

    arm64_source -= [ "libunwind/src/aarch64/getcontext.S" ]

    sources += arm64_source
    sources -= remove_sources
  }

  source_set("unwind_source_x64") {
    configs += [ ":unwind_config_remote" ]
    public_configs = [
      ":unwind_config_public",
      ":unwind_config_remote_public",
      ":unwind_config_x64",
    ]
    sources = common_source

    # no jump lib
    x64_source -= [
      "libunwind/src/x86_64/getcontext.S",
      "libunwind/src/x86_64/setcontext.S",
    ]
    sources += x64_source
    sources -= remove_sources
  }

  source_set("unwind_source_riscv64") {
    configs += [ ":unwind_config_remote" ]
    public_configs = [
      ":unwind_config_public",
      ":unwind_config_remote_public",
      ":unwind_config_riscv64",
    ]
    sources = common_source

    # no jump lib
    riscv64_source -= [
      "libunwind/src/riscv/getcontext.S",
      "libunwind/src/riscv/setcontext.S",
    ]

    sources += riscv64_source
    sources -= remove_sources
  }

  source_set("unwind_source") {
    configs += [ ":unwind_config_public" ]
    sources = common_source

    if (target_cpu == "arm") {
      # no jump lib
      arm_source -= [
        "libunwind/src/arm/getcontext.S",
        "libunwind/src/arm/siglongjmp.S",
      ]

      # as libc++ is static linked with libunwind.a
      # we remove the Gstep.c for duplicated symbol violation
      sources += arm_source
      public_configs = [ ":unwind_config_arm" ]
    } else if (target_cpu == "arm64") {
      sources += arm64_source
      public_configs = [ ":unwind_config_arm64" ]
    } else if (target_cpu == "riscv64") {
      sources += riscv64_source
      public_configs = [ ":unwind_config_riscv64" ]
    } else if (target_cpu == "x64") {
      sources += x64_source
      public_configs = [ ":unwind_config_x64" ]
    } else if (target_cpu == "x86_64") {
      sources += x64_source
      public_configs = [ ":unwind_config_x86_64" ]
    }
  }

  shared_library("libunwind") {
    deps = [ ":unwind_source" ]
    public_configs = [ ":unwind_config_public" ]
  }

  static_library("libunwind_local") {
    sources = common_source
    public_configs = [ ":unwind_config_public" ]
    public_configs += [ ":unwind_config_local_only" ]

    if (target_cpu == "arm") {
      sources += arm_source
      sources -= arm_source_local
      public_configs += [ ":unwind_config_arm" ]
    } else if (target_cpu == "arm64") {
      sources += arm64_source
      sources -= arm64_source_local
      public_configs += [ ":unwind_config_arm64" ]
    } else if (target_cpu == "riscv64") {
      sources += riscv64_source
      sources -= riscv64_source_local
      public_configs += [ ":unwind_config_riscv64" ]
    } else if (target_cpu == "x64") {
      sources += x64_source
      sources -= x64_source_local
      public_configs += [ ":unwind_config_x64" ]
    } else if (target_cpu == "x86_64") {
      sources += x64_source
      sources -= x64_source_local
      public_configs += [ ":unwind_config_x86_64" ]
    }

    sources -= libunwind_dwarf_local_la_SOURCES
    sources -= libunwind_la_SOURCES_local
    sources -= ptrace_sources

    cflags = [
      "-DHAS_ARK_FRAME",
      "-DPARSE_BUILD_ID",
      "-DUNW_LOCAL_ONLY",
      "-DNO_RESERVE_CACHE",
    ]
  }
} else {
  ohos_source_set("unwind_source_arm") {
    configs = [ ":unwind_config_remote" ]
    public_configs = [
      ":unwind_config_public",
      ":unwind_config_remote_public",
      ":unwind_config_arm",
    ]
    sources = common_source

    # no jump lib
    arm_source -= [
      "libunwind/src/arm/getcontext.S",
      "libunwind/src/arm/siglongjmp.S",
    ]
    sources += arm_source
    sources -= remove_sources
  }

  ohos_source_set("unwind_source_arm64") {
    configs = [ ":unwind_config_remote" ]
    public_configs = [
      ":unwind_config_public",
      ":unwind_config_remote_public",
      ":unwind_config_arm64",
    ]
    sources = common_source

    arm64_source -= [ "libunwind/src/aarch64/getcontext.S" ]

    sources += arm64_source
    sources -= remove_sources
  }

  ohos_source_set("unwind_source_arm64_opt") {
    configs = [ ":unwind_config_remote" ]
    public_configs = [
      ":unwind_config_public",
      ":unwind_config_remote_public",
      ":unwind_config_arm64",
      ":unwind_config_arm64_opt",
    ]
    sources = common_source

    arm64_source -= [ "libunwind/src/aarch64/getcontext.S" ]

    sources += arm64_source
    sources -= remove_sources
  }

  ohos_source_set("unwind_source_x64") {
    configs = [ ":unwind_config_remote" ]
    public_configs = [
      ":unwind_config_public",
      ":unwind_config_remote_public",
      ":unwind_config_x64",
    ]
    sources = common_source

    # no jump lib
    x64_source -= [
      "libunwind/src/x86_64/getcontext.S",
      "libunwind/src/x86_64/setcontext.S",
    ]
    sources += x64_source
    sources -= remove_sources
  }

  ohos_source_set("unwind_source_x86_64") {
    configs = [ ":unwind_config_remote" ]
    public_configs = [
      ":unwind_config_public",
      ":unwind_config_remote_public",
      ":unwind_config_x86_64",
    ]
    sources = common_source

    # no jump lib
    x64_source -= [
      "libunwind/src/x86_64/getcontext.S",
      "libunwind/src/x86_64/setcontext.S",
    ]
    sources += x64_source
    sources -= remove_sources
  }

  ohos_source_set("unwind_source_riscv64") {
    configs = [ ":unwind_config_remote" ]
    public_configs = [
      ":unwind_config_public",
      ":unwind_config_remote_public",
      ":unwind_config_riscv64",
    ]
    sources = common_source

    # no jump lib
    riscv64_source -= [
      "libunwind/src/riscv/getcontext.S",
      "libunwind/src/riscv/setcontext.S",
    ]

    sources += riscv64_source
    sources -= remove_sources
  }

  ohos_source_set("unwind_source") {
    configs = [ ":unwind_config_public" ]
    sources = common_source

    if (target_cpu == "riscv64") {
      # as libc++ is static linked with libunwind.a
      # we remove the Gstep.c for duplicated symbol violation
      sources += riscv64_source
      public_configs = [ ":unwind_config_riscv64" ]
    } else if (target_cpu == "arm") {
      sources += arm_source
      public_configs = [ ":unwind_config_arm" ]
    } else if (target_cpu == "arm64") {
      sources += arm64_source
      public_configs = [ ":unwind_config_arm64" ]
    } else if (target_cpu == "x64") {
      sources += x64_source
      public_configs = [ ":unwind_config_x64" ]
    } else if (target_cpu == "x86_64") {
      sources += x64_source
      public_configs = [ ":unwind_config_x86_64" ]
    }

    cflags = [
      "-DHAS_ARK_FRAME",
      "-DPARSE_BUILD_ID",
      "-DPARSE_ELF_IN_HAP",
    ]
  }

  ohos_shared_library("libunwind") {
    deps = [ ":unwind_source" ]
    install_images = [
      "system",
      "updater",
    ]
    public_configs = [ ":unwind_config_public" ]
    innerapi_tags = [
      "platformsdk",
      "chipsetsdk",
    ]
    subsystem_name = "thirdparty"
    part_name = "libunwind"
  }

  # for internal use only, the interfaces may have compatible issue
  ohos_static_library("libunwind_local") {
    sources = common_source
    public_configs = [ ":unwind_config_public" ]
    public_configs += [ ":unwind_config_local_only" ]

    if (target_cpu == "arm") {
      sources += arm_source
      sources -= arm_source_local
      public_configs += [ ":unwind_config_arm" ]
    } else if (target_cpu == "arm64") {
      sources += arm64_source
      sources -= arm64_source_local
      public_configs += [ ":unwind_config_arm64" ]
    } else if (target_cpu == "riscv64") {
      sources += riscv64_source
      sources -= riscv64_source_local
      public_configs += [ ":unwind_config_riscv64" ]
    } else if (target_cpu == "x64") {
      sources += x64_source
      sources -= x64_source_local
      public_configs += [ ":unwind_config_x64" ]
    } else if (target_cpu == "x86_64") {
      sources += x64_source
      sources -= x64_source_local
      public_configs += [ ":unwind_config_x86_64" ]
    }

    sources -= libunwind_dwarf_local_la_SOURCES
    sources -= libunwind_la_SOURCES_local
    sources -= ptrace_sources

    cflags = [
      "-DHAS_ARK_FRAME",
      "-DPARSE_BUILD_ID",
      "-DUNW_LOCAL_ONLY",
      "-DNO_RESERVE_CACHE",
      "-DHAVE_PIPE2",
    ]

    subsystem_name = "thirdparty"
    part_name = "libunwind"
  }
}

if (!defined(ohos_lite)) {
  import("//build/test.gni")
  module_output_path = "thirdparty/libunwind"
  group("unittest") {
    testonly = true
    deps = [
      ":Gtest_bt",
      ":Gtest_dyn1",
      ":Gtest_init",
      ":Gtest_trace",
      ":Ltest_bt",
      ":Ltest_cxx_exceptions",
      ":Ltest_dyn1",
      ":Ltest_init",
      ":Ltest_init_local_signal",
      ":Ltest_mem_validate",
      ":Ltest_nocalloc",
      ":Ltest_nomalloc",
      ":Ltest_trace",
      ":test_ptrace_misc",
      ":test_static_link",
    ]
  }
  config("unwind_test") {
    cflags = [ "-O0" ]
  }

  ohos_unittest("Gtest_init") {
    module_out_path = module_output_path
    sources = [ "libunwind/test/Gtest-init.cxx" ]
    include_dirs = [
      "libunwind/test",
      "libunwind/include",
    ]

    configs = [ ":unwind_test" ]
    deps = [ ":libunwind" ]
    subsystem_name = "thirdparty"
    part_name = "libunwind"
  }

  ohos_unittest("Ltest_init") {
    module_out_path = module_output_path
    sources = [ "libunwind/test/Ltest-init.cxx" ]
    include_dirs = [
      "libunwind/test",
      "libunwind/include",
    ]
    configs = [ ":unwind_test" ]
    deps = [ ":libunwind" ]
    subsystem_name = "thirdparty"
    part_name = "libunwind"
  }

  ohos_unittest("Ltest_cxx_exceptions") {
    module_out_path = module_output_path
    sources = [ "libunwind/test/Ltest-cxx-exceptions.cxx" ]
    include_dirs = [
      "libunwind/test",
      "libunwind/include",
    ]
    configs = [ ":unwind_test" ]
    cflags = [ "-fexceptions" ]
    deps = [ ":libunwind" ]
    subsystem_name = "thirdparty"
    part_name = "libunwind"
    remove_configs = [ "//build/config/compiler:no_exceptions" ]
  }

  ohos_unittest("Ltest_init_local_signal") {
    module_out_path = module_output_path
    sources = [
      "libunwind/test/Ltest-init-local-signal-lib.c",
      "libunwind/test/Ltest-init-local-signal.c",
    ]
    include_dirs = [
      "libunwind/test",
      "libunwind/include",
    ]
    configs = [ ":unwind_test" ]
    deps = [ ":libunwind" ]
    subsystem_name = "thirdparty"
    part_name = "libunwind"
  }

  ohos_unittest("Gtest_dyn1") {
    module_out_path = module_output_path
    sources = [
      "libunwind/test/Gtest-dyn1.c",
      "libunwind/test/flush-cache.h",
    ]
    if (target_cpu == "arm") {
      sources += [ "libunwind/test/flush-cache.S" ]
    }
    include_dirs = [
      "libunwind/test",
      "libunwind/include",
    ]
    configs = [ ":unwind_test" ]
    cflags = [ "-DHAVE__BUILTIN___CLEAR_CACHE" ]
    deps = [ ":libunwind" ]
    subsystem_name = "thirdparty"
    part_name = "libunwind"
  }

  ohos_unittest("Ltest_dyn1") {
    module_out_path = module_output_path
    sources = [
      "libunwind/test/Ltest-dyn1.c",
      "libunwind/test/flush-cache.h",
    ]
    if (target_cpu == "arm") {
      sources += [ "libunwind/test/flush-cache.S" ]
    }
    include_dirs = [
      "libunwind/test",
      "libunwind/include",
    ]
    configs = [ ":unwind_test" ]
    cflags = [ "-DHAVE__BUILTIN___CLEAR_CACHE" ]
    deps = [ ":libunwind" ]
    subsystem_name = "thirdparty"
    part_name = "libunwind"
  }

  ohos_unittest("test_static_link") {
    module_out_path = module_output_path
    sources = [
      "libunwind/test/test-static-link-gen.c",
      "libunwind/test/test-static-link-loc.c",
    ]
    include_dirs = [
      "libunwind/test",
      "libunwind/include",
    ]
    configs = [ ":unwind_test" ]
    deps = [ ":libunwind" ]
    subsystem_name = "thirdparty"
    part_name = "libunwind"
  }

  ohos_unittest("Gtest_bt") {
    module_out_path = module_output_path
    sources = [
      "libunwind/test/Gtest-bt.c",
      "libunwind/test/dummy_backtrace.c",
      "libunwind/test/ident.c",
    ]
    include_dirs = [
      "libunwind/test",
      "libunwind/include",
    ]
    configs = [ ":unwind_test" ]
    deps = [ ":libunwind" ]
    subsystem_name = "thirdparty"
    part_name = "libunwind"
  }

  ohos_unittest("Ltest_bt") {
    module_out_path = module_output_path
    sources = [
      "libunwind/test/Ltest-bt.c",
      "libunwind/test/dummy_backtrace.c",
      "libunwind/test/ident.c",
    ]
    include_dirs = [
      "libunwind/test",
      "libunwind/include",
    ]
    configs = [ ":unwind_test" ]
    deps = [ ":libunwind" ]
    subsystem_name = "thirdparty"
    part_name = "libunwind"
  }

  ohos_unittest("test_ptrace_misc") {
    module_out_path = module_output_path
    sources = [
      "libunwind/test/ident.c",
      "libunwind/test/test-ptrace-misc.c",
    ]
    include_dirs = [
      "libunwind/test",
      "libunwind/include",
    ]
    configs = [ ":unwind_test" ]
    deps = [ ":libunwind" ]
    subsystem_name = "thirdparty"
    part_name = "libunwind"
  }

  ohos_unittest("Ltest_nomalloc") {
    module_out_path = module_output_path
    sources = [ "libunwind/test/Ltest-nomalloc.c" ]
    include_dirs = [
      "libunwind/test",
      "libunwind/include",
    ]
    configs = [ ":unwind_test" ]
    deps = [ ":libunwind" ]
    subsystem_name = "thirdparty"
    part_name = "libunwind"
  }

  ohos_unittest("Ltest_nocalloc") {
    module_out_path = module_output_path
    sources = [ "libunwind/test/Ltest-nocalloc.c" ]
    include_dirs = [
      "libunwind/test",
      "libunwind/include",
    ]
    configs = [ ":unwind_test" ]
    deps = [ ":libunwind" ]
    subsystem_name = "thirdparty"
    part_name = "libunwind"
  }

  ohos_unittest("Gtest_trace") {
    module_out_path = module_output_path
    sources = [
      "libunwind/test/Gtest-trace.c",
      "libunwind/test/dummy_backtrace.c",
      "libunwind/test/ident.c",
    ]
    include_dirs = [
      "libunwind/test",
      "libunwind/include",
    ]
    configs = [ ":unwind_test" ]
    deps = [ ":libunwind" ]
    subsystem_name = "thirdparty"
    part_name = "libunwind"
  }

  ohos_unittest("Ltest_trace") {
    module_out_path = module_output_path
    sources = [
      "libunwind/test/Ltest-trace.c",
      "libunwind/test/dummy_backtrace.c",
      "libunwind/test/ident.c",
    ]
    include_dirs = [
      "libunwind/test",
      "libunwind/include",
    ]
    configs = [ ":unwind_test" ]
    deps = [ ":libunwind" ]
    subsystem_name = "thirdparty"
    part_name = "libunwind"
  }

  ohos_unittest("Ltest_mem_validate") {
    module_out_path = module_output_path
    sources = [ "libunwind/test/Ltest-mem-validate.c" ]
    include_dirs = [
      "libunwind/test",
      "libunwind/include",
    ]
    configs = [ ":unwind_test" ]
    deps = [ ":libunwind" ]
    subsystem_name = "thirdparty"
    part_name = "libunwind"
  }
} else {
  group("unittest") {
    testonly = true
    deps = []
  }
}