xref: /aosp_15_r20/external/webrtc/webrtc.gni (revision d9f758449e529ab9291ac668be2861e7a55c2422)
1# Copyright (c) 2014 The WebRTC project authors. All Rights Reserved.
2#
3# Use of this source code is governed by a BSD-style license
4# that can be found in the LICENSE file in the root of the source
5# tree. An additional intellectual property rights grant can be found
6# in the file PATENTS.  All contributing project authors may
7# be found in the AUTHORS file in the root of the source tree.
8import("//build/config/arm.gni")
9import("//build/config/features.gni")
10import("//build/config/mips.gni")
11import("//build/config/ozone.gni")
12import("//build/config/sanitizers/sanitizers.gni")
13import("//build/config/sysroot.gni")
14import("//build_overrides/build.gni")
15
16if (!build_with_chromium && is_component_build) {
17  print("The Gn argument `is_component_build` is currently " +
18        "ignored for WebRTC builds.")
19  print("Component builds are supported by Chromium and the argument " +
20        "`is_component_build` makes it possible to create shared libraries " +
21        "instead of static libraries.")
22  print("If an app depends on WebRTC it makes sense to just depend on the " +
23        "WebRTC static library, so there is no difference between " +
24        "`is_component_build=true` and `is_component_build=false`.")
25  print(
26      "More info about component builds at: " + "https://chromium.googlesource.com/chromium/src/+/main/docs/component_build.md")
27  assert(!is_component_build, "Component builds are not supported in WebRTC.")
28}
29
30if (is_ios) {
31  import("//build/config/ios/rules.gni")
32}
33
34if (is_mac) {
35  import("//build/config/mac/rules.gni")
36}
37
38if (is_fuchsia) {
39  import("//build/config/fuchsia/config.gni")
40}
41
42# This declare_args is separated from the next one because args declared
43# in this one, can be read from the next one (args defined in the same
44# declare_args cannot be referenced in that scope).
45declare_args() {
46  # Setting this to true will make RTC_EXPORT (see rtc_base/system/rtc_export.h)
47  # expand to code that will manage symbols visibility.
48  rtc_enable_symbol_export = false
49}
50
51declare_args() {
52  # Setting this to true, will make RTC_DLOG() expand to log statements instead
53  # of being removed by the preprocessor.
54  # This is useful for example to be able to get RTC_DLOGs on a release build.
55  rtc_dlog_always_on = false
56
57  # Setting this to true will make RTC_OBJC_EXPORT expand to code that will
58  # manage symbols visibility. By default, Obj-C/Obj-C++ symbols are exported
59  # if C++ symbols are but setting this arg to true while keeping
60  # rtc_enable_symbol_export=false will only export RTC_OBJC_EXPORT
61  # annotated symbols.
62  rtc_enable_objc_symbol_export = rtc_enable_symbol_export
63
64  # Setting this to true will define WEBRTC_EXCLUDE_FIELD_TRIAL_DEFAULT which
65  # will tell the pre-processor to remove the default definition of symbols
66  # needed to use field_trial. In that case a new implementation needs to be
67  # provided.
68  if (build_with_chromium) {
69    # When WebRTC is built as part of Chromium it should exclude the default
70    # implementation of field_trial unless it is building for NACL or
71    # Chromecast.
72    rtc_exclude_field_trial_default = !is_nacl && !is_castos && !is_cast_android
73  } else {
74    rtc_exclude_field_trial_default = false
75  }
76
77  # Setting this to true will define WEBRTC_EXCLUDE_METRICS_DEFAULT which
78  # will tell the pre-processor to remove the default definition of symbols
79  # needed to use metrics. In that case a new implementation needs to be
80  # provided.
81  rtc_exclude_metrics_default = build_with_chromium
82
83  # Setting this to true will define WEBRTC_EXCLUDE_SYSTEM_TIME which
84  # will tell the pre-processor to remove the default definition of the
85  # SystemTimeNanos() which is defined in rtc_base/system_time.cc. In
86  # that case a new implementation needs to be provided.
87  rtc_exclude_system_time = build_with_chromium
88
89  # Setting this to false will require the API user to pass in their own
90  # SSLCertificateVerifier to verify the certificates presented from a
91  # TLS-TURN server. In return disabling this saves around 100kb in the binary.
92  rtc_builtin_ssl_root_certificates = true
93
94  # Include the iLBC audio codec?
95  rtc_include_ilbc = true
96
97  # Disable this to avoid building the Opus audio codec.
98  rtc_include_opus = true
99
100  # Enable this if the Opus version upon which WebRTC is built supports direct
101  # encoding of 120 ms packets.
102  rtc_opus_support_120ms_ptime = true
103
104  # Enable this to let the Opus audio codec change complexity on the fly.
105  rtc_opus_variable_complexity = false
106
107  # Used to specify an external Jsoncpp include path when not compiling the
108  # library that comes with WebRTC (i.e. rtc_build_json == 0).
109  rtc_jsoncpp_root = "//third_party/jsoncpp/source/include"
110
111  # Used to specify an external OpenSSL include path when not compiling the
112  # library that comes with WebRTC (i.e. rtc_build_ssl == 0).
113  rtc_ssl_root = ""
114
115  # Enable when an external authentication mechanism is used for performing
116  # packet authentication for RTP packets instead of libsrtp.
117  rtc_enable_external_auth = build_with_chromium
118
119  # Selects whether debug dumps for the audio processing module
120  # should be generated.
121  apm_debug_dump = false
122
123  # Selects whether the audio processing module should be excluded.
124  rtc_exclude_audio_processing_module = false
125
126  # Set this to true to enable BWE test logging.
127  rtc_enable_bwe_test_logging = false
128
129  # Set this to false to skip building examples.
130  rtc_build_examples = true
131
132  # Set this to false to skip building tools.
133  rtc_build_tools = true
134
135  # Set this to false to skip building code that requires X11.
136  rtc_use_x11 = ozone_platform_x11
137
138  # Set this to use PipeWire on the Wayland display server.
139  # By default it's only enabled on desktop Linux (excludes ChromeOS) and
140  # only when using the sysroot as PipeWire is not available in older and
141  # supported Ubuntu and Debian distributions.
142  rtc_use_pipewire = is_linux && use_sysroot
143
144  # Set this to link PipeWire and required libraries directly instead of using the dlopen.
145  rtc_link_pipewire = false
146
147  # Enable to use the Mozilla internal settings.
148  build_with_mozilla = false
149
150  # Experimental: enable use of Android AAudio which requires Android SDK 26 or above
151  # and NDK r16 or above.
152  rtc_enable_android_aaudio = false
153
154  # Set to "func", "block", "edge" for coverage generation.
155  # At unit test runtime set UBSAN_OPTIONS="coverage=1".
156  # It is recommend to set include_examples=0.
157  # Use llvm's sancov -html-report for human readable reports.
158  # See http://clang.llvm.org/docs/SanitizerCoverage.html .
159  rtc_sanitize_coverage = ""
160
161  # Selects fixed-point code where possible.
162  rtc_prefer_fixed_point = false
163  if (current_cpu == "arm" || current_cpu == "arm64") {
164    rtc_prefer_fixed_point = true
165  }
166
167  # Determines whether NEON code will be built.
168  rtc_build_with_neon =
169      (current_cpu == "arm" && arm_use_neon) || current_cpu == "arm64"
170
171  # Enable this to build OpenH264 encoder/FFmpeg decoder. This is supported on
172  # all platforms except Android and iOS. Because FFmpeg can be built
173  # with/without H.264 support, `ffmpeg_branding` has to separately be set to a
174  # value that includes H.264, for example "Chrome". If FFmpeg is built without
175  # H.264, compilation succeeds but `H264DecoderImpl` fails to initialize.
176  # CHECK THE OPENH264, FFMPEG AND H.264 LICENSES/PATENTS BEFORE BUILDING.
177  # http://www.openh264.org, https://www.ffmpeg.org/
178  #
179  # Enabling H264 when building with MSVC is currently not supported, see
180  # bugs.webrtc.org/9213#c13 for more info.
181  rtc_use_h264 =
182      proprietary_codecs && !is_android && !is_ios && !(is_win && !is_clang)
183
184  # Enable this flag to make webrtc::Mutex be implemented by absl::Mutex.
185  rtc_use_absl_mutex = false
186
187  # By default, use normal platform audio support or dummy audio, but don't
188  # use file-based audio playout and record.
189  rtc_use_dummy_audio_file_devices = false
190
191  # When set to true, replace the audio output with a sinus tone at 440Hz.
192  # The ADM will ask for audio data from WebRTC but instead of reading real
193  # audio samples from NetEQ, a sinus tone will be generated and replace the
194  # real audio samples.
195  rtc_audio_device_plays_sinus_tone = false
196
197  if (is_ios) {
198    # Build broadcast extension in AppRTCMobile for iOS. This results in the
199    # binary only running on iOS 11+, which is why it is disabled by default.
200    rtc_apprtcmobile_broadcast_extension = false
201  }
202
203  # Determines whether OpenGL is available on iOS/macOS.
204  rtc_ios_macos_use_opengl_rendering =
205      !(is_ios && target_environment == "catalyst")
206
207  # When set to false, builtin audio encoder/decoder factories and all the
208  # audio codecs they depend on will not be included in libwebrtc.{a|lib}
209  # (they will still be included in libjingle_peerconnection_so.so and
210  # WebRTC.framework)
211  rtc_include_builtin_audio_codecs = true
212
213  # When set to false, builtin video encoder/decoder factories and all the
214  # video codecs they depends on will not be included in libwebrtc.{a|lib}
215  # (they will still be included in libjingle_peerconnection_so.so and
216  # WebRTC.framework)
217  rtc_include_builtin_video_codecs = true
218
219  # When set to true and in a standalone build, it will undefine UNICODE and
220  # _UNICODE (which are always defined globally by the Chromium Windows
221  # toolchain).
222  # This is only needed for testing purposes, WebRTC wants to be sure it
223  # doesn't assume /DUNICODE and /D_UNICODE but that it explicitly uses
224  # wide character functions.
225  rtc_win_undef_unicode = false
226
227  # When set to true, a capturer implementation that uses the
228  # Windows.Graphics.Capture APIs will be available for use. This introduces a
229  # dependency on the Win 10 SDK v10.0.17763.0.
230  rtc_enable_win_wgc = is_win
231
232  # Includes the dav1d decoder in the internal decoder factory when set to true.
233  rtc_include_dav1d_in_internal_decoder_factory = true
234
235  # When set to true, a run-time check will make sure that all field trial keys
236  # have been registered in accordance with the field trial policy. The check
237  # will only run with builds that have RTC_DCHECKs enabled.
238  rtc_strict_field_trials = false
239}
240
241if (!build_with_mozilla) {
242  import("//testing/test.gni")
243}
244
245# A second declare_args block, so that declarations within it can
246# depend on the possibly overridden variables in the first
247# declare_args block.
248declare_args() {
249  # Enables the use of protocol buffers for debug recordings.
250  rtc_enable_protobuf = !build_with_mozilla
251
252  # Set this to disable building with support for SCTP data channels.
253  rtc_enable_sctp = !build_with_mozilla
254
255  # Disable these to not build components which can be externally provided.
256  rtc_build_json = !build_with_mozilla
257  rtc_build_libsrtp = !build_with_mozilla
258  rtc_build_libvpx = !build_with_mozilla
259  rtc_libvpx_build_vp9 = !build_with_mozilla
260  rtc_build_opus = !build_with_mozilla
261  rtc_build_ssl = !build_with_mozilla
262
263  # Enable libevent task queues on platforms that support it.
264  if (is_win || is_mac || is_ios || is_nacl || is_fuchsia ||
265      target_cpu == "wasm") {
266    rtc_enable_libevent = false
267    rtc_build_libevent = false
268  } else {
269    rtc_enable_libevent = true
270    rtc_build_libevent = !build_with_mozilla
271  }
272
273  # Excluded in Chromium since its prerequisites don't require Pulse Audio.
274  rtc_include_pulse_audio = !build_with_chromium
275
276  # Chromium uses its own IO handling, so the internal ADM is only built for
277  # standalone WebRTC.
278  rtc_include_internal_audio_device = !build_with_chromium
279
280  # Set this to true to enable the avx2 support in webrtc.
281  # TODO: Make sure that AVX2 works also for non-clang compilers.
282  if (is_clang == true) {
283    rtc_enable_avx2 = true
284  } else {
285    rtc_enable_avx2 = false
286  }
287
288  # Set this to true to build the unit tests.
289  # Disabled when building with Chromium or Mozilla.
290  rtc_include_tests = !build_with_chromium && !build_with_mozilla
291
292  # Set this to false to skip building code that also requires X11 extensions
293  # such as Xdamage, Xfixes.
294  rtc_use_x11_extensions = rtc_use_x11
295
296  # Set this to true to fully remove logging from WebRTC.
297  rtc_disable_logging = false
298
299  # Set this to true to disable trace events.
300  rtc_disable_trace_events = false
301
302  # Set this to true to disable detailed error message and logging for
303  # RTC_CHECKs.
304  rtc_disable_check_msg = false
305
306  # Set this to true to disable webrtc metrics.
307  rtc_disable_metrics = false
308
309  # Set this to true to exclude the transient suppressor in the audio processing
310  # module from the build.
311  rtc_exclude_transient_suppressor = false
312}
313
314declare_args() {
315  # Enable the dcsctp backend for DataChannels and related unittests
316  rtc_build_dcsctp = !build_with_mozilla && rtc_enable_sctp
317
318  # Enable gRPC used for negotiation in multiprocess tests
319  rtc_enable_grpc = rtc_enable_protobuf && (is_linux || is_mac)
320}
321
322# Make it possible to provide custom locations for some libraries (move these
323# up into declare_args should we need to actually use them for the GN build).
324rtc_libvpx_dir = "//third_party/libvpx"
325rtc_opus_dir = "//third_party/opus"
326
327# Desktop capturer is supported only on Windows, OSX and Linux.
328rtc_desktop_capture_supported =
329    (is_win && current_os != "winuwp") || is_mac ||
330    ((is_linux || is_chromeos) && (rtc_use_x11_extensions || rtc_use_pipewire))
331
332###############################################################################
333# Templates
334#
335
336# Points to // in webrtc stand-alone or to //third_party/webrtc/ in
337# chromium.
338# We need absolute paths for all configs in templates as they are shared in
339# different subdirectories.
340webrtc_root = get_path_info(".", "abspath")
341
342# Global configuration that should be applied to all WebRTC targets.
343# You normally shouldn't need to include this in your target as it's
344# automatically included when using the rtc_* templates.
345# It sets defines, include paths and compilation warnings accordingly,
346# both for WebRTC stand-alone builds and for the scenario when WebRTC
347# native code is built as part of Chromium.
348rtc_common_configs = [ webrtc_root + ":common_config" ]
349
350if (is_mac || is_ios) {
351  rtc_common_configs += [ "//build/config/compiler:enable_arc" ]
352}
353
354# Global public configuration that should be applied to all WebRTC targets. You
355# normally shouldn't need to include this in your target as it's automatically
356# included when using the rtc_* templates. It set the defines, include paths and
357# compilation warnings that should be propagated to dependents of the targets
358# depending on the target having this config.
359rtc_common_inherited_config = webrtc_root + ":common_inherited_config"
360
361# Common configs to remove or add in all rtc targets.
362rtc_remove_configs = []
363if (!build_with_chromium && is_clang) {
364  rtc_remove_configs += [ "//build/config/clang:find_bad_constructs" ]
365}
366rtc_add_configs = rtc_common_configs
367rtc_prod_configs = [ webrtc_root + ":rtc_prod_config" ]
368rtc_library_impl_config = [ webrtc_root + ":library_impl_config" ]
369
370set_defaults("rtc_test") {
371  configs = rtc_add_configs
372  suppressed_configs = []
373}
374
375set_defaults("rtc_library") {
376  configs = rtc_add_configs
377  suppressed_configs = []
378  absl_deps = []
379}
380
381set_defaults("rtc_source_set") {
382  configs = rtc_add_configs
383  suppressed_configs = []
384  absl_deps = []
385}
386
387set_defaults("rtc_static_library") {
388  configs = rtc_add_configs
389  suppressed_configs = []
390  absl_deps = []
391}
392
393set_defaults("rtc_executable") {
394  configs = rtc_add_configs
395  suppressed_configs = []
396}
397
398set_defaults("rtc_shared_library") {
399  configs = rtc_add_configs
400  suppressed_configs = []
401}
402
403webrtc_default_visibility = [ webrtc_root + "/*" ]
404if (build_with_chromium) {
405  # Allow Chromium's WebRTC overrides targets to bypass the regular
406  # visibility restrictions.
407  webrtc_default_visibility += [ webrtc_root + "/../webrtc_overrides/*" ]
408}
409
410# ---- Poisons ----
411#
412# The general idea is that some targets declare that they contain some
413# kind of poison, which makes it impossible for other targets to
414# depend on them (even transitively) unless they declare themselves
415# immune to that particular type of poison.
416#
417# Targets that *contain* poison of type foo should contain the line
418#
419#   poisonous = [ "foo" ]
420#
421# and targets that *are immune but arent't themselves poisonous*
422# should contain
423#
424#   allow_poison = [ "foo" ]
425#
426# This useful in cases where we have some large target or set of
427# targets and want to ensure that most other targets do not
428# transitively depend on them. For example, almost no high-level
429# target should depend on the audio codecs, since we want WebRTC users
430# to be able to inject any subset of them and actually end up with a
431# binary that doesn't include the codecs they didn't inject.
432#
433# Test-only targets (`testonly` set to true) and non-public targets
434# (`visibility` not containing "*") are automatically immune to all
435# types of poison.
436#
437# Here's the complete list of all types of poison. It must be kept in
438# 1:1 correspondence with the set of //:poison_* targets.
439#
440all_poison_types = [
441  # Encoders and decoders for specific audio codecs such as Opus and iSAC.
442  "audio_codecs",
443
444  # Default task queue implementation.
445  "default_task_queue",
446
447  # Default echo detector implementation.
448  "default_echo_detector",
449
450  # JSON parsing should not be needed in the "slim and modular" WebRTC.
451  "rtc_json",
452
453  # Software video codecs (VP8 and VP9 through libvpx).
454  "software_video_codecs",
455]
456
457absl_include_config = "//third_party/abseil-cpp:absl_include_config"
458absl_define_config = "//third_party/abseil-cpp:absl_define_config"
459
460# Abseil Flags are testonly, so this config will only be applied to WebRTC targets
461# that are testonly.
462absl_flags_config = webrtc_root + ":absl_flags_configs"
463
464# WebRTC wrapper of Chromium's test() template. This template just adds some
465# WebRTC only configuration in order to avoid to duplicate it for every WebRTC
466# target.
467# The parameter `is_xctest` is different from the one in the Chromium's test()
468# template (and it is not forwarded to it). In rtc_test(), the argument
469# `is_xctest` is used to avoid to take dependencies that are not needed
470# in case the test is a real XCTest (using the XCTest framework).
471template("rtc_test") {
472  test(target_name) {
473    forward_variables_from(invoker,
474                           "*",
475                           [
476                             "configs",
477                             "is_xctest",
478                             "public_configs",
479                             "suppressed_configs",
480                             "visibility",
481                           ])
482
483    # Always override to public because when target_os is Android the `test`
484    # template can override it to [ "*" ] and we want to avoid conditional
485    # visibility.
486    visibility = [ "*" ]
487    configs += invoker.configs
488    configs -= rtc_remove_configs
489    configs -= invoker.suppressed_configs
490    public_configs = [
491      rtc_common_inherited_config,
492      absl_include_config,
493      absl_define_config,
494      absl_flags_config,
495    ]
496    if (defined(invoker.public_configs)) {
497      public_configs += invoker.public_configs
498    }
499    if (!build_with_chromium && is_android) {
500      android_manifest = webrtc_root + "test/android/AndroidManifest.xml"
501      use_raw_android_executable = false
502      min_sdk_version = 21
503      target_sdk_version = 23
504      deps += [
505        "//build/android/gtest_apk:native_test_instrumentation_test_runner_java",
506        webrtc_root + "test:native_test_java",
507      ]
508    }
509
510    # Build //test:google_test_runner_objc when the test is not a real XCTest.
511    if (is_ios && rtc_include_tests) {
512      if (!defined(invoker.is_xctest) || !invoker.is_xctest) {
513        xctest_module_target = "//test:google_test_runner_objc"
514      }
515    }
516
517    # If absl_deps is [], no action is needed. If not [], then it needs to be
518    # converted to //third_party/abseil-cpp:absl when build_with_chromium=true
519    # otherwise it just needs to be added to deps.
520    if (defined(absl_deps) && absl_deps != []) {
521      if (!defined(deps)) {
522        deps = []
523      }
524      if (build_with_chromium) {
525        deps += [ "//third_party/abseil-cpp:absl" ]
526      } else {
527        deps += absl_deps
528      }
529    }
530
531    # TODO(crbug.com/webrtc/13556): Adding the .app folder in the runtime_deps
532    # shoulnd't be necessary. this code should be removed and the same solution
533    # as Chromium should be used.
534    if (is_ios) {
535      if (!defined(invoker.data)) {
536        data = []
537      }
538      data += [ "${root_out_dir}/${target_name}.app" ]
539    }
540  }
541}
542
543template("rtc_source_set") {
544  source_set(target_name) {
545    forward_variables_from(invoker,
546                           "*",
547                           [
548                             "configs",
549                             "public_configs",
550                             "suppressed_configs",
551                             "visibility",
552                           ])
553    forward_variables_from(invoker, [ "visibility" ])
554    if (!defined(visibility)) {
555      visibility = webrtc_default_visibility
556    }
557
558    # What's your poison?
559    if (defined(testonly) && testonly) {
560      assert(!defined(poisonous))
561      assert(!defined(allow_poison))
562    } else {
563      if (!defined(poisonous)) {
564        poisonous = []
565      }
566      if (!defined(allow_poison)) {
567        allow_poison = []
568      }
569      if (!defined(assert_no_deps)) {
570        assert_no_deps = []
571      }
572      if (!defined(deps)) {
573        deps = []
574      }
575      foreach(p, poisonous) {
576        deps += [ webrtc_root + ":poison_" + p ]
577      }
578      foreach(poison_type, all_poison_types) {
579        allow_dep = true
580        foreach(v, visibility) {
581          if (v == "*") {
582            allow_dep = false
583          }
584        }
585        foreach(p, allow_poison + poisonous) {
586          if (p == poison_type) {
587            allow_dep = true
588          }
589        }
590        if (!allow_dep) {
591          assert_no_deps += [ webrtc_root + ":poison_" + poison_type ]
592        }
593      }
594    }
595
596    # Chromium should only depend on the WebRTC component in order to
597    # avoid to statically link WebRTC in a component build.
598    if (build_with_chromium) {
599      publicly_visible = false
600      foreach(v, visibility) {
601        if (v == "*") {
602          publicly_visible = true
603        }
604      }
605      if (publicly_visible) {
606        visibility = []
607        visibility = webrtc_default_visibility
608      }
609    }
610
611    if (!defined(testonly) || !testonly) {
612      configs += rtc_prod_configs
613    }
614
615    configs += invoker.configs
616    configs += rtc_library_impl_config
617    configs -= rtc_remove_configs
618    configs -= invoker.suppressed_configs
619    public_configs = [
620      rtc_common_inherited_config,
621      absl_include_config,
622      absl_define_config,
623    ]
624    if (defined(testonly) && testonly) {
625      public_configs += [ absl_flags_config ]
626    }
627    if (defined(invoker.public_configs)) {
628      public_configs += invoker.public_configs
629    }
630
631    # If absl_deps is [], no action is needed. If not [], then it needs to be
632    # converted to //third_party/abseil-cpp:absl when build_with_chromium=true
633    # otherwise it just needs to be added to deps.
634    if (absl_deps != []) {
635      if (!defined(deps)) {
636        deps = []
637      }
638      if (build_with_chromium) {
639        deps += [ "//third_party/abseil-cpp:absl" ]
640      } else {
641        deps += absl_deps
642      }
643    }
644  }
645}
646
647template("rtc_static_library") {
648  static_library(target_name) {
649    forward_variables_from(invoker,
650                           "*",
651                           [
652                             "configs",
653                             "public_configs",
654                             "suppressed_configs",
655                             "visibility",
656                           ])
657    forward_variables_from(invoker, [ "visibility" ])
658    if (!defined(visibility)) {
659      visibility = webrtc_default_visibility
660    }
661
662    # What's your poison?
663    if (defined(testonly) && testonly) {
664      assert(!defined(poisonous))
665      assert(!defined(allow_poison))
666    } else {
667      if (!defined(poisonous)) {
668        poisonous = []
669      }
670      if (!defined(allow_poison)) {
671        allow_poison = []
672      }
673      if (!defined(assert_no_deps)) {
674        assert_no_deps = []
675      }
676      if (!defined(deps)) {
677        deps = []
678      }
679      foreach(p, poisonous) {
680        deps += [ webrtc_root + ":poison_" + p ]
681      }
682      foreach(poison_type, all_poison_types) {
683        allow_dep = true
684        foreach(v, visibility) {
685          if (v == "*") {
686            allow_dep = false
687          }
688        }
689        foreach(p, allow_poison + poisonous) {
690          if (p == poison_type) {
691            allow_dep = true
692          }
693        }
694        if (!allow_dep) {
695          assert_no_deps += [ webrtc_root + ":poison_" + poison_type ]
696        }
697      }
698    }
699
700    if (!defined(testonly) || !testonly) {
701      configs += rtc_prod_configs
702    }
703
704    configs += invoker.configs
705    configs += rtc_library_impl_config
706    configs -= rtc_remove_configs
707    configs -= invoker.suppressed_configs
708    public_configs = [
709      rtc_common_inherited_config,
710      absl_include_config,
711      absl_define_config,
712    ]
713    if (defined(testonly) && testonly) {
714      public_configs += [ absl_flags_config ]
715    }
716    if (defined(invoker.public_configs)) {
717      public_configs += invoker.public_configs
718    }
719
720    # If absl_deps is [], no action is needed. If not [], then it needs to be
721    # converted to //third_party/abseil-cpp:absl when build_with_chromium=true
722    # otherwise it just needs to be added to deps.
723    if (absl_deps != []) {
724      if (!defined(deps)) {
725        deps = []
726      }
727      if (build_with_chromium) {
728        deps += [ "//third_party/abseil-cpp:absl" ]
729      } else {
730        deps += absl_deps
731      }
732    }
733  }
734}
735
736# This template automatically switches the target type between source_set
737# and static_library.
738#
739# This should be the default target type for all the WebRTC targets.
740#
741# How does it work:
742# Since all files in a source_set are linked into a final binary, while files
743# in a static library are only linked in if at least one symbol in them is
744# referenced, in component builds source_sets are easy to deal with because
745# all their object files are passed to the linker to create a shared library.
746# In release builds instead, static_libraries are preferred since they allow
747# the linker to discard dead code.
748# For the same reason, testonly targets will always be expanded to
749# source_set in order to be sure that tests are present in the test binary.
750template("rtc_library") {
751  header_only = true
752  if (defined(invoker.sources)) {
753    non_header_sources = filter_exclude(invoker.sources,
754                                        [
755                                          "*.h",
756                                          "*.hh",
757                                          "*.inc",
758                                        ])
759    if (non_header_sources != []) {
760      header_only = false
761    }
762  }
763
764  # Header only libraries should use source_set as a static_library with no
765  # source files will cause issues with macOS libtool.
766  if (header_only || is_component_build ||
767      (defined(invoker.testonly) && invoker.testonly)) {
768    target_type = "source_set"
769  } else {
770    target_type = "static_library"
771  }
772  target(target_type, target_name) {
773    forward_variables_from(invoker,
774                           "*",
775                           [
776                             "configs",
777                             "public_configs",
778                             "suppressed_configs",
779                             "visibility",
780                           ])
781    forward_variables_from(invoker, [ "visibility" ])
782    if (!defined(visibility)) {
783      visibility = webrtc_default_visibility
784    }
785
786    # What's your poison?
787    if (defined(testonly) && testonly) {
788      assert(!defined(poisonous))
789      assert(!defined(allow_poison))
790    } else {
791      if (!defined(poisonous)) {
792        poisonous = []
793      }
794      if (!defined(allow_poison)) {
795        allow_poison = []
796      }
797      if (!defined(assert_no_deps)) {
798        assert_no_deps = []
799      }
800      if (!defined(deps)) {
801        deps = []
802      }
803      foreach(p, poisonous) {
804        deps += [ webrtc_root + ":poison_" + p ]
805      }
806      foreach(poison_type, all_poison_types) {
807        allow_dep = true
808        foreach(v, visibility) {
809          if (v == "*") {
810            allow_dep = false
811          }
812        }
813        foreach(p, allow_poison + poisonous) {
814          if (p == poison_type) {
815            allow_dep = true
816          }
817        }
818        if (!allow_dep) {
819          assert_no_deps += [ webrtc_root + ":poison_" + poison_type ]
820        }
821      }
822    }
823
824    # Chromium should only depend on the WebRTC component in order to
825    # avoid to statically link WebRTC in a component build.
826    if (build_with_chromium) {
827      publicly_visible = false
828      foreach(v, visibility) {
829        if (v == "*") {
830          publicly_visible = true
831        }
832      }
833      if (publicly_visible) {
834        visibility = []
835        visibility = webrtc_default_visibility
836      }
837    }
838
839    if (!defined(testonly) || !testonly) {
840      configs += rtc_prod_configs
841    }
842
843    configs += invoker.configs
844    configs += rtc_library_impl_config
845    configs -= rtc_remove_configs
846    configs -= invoker.suppressed_configs
847    public_configs = [
848      rtc_common_inherited_config,
849      absl_include_config,
850      absl_define_config,
851    ]
852    if (defined(testonly) && testonly) {
853      public_configs += [ absl_flags_config ]
854    }
855    if (defined(invoker.public_configs)) {
856      public_configs += invoker.public_configs
857    }
858
859    # If absl_deps is [], no action is needed. If not [], then it needs to be
860    # converted to //third_party/abseil-cpp:absl when build_with_chromium=true
861    # otherwise it just needs to be added to deps.
862    if (absl_deps != []) {
863      if (!defined(deps)) {
864        deps = []
865      }
866      if (build_with_chromium) {
867        deps += [ "//third_party/abseil-cpp:absl" ]
868      } else {
869        deps += absl_deps
870      }
871    }
872  }
873}
874
875template("rtc_executable") {
876  executable(target_name) {
877    forward_variables_from(invoker,
878                           "*",
879                           [
880                             "deps",
881                             "configs",
882                             "public_configs",
883                             "suppressed_configs",
884                             "visibility",
885                           ])
886    forward_variables_from(invoker, [ "visibility" ])
887    if (!defined(visibility)) {
888      visibility = webrtc_default_visibility
889    }
890    configs += invoker.configs
891    configs -= rtc_remove_configs
892    configs -= invoker.suppressed_configs
893    deps = invoker.deps
894
895    public_configs = [
896      rtc_common_inherited_config,
897      absl_include_config,
898      absl_define_config,
899    ]
900    if (defined(testonly) && testonly) {
901      public_configs += [ absl_flags_config ]
902    }
903    if (defined(invoker.public_configs)) {
904      public_configs += invoker.public_configs
905    }
906    if (is_win) {
907      deps += [
908        # Give executables the default manifest on Windows (a no-op elsewhere).
909        "//build/win:default_exe_manifest",
910      ]
911    }
912  }
913}
914
915template("rtc_shared_library") {
916  shared_library(target_name) {
917    forward_variables_from(invoker,
918                           "*",
919                           [
920                             "configs",
921                             "public_configs",
922                             "suppressed_configs",
923                             "visibility",
924                           ])
925    forward_variables_from(invoker, [ "visibility" ])
926    if (!defined(visibility)) {
927      visibility = webrtc_default_visibility
928    }
929
930    # What's your poison?
931    if (defined(testonly) && testonly) {
932      assert(!defined(poisonous))
933      assert(!defined(allow_poison))
934    } else {
935      if (!defined(poisonous)) {
936        poisonous = []
937      }
938      if (!defined(allow_poison)) {
939        allow_poison = []
940      }
941      if (!defined(assert_no_deps)) {
942        assert_no_deps = []
943      }
944      if (!defined(deps)) {
945        deps = []
946      }
947      foreach(p, poisonous) {
948        deps += [ webrtc_root + ":poison_" + p ]
949      }
950      foreach(poison_type, all_poison_types) {
951        allow_dep = true
952        foreach(v, visibility) {
953          if (v == "*") {
954            allow_dep = false
955          }
956        }
957        foreach(p, allow_poison + poisonous) {
958          if (p == poison_type) {
959            allow_dep = true
960          }
961        }
962        if (!allow_dep) {
963          assert_no_deps += [ webrtc_root + ":poison_" + poison_type ]
964        }
965      }
966    }
967
968    configs += invoker.configs
969    configs -= rtc_remove_configs
970    configs -= invoker.suppressed_configs
971    public_configs = [
972      rtc_common_inherited_config,
973      absl_include_config,
974      absl_define_config,
975    ]
976    if (defined(testonly) && testonly) {
977      public_configs += [ absl_flags_config ]
978    }
979    if (defined(invoker.public_configs)) {
980      public_configs += invoker.public_configs
981    }
982  }
983}
984
985if (is_mac || is_ios) {
986  template("apple_framework_bundle_with_umbrella_header") {
987    forward_variables_from(invoker, [ "output_name" ])
988    this_target_name = target_name
989    umbrella_header_path =
990        "$target_gen_dir/$output_name.framework/WebRTC/$output_name.h"
991    modulemap_path = "$target_gen_dir/Modules/module.modulemap"
992
993    action_foreach("create_bracket_include_headers_$target_name") {
994      script = "//tools_webrtc/apple/copy_framework_header.py"
995      sources = invoker.sources
996      output_name = invoker.output_name
997      outputs = [
998        "$target_gen_dir/$output_name.framework/WebRTC/{{source_file_part}}",
999      ]
1000      args = [
1001        "--input",
1002        "{{source}}",
1003        "--output",
1004        rebase_path(target_gen_dir, root_build_dir) +
1005            "/$output_name.framework/WebRTC/{{source_file_part}}",
1006      ]
1007    }
1008
1009    if (is_mac) {
1010      mac_framework_bundle(target_name) {
1011        forward_variables_from(invoker, "*", [ "configs" ])
1012        if (defined(invoker.configs)) {
1013          configs += invoker.configs
1014        }
1015
1016        framework_version = "A"
1017        framework_contents = [
1018          "Headers",
1019          "Modules",
1020          "Resources",
1021        ]
1022
1023        ldflags = [
1024          "-all_load",
1025          "-install_name",
1026          "@rpath/$output_name.framework/$output_name",
1027        ]
1028
1029        deps += [
1030          ":copy_framework_headers_$this_target_name",
1031          ":copy_modulemap_$this_target_name",
1032          ":copy_umbrella_header_$this_target_name",
1033          ":create_bracket_include_headers_$this_target_name",
1034          ":modulemap_$this_target_name",
1035          ":umbrella_header_$this_target_name",
1036        ]
1037      }
1038    }
1039    if (is_ios) {
1040      ios_framework_bundle(target_name) {
1041        forward_variables_from(invoker,
1042                               "*",
1043                               [
1044                                 "configs",
1045                                 "public_headers",
1046                               ])
1047        if (defined(invoker.configs)) {
1048          configs += invoker.configs
1049        }
1050        public_headers = get_target_outputs(
1051                ":create_bracket_include_headers_$this_target_name")
1052
1053        deps += [
1054          ":copy_umbrella_header_$this_target_name",
1055          ":create_bracket_include_headers_$this_target_name",
1056        ]
1057      }
1058    }
1059
1060    if (is_mac || target_environment == "catalyst") {
1061      # Catalyst frameworks use the same layout as regular Mac frameworks.
1062      headers_dir = "Versions/A/Headers"
1063    } else {
1064      headers_dir = "Headers"
1065    }
1066
1067    bundle_data("copy_framework_headers_$this_target_name") {
1068      sources = get_target_outputs(
1069              ":create_bracket_include_headers_$this_target_name")
1070
1071      outputs = [ "{{bundle_contents_dir}}/Headers/{{source_file_part}}" ]
1072      deps = [ ":create_bracket_include_headers_$this_target_name" ]
1073    }
1074
1075    action("modulemap_$this_target_name") {
1076      script = "//tools_webrtc/ios/generate_modulemap.py"
1077      args = [
1078        "--out",
1079        rebase_path(modulemap_path, root_build_dir),
1080        "--name",
1081        output_name,
1082      ]
1083      outputs = [ modulemap_path ]
1084    }
1085
1086    bundle_data("copy_modulemap_$this_target_name") {
1087      sources = [ modulemap_path ]
1088      outputs = [ "{{bundle_contents_dir}}/Modules/module.modulemap" ]
1089      deps = [ ":modulemap_$this_target_name" ]
1090    }
1091
1092    action("umbrella_header_$this_target_name") {
1093      sources = get_target_outputs(
1094              ":create_bracket_include_headers_$this_target_name")
1095
1096      script = "//tools_webrtc/ios/generate_umbrella_header.py"
1097
1098      outputs = [ umbrella_header_path ]
1099      args = [
1100               "--out",
1101               rebase_path(umbrella_header_path, root_build_dir),
1102               "--sources",
1103             ] + sources
1104      deps = [ ":create_bracket_include_headers_$this_target_name" ]
1105    }
1106
1107    copy("copy_umbrella_header_$target_name") {
1108      sources = [ umbrella_header_path ]
1109      outputs =
1110          [ "$root_out_dir/$output_name.framework/$headers_dir/$output_name.h" ]
1111
1112      deps = [ ":umbrella_header_$target_name" ]
1113    }
1114  }
1115}
1116
1117if (is_android) {
1118  template("rtc_android_library") {
1119    android_library(target_name) {
1120      forward_variables_from(invoker,
1121                             "*",
1122                             [
1123                               "configs",
1124                               "public_configs",
1125                               "suppressed_configs",
1126                               "visibility",
1127                             ])
1128
1129      errorprone_args = []
1130
1131      # Treat warnings as errors.
1132      errorprone_args += [ "-Werror" ]
1133
1134      # Add any arguments defined by the invoker.
1135      if (defined(invoker.errorprone_args)) {
1136        errorprone_args += invoker.errorprone_args
1137      }
1138
1139      if (!defined(deps)) {
1140        deps = []
1141      }
1142
1143      no_build_hooks = true
1144      not_needed([ "android_manifest" ])
1145    }
1146  }
1147
1148  template("rtc_android_apk") {
1149    android_apk(target_name) {
1150      forward_variables_from(invoker,
1151                             "*",
1152                             [
1153                               "configs",
1154                               "public_configs",
1155                               "suppressed_configs",
1156                               "visibility",
1157                             ])
1158
1159      # Treat warnings as errors.
1160      errorprone_args = []
1161      errorprone_args += [ "-Werror" ]
1162
1163      if (!defined(deps)) {
1164        deps = []
1165      }
1166
1167      no_build_hooks = true
1168    }
1169  }
1170
1171  template("rtc_instrumentation_test_apk") {
1172    instrumentation_test_apk(target_name) {
1173      forward_variables_from(invoker,
1174                             "*",
1175                             [
1176                               "configs",
1177                               "public_configs",
1178                               "suppressed_configs",
1179                               "visibility",
1180                             ])
1181
1182      # Treat warnings as errors.
1183      errorprone_args = []
1184      errorprone_args += [ "-Werror" ]
1185
1186      if (!defined(deps)) {
1187        deps = []
1188      }
1189
1190      no_build_hooks = true
1191    }
1192  }
1193}
1194