Fix issue with multiple tf-lite-includes

If multiple libraries include tf_lite_includes.h, multiple definitions
of dlsym and dlopen will be present. Split these dummy functions into
a separate library.

Change-Id: Iea4a874dddebdfd53f8a86318f41c221ff54fe6a
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 2c3b8fd..e8a2d07 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -650,7 +650,7 @@
       list(APPEND AOM_EXAMPLE_TARGETS tf_lite_model)
       list(APPEND AOM_APP_TARGETS tf_lite_model)
       target_link_tf_lite_libraries(tf_lite_model)
-      add_dependencies(tf_lite_model tensorflow_lite)
+      add_dependencies(tf_lite_model tensorflow_lite fake_dl)
     endif()
   endif()
 endif()
diff --git a/build/cmake/tensorflow_lite.cmake b/build/cmake/tensorflow_lite.cmake
index c76e343..becd790 100644
--- a/build/cmake/tensorflow_lite.cmake
+++ b/build/cmake/tensorflow_lite.cmake
@@ -71,6 +71,7 @@
 # "experiment_requires_tf_lite" function.
 function(target_link_tf_lite_libraries named_target)
   target_link_libraries(${named_target} ${AOM_LIB_LINK_TYPE} Threads::Threads)
+  target_link_libraries(${named_target} PRIVATE fake_dl)
   target_link_tf_lite_dep_(${named_target} "" tensorflow-lite)
   target_link_tf_lite_dep_(${named_target} _deps/abseil-cpp-build/absl/flags/
                            absl_flags)
@@ -198,13 +199,19 @@
     CMAKE_ARGS "-DCMAKE_BUILD_TYPE=Release"
     LOG_BUILD 1)
 
+  # TF-Lite uses dlsym and dlopen for delegation, but linking with -ldl is not
+  # supported in static builds. Use a dummy implementation (callers must not use
+  # delegation).
+  add_library(fake_dl OBJECT "${AOM_ROOT}/common/fake_dl.h"
+                      "${AOM_ROOT}/common/fake_dl.cc")
+
   # TF-Lite depends on this, and downloads it during compilation.
   include_directories(
     "${CMAKE_CURRENT_BINARY_DIR}/tensorflow_lite/flatbuffers/include/")
 
-  add_dependencies(aom_av1_common tensorflow_lite)
+  add_dependencies(aom_av1_common tensorflow_lite fake_dl)
   foreach(aom_app ${AOM_APP_TARGETS})
-    add_dependencies(${aom_app} tensorflow_lite)
+    add_dependencies(${aom_app} tensorflow_lite fake_dl)
     target_link_tf_lite_libraries(${aom_app})
   endforeach()
 endfunction()
diff --git a/common/fake_dl.cc b/common/fake_dl.cc
new file mode 100644
index 0000000..609c414
--- /dev/null
+++ b/common/fake_dl.cc
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2020, Alliance for Open Media. All rights reserved
+ *
+ * This source code is subject to the terms of the BSD 2 Clause License and
+ * the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
+ * was not distributed with this source code in the LICENSE file, you can
+ * obtain it at www.aomedia.org/license/software. If the Alliance for Open
+ * Media Patent License 1.0 was not distributed with this source code in the
+ * PATENTS file, you can obtain it at www.aomedia.org/license/patent.
+ */
+
+// TensorFlow Lite uses dlsym and dlopen when using delegates,
+// e.g., GPU or TPU processing. Static builds of the AOM encoder
+// do not support linking with -ldl. Define dummy functions
+// to allow linking. Do not use delegation with TensorFlow Lite.
+
+#include <cassert>
+#include <cstddef>
+
+#include "common/fake_dl.h"
+
+void *dlopen(const char *filename, int flags) {
+  (void)filename;
+  (void)flags;
+  assert(false);
+  return NULL;
+}
+
+void *dlsym(void *handle, const char *symbol) {
+  (void)handle;
+  (void)symbol;
+  assert(false);
+  return NULL;
+}
diff --git a/common/fake_dl.h b/common/fake_dl.h
new file mode 100644
index 0000000..5f0604b
--- /dev/null
+++ b/common/fake_dl.h
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2020, Alliance for Open Media. All rights reserved
+ *
+ * This source code is subject to the terms of the BSD 2 Clause License and
+ * the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
+ * was not distributed with this source code in the LICENSE file, you can
+ * obtain it at www.aomedia.org/license/software. If the Alliance for Open
+ * Media Patent License 1.0 was not distributed with this source code in the
+ * PATENTS file, you can obtain it at www.aomedia.org/license/patent.
+ */
+
+#ifndef AOM_COMMON_FAKE_DL_H_
+#define AOM_COMMON_FAKE_DL_H_
+
+// TensorFlow Lite uses dlsym and dlopen when using delegates,
+// e.g., GPU or TPU processing. Static builds of the AOM encoder
+// do not support linking with -ldl. Define dummy functions
+// to allow linking. Do not use delegation with TensorFlow Lite.
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void *dlopen(const char *filename, int flags);
+void *dlsym(void *handle, const char *symbol);
+
+#ifdef __cplusplus
+}  // extern "C"
+#endif
+
+#endif  // AOM_COMMON_FAKE_DL_H_
diff --git a/common/tf_lite_includes.h b/common/tf_lite_includes.h
index 7ea2b1c..39da4dc 100644
--- a/common/tf_lite_includes.h
+++ b/common/tf_lite_includes.h
@@ -30,31 +30,4 @@
 
 #pragma GCC diagnostic pop
 
-// TensorFlow Lite uses dlsym and dlopen when using delegates,
-// e.g., GPU or TPU processing. Static builds of the AOM encoder
-// do not support linking with -ldl. Define dummy functions
-// to allow linking. Do not use delegation with TensorFlow Lite.
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-void *dlopen(const char *filename, int flags) {
-  (void)filename;
-  (void)flags;
-  assert(0);
-  return NULL;
-}
-
-void *dlsym(void *handle, const char *symbol) {
-  (void)handle;
-  (void)symbol;
-  assert(0);
-  return NULL;
-}
-
-#ifdef __cplusplus
-}  // extern "C"
-#endif
-
 #endif  // AOM_COMMON_TF_LITE_INCLUDES_H_