[freetype] Enable building freetype2 for Rust host targets

Add a new target that disables FT_CONFIG_OPTION_USE_PNG and uses `-fPIC`.

freetype2 and libpng fail to link when building for host, apparently due to
freetype2's use of private libpng symbols.

Bug: 8892
Bug: 36015
Bug: 36315

Depends-On: I0386586e7d69f0994a28438d5a0f652c983ab648
Change-Id: Id0e75da5176dcabc46a346ebcf81f16269f8df9a
diff --git a/BUILD.gn b/BUILD.gn
index bebad67..8ef8846 100644
--- a/BUILD.gn
+++ b/BUILD.gn
@@ -41,6 +41,13 @@
   }
 }
 
+config("freetype_config_for_rust_host") {
+  # Without `-fPIC`, we get the error:
+  # > ld.lld: error: can't create dynamic relocation R_X86_64_64 against local symbol in readonly
+  # > segment
+  cflags = ["-fPIC"]
+}
+
 #TODO(mikejurka): Remove once we've migrated to the freetype2 target everywhere
 group("freetype") {
   public_deps = [
@@ -48,58 +55,96 @@
   ]
 }
 
-target(default_library_type, "freetype2") {
-  sources = [
-    "src/autofit/autofit.c",
-    "src/base/ftbase.c",
-    "src/base/ftbbox.c",
-    "src/base/ftbdf.c",
-    "src/base/ftbitmap.c",
-    "src/base/ftfstype.c",
-    "src/base/ftgasp.c",
-    "src/base/ftglyph.c",
-    "src/base/ftinit.c",
-    "src/base/ftmm.c",
-    "src/base/ftstroke.c",
-    "src/base/ftsystem.c",
-    "src/base/fttype1.c",
-    "src/base/ftsynth.c",
-    "src/gzip/ftgzip.c",
-    "src/lzw/ftlzw.c",
-    "src/psaux/psaux.c",
-    "src/pshinter/pshinter.c",
-    "src/psnames/psnames.c",
-    "src/sfnt/sfnt.c",
-    "src/smooth/smooth.c",
+template("freetype_library") {
+  target(invoker.library_type, target_name) {
+    forward_variables_from(invoker, "*")
 
-    # Font Drivers. Drivers need to be enabled in ftmodule.h explicitly.
-    "src/cff/cff.c",           # OpenType, (.cff, .cef)
-    "src/truetype/truetype.c", # TrueType
-  ]
+    if (!defined(rust_host)) {
+      rust_host = false
+    }
 
-  defines = [
-    "FT2_BUILD_LIBRARY",
-    "DARWIN_NO_CARBON",
-    # Long directory name to avoid accidentally using wrong headers.
-    "FT_CONFIG_MODULES_H=<freetype-fuchsia-config/ftmodule.h>",
-    "FT_CONFIG_OPTIONS_H=<freetype-fuchsia-config/ftoption.h>",
-  ]
+    shared_lib = (library_type == "shared_library")
 
-  if (default_library_type == "shared_library") {
-    defines += [
-      "FT_EXPORT(x)=extern __attribute__(( visibility( \"default\" ) )) x",
-      "FT_EXPORT_DEF(x)=extern __attribute__(( visibility( \"default\" ) )) x",
-      "FT_EXPORT_VAR(x)=extern __attribute__(( visibility( \"default\" ) )) x",
+    sources = [
+      "src/autofit/autofit.c",
+      "src/base/ftbase.c",
+      "src/base/ftbbox.c",
+      "src/base/ftbdf.c",
+      "src/base/ftbitmap.c",
+      "src/base/ftfstype.c",
+      "src/base/ftgasp.c",
+      "src/base/ftglyph.c",
+      "src/base/ftinit.c",
+      "src/base/ftmm.c",
+      "src/base/ftstroke.c",
+      "src/base/ftsystem.c",
+      "src/base/fttype1.c",
+      "src/base/ftsynth.c",
+      "src/gzip/ftgzip.c",
+      "src/lzw/ftlzw.c",
+      "src/psaux/psaux.c",
+      "src/pshinter/pshinter.c",
+      "src/psnames/psnames.c",
+      "src/sfnt/sfnt.c",
+      "src/smooth/smooth.c",
+
+      # Font Drivers. Drivers need to be enabled in ftmodule.h explicitly.
+      "src/cff/cff.c",           # OpenType, (.cff, .cef)
+      "src/truetype/truetype.c", # TrueType
     ]
-  } else {
-    # Reduce visibility of symbols.
-    defines += [ "FT_EXPORT(x)=x" ]
+
+    defines = [
+      "FT2_BUILD_LIBRARY",
+      "DARWIN_NO_CARBON",
+
+      # Long directory name to avoid accidentally using wrong headers.
+      "FT_CONFIG_MODULES_H=<freetype-fuchsia-config/ftmodule.h>",
+      "FT_CONFIG_OPTIONS_H=<freetype-fuchsia-config/ftoption.h>",
+    ]
+
+    if (shared_lib) {
+      defines += [
+        "FT_EXPORT(x)=extern __attribute__(( visibility( \"default\" ) )) x",
+        "FT_EXPORT_DEF(x)=extern __attribute__(( visibility( \"default\" ) )) x",
+        "FT_EXPORT_VAR(x)=extern __attribute__(( visibility( \"default\" ) )) x",
+      ]
+    } else {
+      # Reduce visibility of symbols.
+      defines += [ "FT_EXPORT(x)=x" ]
+    }
+
+    if (!rust_host) {
+      defines += [ "FT_CONFIG_OPTION_USE_PNG" ]
+    }
+
+    public_configs = [ ":freetype_config" ]
+
+    if (rust_host) {
+      public_configs += [":freetype_config_for_rust_host"]
+    }
+
+    if (rust_host) {
+      deps = ["//third_party/zlib:zlib_for_rust_host"]
+    } else {
+      deps = [
+        "//third_party/libpng",
+        "//third_party/zlib"
+      ]
+    }
   }
+}
 
-  public_configs = [ ":freetype_config" ]
+freetype_library("freetype2") {
+  # Shared libs are disabled in host toolchain.
+  if (current_toolchain == host_toolchain) {
+    library_type = "source_set"
+  } else {
+    library_type = "shared_library"
+  }
+}
 
-  deps = [
-    "//third_party/libpng",
-    "//third_party/zlib",
-  ]
+# TODO(36315): Remove workaround for Rust host_toolchain
+freetype_library("freetype2_for_rust_host") {
+  library_type = "static_library"
+  rust_host = true
 }
diff --git a/include/freetype-fuchsia-config/ftoption.h b/include/freetype-fuchsia-config/ftoption.h
index b3b60e0..790383c 100644
--- a/include/freetype-fuchsia-config/ftoption.h
+++ b/include/freetype-fuchsia-config/ftoption.h
@@ -225,7 +225,7 @@
   /*                                                                       */
   /*   Define this macro if you want to enable this `feature'.             */
   /*                                                                       */
-#define FT_CONFIG_OPTION_USE_PNG
+/* #define FT_CONFIG_OPTION_USE_PNG */
 
 
   /*************************************************************************/