[tls] Generate size report for tls example

Generate size report for the tls example application. The report is
on additional binary size contributed by the use of tls library. This is
done by building another executable target that uses a noop tls backend,
then bloating it against the original target.

Change-Id: Ibb4514376c22b18f27b1e910248d46627766402f
Reviewed-on: https://pigweed-review.googlesource.com/c/pigweed/experimental/+/39462
Commit-Queue: Yecheng Zhao <zyecheng@google.com>
Reviewed-by: Ali Zhang <alizhang@google.com>
diff --git a/applications/tls_example/BUILD.gn b/applications/tls_example/BUILD.gn
index a37c1ce..11631c0 100644
--- a/applications/tls_example/BUILD.gn
+++ b/applications/tls_example/BUILD.gn
@@ -16,17 +16,22 @@
 import("$dir_pw_build/target_types.gni")
 import("tls_client_example.gni")
 
+teensy_bloaty_config = rebase_path("./teensy41_bloaty_config.bloaty")
+
 tls_client_example("boringssl_teensy_ethernet") {
   tls_backend = "backends/tls/boringssl"
   transport_backend = "backends/transport/teensy_ethernet"
+  bloaty_config = teensy_bloaty_config
 }
 
 tls_client_example("picotls_teensy_ethernet") {
   tls_backend = "backends/tls/picotls"
   transport_backend = "backends/transport/teensy_ethernet"
+  bloaty_config = teensy_bloaty_config
 }
 
 tls_client_example("mbedtls_teensy_ethernet") {
   tls_backend = "backends/tls/mbedtls"
   transport_backend = "backends/transport/teensy_ethernet"
-}
\ No newline at end of file
+  bloaty_config = teensy_bloaty_config
+}
diff --git a/applications/tls_example/backends/tls/dummy/BUILD.gn b/applications/tls_example/backends/tls/dummy/BUILD.gn
new file mode 100644
index 0000000..6d83d65
--- /dev/null
+++ b/applications/tls_example/backends/tls/dummy/BUILD.gn
@@ -0,0 +1,22 @@
+# 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("$dir_pw_build/target_types.gni")
+
+pw_source_set("dummy") {
+  sources = [ "dummy.cc" ]
+  include_dirs = [ "//applications/tls_example/backends" ]
+  deps = [ "$dir_pw_log" ]
+}
diff --git a/applications/tls_example/backends/tls/dummy/dummy.cc b/applications/tls_example/backends/tls/dummy/dummy.cc
new file mode 100644
index 0000000..e4a7649
--- /dev/null
+++ b/applications/tls_example/backends/tls/dummy/dummy.cc
@@ -0,0 +1,17 @@
+// 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.
+
+#include "dummy.h"
+
+TlsInterface* CreateTls() { return new DummyTls(); }
diff --git a/applications/tls_example/backends/tls/dummy/dummy.h b/applications/tls_example/backends/tls/dummy/dummy.h
new file mode 100644
index 0000000..f7dfc78
--- /dev/null
+++ b/applications/tls_example/backends/tls/dummy/dummy.h
@@ -0,0 +1,29 @@
+// 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.
+
+#pragma once
+
+#include "backend_interface.h"
+
+class DummyTls final : public TlsInterface {
+public:
+  DummyTls()  {}
+  const char* Name() override { return ""; }
+  int SetHostName(const char *) override { return 0; }
+  int Handshake(TransportInterface* ) override { return 0; }
+  int Write(const void* , size_t , TransportInterface* ) override { return 0; }
+  int Read(void* , size_t , TransportInterface* ) override { return 0; }
+  int LoadCACert(const void* , size_t ) override { return 0; }
+  int LoadCrl(const void* , size_t ) override { return 0; }
+};
diff --git a/applications/tls_example/teensy41_bloaty_config.bloaty b/applications/tls_example/teensy41_bloaty_config.bloaty
new file mode 100644
index 0000000..f1d4968
--- /dev/null
+++ b/applications/tls_example/teensy41_bloaty_config.bloaty
@@ -0,0 +1,49 @@
+# 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.
+
+source_filter: "^(FLASH|RAM)$"
+
+# Number of symbols to expand for each section.
+# The rest will be collapsed into "Others"
+max_rows_per_level: 2000
+
+custom_data_source: {
+  name: "segment_names"
+  base_data_source: "sections"
+
+  rewrite: {
+    pattern: ".text.progmem"
+    replacement: "FLASH"
+  }
+  rewrite: {
+    pattern: ".data"
+    replacement: "RAM"
+  }
+  rewrite: {
+    pattern: ".text.itcm"
+    replacement: "RAM"
+  }
+  rewrite: {
+    pattern: ".text.itcm.padding"
+    replacement: "RAM"
+  }
+  rewrite: {
+    pattern: ".bss.dma"
+    replacement: "RAM"
+  }
+  rewrite: {
+    pattern: ".bss"
+    replacement: "RAM"
+  }
+}
diff --git a/applications/tls_example/tls_client_example.gni b/applications/tls_example/tls_client_example.gni
index ca6686d..03736cb 100644
--- a/applications/tls_example/tls_client_example.gni
+++ b/applications/tls_example/tls_client_example.gni
@@ -13,6 +13,7 @@
 # the License.
 
 import("//build_overrides/pigweed.gni")
+import("$dir_pw_bloat/bloat.gni")
 import("$dir_pw_build/target_types.gni")
 
 # A convenient template for generating example applications with different
@@ -22,17 +23,77 @@
          "must provide a tls backend")
   assert(defined(invoker.transport_backend) && invoker.transport_backend != "",
          "must provide a transport backend")
-  pw_executable(target_name) {
-    sources = [
+
+  example_binary_target_name = target_name + "_binary"
+  size_report_target_name = target_name + "_tls_size_report"
+
+  group(target_name) {
+    deps = [
+      ":$example_binary_target_name",
+      ":$size_report_target_name",
+    ]
+  }
+
+  executable_exclude_vars = [
+    "tls_backend",
+    "transport_backend",
+    "no_bloaty",
+    "bloaty_config",
+  ]
+
+  executable_common_vars = {
+    forward_variables_from(invoker, "*", executable_exclude_vars)
+    if (!defined(sources)) {
+      sources = []
+    }
+    sources += [
       "sysdeps.cc",
       "tls_client_example.cc",
     ]
-    deps = [
+
+    if (!defined(deps)) {
+      deps = []
+    }
+    deps += [
       "$dir_pw_log",
       "$dir_pw_spin_delay",
       "$dir_pw_sys_io",
-      invoker.tls_backend,
       invoker.transport_backend,
     ]
   }
+
+  # Runnable target
+  pw_executable(example_binary_target_name) {
+    forward_variables_from(executable_common_vars, "*")
+    deps += [ invoker.tls_backend ]
+  }
+
+  # Size report target.
+  if (!defined(invoker.no_bloaty) || !invoker.no_bloaty) {
+    # A similar target but with a noop tls backend for size comparison
+    base_target_name = example_binary_target_name + "_without_tls"
+    pw_executable(base_target_name) {
+      forward_variables_from(executable_common_vars, "*")
+      deps += [ "//applications/tls_example/backends/tls/dummy:dummy" ]
+    }
+
+    # Bloaty size report.
+    pw_size_report(size_report_target_name) {
+      title = size_report_target_name
+      base = ":$base_target_name"
+      full_report = true
+      binaries = [
+        {
+          target = ":$example_binary_target_name"
+          label = "$example_binary_target_name"
+          if (defined(invoker.bloaty_config)) {
+            bloaty_config = invoker.bloaty_config
+          }
+        },
+      ]
+    }
+  } else {
+    group(size_report_target_name) {
+    }
+  }
 }