Description: Debian-specific makefile.
Forwarded: not-needed
Author: Filip Strömbäck <filip@fprg.se>
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,97 @@
+CXX := c++
+# Build directory.
+BUILD := debbuild
+
+# Skia version, for proper .so names.
+export FULL_VERSION := $(shell head -n 1 debian/changelog | sed -E 's/^.*\(([0-9.]+)\+[a-z]+-.*\).*$$/\1/')
+export MAJOR_VERSION := $(shell head -n 1 debian/changelog | sed -E 's/^.*\(([0-9]+)[.0-9]+\+dfsg-.*\).*$$/\1/')
+
+# GCC fails to do tail- or sibling calls on ppc64el, so use the version
+# that don't depend on tail calls for ppc64el, even though the attribute
+# clang::musttail is available in the compiler!
+ifeq ($(DEB_HOST_ARCH),ppc64el)
+export CXXFLAGS := $(CXXFLAGS) -DSKCMS_HAS_MUSTTAIL=0
+endif
+
+COMMA = ,
+
+ALL_ARGS := is_official_build=true \
+	extra_cflags_cc=string_split(getenv("CXXFLAGS")) \
+	extra_cflags_c=string_split(getenv("CFLAGS")) \
+	skia_use_system_expat=true \
+	skia_use_system_harfbuzz=true \
+	skia_use_system_icu=true \
+	skia_use_system_libjpeg_turbo=true \
+	skia_use_system_libpng=true \
+	skia_use_system_libwebp=true \
+	skia_use_system_zlib=true \
+	skia_use_dng_sdk=false \
+	skia_use_wuffs=false \
+	skia_enable_spirv_validation=false
+
+# Note: We can't set LDFLAGS here, the GN build system sets them for us...
+SHARED_ARGS := is_component_build=true \
+	extra_ldflags=string_split(getenv("LDFLAGS")) \
+	skia_so_version=$(MAJOR_VERSION)
+
+# Headers to be removed because we have disabled the underlying functionality:
+REMOVE_HEADERS := \
+	include/codec/SkRawDecoder.h \
+	include/codec/SkJpegxlDecoder.h \
+	include/codec/SkAvifDecocer.h
+
+# Extra headers?
+EXTRA_HEADERS := \
+	src/shaders/SkShaderBase.h \
+	src/core/SkReadBuffer.h \
+	src/core/SkWriteBuffer.h \
+	src/core/SkFontDescriptor.h \
+	src/ports/SkFontHost_FreeType_common.h \
+	src/ports/SkTypeface_FreeType.h
+
+# Extra libs? vulkan EGL
+
+.PHONY: all
+all: $(BUILD)/shared/libskia.so $(BUILD)/static/libskia.a
+
+.PHONY: print
+print:
+	@echo "Flags: $(CXXFLAGS)"
+	@echo "Version: $(FULL_VERSION)"
+	@echo "Major version: $(MAJOR_VERSION)"
+
+# Note: Ninja should (as of a fairly recent version) respect the make jobserver flags!
+# Note: We need to update the soname, we can't set it through the gn build system...
+$(BUILD)/shared/libskia.so: extra_headers.stamp
+	mkdir -p $(BUILD)/shared/
+	gn gen $(BUILD)/shared --args='$(ALL_ARGS) $(SHARED_ARGS)'
+	ninja -C $(BUILD)/shared --verbose skia
+
+ $(BUILD)/static/libskia.a: extra_headers.stamp
+	mkdir -p $(BUILD)/static/
+	gn gen $(BUILD)/static --args='$(ALL_ARGS)'
+	ninja -C $(BUILD)/static --verbose skia
+
+# Patch headers once, if necessary.
+extra_headers.stamp: $(EXTRA_HEADERS)
+	python3 bin/extra-headers.py --out extra_headers.stamp $^
+
+$(BUILD):
+	mkdir -p $(BUILD)
+
+.PHONY: clean
+clean:
+	rm -rf $(BUILD)
+	if [ -f extra_headers.stamp ]; then bash extra_headers.stamp; rm extra_headers.stamp; fi
+
+.PHONY: install
+install:
+	install -D -m 0755 $(BUILD)/shared/libskia.so $(DESTDIR)/usr/lib/$(DEB_HOST_MULTIARCH)/libskia.so.$(FULL_VERSION)
+	ln -s libskia.so.$(FULL_VERSION) $(DESTDIR)/usr/lib/$(DEB_HOST_MULTIARCH)/libskia.so.$(MAJOR_VERSION)
+	ln -s libskia.so.$(MAJOR_VERSION) $(DESTDIR)/usr/lib/$(DEB_HOST_MULTIARCH)/libskia.so
+	install -D -m 0644 $(BUILD)/static/libskia.a $(DESTDIR)/usr/lib/$(DEB_HOST_MULTIARCH)/libskia.a
+	python3 bin/install-headers.py --src include/ --dest $(DESTDIR)/usr/include/skia --ignore '.*/android/.*' $(addprefix --ignore ,$(REMOVE_HEADERS))
+	cp modules/skcms/src/skcms_public.h $(DESTDIR)/usr/include/skia/skcms.h
+	python3 bin/install-pc.py $(DESTDIR)/usr/lib/$(DEB_HOST_MULTIARCH)/pkgconfig/skia.pc
+
+-include $(DEPS)
--- /dev/null
+++ b/bin/install-headers.py
@@ -0,0 +1,47 @@
+#!/usr/bin/env python3
+
+import argparse
+import os, os.path
+import re
+
+parser = argparse.ArgumentParser()
+parser.add_argument("--src", help="Source directory for includes", required=True)
+parser.add_argument("--dest", help="Destination path for includes", required=True)
+parser.add_argument("--ignore", help="Ignore files matching regex", action="append")
+args = parser.parse_args()
+
+filemode = 0o644
+
+def update_file(filename):
+    global args, filemode
+
+    if not filename.endswith(".h"):
+        return
+
+    if args.ignore:
+        for i in args.ignore:
+            if re.fullmatch(i, filename):
+                return
+
+    skia_include = re.compile(r'^([ \t]*)# *include *"include/([^"]*)"[ \t]*(//.*)?\n?$')
+    skcms_include = re.compile('^([ \t]*)# *include *"modules/skcms/skcms.h"[ \t]*(//.*)?\n?$')
+
+    dstfile = os.path.join(args.dest, filename[len(args.src):])
+    os.makedirs(os.path.dirname(dstfile), exist_ok=True)
+
+    with open(filename, "r") as src:
+        with open(dstfile, "w") as dst:
+            for line in src:
+                if match := skia_include.fullmatch(line):
+                    dst.write("{}#include <skia/{}>\n".format(match[1], match[2]))
+                elif match := skcms_include.fullmatch(line):
+                    dst.write("{}#include <skia/skcms.h>\n".format(match[1]))
+                else:
+                    dst.write(line)
+
+
+    os.chmod(dstfile, filemode)
+
+for dirname, dirs, files in os.walk(args.src):
+    for f in files:
+        update_file(os.path.join(dirname, f))
--- /dev/null
+++ b/bin/extra-headers.py
@@ -0,0 +1,83 @@
+#!/usr/bin/env python3
+
+import argparse
+import os, os.path
+import re
+import shutil
+
+parser = argparse.ArgumentParser()
+parser.add_argument("--out", help="Output file containing actions done", required=True)
+parser.add_argument("files", help="Files to include", nargs='*')
+args = parser.parse_args()
+
+actions = []
+
+def src_to_priv(path):
+    if len(path) <= 4 or path[0:4] != "src/":
+        return None
+
+    return "include/private/" + path[4:]
+
+def make_dirs(path):
+    global actions
+    if os.path.exists(path):
+        return
+    make_dirs(os.path.dirname(path))
+    actions.append("rmdir " + path)
+    os.mkdir(path)
+
+def update_file(files, visited):
+    f = files[0]
+
+    include = re.compile(r'^([ \t]*)# *include *"([^"]*)"[ \t]*\n?$')
+    cls = re.compile(r'^([ \t]*class|[ \t]*struct) *([A-Za-z_:]+ .*\n?)$')
+
+    first_define = re.compile(r'^#define.*DEFINED *\n?$')
+    api_include_inserted = False
+
+    shutil.copyfile(f, f + ".orig")
+    actions.append("mv {}.orig {}".format(f, f))
+    with open(f, "r") as src:
+        create_file = src_to_priv(f)
+        make_dirs(os.path.dirname(create_file))
+        actions.append("rm " + create_file)
+        with open(create_file, "w") as dst:
+            for line in src:
+                match = cls.fullmatch(line)
+                if match:
+                    line = "{} SK_API {}".format(match[1], match[2])
+
+                match = include.fullmatch(line)
+                if match is None:
+                    dst.write(line)
+                else:
+                    replace = src_to_priv(match[2])
+                    if replace:
+                        if match[2] not in visited:
+                            visited.add(match[2])
+                            files.append(match[2])
+
+                        dst.write("{}#include \"{}\"\n".format(match[1], replace))
+                    else:
+                        dst.write(line)
+
+                match = first_define.fullmatch(line)
+                if not api_include_inserted and match:
+                    dst.write('#include "include/private/base/SkAPI.h"\n')
+                    api_include_inserted = True
+
+    with open(f, "w") as src:
+        src.write("#include \"{}\"\n".format(src_to_priv(f)))
+
+
+files = list(args.files)
+visited = set(files)
+
+while len(files) > 0:
+    update_file(files, visited)
+
+    files = files[1:]
+
+with open(args.out, "w") as f:
+    for x in reversed(actions):
+        f.write(x + "\n")
--- a/BUILD.gn
+++ b/BUILD.gn
@@ -2,13 +2,12 @@
 #
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
-
 import("gn/codec.gni")
 import("gn/pathops.gni")
 import("gn/rust.gni")
 import("gn/shared_sources.gni")
 import("gn/skia.gni")
-import("gn/toolchain/wasm.gni")
+#import("gn/toolchain/wasm.gni")
 
 if (defined(skia_settings)) {
   import(skia_settings)
@@ -1333,7 +1332,11 @@
   enabled = skia_use_freetype
 
   public_defines = [ "SK_TYPEFACE_FACTORY_FREETYPE" ]
-  deps = [ "//third_party/freetype2" ]
+  # Use system freetype instead:
+  #deps = [ "//third_party/freetype2" ]
+  libs = [ "freetype" ]
+  cflags = [ "-isystem/usr/include/freetype2" ]
+
   sources = skia_ports_freetype_sources
   sources_for_tests = [ "tests/FontScanner_FreeTypeTest.cpp" ]
 }
--- a/gn/toolchain/BUILD.gn
+++ b/gn/toolchain/BUILD.gn
@@ -7,6 +7,8 @@
   host_cc = cc
   host_cxx = cxx
 
+  skia_so_version = -1
+
   if (is_android) {
     _prefix = "$ndk/toolchains/llvm/prebuilt/$ndk_host/bin"
     if (host_os == "win") {
@@ -322,6 +324,10 @@
       soname = "{{target_output_name}}{{output_extension}}"
 
       rpath = "-Wl,-soname,$soname"
+      if (skia_so_version >= 0) {
+        rpath = "$rpath.$skia_so_version"
+      }
+
       if (is_mac || is_ios) {
         rpath = "-Wl,-install_name,@rpath/$soname"
       }
--- a/gn/BUILDCONFIG.gn
+++ b/gn/BUILDCONFIG.gn
@@ -182,7 +182,8 @@
 default_configs = [
   "//gn/skia:default",
   "//gn/skia:no_exceptions",
-  "//gn/skia:no_rtti",
+  # We want RTTI, otherwise builds *with* RTTI don't work.
+  # "//gn/skia:no_rtti",
   "//gn/skia:strict_aliasing",
 ]
 if (!is_debug) {
--- /dev/null
+++ b/bin/install-pc.py
@@ -0,0 +1,29 @@
+#!/usr/bin/env python3
+import os
+import os.path
+import sys
+
+template = '''
+prefix=/usr
+exec_prefix=${prefix}
+libdir=${prefix}/lib/%(DEB_HOST_MULTIARCH)s
+includedir=${prefix}/include
+
+Name: skia
+Description: 2D graphics library
+Version: %(FULL_VERSION)s
+Libs: -L${libdir} -lskia
+Cflags: -I${includedir}/skia
+'''
+
+if len(sys.argv) < 2:
+    print("Expected output path.")
+    exit(1)
+
+output = sys.argv[1]
+
+os.makedirs(os.path.dirname(output), exist_ok=True)
+
+with open(output, 'w') as f:
+    f.write((template.strip() % os.environ) + "\n")
+
