# Copyright (C) 2017 The Android Open Source Project
#
# 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("//gn/standalone/android.gni")
import("llvm.gni")

declare_args() {
  if (is_clang) {
    if (is_linux) {
      cc = linux_clang_bin
      cxx = linux_clangxx_bin
    } else {
      cc = "clang"
      cxx = "clang++"
    }
  } else {
    cc = "gcc"
    cxx = "g++"
  }
}

declare_args() {
  host_ar = ar
  if (is_linux_host && is_clang) {
    host_cc = linux_clang_bin
    host_cxx = linux_clangxx_bin
  } else {
    host_cc = cc
    host_cxx = cxx
  }

  if (is_android) {
    target_ar = "$android_toolchain_root/bin/$android_abi_target-ar"
    target_cc = "$android_llvm_dir/bin/clang"
    target_cxx = "$android_llvm_dir/bin/clang++"
  } else {
    target_ar = ar
    target_cc = cc
    target_cxx = cxx
  }
  cc_wrapper = ""
}

python = "python"
stamp = "touch"

template("gcc_like_toolchain") {
  toolchain(target_name) {
    ar = invoker.ar
    cc = invoker.cc
    cxx = invoker.cxx
    lib_switch = "-l"
    lib_dir_switch = "-L"

    tool("cc") {
      depfile = "{{output}}.d"
      command = "$cc_wrapper $cc -MMD -MF $depfile {{defines}} {{include_dirs}} {{cflags}} {{cflags_c}} -c {{source}} -o {{output}}"
      depsformat = "gcc"
      outputs = [
        "{{source_out_dir}}/{{target_output_name}}.{{source_name_part}}.o",
      ]
      description = "compile {{source}}"
    }

    tool("cxx") {
      depfile = "{{output}}.d"
      command = "$cc_wrapper $cxx -MMD -MF $depfile {{defines}} {{include_dirs}} {{cflags}} {{cflags_cc}} -c {{source}} -o {{output}}"
      depsformat = "gcc"
      outputs = [
        "{{source_out_dir}}/{{target_output_name}}.{{source_name_part}}.o",
      ]
      description = "compile {{source}}"
    }

    tool("asm") {
      depfile = "{{output}}.d"
      command = "$cc_wrapper $cc -MMD -MF $depfile {{defines}} {{include_dirs}} {{asmflags}} -c {{source}} -o {{output}}"
      depsformat = "gcc"
      outputs = [
        "{{source_out_dir}}/{{target_output_name}}.{{source_name_part}}.o",
      ]
      description = "assemble {{source}}"
    }

    tool("alink") {
      if (is_mac && ar != "suppress_unused_ar_variable_warning") {
        command = "rm -f {{output}} && libtool -static {{arflags}} -o {{output}} {{inputs}}"
      } else {
        rspfile = "{{output}}.rsp"
        rspfile_content = "{{inputs}}"
        command = "$ar rcsD {{output}} @$rspfile"
      }
      outputs = [
        "{{root_out_dir}}/{{target_output_name}}{{output_extension}}",
      ]
      default_output_extension = ".a"
      output_prefix = "lib"
      description = "link {{output}}"
    }

    tool("solink") {
      soname = "{{target_output_name}}{{output_extension}}"

      rpath = "-Wl,-soname,$soname"
      if (is_mac) {
        rpath = "-Wl,-install_name,@rpath/$soname"
      }

      command = "$cc_wrapper $cxx -shared {{ldflags}} {{inputs}} {{solibs}} {{libs}} $rpath -o {{output}}"
      outputs = [
        "{{root_out_dir}}/$soname",
      ]
      output_prefix = "lib"
      default_output_extension = ".so"
      description = "link {{output}}"
    }

    tool("link") {
      command = "$cc_wrapper $cxx {{ldflags}} {{inputs}} {{solibs}} {{libs}} -o {{output}}"
      outputs = [
        "{{root_out_dir}}/{{target_output_name}}{{output_extension}}",
      ]
      description = "link {{output}}"
    }

    tool("stamp") {
      command = "touch {{output}}"
      description = "stamp {{output}}"
    }

    tool("copy") {
      command = "cp -af {{source}} {{output}}"
      description = "COPY {{source}} {{output}}"
    }

    toolchain_args = {
      current_cpu = invoker.cpu
      current_os = invoker.os
    }
  }
}

gcc_like_toolchain("gcc_like") {
  cpu = current_cpu
  os = current_os
  ar = target_ar
  cc = target_cc
  cxx = target_cxx
}

gcc_like_toolchain("gcc_like_host") {
  cpu = host_cpu
  os = host_os
  ar = host_ar
  cc = host_cc
  cxx = host_cxx
}