Don't use the bazel toolchain to link against libllvm

Managing versions and standard libraries to keep these compatible is
annoying, so just use a shell script to compile this one file.

Change-Id: I6167b9c6cc5395430be1ce9964dea4c1b1e6f3ad
Signed-off-by: Brian Silverman <bsilver16834@gmail.com>
diff --git a/y2020/vision/sift/BUILD b/y2020/vision/sift/BUILD
index c2a71fe..c6afc98 100644
--- a/y2020/vision/sift/BUILD
+++ b/y2020/vision/sift/BUILD
@@ -1,6 +1,8 @@
 load(":fast_gaussian.bzl", "fast_gaussian")
 load("@com_github_google_flatbuffers//:build_defs.bzl", "flatbuffer_cc_library", "flatbuffer_py_library", "flatbuffer_ts_library")
 
+# Note that this file is also used directly by :fast_gaussian_halide_generator,
+# without any dependencies added here.
 cc_library(
     name = "get_gaussian_kernel",
     hdrs = [
@@ -21,23 +23,32 @@
     ],
 )
 
-cc_binary(
-    name = "fast_gaussian_generator",
+sh_binary(
+    name = "fast_gaussian_halide_generator",
     srcs = [
+        "fast_gaussian_halide_generator.sh",
+    ],
+    data = [
         "fast_gaussian_generator.cc",
+        "get_gaussian_kernel.h",
+        "@amd64_debian_sysroot//:sysroot_files",
+        "@deb_zlib1g_dev_1_2_11_dfsg_1_amd64_deb_repo//file",
+        "@halide_k8//:build_files",
+        "@llvm_toolchain//:all-components-x86_64-linux",
     ],
-    linkopts = [
-        "-lpthread",
-        "-ldl",
-    ],
-    target_compatible_with = ["@platforms//os:linux"],
     deps = [
-        ":get_gaussian_kernel",
-        "//third_party:halide",
-        "//third_party:halide_gengen",
-        # This somehow brings in a zlib that libllvm needs?
-        # TODO(Brian): Remove this dependency, it's not really used.
-        "//third_party:opencv",
+        "@bazel_tools//tools/bash/runfiles",
+    ],
+)
+
+genrule(
+    name = "run_fast_gaussian_halide_generator",
+    outs = [
+        "fast_gaussian_generator",
+    ],
+    cmd = "$(location :fast_gaussian_halide_generator) $@",
+    tools = [
+        ":fast_gaussian_halide_generator",
     ],
 )
 
diff --git a/y2020/vision/sift/fast_gaussian_generator.cc b/y2020/vision/sift/fast_gaussian_generator.cc
index aaaea6d..aefb3d9 100644
--- a/y2020/vision/sift/fast_gaussian_generator.cc
+++ b/y2020/vision/sift/fast_gaussian_generator.cc
@@ -1,5 +1,5 @@
 #include "Halide.h"
-#include "y2020/vision/sift/get_gaussian_kernel.h"
+#include "get_gaussian_kernel.h"
 
 #define CHECK(x, message, ...)                                              \
   do {                                                                      \
diff --git a/y2020/vision/sift/fast_gaussian_halide_generator.sh b/y2020/vision/sift/fast_gaussian_halide_generator.sh
new file mode 100755
index 0000000..d808296
--- /dev/null
+++ b/y2020/vision/sift/fast_gaussian_halide_generator.sh
@@ -0,0 +1,63 @@
+#!/bin/bash
+
+# We need to build code linked against Halide. This means we need to use a
+# compatible ABI. This means we need to use libstdc++, not libc++ like our main
+# toolchains are set up for.
+#
+# Rebuilding Halide itself is only moderately annoying. However, it needs to
+# link against LLVM, which is a much bigger pain to rebuild with libc++.
+#
+# To deal with this problem, this script runs clang hermetically on the
+# appropriate sources.
+
+# --- begin runfiles.bash initialization v2 ---
+# Copy-pasted from the Bazel Bash runfiles library v2.
+set -uo pipefail; f=bazel_tools/tools/bash/runfiles/runfiles.bash
+source "${RUNFILES_DIR:-/dev/null}/$f" 2>/dev/null || \
+  source "$(grep -sm1 "^$f " "${RUNFILES_MANIFEST_FILE:-/dev/null}" | cut -f2- -d' ')" 2>/dev/null || \
+  source "$0.runfiles/$f" 2>/dev/null || \
+  source "$(grep -sm1 "^$f " "$0.runfiles_manifest" | cut -f2- -d' ')" 2>/dev/null || \
+  source "$(grep -sm1 "^$f " "$0.exe.runfiles_manifest" | cut -f2- -d' ')" 2>/dev/null || \
+  { echo>&2 "ERROR: cannot find $f"; exit 1; }; f=; set -e
+# --- end runfiles.bash initialization v2 ---
+
+BINARY="$1"
+SOURCE="$(rlocation org_frc971/y2020/vision/sift/fast_gaussian_generator.cc)"
+HALIDE="$(rlocation halide_k8)"
+SYSROOT="$(rlocation amd64_debian_sysroot)"
+ZLIB1G_DEV_AMD64_DEB="$(rlocation deb_zlib1g_dev_1_2_11_dfsg_1_amd64_deb_repo/file/zlib1g-dev_1.2.11.dfsg-1_amd64.deb)"
+
+ZLIB1G_DEV="$(mktemp -d)"
+
+LLVM_TOOLCHAIN="$(dirname "$(dirname "$(rlocation llvm_toolchain_llvm/bin/clang)")")"
+dpkg-deb -x "${ZLIB1G_DEV_AMD64_DEB}" "${ZLIB1G_DEV}"
+TARGET=x86_64-unknown-linux-gnu
+MULTIARCH=x86_64-linux-gnu
+
+export LD_LIBRARY_PATH="${SYSROOT}/usr/lib:${SYSROOT}/lib:${ZLIB1G_DEV}/usr/lib/${MULTIARCH}"
+
+"${LLVM_TOOLCHAIN}/bin/clang++" \
+  -fcolor-diagnostics \
+  -I"${HALIDE}/include" \
+  -nostdinc \
+  -isystem"${SYSROOT}/usr/include/c++/7" \
+  -isystem"${SYSROOT}/usr/include/${MULTIARCH}/c++/7" \
+  -isystem"${SYSROOT}/usr/include/c++/7/backward" \
+  -isystem"${LLVM_TOOLCHAIN}/lib/clang/13.0.0/include" \
+  -isystem"${SYSROOT}/usr/include/${MULTIARCH}" \
+  -isystem"${SYSROOT}/usr/include" \
+  -isystem"${SYSROOT}/include" \
+  "--sysroot=${SYSROOT}" \
+  -resource-dir "${LLVM_TOOLCHAIN}/lib/clang/13.0.0" \
+  -target "${TARGET}" \
+  -fuse-ld=lld \
+  -L"${LLVM_TOOLCHAIN}/lib" \
+  -L"${SYSROOT}/usr/lib" \
+  -L"${SYSROOT}/usr/lib/gcc/${MULTIARCH}/7" \
+  -L"${ZLIB1G_DEV}/usr/lib/${MULTIARCH}" \
+  "${HALIDE}/lib/libHalide.a" \
+  -lstdc++ -lpthread -ldl -lm -lz \
+  "${SOURCE}" \
+  "${HALIDE}/tools/GenGen.cpp" \
+  -ggdb3 \
+  -o "${BINARY}"