# Copyright 2020 The Fuchsia Authors
#
# Use of this source code is governed by a MIT-style
# license that can be found in the LICENSE file or at
# https://opensource.org/licenses/MIT

# TODO(fxbug.dev/54160): Keep in sync with BUILD.gn

if (zx == "/") {
  import("$zx/public/gn/toolchain/environment.gni")
  import("$zx/public/gn/toolchain/environment_redirect.gni")
  import("$zx_build_config/levels.gni")
  import("$zx_build_config/standard.gni")
} else {
  import("//build/config/zircon/standard.gni")
  import("//build/toolchain/zircon/zircon_toolchain_suite.gni")
  import("//build/unification/global_variables.gni")
}

if (current_toolchain == default_toolchain) {
  # Default toolchain (current_cpu == "") just defines the phys environment.
  # Note: see $zx/kernel/arch/x86/phys:kernel.phys32 too.
  foreach(cpu, standard_fuchsia_cpus) {
    kernel_cpu = cpu
    if (kernel_cpu == "x64") {
      kernel_cpu = "x86"
    }

    if (zx == "/") {
      environment("kernel.phys") {
        cpu = cpu  # Would be inherited, but this is more obvious.

        globals = {
          is_kernel = true
        }

        configs += standard_fuchsia_configs
        configs += [
          "$zx/kernel:standalone",
          "$zx/kernel:warnings",
          "$zx/kernel/arch/$kernel_cpu:abi",
          ":defines",

          # All physmem code is inherently sensitive and in a position for
          # any bug to be unusually dangerous.  So compile with minimal
          # undefined behavior checking in all builds, regardless of variant.
          "$zx_build_config/instrumentation:ubsan-trap",
        ]

        # Always enable frame pointers.
        configs -= [ "$zx_build_config:default_frame_pointers" ]
        configs += [ "$zx_build_config:frame_pointers" ]

        tags = [
          "physmem",
          "standalone",
        ]
        exclude_variant_tags = [
          # There is no possibility of fancy runtimes like ASan for phys.
          "instrumentation-runtime",

          # TOOD(51994): Remove this when profile is supported.
          "instrumented",
        ]

        # Append the arch-specific lists.  The phys/phys.gni file in each
        # arch subdirectory defines phys_* lists to append to the parameters.
        import("$zx/kernel/arch/$kernel_cpu/phys/phys.gni")
        configs += phys_configs
        tags += phys_tags
        exclude_variant_tags += phys_exclude_variant_tags
      }
    } else {
      zircon_toolchain_suite("kernel.phys_$cpu") {
        cpu = cpu
        os = "fuchsia"
        environment = "kernel.phys"
        with_shared = false

        toolchain_variant_args = {
          configs = [ "//zircon/kernel/phys:phys_config" ]

          # Always enable frame pointers. This works because frame_pointers
          # is added as part of :phys_config below.
          remove_common_configs = [ "$zx_build_config:default_frame_pointers" ]

          tags = [ "kernel" ]
        }

        exclude_variant_tags = [
          # There is no possibility of fancy runtimes like ASan for phys.
          "instrumentation-runtime",

          # TOOD(51994): Remove this when profile is supported.
          "instrumented",
        ]

        # Append the arch-specific lists.  The phys/phys.gni file in each
        # arch subdirectory defines phys_* lists to append to the parameters.
        import("$zx/kernel/arch/$kernel_cpu/phys/phys.gni")
        toolchain_variant_args.tags += phys_tags
        exclude_variant_tags += phys_exclude_variant_tags
      }
    }
  }
} else if (zx != "/" && toolchain.environment == "kernel.phys") {
  kernel_cpu = current_cpu
  if (current_cpu == "x64") {
    kernel_cpu = "x86"
  }

  config("phys_config") {
    configs = [
      "$zx/kernel:standalone",
      "$zx/kernel:warnings",
      "$zx/kernel/arch/$kernel_cpu:abi",
      ":defines",

      # All physmem code is inherently sensitive and in a position for
      # any bug to be unusually dangerous.  So compile with minimal
      # undefined behavior checking in all builds, regardless of variant.
      "$zx_build_config/instrumentation:ubsan-trap",
    ]

    # Always enable frame pointers.
    configs += [ "$zx_build_config:frame_pointers" ]

    # Add arch-specific configs here. The reason this is not done
    # in the zircon_toolchain_suite() call is because every config listed
    # in toolchain_variant_args.configs 'foo' needs to have a corresponding
    # 'foo_deps' group.
    import("$zx/kernel/arch/$kernel_cpu/phys/phys.gni")
    configs += phys_configs
  }

  group("phys_config_deps") {
  }
}

if (zx != "/" || current_toolchain != default_toolchain) {
  if (toolchain.environment != "kernel.phys" &&
      toolchain.environment != "kernel.phys32") {
    # From another environment (e.g. user, kernel), the public targets
    # redirect into the phys environment.
    assert(current_cpu != "")

    if (zx == "/") {
      environment_redirect("tests") {
        testonly = true
        direct = true
        environment_label = ":kernel.phys"
        deps = [ "test" ]
      }
    } else {
      group("tests") {
        testonly = true
        deps = [ "test" ]
      }
    }

    foreach(target, []) {  # TODO: ["physboot"]
      if (zx == "/") {
        environment_redirect(target) {
          environment_label = ":kernel.phys"
          deps = [ ":$target_name" ]
        }
      } else {
        group(target) {
          deps = [ ":$target($zx/kernel/phys:kernel.phys_${current_cpu}" ]
        }
      }
    }
  } else if (current_toolchain != default_toolchain) {
    # All the code gets built here in the phys environment.

    config("defines") {
      # Always enable tests and asserts in phys code.
      defines = [ "LK_DEBUGLEVEL=2" ]
    }

    source_set("phys_executable.headers") {
      public = [
        "frame-pointer.h",
        "stack.h",
        "symbolize.h",
      ]

      # symnbolize.h includes main.h
      public_deps = [ ":main" ]
    }

    # This is used implicitly by phys_executable() targets,
    # including zbi_executable() targets.
    source_set("phys_executable.deps") {
      sources = [
        "frame-pointer.cc",
        "panic.cc",
        "stack.cc",
        "symbolize.cc",
      ]
      deps = [
        ":main",
        ":phys_executable.headers",
        "$zx/kernel/arch/$zircon_cpu/phys",
        "$zx/kernel/lib/ktl",
        "$zx/kernel/lib/libc",
      ]
    }

    # This is used implicitly by zbi_executable() targets.
    source_set("zbi_executable.deps") {
      sources = [
        "zbi-header.S",
        "zbi-main.cc",
      ]
      deps = [
        ":main",
        "$zx/kernel/lib/arch",
        "$zx/kernel/lib/boot-options",
        "$zx/system/ulib/uart",
        "$zx/system/ulib/zbitl",
      ]
      public_configs =
          [ "$zx/kernel/arch/$zircon_cpu/phys:zbi_executable.config" ]
    }

    # Things in other directories include main.h by source-absolute path.
    # But they put this in their deps to get its transitive deps.
    source_set("main") {
      sources = [ "main.h" ]
      public_deps = [
        # "main.h" has #include <lib/arch/ticks.h>.
        "$zx/kernel/lib/arch",
      ]

      # If the toolchain is compiling a PIE executable, include required libraries.
      if (toolchain.tags + [ "static-pie" ] - [ "static-pie" ] !=
          toolchain.tags) {
        # "main.h" has #include <lib/static-pie/static-pie.h>
        public_deps += [ "$zx/system/ulib/static-pie" ]
      }
    }

    # This is linked into the special-case phys_executable() tests that
    # are run directly as QEMU kernels.
    source_set("qemu-header") {
      sources = [ "qemu-header.S" ]
      public_configs = [ "$zx/kernel/arch/$zircon_cpu/phys:qemu.config" ]
    }
  }
}
