Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
122 changes: 102 additions & 20 deletions setup-build-freetype.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,6 @@
# GCC, Visual Studio Community 2017, ...)

import distutils.dir_util
import distutils.file_util
import distutils.spawn
import glob
import hashlib
import os
Expand All @@ -21,37 +19,54 @@
import urllib.request
from os import path
import platform
import fileinput

# Needed for the GitHub Actions macOS CI runner, which appears to come without CAs.
import certifi

FREETYPE_HOST = "https://mirrors.sarata.com/non-gnu/freetype/"
FREETYPE_TARBALL = "freetype-2.13.2.tar.xz"
FREETYPE_HOST = "https://download.savannah.gnu.org/releases/freetype/"
FREETYPE_TARBALL = "freetype-2.13.3.tar.xz"
FREETYPE_URL = FREETYPE_HOST + FREETYPE_TARBALL
FREETYPE_SHA256 = "12991c4e55c506dd7f9b765933e62fd2be2e06d421505d7950a132e4f1bb484d"
FREETYPE_SHA256 = "0550350666d427c74daeb85d5ac7bb353acba5f76956395995311a9c6f063289"
HARFBUZZ_HOST = "https://github.com/harfbuzz/harfbuzz/releases/download/8.3.0/"
HARFBUZZ_TARBALL = "harfbuzz-8.3.0.tar.xz"
HARFBUZZ_URL = HARFBUZZ_HOST + HARFBUZZ_TARBALL
HARFBUZZ_SHA256 = "109501eaeb8bde3eadb25fab4164e993fbace29c3d775bcaa1c1e58e2f15f847"

ZLIB_HOST = "https://zlib.net/"
ZLIB_TARBALL = "zlib-1.3.1.tar.xz"
ZLIB_URL = ZLIB_HOST + ZLIB_TARBALL
ZLIB_SH256 = "38ef96b8dfe510d42707d9c781877914792541133e1870841463bfa73f883e32"

LIBPNG_HOST = "https://download.sourceforge.net/libpng/"
LIBPNG_TARBALL = "libpng-1.6.48.tar.xz"
LIBPNG_URL = LIBPNG_HOST + LIBPNG_TARBALL
LIBPNG_SH256 = "46fd06ff37db1db64c0dc288d78a3f5efd23ad9ac41561193f983e20937ece03"

BUILD_ZLIB = os.environ.get("FREETYPEPY_WITH_ZLIB", "")
BUILD_LIBPNG = os.environ.get("FREETYPEPY_WITH_LIBPNG", "")

root_dir = "."
build_dir = path.join(root_dir, "build")
# CMake requires an absolute path to a prefix.
prefix_dir = path.abspath(path.join(build_dir, "local"))
lib_dir = path.join(prefix_dir, "lib")
build_dir_ft = path.join(build_dir, FREETYPE_TARBALL.split(".tar")[0], "build")
build_dir_hb = path.join(build_dir, HARFBUZZ_TARBALL.split(".tar")[0], "build")
build_dir_zl = path.join(build_dir, ZLIB_TARBALL.split(".tar")[0], "build")
build_dir_lp = path.join(build_dir, LIBPNG_TARBALL.split(".tar")[0], "build")

CMAKE_GLOBAL_SWITCHES = (
"-DCMAKE_COLOR_MAKEFILE=false "
'-DCMAKE_PREFIX_PATH="{}" '
'-DCMAKE_INSTALL_PREFIX="{}" '
).format(prefix_dir, prefix_dir)
CMAKE_PREVENT_REEXPORT = ""

# Try to use Ninja to build things if it's available. Much faster.
# On Windows, I first need to figure out how to make it aware of VC, bitness,
# etc.
if sys.platform != "win32" and distutils.spawn.find_executable("ninja"):
if sys.platform != "win32" and shutil.which("ninja"):
CMAKE_GLOBAL_SWITCHES += "-G Ninja "

bitness = None
Expand All @@ -67,6 +82,12 @@
print("# Making a 32 bit build.")
bitness = 32

CMAKE_PREVENT_REEXPORT += "-Wl,--exclude-libs,libharfbuzz "
if BUILD_ZLIB or BUILD_LIBPNG:
CMAKE_PREVENT_REEXPORT += "-Wl,--exclude-libs,libz "
if BUILD_LIBPNG:
CMAKE_PREVENT_REEXPORT += "-Wl,--exclude-libs,libpng "

if sys.platform == "darwin":
print("# Making a 64 bit build.")
CMAKE_GLOBAL_SWITCHES += (
Expand All @@ -77,6 +98,14 @@
)
bitness = 64

# the library path is needed for the '-hidden-lx' option to work
CMAKE_PREVENT_REEXPORT += "-Wl,-L{} ".format(lib_dir)
CMAKE_PREVENT_REEXPORT += "-Wl,-hidden-lharfbuzz "
if BUILD_ZLIB or BUILD_LIBPNG:
CMAKE_PREVENT_REEXPORT += "-Wl,-hidden-lz "
if BUILD_LIBPNG:
CMAKE_PREVENT_REEXPORT += "-Wl,-hidden-lpng "

if "linux" in sys.platform:
c_flags = cxx_flags = "-O2"
ld_flags = ""
Expand Down Expand Up @@ -110,6 +139,12 @@
'-DCMAKE_LD_FLAGS="{}" '.format(ld_flags)
)

CMAKE_PREVENT_REEXPORT += "-Wl,--exclude-libs,libharfbuzz "
if BUILD_ZLIB or BUILD_LIBPNG:
CMAKE_PREVENT_REEXPORT += "-Wl,--exclude-libs,libz "
if BUILD_LIBPNG:
CMAKE_PREVENT_REEXPORT += "-Wl,--exclude-libs,libpng "


def shell(cmd, cwd=None):
"""Run a shell command specified by cmd string."""
Expand Down Expand Up @@ -154,18 +189,26 @@ def ensure_downloaded(url, sha256_sum):
distutils.dir_util.mkpath(prefix_dir)
distutils.dir_util.mkpath(build_dir_ft)
distutils.dir_util.mkpath(build_dir_hb)
if BUILD_ZLIB or BUILD_LIBPNG:
distutils.dir_util.mkpath(build_dir_zl)
if BUILD_LIBPNG:
distutils.dir_util.mkpath(build_dir_lp)

ensure_downloaded(FREETYPE_URL, FREETYPE_SHA256)
ensure_downloaded(HARFBUZZ_URL, HARFBUZZ_SHA256)
if BUILD_ZLIB or BUILD_LIBPNG:
ensure_downloaded(ZLIB_URL, ZLIB_SH256)
if BUILD_LIBPNG:
ensure_downloaded(LIBPNG_URL, LIBPNG_SH256)

print("# First, build FreeType without Harfbuzz support")
print("# First, build FreeType without additional libraries")
shell(
"cmake -DBUILD_SHARED_LIBS=OFF "
"-DCMAKE_DISABLE_FIND_PACKAGE_HarfBuzz=TRUE -DFT_WITH_HARFBUZZ=OFF "
"-DCMAKE_DISABLE_FIND_PACKAGE_PNG=TRUE "
"-DCMAKE_DISABLE_FIND_PACKAGE_BZip2=TRUE "
"-DCMAKE_DISABLE_FIND_PACKAGE_ZLIB=TRUE "
"-DCMAKE_DISABLE_FIND_PACKAGE_BrotliDec=TRUE "
"-DFT_DISABLE_HARFBUZZ=TRUE "
"-DFT_DISABLE_PNG=TRUE "
"-DFT_DISABLE_BZIP2=TRUE "
"-DFT_DISABLE_ZLIB=TRUE "
"-DFT_DISABLE_BROTLI=TRUE "
"{} ..".format(CMAKE_GLOBAL_SWITCHES),
cwd=build_dir_ft,
)
Expand All @@ -182,19 +225,58 @@ def ensure_downloaded(url, sha256_sum):
)
shell("cmake --build . --config Release --target install --parallel", cwd=build_dir_hb)

print("\n# Lastly, rebuild FreeType, this time with Harfbuzz support.")
if BUILD_ZLIB or BUILD_LIBPNG:
print("\n# Next, build zlib.")
# workaround to only build the static library of zlib
# see https://github.com/madler/zlib/issues/359
with fileinput.input(path.join(path.dirname(build_dir_zl), "CMakeLists.txt"), inplace=True) as f:
for line in f:
if "install(TARGETS zlib zlibstatic" in line:
line = line.replace(" install(TARGETS zlib zlibstatic", " install(TARGETS zlibstatic")
print(line, end='')

shell(
"cmake " +
# https://stackoverflow.com/questions/3961446
("-DCMAKE_POSITION_INDEPENDENT_CODE=ON " if bitness > 32 else "") +
"{} ..".format(CMAKE_GLOBAL_SWITCHES),
cwd=build_dir_zl,
)
shell("cmake --build . --config Release --target install --parallel", cwd=build_dir_zl)

if BUILD_LIBPNG:
print("\n# Next, build libpng.")
shell(
"cmake -DPNG_SHARED=OFF " +
# https://stackoverflow.com/questions/3961446
("-DCMAKE_POSITION_INDEPENDENT_CODE=ON " if bitness > 32 else "") +
"{} ..".format(CMAKE_GLOBAL_SWITCHES),
cwd=build_dir_lp,
)
shell("cmake --build . --config Release --target install --parallel", cwd=build_dir_lp)

print("\n# Lastly, rebuild FreeType, this time with additional libraries support.")
# clean cmake build dir for a clean build
distutils.dir_util.remove_tree(build_dir_ft)
distutils.dir_util.mkpath(build_dir_ft)
harfbuzz_includes = path.join(prefix_dir, "include", "harfbuzz")
libpng_includes = path.join(prefix_dir, "include", "libpng16")
zlib_includes = path.join(prefix_dir, "include")
shell(
"cmake -DBUILD_SHARED_LIBS=ON "
"-DCMAKE_DISABLE_FIND_PACKAGE_HarfBuzz=FALSE -DFT_WITH_HARFBUZZ=ON "
"-DCMAKE_DISABLE_FIND_PACKAGE_PNG=TRUE "
"-DCMAKE_DISABLE_FIND_PACKAGE_BZip2=TRUE "
"-DCMAKE_DISABLE_FIND_PACKAGE_ZLIB=TRUE "
"-DCMAKE_DISABLE_FIND_PACKAGE_BrotliDec=TRUE "
"-DFT_REQUIRE_HARFBUZZ=TRUE " +
("-DFT_REQUIRE_PNG=TRUE " if BUILD_LIBPNG else "-DFT_DISABLE_PNG=TRUE ") +
"-DFT_DISABLE_BZIP2=TRUE " +
("-DFT_REQUIRE_ZLIB=TRUE " if BUILD_ZLIB or BUILD_LIBPNG else "-DFT_DISABLE_ZLIB=TRUE ") +
"-DFT_DISABLE_BROTLI=TRUE "
'-DPKG_CONFIG_EXECUTABLE="" ' # Prevent finding system libraries
'-DHARFBUZZ_INCLUDE_DIRS="{}" '
'-DHarfBuzz_INCLUDE_DIRS="{}" '
'-DPNG_INCLUDE_DIRS="{}" '
'-DZLIB_INCLUDE_DIRS="{}" '
# prevent re-export of symbols from harfbuzz, libpng and zlib
'-DCMAKE_SHARED_LINKER_FLAGS="{}" '
"-DSKIP_INSTALL_HEADERS=ON "
"{} ..".format(harfbuzz_includes, CMAKE_GLOBAL_SWITCHES),
"{} ..".format(harfbuzz_includes, libpng_includes, zlib_includes, CMAKE_PREVENT_REEXPORT, CMAKE_GLOBAL_SWITCHES),
cwd=build_dir_ft,
)
shell("cmake --build . --config Release --target install --parallel", cwd=build_dir_ft)
Expand Down
Loading