GN hack to tag targets as poisonous (and use it with audio codecs)

Only specially taggged targets may transitively depend on poisonous
targets. We first apply it to audio codecs.

This makes it much clearer exactly what parts of the code still have
dependencies on the audio codecs (and we want to eventually get rid of
pretty much all of them).

Bug: webrtc:8396, webrtc:9121
Change-Id: Iba5c2e806c702b5cfe881022674705f647896d43
Reviewed-on: https://webrtc-review.googlesource.com/69520
Commit-Queue: Karl Wiberg <kwiberg@webrtc.org>
Reviewed-by: Patrik Höglund <phoglund@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#22979}
diff --git a/BUILD.gn b/BUILD.gn
index 8eab817..797467c 100644
--- a/BUILD.gn
+++ b/BUILD.gn
@@ -587,3 +587,15 @@
     }
   }
 }
+
+# ---- Poisons ----
+#
+# Here is one empty dummy target for each poison type (needed because
+# "being poisonous with poison type foo" is implemented as "depends on
+# //:poison_foo").
+#
+# The set of poison_* targets needs to be kept in sync with the
+# `all_poison_types` list in webrtc.gni.
+#
+group("poison_audio_codecs") {
+}
diff --git a/api/BUILD.gn b/api/BUILD.gn
index fddea97..7690624 100644
--- a/api/BUILD.gn
+++ b/api/BUILD.gn
@@ -268,6 +268,7 @@
 
 rtc_source_set("video_stream_decoder_create") {
   visibility = [ "*" ]
+  allow_poison = [ "audio_codecs" ]  # TODO(bugs.webrtc.org/8396): Remove.
   sources = [
     "video/video_stream_decoder_create.cc",
     "video/video_stream_decoder_create.h",
diff --git a/api/audio/BUILD.gn b/api/audio/BUILD.gn
index 5558ab1..60f9844 100644
--- a/api/audio/BUILD.gn
+++ b/api/audio/BUILD.gn
@@ -44,6 +44,7 @@
 
 rtc_source_set("aec3_factory") {
   visibility = [ "*" ]
+  allow_poison = [ "audio_codecs" ]  # TODO(bugs.webrtc.org/8396): Remove.
   configs += [ "../../modules/audio_processing:apm_debug_dump" ]
   sources = [
     "echo_canceller3_factory.cc",
diff --git a/api/audio_codecs/BUILD.gn b/api/audio_codecs/BUILD.gn
index fb033f2..ee943a1 100644
--- a/api/audio_codecs/BUILD.gn
+++ b/api/audio_codecs/BUILD.gn
@@ -44,6 +44,7 @@
 
 rtc_static_library("builtin_audio_decoder_factory") {
   visibility = [ "*" ]
+  allow_poison = [ "audio_codecs" ]
   sources = [
     "builtin_audio_decoder_factory.cc",
     "builtin_audio_decoder_factory.h",
@@ -73,6 +74,7 @@
 
 rtc_static_library("builtin_audio_encoder_factory") {
   visibility = [ "*" ]
+  allow_poison = [ "audio_codecs" ]
   sources = [
     "builtin_audio_encoder_factory.cc",
     "builtin_audio_encoder_factory.h",
diff --git a/api/audio_codecs/L16/BUILD.gn b/api/audio_codecs/L16/BUILD.gn
index f047bf1..01554aa 100644
--- a/api/audio_codecs/L16/BUILD.gn
+++ b/api/audio_codecs/L16/BUILD.gn
@@ -14,6 +14,7 @@
 
 rtc_static_library("audio_encoder_L16") {
   visibility = [ "*" ]
+  poisonous = [ "audio_codecs" ]
   sources = [
     "audio_encoder_L16.cc",
     "audio_encoder_L16.h",
@@ -29,6 +30,7 @@
 
 rtc_static_library("audio_decoder_L16") {
   visibility = [ "*" ]
+  poisonous = [ "audio_codecs" ]
   sources = [
     "audio_decoder_L16.cc",
     "audio_decoder_L16.h",
diff --git a/api/audio_codecs/g711/BUILD.gn b/api/audio_codecs/g711/BUILD.gn
index f28342f..7026abb 100644
--- a/api/audio_codecs/g711/BUILD.gn
+++ b/api/audio_codecs/g711/BUILD.gn
@@ -14,6 +14,7 @@
 
 rtc_static_library("audio_encoder_g711") {
   visibility = [ "*" ]
+  poisonous = [ "audio_codecs" ]
   sources = [
     "audio_encoder_g711.cc",
     "audio_encoder_g711.h",
@@ -30,6 +31,7 @@
 
 rtc_static_library("audio_decoder_g711") {
   visibility = [ "*" ]
+  poisonous = [ "audio_codecs" ]
   sources = [
     "audio_decoder_g711.cc",
     "audio_decoder_g711.h",
diff --git a/api/audio_codecs/g722/BUILD.gn b/api/audio_codecs/g722/BUILD.gn
index b3ef381..7078aa4 100644
--- a/api/audio_codecs/g722/BUILD.gn
+++ b/api/audio_codecs/g722/BUILD.gn
@@ -21,6 +21,7 @@
 
 rtc_static_library("audio_encoder_g722") {
   visibility = [ "*" ]
+  poisonous = [ "audio_codecs" ]
   sources = [
     "audio_encoder_g722.cc",
     "audio_encoder_g722.h",
@@ -38,6 +39,7 @@
 
 rtc_static_library("audio_decoder_g722") {
   visibility = [ "*" ]
+  poisonous = [ "audio_codecs" ]
   sources = [
     "audio_decoder_g722.cc",
     "audio_decoder_g722.h",
diff --git a/api/audio_codecs/ilbc/BUILD.gn b/api/audio_codecs/ilbc/BUILD.gn
index 765e279..52dac5f 100644
--- a/api/audio_codecs/ilbc/BUILD.gn
+++ b/api/audio_codecs/ilbc/BUILD.gn
@@ -21,6 +21,7 @@
 
 rtc_static_library("audio_encoder_ilbc") {
   visibility = [ "*" ]
+  poisonous = [ "audio_codecs" ]
   sources = [
     "audio_encoder_ilbc.cc",
     "audio_encoder_ilbc.h",
@@ -38,6 +39,7 @@
 
 rtc_static_library("audio_decoder_ilbc") {
   visibility = [ "*" ]
+  poisonous = [ "audio_codecs" ]
   sources = [
     "audio_decoder_ilbc.cc",
     "audio_decoder_ilbc.h",
diff --git a/api/audio_codecs/isac/BUILD.gn b/api/audio_codecs/isac/BUILD.gn
index f63435c..08cabc5 100644
--- a/api/audio_codecs/isac/BUILD.gn
+++ b/api/audio_codecs/isac/BUILD.gn
@@ -19,6 +19,7 @@
 
 rtc_source_set("audio_encoder_isac") {
   visibility = [ "*" ]
+  poisonous = [ "audio_codecs" ]
   public = [
     "audio_encoder_isac.h",
   ]
@@ -36,6 +37,7 @@
 
 rtc_source_set("audio_decoder_isac") {
   visibility = [ "*" ]
+  poisonous = [ "audio_codecs" ]
   public = [
     "audio_decoder_isac.h",
   ]
@@ -68,6 +70,7 @@
 
 rtc_static_library("audio_encoder_isac_fix") {
   visibility = [ "*" ]
+  poisonous = [ "audio_codecs" ]
   sources = [
     "audio_encoder_isac_fix.cc",
     "audio_encoder_isac_fix.h",
@@ -83,6 +86,7 @@
 
 rtc_static_library("audio_decoder_isac_fix") {
   visibility = [ "*" ]
+  poisonous = [ "audio_codecs" ]
   sources = [
     "audio_decoder_isac_fix.cc",
     "audio_decoder_isac_fix.h",
@@ -98,6 +102,7 @@
 
 rtc_static_library("audio_encoder_isac_float") {
   visibility = [ "*" ]
+  poisonous = [ "audio_codecs" ]
   sources = [
     "audio_encoder_isac_float.cc",
     "audio_encoder_isac_float.h",
@@ -113,6 +118,7 @@
 
 rtc_static_library("audio_decoder_isac_float") {
   visibility = [ "*" ]
+  poisonous = [ "audio_codecs" ]
   sources = [
     "audio_decoder_isac_float.cc",
     "audio_decoder_isac_float.h",
diff --git a/api/audio_codecs/opus/BUILD.gn b/api/audio_codecs/opus/BUILD.gn
index 934dbc2..d235d1a 100644
--- a/api/audio_codecs/opus/BUILD.gn
+++ b/api/audio_codecs/opus/BUILD.gn
@@ -32,6 +32,7 @@
 
 rtc_source_set("audio_encoder_opus") {
   visibility = [ "*" ]
+  poisonous = [ "audio_codecs" ]
   public = [
     "audio_encoder_opus.h",
   ]
@@ -49,6 +50,7 @@
 
 rtc_static_library("audio_decoder_opus") {
   visibility = [ "*" ]
+  poisonous = [ "audio_codecs" ]
   sources = [
     "audio_decoder_opus.cc",
     "audio_decoder_opus.h",
diff --git a/media/BUILD.gn b/media/BUILD.gn
index faee980..67d6328 100644
--- a/media/BUILD.gn
+++ b/media/BUILD.gn
@@ -64,6 +64,7 @@
 
 rtc_static_library("rtc_media_base") {
   visibility = [ "*" ]
+  allow_poison = [ "audio_codecs" ]  # TODO(bugs.webrtc.org/8396): Remove.
   defines = []
   libs = []
   deps = [
@@ -155,6 +156,7 @@
 
 rtc_static_library("rtc_internal_video_codecs") {
   visibility = [ "*" ]
+  allow_poison = [ "audio_codecs" ]  # TODO(bugs.webrtc.org/8396): Remove.
   defines = []
   libs = []
   deps = [
@@ -253,6 +255,7 @@
 
 rtc_static_library("rtc_audio_video") {
   visibility = [ "*" ]
+  allow_poison = [ "audio_codecs" ]  # TODO(bugs.webrtc.org/8396): Remove.
   defines = []
   libs = []
   deps = [
@@ -420,6 +423,7 @@
 
 rtc_source_set("rtc_media") {
   visibility = [ "*" ]
+  allow_poison = [ "audio_codecs" ]  # TODO(bugs.webrtc.org/8396): Remove.
   deps = [
     ":rtc_audio_video",
     ":rtc_data",
diff --git a/modules/audio_coding/BUILD.gn b/modules/audio_coding/BUILD.gn
index 7cea425..7dfe70b 100644
--- a/modules/audio_coding/BUILD.gn
+++ b/modules/audio_coding/BUILD.gn
@@ -104,6 +104,7 @@
 
 rtc_static_library("audio_coding") {
   visibility += [ "*" ]
+  allow_poison = [ "audio_codecs" ]  # TODO(bugs.webrtc.org/8396): Remove.
   sources = [
     "acm2/acm_receiver.cc",
     "acm2/acm_receiver.h",
@@ -220,6 +221,7 @@
 
 rtc_static_library("g711") {
   visibility += [ "*" ]
+  poisonous = [ "audio_codecs" ]
   sources = [
     "codecs/g711/audio_decoder_pcm.cc",
     "codecs/g711/audio_decoder_pcm.h",
@@ -242,6 +244,7 @@
 }
 
 rtc_source_set("g711_c") {
+  poisonous = [ "audio_codecs" ]
   sources = [
     "codecs/g711/g711.c",
     "codecs/g711/g711.h",
@@ -260,6 +263,7 @@
 
 rtc_static_library("g722") {
   visibility += [ "*" ]
+  poisonous = [ "audio_codecs" ]
   sources = [
     "codecs/g722/audio_decoder_g722.cc",
     "codecs/g722/audio_decoder_g722.h",
@@ -283,6 +287,7 @@
 }
 
 rtc_source_set("g722_c") {
+  poisonous = [ "audio_codecs" ]
   sources = [
     "codecs/g722/g722_decode.c",
     "codecs/g722/g722_enc_dec.h",
@@ -302,6 +307,7 @@
 
 rtc_static_library("ilbc") {
   visibility += webrtc_default_visibility
+  poisonous = [ "audio_codecs" ]
   sources = [
     "codecs/ilbc/audio_decoder_ilbc.cc",
     "codecs/ilbc/audio_decoder_ilbc.h",
@@ -326,6 +332,7 @@
 }
 
 rtc_source_set("ilbc_c") {
+  poisonous = [ "audio_codecs" ]
   sources = [
     "codecs/ilbc/abs_quant.c",
     "codecs/ilbc/abs_quant.h",
@@ -483,6 +490,7 @@
 }
 
 rtc_static_library("isac_common") {
+  poisonous = [ "audio_codecs" ]
   sources = [
     "codecs/isac/audio_decoder_isac_t.h",
     "codecs/isac/audio_decoder_isac_t_impl.h",
@@ -508,6 +516,7 @@
 
 rtc_static_library("isac") {
   visibility += [ "*" ]
+  poisonous = [ "audio_codecs" ]
   sources = [
     "codecs/isac/main/include/audio_decoder_isac.h",
     "codecs/isac/main/include/audio_encoder_isac.h",
@@ -525,6 +534,7 @@
 }
 
 rtc_static_library("isac_c") {
+  poisonous = [ "audio_codecs" ]
   sources = [
     "codecs/isac/main/include/isac.h",
     "codecs/isac/main/source/arith_routines.c",
@@ -602,6 +612,7 @@
 
 rtc_static_library("isac_fix") {
   visibility += [ "*" ]
+  poisonous = [ "audio_codecs" ]
   sources = [
     "codecs/isac/fix/source/audio_decoder_isacfix.cc",
     "codecs/isac/fix/source/audio_encoder_isacfix.cc",
@@ -625,6 +636,7 @@
 }
 
 rtc_source_set("isac_fix_common") {
+  poisonous = [ "audio_codecs" ]
   sources = [
     "codecs/isac/fix/source/codec.h",
     "codecs/isac/fix/source/entropy_coding.h",
@@ -645,6 +657,7 @@
 }
 
 rtc_source_set("isac_fix_c_arm_asm") {
+  poisonous = [ "audio_codecs" ]
   sources = []
   if (current_cpu == "arm" && arm_version >= 7) {
     sources += [
@@ -659,6 +672,7 @@
 }
 
 rtc_source_set("isac_fix_c") {
+  poisonous = [ "audio_codecs" ]
   sources = [
     "codecs/isac/fix/include/audio_decoder_isacfix.h",
     "codecs/isac/fix/include/audio_encoder_isacfix.h",
@@ -760,6 +774,7 @@
 
 if (rtc_build_with_neon) {
   rtc_static_library("isac_neon") {
+    poisonous = [ "audio_codecs" ]
     sources = [
       "codecs/isac/fix/source/entropy_coding_neon.c",
       "codecs/isac/fix/source/filterbanks_neon.c",
@@ -801,6 +816,7 @@
 
 rtc_static_library("pcm16b") {
   visibility += [ "*" ]
+  poisonous = [ "audio_codecs" ]
   sources = [
     "codecs/pcm16b/audio_decoder_pcm16b.cc",
     "codecs/pcm16b/audio_decoder_pcm16b.h",
@@ -825,6 +841,7 @@
 }
 
 rtc_source_set("pcm16b_c") {
+  poisonous = [ "audio_codecs" ]
   sources = [
     "codecs/pcm16b/pcm16b.c",
     "codecs/pcm16b/pcm16b.h",
@@ -839,6 +856,7 @@
 
 rtc_static_library("webrtc_opus") {
   visibility += webrtc_default_visibility
+  poisonous = [ "audio_codecs" ]
   sources = [
     "codecs/opus/audio_decoder_opus.cc",
     "codecs/opus/audio_decoder_opus.h",
@@ -874,6 +892,7 @@
 }
 
 rtc_source_set("webrtc_opus_c") {
+  poisonous = [ "audio_codecs" ]
   sources = [
     "codecs/opus/opus_inst.h",
     "codecs/opus/opus_interface.c",
diff --git a/modules/audio_processing/BUILD.gn b/modules/audio_processing/BUILD.gn
index 38ff7a9..a64fc6f 100644
--- a/modules/audio_processing/BUILD.gn
+++ b/modules/audio_processing/BUILD.gn
@@ -29,6 +29,7 @@
 
 rtc_static_library("audio_processing") {
   visibility = [ "*" ]
+  allow_poison = [ "audio_codecs" ]  # TODO(bugs.webrtc.org/8396): Remove.
   configs += [ ":apm_debug_dump" ]
   sources = [
     "aec/aec_resampler.cc",
diff --git a/modules/audio_processing/aec3/BUILD.gn b/modules/audio_processing/aec3/BUILD.gn
index 0f58629..2773d35 100644
--- a/modules/audio_processing/aec3/BUILD.gn
+++ b/modules/audio_processing/aec3/BUILD.gn
@@ -11,6 +11,7 @@
 
 rtc_static_library("aec3") {
   visibility = [ "*" ]
+  allow_poison = [ "audio_codecs" ]  # TODO(bugs.webrtc.org/8396): Remove.
   configs += [ "..:apm_debug_dump" ]
   sources = [
     "adaptive_fir_filter.cc",
diff --git a/modules/video_capture/BUILD.gn b/modules/video_capture/BUILD.gn
index 9843b4d..ea54b1e 100644
--- a/modules/video_capture/BUILD.gn
+++ b/modules/video_capture/BUILD.gn
@@ -14,6 +14,7 @@
 # use the internal capturer.
 rtc_static_library("video_capture_module") {
   visibility = [ "*" ]
+  allow_poison = [ "audio_codecs" ]  # TODO(bugs.webrtc.org/8396): Remove.
   sources = [
     "device_info_impl.cc",
     "device_info_impl.h",
@@ -50,6 +51,7 @@
 
 rtc_static_library("video_capture") {
   visibility = [ "*" ]
+  allow_poison = [ "audio_codecs" ]  # TODO(bugs.webrtc.org/8396): Remove.
   sources = [
     "external/device_info_external.cc",
     "external/video_capture_external.cc",
diff --git a/modules/video_coding/BUILD.gn b/modules/video_coding/BUILD.gn
index 3a37bcb..619f15e 100644
--- a/modules/video_coding/BUILD.gn
+++ b/modules/video_coding/BUILD.gn
@@ -38,6 +38,7 @@
 
 rtc_static_library("video_coding") {
   visibility = [ "*" ]
+  allow_poison = [ "audio_codecs" ]  # TODO(bugs.webrtc.org/8396): Remove.
   deps = []
 
   sources = [
@@ -249,6 +250,7 @@
 
 rtc_static_library("webrtc_h264") {
   visibility = [ "*" ]
+  allow_poison = [ "audio_codecs" ]  # TODO(bugs.webrtc.org/8396): Remove.
   sources = [
     "codecs/h264/h264.cc",
     "codecs/h264/include/h264.h",
diff --git a/pc/BUILD.gn b/pc/BUILD.gn
index b9b2f84..9d3f147 100644
--- a/pc/BUILD.gn
+++ b/pc/BUILD.gn
@@ -27,6 +27,7 @@
 
 rtc_static_library("rtc_pc_base") {
   visibility = [ "*" ]
+  allow_poison = [ "audio_codecs" ]  # TODO(bugs.webrtc.org/8396): Remove.
   defines = []
   sources = [
     "audiomonitor.h",
@@ -102,6 +103,7 @@
 
 rtc_source_set("rtc_pc") {
   visibility = [ "*" ]
+  allow_poison = [ "audio_codecs" ]  # TODO(bugs.webrtc.org/8396): Remove.
   deps = [
     ":rtc_pc_base",
     "../media:rtc_audio_video",
@@ -119,6 +121,7 @@
 
 rtc_static_library("peerconnection") {
   visibility = [ "*" ]
+  allow_poison = [ "audio_codecs" ]  # TODO(bugs.webrtc.org/8396): Remove.
   cflags = []
   sources = [
     "audiotrack.cc",
@@ -250,6 +253,7 @@
 
 rtc_source_set("libjingle_peerconnection") {
   visibility = [ "*" ]
+  allow_poison = [ "audio_codecs" ]  # TODO(bugs.webrtc.org/8396): Remove.
   deps = [
     ":create_pc_factory",
     ":peerconnection",
diff --git a/rtc_tools/BUILD.gn b/rtc_tools/BUILD.gn
index bc0648d..d1d2b55 100644
--- a/rtc_tools/BUILD.gn
+++ b/rtc_tools/BUILD.gn
@@ -203,6 +203,7 @@
 
     rtc_static_library("event_log_visualizer_utils") {
       visibility = [ "*" ]
+      allow_poison = [ "audio_codecs" ]  # TODO(bugs.webrtc.org/8396): Remove.
       sources = [
         "event_log_visualizer/analyzer.cc",
         "event_log_visualizer/analyzer.h",
diff --git a/sdk/BUILD.gn b/sdk/BUILD.gn
index b13c50b..00f94a2 100644
--- a/sdk/BUILD.gn
+++ b/sdk/BUILD.gn
@@ -229,6 +229,7 @@
 
     rtc_static_library("ui_objc") {
       visibility = [ "*" ]
+      allow_poison = [ "audio_codecs" ]  # TODO(bugs.webrtc.org/8396): Remove.
       if (is_ios) {
         sources = [
           "objc/Framework/Classes/UI/RTCCameraPreviewView.m",
@@ -255,6 +256,7 @@
     if (rtc_use_metal_rendering) {
       rtc_static_library("metal_objc") {
         visibility = [ "*" ]
+        allow_poison = [ "audio_codecs" ]  # TODO(bugs.webrtc.org/8396): Remove.
         sources = [
           "objc/Framework/Classes/Metal/RTCMTLI420Renderer.h",
           "objc/Framework/Classes/Metal/RTCMTLI420Renderer.mm",
@@ -316,6 +318,7 @@
 
     rtc_static_library("videocapture_objc") {
       visibility = [ "*" ]
+      allow_poison = [ "audio_codecs" ]  # TODO(bugs.webrtc.org/8396): Remove.
       sources = [
         "objc/Framework/Classes/PeerConnection/RTCCameraVideoCapturer.m",
         "objc/Framework/Headers/WebRTC/RTCCameraVideoCapturer.h",
@@ -347,6 +350,8 @@
     }
 
     rtc_static_library("videocodec_objc") {
+      visibility = [ "*" ]
+      allow_poison = [ "audio_codecs" ]  # TODO(bugs.webrtc.org/8396): Remove.
       sources = [
         "objc/Framework/Classes/PeerConnection/RTCEncodedImage.mm",
         "objc/Framework/Classes/PeerConnection/RTCRtpFragmentationHeader.mm",
@@ -363,7 +368,6 @@
         # (bugs.webrtc.org/163).
         suppressed_configs += [ "//build/config/clang:find_bad_constructs" ]
       }
-      visibility = [ "*" ]
       public_configs = [ ":common_config_objc" ]
       deps = [
         ":common_objc",
@@ -398,6 +402,7 @@
 
     rtc_static_library("vp8") {
       visibility = [ "*" ]
+      allow_poison = [ "audio_codecs" ]  # TODO(bugs.webrtc.org/8396): Remove.
       sources = [
         "objc/Framework/Classes/PeerConnection/RTCVideoCodecVP8.mm",
         "objc/Framework/Headers/WebRTC/RTCVideoDecoderVP8.h",
@@ -419,6 +424,7 @@
 
     rtc_static_library("vp9") {
       visibility = [ "*" ]
+      allow_poison = [ "audio_codecs" ]  # TODO(bugs.webrtc.org/8396): Remove.
       sources = [
         "objc/Framework/Classes/PeerConnection/RTCVideoCodecVP9.mm",
         "objc/Framework/Headers/WebRTC/RTCVideoDecoderVP9.h",
@@ -447,6 +453,7 @@
     # The applications which only use WebRTC DataChannel can depend on this.
     rtc_static_library("peerconnectionfactory_no_media_objc") {
       visibility = [ "*" ]
+      allow_poison = [ "audio_codecs" ]  # TODO(bugs.webrtc.org/8396): Remove.
       defines = [ "HAVE_NO_MEDIA" ]
 
       sources = [
@@ -500,6 +507,8 @@
     }
 
     rtc_static_library("videorendereradapter_objc") {
+      visibility = [ "*" ]
+      allow_poison = [ "audio_codecs" ]  # TODO(bugs.webrtc.org/8396): Remove.
       sources = [
         "objc/Framework/Classes/PeerConnection/RTCVideoRendererAdapter+Private.h",
         "objc/Framework/Classes/PeerConnection/RTCVideoRendererAdapter.h",
@@ -507,7 +516,6 @@
       ]
 
       configs += [ "..:common_objc" ]
-      visibility = [ "*" ]
       public_configs = [ ":common_config_objc" ]
 
       deps = [
@@ -537,6 +545,8 @@
     }
 
     rtc_static_library("peerconnectionfactory_base_objc") {
+      visibility = [ "*" ]
+      allow_poison = [ "audio_codecs" ]  # TODO(bugs.webrtc.org/8396): Remove.
       sources = [
         "objc/Framework/Classes/PeerConnection/RTCAudioSource+Private.h",
         "objc/Framework/Classes/PeerConnection/RTCAudioSource.mm",
@@ -624,7 +634,6 @@
       ]
 
       configs += [ "..:common_objc" ]
-      visibility = [ "*" ]
       public_configs = [ ":common_config_objc" ]
 
       if (!build_with_chromium && is_clang) {
@@ -958,6 +967,7 @@
     # The native API is currently experimental and may change without notice.
     rtc_static_library("native_api") {
       visibility = [ "*" ]
+      allow_poison = [ "audio_codecs" ]  # TODO(bugs.webrtc.org/8396): Remove.
       sources = [
         "objc/Framework/Native/api/video_capturer.h",
         "objc/Framework/Native/api/video_capturer.mm",
@@ -1067,6 +1077,7 @@
 
     rtc_static_library("videotoolbox_objc") {
       visibility = [ "*" ]
+      allow_poison = [ "audio_codecs" ]  # TODO(bugs.webrtc.org/8396): Remove.
       sources = [
         "objc/Framework/Classes/VideoToolbox/RTCVideoDecoderH264.mm",
         "objc/Framework/Classes/VideoToolbox/RTCVideoEncoderH264.mm",
diff --git a/sdk/android/BUILD.gn b/sdk/android/BUILD.gn
index 0fb77fa..ae3b0af 100644
--- a/sdk/android/BUILD.gn
+++ b/sdk/android/BUILD.gn
@@ -519,6 +519,7 @@
   # made public because we don't have a proper NDK yet. Header APIs here are not
   # considered public and are subject to change.
   visibility = [ "*" ]
+  allow_poison = [ "audio_codecs" ]  # TODO(bugs.webrtc.org/8396): Remove.
 
   sources = [
     "src/jni/androidnetworkmonitor_jni.h",
@@ -611,6 +612,7 @@
 
 rtc_static_library("libjingle_peerconnection_jni") {
   visibility = [ "*" ]
+  allow_poison = [ "audio_codecs" ]  # TODO(bugs.webrtc.org/8396): Remove.
   public_deps = [
     ":audio_jni",
     ":base_jni",
@@ -631,6 +633,7 @@
 
 rtc_static_library("libjingle_peerconnection_metrics_default_jni") {
   visibility = [ "*" ]
+  allow_poison = [ "audio_codecs" ]  # TODO(bugs.webrtc.org/8396): Remove.
   sources = [
     "src/jni/androidmetrics.cc",
   ]
@@ -1143,6 +1146,7 @@
 # objects.
 rtc_static_library("native_api_codecs") {
   visibility = [ "*" ]
+  allow_poison = [ "audio_codecs" ]  # TODO(bugs.webrtc.org/8396): Remove.
   sources = [
     "native_api/codecs/wrapper.cc",
     "native_api/codecs/wrapper.h",
@@ -1160,6 +1164,7 @@
 # API for creating Java PeerConnectionFactory from C++ equivalents.
 rtc_static_library("native_api_peerconnection") {
   visibility = [ "*" ]
+  allow_poison = [ "audio_codecs" ]  # TODO(bugs.webrtc.org/8396): Remove.
   sources = [
     "native_api/peerconnection/peerconnectionfactory.cc",
     "native_api/peerconnection/peerconnectionfactory.h",
@@ -1186,6 +1191,7 @@
 # video interfaces from their Java equivalents.
 rtc_static_library("native_api_video") {
   visibility = [ "*" ]
+  allow_poison = [ "audio_codecs" ]  # TODO(bugs.webrtc.org/8396): Remove.
   sources = [
     "native_api/video/wrapper.cc",
     "native_api/video/wrapper.h",
diff --git a/video/BUILD.gn b/video/BUILD.gn
index 1400814..a31b366 100644
--- a/video/BUILD.gn
+++ b/video/BUILD.gn
@@ -108,6 +108,7 @@
 
 rtc_source_set("video_stream_decoder_impl") {
   visibility = [ "*" ]
+  allow_poison = [ "audio_codecs" ]  # TODO(bugs.webrtc.org/8396): Remove.
   sources = [
     "video_stream_decoder_impl.cc",
     "video_stream_decoder_impl.h",
diff --git a/webrtc.gni b/webrtc.gni
index cfc9cb0..b3f06ae 100644
--- a/webrtc.gni
+++ b/webrtc.gni
@@ -278,6 +278,41 @@
   webrtc_default_visibility += [ webrtc_root + "/../webrtc_overrides/*" ]
 }
 
+# ---- Poisons ----
+#
+# The general idea is that some targets declare that they contain some
+# kind of poison, which makes it impossible for other targets to
+# depend on them (even transitively) unless they declare themselves
+# immune to that particular type of poison.
+#
+# Targets that *contain* poison of type foo should contain the line
+#
+#   poisonous = [ "foo" ]
+#
+# and targets that *are immune but arent't themselves poisonous*
+# should contain
+#
+#   allow_poison = [ "foo" ]
+#
+# This useful in cases where we have some large target or set of
+# targets and want to ensure that most other targets do not
+# transitively depend on them. For example, almost no high-level
+# target should depend on the audio codecs, since we want WebRTC users
+# to be able to inject any subset of them and actually end up with a
+# binary that doesn't include the codecs they didn't inject.
+#
+# Test-only targets (`testonly` set to true) and non-public targets
+# (`visibility` not containing "*") are automatically immune to all
+# types of poison.
+#
+# Here's the complete list of all types of poison. It must be kept in
+# 1:1 correspondence with the set of //:poison_* targets.
+#
+all_poison_types = [
+  # Encoders and decoders for specific audio codecs such as Opus and iSAC.
+  "audio_codecs",
+]
+
 template("rtc_test") {
   test(target_name) {
     forward_variables_from(invoker,
@@ -321,6 +356,45 @@
     if (!defined(visibility)) {
       visibility = webrtc_default_visibility
     }
+
+    # What's your poison?
+    if (defined(testonly) && testonly) {
+      assert(!defined(poisonous))
+      assert(!defined(allow_poison))
+    } else {
+      if (!defined(poisonous)) {
+        poisonous = []
+      }
+      if (!defined(allow_poison)) {
+        allow_poison = []
+      }
+      if (!defined(assert_no_deps)) {
+        assert_no_deps = []
+      }
+      if (!defined(deps)) {
+        deps = []
+      }
+      foreach(p, poisonous) {
+        deps += [ webrtc_root + ":poison_" + p ]
+      }
+      foreach(poison_type, all_poison_types) {
+        allow_dep = true
+        foreach(v, visibility) {
+          if (v == "*") {
+            allow_dep = false
+          }
+        }
+        foreach(p, allow_poison + poisonous) {
+          if (p == poison_type) {
+            allow_dep = true
+          }
+        }
+        if (!allow_dep) {
+          assert_no_deps += [ webrtc_root + ":poison_" + poison_type ]
+        }
+      }
+    }
+
     configs += invoker.configs
     configs -= rtc_remove_configs
     configs -= invoker.suppressed_configs
@@ -375,6 +449,45 @@
     if (!defined(visibility)) {
       visibility = webrtc_default_visibility
     }
+
+    # What's your poison?
+    if (defined(testonly) && testonly) {
+      assert(!defined(poisonous))
+      assert(!defined(allow_poison))
+    } else {
+      if (!defined(poisonous)) {
+        poisonous = []
+      }
+      if (!defined(allow_poison)) {
+        allow_poison = []
+      }
+      if (!defined(assert_no_deps)) {
+        assert_no_deps = []
+      }
+      if (!defined(deps)) {
+        deps = []
+      }
+      foreach(p, poisonous) {
+        deps += [ webrtc_root + ":poison_" + p ]
+      }
+      foreach(poison_type, all_poison_types) {
+        allow_dep = true
+        foreach(v, visibility) {
+          if (v == "*") {
+            allow_dep = false
+          }
+        }
+        foreach(p, allow_poison + poisonous) {
+          if (p == poison_type) {
+            allow_dep = true
+          }
+        }
+        if (!allow_dep) {
+          assert_no_deps += [ webrtc_root + ":poison_" + poison_type ]
+        }
+      }
+    }
+
     configs += invoker.configs
     configs -= rtc_remove_configs
     configs -= invoker.suppressed_configs
@@ -399,6 +512,45 @@
     if (!defined(visibility)) {
       visibility = webrtc_default_visibility
     }
+
+    # What's your poison?
+    if (defined(testonly) && testonly) {
+      assert(!defined(poisonous))
+      assert(!defined(allow_poison))
+    } else {
+      if (!defined(poisonous)) {
+        poisonous = []
+      }
+      if (!defined(allow_poison)) {
+        allow_poison = []
+      }
+      if (!defined(assert_no_deps)) {
+        assert_no_deps = []
+      }
+      if (!defined(deps)) {
+        deps = []
+      }
+      foreach(p, poisonous) {
+        deps += [ webrtc_root + ":poison_" + p ]
+      }
+      foreach(poison_type, all_poison_types) {
+        allow_dep = true
+        foreach(v, visibility) {
+          if (v == "*") {
+            allow_dep = false
+          }
+        }
+        foreach(p, allow_poison + poisonous) {
+          if (p == poison_type) {
+            allow_dep = true
+          }
+        }
+        if (!allow_dep) {
+          assert_no_deps += [ webrtc_root + ":poison_" + poison_type ]
+        }
+      }
+    }
+
     configs += invoker.configs
     configs -= rtc_remove_configs
     configs -= invoker.suppressed_configs