# Copyright 2020 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.

# gn-format disable
import("//build_overrides/pigweed.gni")

import("$dir_pw_arduino_build/arduino.gni")
import("$dir_pw_build/host_tool.gni")
import("$dir_pw_docgen/docs.gni")
import("$dir_pw_toolchain/generate_toolchain.gni")
import("$dir_pw_unit_test/test.gni")

# Main build file for upstream Pigweed.

declare_args() {
  # The optimization level to use when building upstream Pigweed targets.
  #
  # Choices:
  #   debug
  #   size_optimized
  #   speed_optimized
  pw_optimization_level = "debug"

  # List of application image GN targets specific to the Pigweed target.
  pw_TARGET_APPLICATIONS = []
}

# Enumerate all of the different targets that upstream Pigweed will build by
# default. Downstream projects should not depend on this target; this target is
# exclusively to facilitate easy upstream development and testing.
group("default") {
  deps = [
    ":docs",
    ":host",
    ":stm32f429i",
  ]
}

# Below are a list of GN targets you can build to force Pigweed to build for a
# specific Pigweed target.
group("host") {
  # Auto select a toolchain based on host OS.
  if (host_os == "linux") {
    _default_host_toolchain = ":host_clang"
  } else if (host_os == "mac") {
    _default_host_toolchain = ":host_clang"
  } else if (host_os == "win") {
    _default_host_toolchain = ":host_gcc"
  } else {
    assert(false, "Please define a host config for your system: $host_os")
  }

  deps = [ _default_host_toolchain ]
}

group("host_clang") {
  deps = [ ":pigweed_default($dir_pigweed/targets/host:host_clang_$pw_optimization_level)" ]
}

group("host_gcc") {
  deps = [ ":pigweed_default($dir_pigweed/targets/host:host_gcc_$pw_optimization_level)" ]
}

group("stm32f429i") {
  deps = [ ":pigweed_default($dir_pigweed/targets/stm32f429i-disc1:stm32f429i_disc1_$pw_optimization_level)" ]
}

if (dir_pw_third_party_arduino != "") {
  group("arduino") {
    deps = [ ":pigweed_default($dir_pigweed/targets/arduino:arduino_$pw_optimization_level)" ]
  }
}

group("qemu") {
  deps = [ ":pigweed_default($dir_pigweed/targets/lm3s6965evb-qemu:lm3s6965evb_qemu_$pw_optimization_level)" ]
}

group("docs") {
  deps = [ ":pigweed_default($dir_pigweed/targets/docs)" ]
}

# By default, Pigweed will build this target when invoking ninja.
group("pigweed_default") {
  deps = []

  # Prevent the default toolchain from parsing any other BUILD.gn files.
  if (current_toolchain != default_toolchain) {
    if (pw_docgen_BUILD_DOCS) {
      deps += [ "$dir_pigweed/docs" ]
    } else {
      deps += [ ":apps" ]
      if (pw_unit_test_AUTOMATIC_RUNNER == "") {
        # Without a test runner defined, build the tests but don't run them.
        deps += [ ":pw_module_tests" ]
      } else {
        # With a test runner, depend on the run targets so they run with the
        # build.
        deps += [ ":pw_module_tests_run" ]
      }
    }
    if (defined(pw_toolchain_SCOPE.is_host_toolchain) &&
        pw_toolchain_SCOPE.is_host_toolchain && pw_build_HOST_TOOLS) {
      deps += [ ":host_tools" ]
    }

    # Trace examples currently only support running on non-windows host
    if (defined(pw_toolchain_SCOPE.is_host_toolchain) &&
        pw_toolchain_SCOPE.is_host_toolchain && host_os != "win") {
      deps += [
        "$dir_pw_trace:trace_example_basic",
        "$dir_pw_trace_tokenized:trace_tokenized_example_basic",
        "$dir_pw_trace_tokenized:trace_tokenized_example_filter",
        "$dir_pw_trace_tokenized:trace_tokenized_example_trigger",
      ]
    }
  }
}

# Prevent the default toolchain from parsing any other BUILD.gn files.
if (current_toolchain != default_toolchain) {
  group("apps") {
    # Application images built for all targets.
    deps = [ "$dir_pw_hdlc_lite/rpc_example" ]

    # Add target-specific images.
    deps += pw_TARGET_APPLICATIONS
  }

  group("host_tools") {
    deps = [
      "$dir_pw_target_runner/go:simple_client",
      "$dir_pw_target_runner/go:simple_server",
    ]
  }

  # All Pigweed modules that can be built using gn. This is not built by default.
  group("pw_modules") {
    deps = [
      "$dir_pigweed/docs",
      "$dir_pw_allocator",
      "$dir_pw_base64",
      "$dir_pw_blob_store",
      "$dir_pw_bytes",
      "$dir_pw_checksum",
      "$dir_pw_cpu_exception",
      "$dir_pw_hdlc_lite",
      "$dir_pw_metric",
      "$dir_pw_polyfill",
      "$dir_pw_preprocessor",
      "$dir_pw_protobuf",
      "$dir_pw_result",
      "$dir_pw_span",
      "$dir_pw_status",
      "$dir_pw_stream",
      "$dir_pw_string",
      "$dir_pw_sys_io",
      "$dir_pw_trace",
      "$dir_pw_unit_test",
      "$dir_pw_varint",
    ]

    if (host_os != "win") {
      deps += [
        # TODO(frolv): Remove these two when new KVS is ready.
        "$dir_pw_kvs",
        "$dir_pw_minimal_cpp_stdlib",

        # TODO(pwbug/111): Remove this when building successfully on Windows.
        "$dir_pw_tokenizer",
      ]
    }
  }

  # Targets for all module unit test groups.
  pw_test_group("pw_module_tests") {
    group_deps = [
      "$dir_pw_allocator:tests",
      "$dir_pw_assert:tests",
      "$dir_pw_base64:tests",
      "$dir_pw_blob_store:tests",
      "$dir_pw_bytes:tests",
      "$dir_pw_checksum:tests",
      "$dir_pw_containers:tests",
      "$dir_pw_fuzzer:tests",
      "$dir_pw_hdlc_lite:tests",
      "$dir_pw_hex_dump:tests",
      "$dir_pw_log:tests",
      "$dir_pw_log_null:tests",
      "$dir_pw_log_tokenized:tests",
      "$dir_pw_malloc_freelist:tests",
      "$dir_pw_metric:tests",
      "$dir_pw_polyfill:tests",
      "$dir_pw_preprocessor:tests",
      "$dir_pw_protobuf:tests",
      "$dir_pw_protobuf_compiler:tests",
      "$dir_pw_random:tests",
      "$dir_pw_result:tests",
      "$dir_pw_ring_buffer:tests",
      "$dir_pw_rpc:tests",
      "$dir_pw_span:tests",
      "$dir_pw_status:tests",
      "$dir_pw_stream:tests",
      "$dir_pw_string:tests",
      "$dir_pw_tokenizer:tests",
      "$dir_pw_trace:tests",
      "$dir_pw_trace_tokenized:tests",
      "$dir_pw_unit_test:tests",
      "$dir_pw_varint:tests",
    ]

    import("$dir_pw_cpu_exception/backend.gni")

    # TODO(pwbug/17): Re-think when Pigweed config system is added.
    if (pw_cpu_exception_ENTRY_BACKEND == dir_pw_cpu_exception_armv7m) {
      group_deps += [ "$dir_pw_cpu_exception_armv7m:tests" ]
    }

    if (defined(pw_toolchain_SCOPE.is_host_toolchain) &&
        pw_toolchain_SCOPE.is_host_toolchain) {
      # TODO(pwbug/196): KVS tests are not compatible with device builds as they
      # use features such as std::map and are computationally expensive. Solving
      # this requires a more complex capabilities-based build and configuration
      # system which allowing enabling specific tests for targets that support
      # them and modifying test parameters for different targets.
      #
      # Checking for pw_build_host_tools (which is only set by the host) is a
      # temporary fix until the problem can be properly solved.
      group_deps += [ "$dir_pw_kvs:tests" ]
    }

    if (host_os != "win") {
      # TODO(amontanez): pw_minimal_cpp_stdlib tests do not build on windows.
      group_deps += [ "$dir_pw_minimal_cpp_stdlib:tests" ]
    }
  }
}
