# Copyright 2014 The Chromium Authors
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

import("//build/config/arm.gni")
import("//build/config/compiler/compiler.gni")

use_arm_neon_optimizations = target_cpu == "arm" || target_cpu == "arm64"

# TODO(crbug.com/1341436) For Windows, to assemble lzma_sdk's assembly files,
# ml64.exe needs to be utilized as llvm-ml cannot yet assemble it. Once llvm-ml
# is able to assemble lzma_sdk assembly files, remove this.
# LzmaDecOpt.asm only works on x64 and not x86.
# https://sourceforge.net/p/sevenzip/discussion/45797/thread/768932e9dd/?limit=25#0d6c
# If enable_lzma_opt is enabled, disable_llvm_ml should be enabled as well.
enable_lzma_opt = host_os == "win" && target_cpu == "x64" && !is_msan
if (enable_lzma_opt) {
  assert(disable_llvm_ml)
}

config("lzma_sdk_config") {
  include_dirs = [
    "./src",
    "./src/C",
  ]

  if (enable_lzma_opt) {
    include_dirs += [ "./src/Asm/x86" ]
  }
}

# Must be in a config for -Wno-self-assign because of how GN orders flags
# (otherwise -Wall will appear after this, and turn it back on).
config("lzma_build_config") {
  defines = [
    "Z7_LZMA_PROB32",
    "Z7_NO_METHODS_FILTERS",
    "Z7_ST",
    "_LZMA_PROB32",
    "Z7_NO_CRC_HW_FORCE",
  ]

  if (enable_lzma_opt) {
    defines += [ "Z7_LZMA_DEC_OPT" ]
  }

  cflags = []
  if (is_clang) {
    # Upstream uses self-assignment to avoid warnings.
    cflags += [ "-Wno-self-assign" ]
  }

  if (use_arm_neon_optimizations) {
    if (target_cpu == "arm" && arm_version >= 8) {
      if (is_clang) {
        cflags += [
          "-march=armv8-a",
          "-Xclang",
          "-target-feature",
          "-Xclang",
          "+crc",
          "-Xclang",
          "-target-feature",
          "-Xclang",
          "+crypto",
        ]
      } else {
        cflags += [ "-march=armv8-a+crc+crypto" ]
      }
    }
  }
}

static_library("lzma_sdk") {
  sources = [
    "src/C/7z.h",
    "src/C/7zAlloc.c",
    "src/C/7zAlloc.h",
    "src/C/7zArcIn.c",
    "src/C/7zBuf.c",
    "src/C/7zBuf.h",
    "src/C/7zCrc.c",
    "src/C/7zCrc.h",
    "src/C/7zCrcOpt.c",
    "src/C/7zDec.c",
    "src/C/7zFile.c",
    "src/C/7zFile.h",
    "src/C/7zStream.c",
    "src/C/7zTypes.h",
    "src/C/7zWindows.h",
    "src/C/Alloc.c",
    "src/C/Alloc.h",
    "src/C/Bcj2.c",
    "src/C/Bcj2.h",
    "src/C/Bra.c",
    "src/C/Bra.h",
    "src/C/Bra86.c",
    "src/C/Compiler.h",
    "src/C/CpuArch.c",
    "src/C/CpuArch.h",
    "src/C/Delta.c",
    "src/C/Delta.h",
    "src/C/DllSecur.c",
    "src/C/DllSecur.h",
    "src/C/LzFind.c",
    "src/C/LzFind.h",
    "src/C/LzHash.h",
    "src/C/Lzma2Dec.c",
    "src/C/Lzma2Dec.h",
    "src/C/Lzma2Enc.c",
    "src/C/Lzma2Enc.h",
    "src/C/LzmaDec.c",
    "src/C/LzmaDec.h",
    "src/C/LzmaEnc.c",
    "src/C/LzmaEnc.h",
    "src/C/LzmaLib.c",
    "src/C/LzmaLib.h",
    "src/C/Precomp.h",
    "src/C/RotateDefs.h",
  ]

  if (enable_lzma_opt) {
    sources += [ "src/Asm/x86/LzmaDecOpt.asm" ]
  }

  configs -= [ "//build/config/compiler:chromium_code" ]
  configs += [
    "//build/config/compiler:no_chromium_code",

    # Must be after no_chromium_code for warning flags to be ordered correctly.
    ":lzma_build_config",
  ]
  public_configs = [ ":lzma_sdk_config" ]
}

static_library("lzma_sdk_xz") {
  sources = [
    "src/C/BraIA64.c",
    "src/C/Sha256.c",
    "src/C/Sha256.h",
    "src/C/Sha256Opt.c",
    "src/C/Xz.c",
    "src/C/Xz.h",
    "src/C/XzCrc64.c",
    "src/C/XzCrc64.h",
    "src/C/XzCrc64Opt.c",
    "src/C/XzDec.c",
    "src/C/XzEnc.c",
    "src/C/XzEnc.h",
    "src/C/XzIn.c",
  ]

  if (enable_lzma_opt) {
    sources += [
      "src/Asm/x86/Sha256Opt.asm",
      "src/Asm/x86/XzCrc64Opt.asm",
    ]
    sources -= [
      "src/C/Sha256Opt.c",
      "src/C/XzCrc64Opt.c",
    ]
  }

  deps = [ ":lzma_sdk" ]

  configs -= [ "//build/config/compiler:chromium_code" ]
  configs += [
    "//build/config/compiler:no_chromium_code",

    # Must be after no_chromium_code for warning flags to be ordered correctly.
    ":lzma_build_config",
  ]
  public_configs = [ ":lzma_sdk_config" ]
}

if (is_win) {
  source_set("7zS2_source") {
    sources = [ "src/C/Util/SfxSetup/SfxSetup.c" ]
    defines = [ "_WIN32" ]
    include_dirs = [
      "src/C/Util/SfxSetup",
      "src/C",
    ]
    public_deps = [ ":lzma_sdk" ]
  }
}
