# Copyright 2021 The Pigweed 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
#
#     https://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_overrides/pigweed.gni")
import("//build_overrides/pigweed_environment.gni")
import("$dir_pw_toolchain/rbe.gni")

_default_llvm_prefix = ""
_default_rust_prefix = ""

# If Pigweed's CIPD environment setup was run, assume a LLVM toolchain and Rust
# compiler are present there.
if (defined(pw_env_setup_CIPD_PIGWEED)) {
  _default_llvm_prefix = pw_env_setup_CIPD_PIGWEED + "/bin/"
}
if (defined(pw_env_setup_CIPD_RUST)) {
  _default_rust_prefix = pw_env_setup_CIPD_RUST + "/bin/"
}

declare_args() {
  # This flag allows you to specify a prefix to use for clang, clang++,
  # and llvm-ar binaries to use when compiling with a clang-based toolchain.
  # This is useful for debugging toolchain-related issues by building with an
  # externally-provided toolchain.
  #
  # Pigweed toolchains should NOT override this variable so projects or users
  # can control it via `.gn` or by setting it as a regular gn argument (e.g.
  # `gn gen --args='pw_toolchain_CLANG_PREFIX=/path/to/my-llvm-'`).
  #
  # Examples:
  #   pw_toolchain_CLANG_PREFIX = ""
  #   command: "clang" (from PATH)
  #
  #   pw_toolchain_CLANG_PREFIX = "my-"
  #   command: "my-clang" (from PATH)
  #
  #   pw_toolchain_CLANG_PREFIX = "/bin/my-"
  #   command: "/bin/my-clang" (absolute path)
  #
  #   pw_toolchain_CLANG_PREFIX = "//environment/clang_next/"
  #   command: "../environment/clang_next/clang" (relative path)
  #
  # GN templates should use `pw_toolchain_clang_tools.*` to get the intended
  # command string rather than relying directly on pw_toolchain_CLANG_PREFIX.
  #
  # If the prefix begins with "//", it will be rebased to be relative to the
  # root build directory.
  pw_toolchain_CLANG_PREFIX = _default_llvm_prefix

  # This flag allows you to specify a prefix for rustc.
  #
  # This follows the same rules as pw_toolchain_CLANG_PREFIX, see above for
  # more information.
  #
  # If the prefix begins with "//", it will be rebased to be relative to the
  # root build directory.
  pw_toolchain_RUST_PREFIX = _default_rust_prefix
}

pw_toolchain_clang_tools = {
  ar = "llvm-ar"
  cc = "clang"
  cxx = "clang++"
  ld = cxx
  llvm_cov = "llvm-cov"
  llvm_profdata = "llvm-profdata"
  rustc = "rustc"

  _toolchain_prefix = pw_toolchain_CLANG_PREFIX
  if (_toolchain_prefix != "") {
    # If the prefix is a GN-absolute path, rebase it so it's relative to the
    # root of the build directory.
    _split_prefix = string_split(_toolchain_prefix, "//")
    if (_split_prefix[0] == "") {
      _toolchain_prefix = rebase_path(_toolchain_prefix, root_build_dir)
    }
    if (host_os == "win") {
      _toolchain_prefix = "./" + _toolchain_prefix
      _toolchain_prefix = string_replace(_toolchain_prefix, "/", "\\")
    }
    ar = _toolchain_prefix + ar
    cc = _toolchain_prefix + cc
    cxx = _toolchain_prefix + cxx
    ld = _toolchain_prefix + ld
    llvm_cov = _toolchain_prefix + llvm_cov
    llvm_profdata = _toolchain_prefix + llvm_profdata
  }

  _rust_prefix = pw_toolchain_RUST_PREFIX
  if (host_os == "win") {
    _rust_prefix = string_replace(_rust_prefix, "/", "\\")
  }
  if (_rust_prefix != "") {
    # If the prefix is a GN-absolute path, rebase it so it's relative to the
    # root of the build directory.
    _split_rust_prefix = string_split(_rust_prefix, "//")
    if (_split_rust_prefix[0] == "") {
      _rust_prefix = rebase_path(_rust_prefix, root_build_dir)
    }
    rustc = _rust_prefix + rustc
  }

  if (pw_toolchain_USE_RBE) {
    _rbe_debug_flag = ""
    if (pw_toolchain_RBE_DEBUG) {
      _rbe_debug_flag = " -v"
    }
    _exec_root = rebase_path("//")
    _rewrapper_binary = "rewrapper"
    _pw_rbe_config = pw_rbe_clang_config
    _rbe_toolchain_prefix =
        _rewrapper_binary +
        " --labels=type=compile,lang=cpp,compiler=clang --cfg=" +
        _pw_rbe_config + " --exec_root=" + _exec_root + " -- "

    cc = _rbe_toolchain_prefix + cc + _rbe_debug_flag
    cxx = _rbe_toolchain_prefix + cxx + _rbe_debug_flag
  }
}
