Build win32 artifacts using meson

As a part of meson migration, this builds hb-shape dependencies
using meson subprojects and removes different unrelated mingw
files we've put on source root about things that aren't really our
concern. This also simplifies all the instructions we've put in
README.mingw.md and makes it easy to build the project on
distros that no mingw libraries (such i686-win32-{freetype,glib,...}
are packaged. The known catch is however lack of hb-view as its need
for build of cairo which apparently isn't that straightforward.
This commit is contained in:
Ebrahim Byagowi 2020-06-01 12:58:31 +04:30 committed by GitHub
parent bb719915d9
commit 6058ede3ae
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
20 changed files with 84 additions and 202 deletions

15
.ci/build-win32.sh Executable file
View File

@ -0,0 +1,15 @@
#!/bin/bash
set -e
meson --cross-file=.ci/win32-cross-file.txt win32build --wrap-mode=forcefallback -Dtests=disabled \
-Dglib=enabled -Dfreetype=enabled -Dgdi=enabled $@
ninja -Cwin32build -j8 # building with all the cores won't work fine with CricleCI for some reason
rm -rf win32build/harfbuzz-win32
mkdir win32build/harfbuzz-win32
cp win32build/util/hb-*.exe win32build/harfbuzz-win32
find win32build -name '*.dll' -exec cp {} win32build/harfbuzz-win32 \;
i686-w64-mingw32-strip win32build/harfbuzz-win32/*.{dll,exe}
rm -f harfbuzz-win32.zip
(cd win32build/harfbuzz-win32 && zip ../../harfbuzz-win32.zip -r .)
echo "harfbuzz-win32.zip is ready."

20
.ci/win32-cross-file.txt Normal file
View File

@ -0,0 +1,20 @@
[host_machine]
system = 'windows'
cpu_family = 'x86'
cpu = 'i686'
endian = 'little'
[properties]
c_args = []
c_link_args = ['-static-libgcc', '-Wl,-Bstatic', '-lpthread']
cpp_args = []
cpp_link_args = ['-static-libgcc', '-static-libstdc++', '-Wl,-Bstatic', '-lpthread']
[binaries]
c = 'i686-w64-mingw32-gcc'
cpp = 'i686-w64-mingw32-g++'
ar = 'i686-w64-mingw32-ar'
ld = 'i686-w64-mingw32-ld'
objcopy = 'i686-w64-mingw32-objcopy'
strip = 'i686-w64-mingw32-strip'
windres = 'i686-w64-mingw32-windres'

20
.ci/win64-cross-file.txt Normal file
View File

@ -0,0 +1,20 @@
[host_machine]
system = 'windows'
cpu_family = 'x86_64'
cpu = 'x86_64'
endian = 'little'
[properties]
c_args = []
c_link_args = ['-static-libgcc', '-Wl,-Bstatic', '-lpthread']
cpp_args = []
cpp_link_args = ['-static-libgcc', '-static-libstdc++', '-Wl,-Bstatic', '-lpthread']
[binaries]
c = 'x86_64-w64-mingw32-gcc'
cpp = 'x86_64-w64-mingw32-g++'
ar = 'x86_64-w64-mingw32-ar'
ld = 'x86_64-w64-mingw32-ld'
objcopy = 'x86_64-w64-mingw32-objcopy'
strip = 'x86_64-w64-mingw32-strip'
windres = 'x86_64-w64-mingw32-windres'

View File

@ -204,31 +204,23 @@ jobs:
- run: make -j32
- run: UBSAN_OPTIONS=print_stacktrace=1 make check || .ci/fail.sh | asan_symbolize | c++filt
fedora-O0-debug-outoftreebuild-mingw:
fedora-O0-debug-outoftreebuild:
docker:
- image: fedora
steps:
- checkout
- run: dnf install -y pkg-config ragel gcc gcc-c++ automake autoconf libtool make which diffutils glib2-devel freetype-devel cairo-devel libicu-devel gobject-introspection-devel graphite2-devel redhat-rpm-config python python-pip mingw32-gcc-c++ mingw64-gcc-c++ mingw32-glib2 mingw32-cairo mingw32-freetype mingw64-glib2 mingw64-cairo mingw64-freetype glibc-devel.i686 || true
- run: dnf install -y pkg-config ragel gcc gcc-c++ automake autoconf libtool make which diffutils glib2-devel freetype-devel cairo-devel libicu-devel gobject-introspection-devel graphite2-devel redhat-rpm-config python python-pip || true
- run: NOCONFIGURE=1 ./autogen.sh
- run: mkdir build && cd build && CFLAGS="-O0" CXXFLAGS="-O0" CPPFLAGS="-DHB_DEBUG" ../configure --with-freetype --with-glib --with-gobject --with-cairo --with-icu --with-graphite2 && make -j32 && (HB_TEST_SUBSET_FUZZER_TIMEOUT=15 make check || ../.ci/fail.sh)
- run: pip install pefile
- run: mkdir winbuild32 && cd winbuild32 && ../mingw32.sh && make -j32 && make dist-win && cp harfbuzz-*-win32.zip harfbuzz-win32.zip
- run: mkdir winbuild64 && cd winbuild64 && ../mingw64.sh && make -j32 && make dist-win && cp harfbuzz-*-win64.zip harfbuzz-win64.zip
- store_artifacts:
path: winbuild32/harfbuzz-win32.zip
destination: harfbuzz-win32.zip
- store_artifacts:
path: winbuild64/harfbuzz-win64.zip
destination: harfbuzz-win64.zip
meson-gcc:
meson-gcc-mingw:
docker:
- image: ubuntu:19.10
steps:
- checkout
- run: apt update && apt install -y ninja-build binutils meson gcc g++ pkg-config ragel gtk-doc-tools libfreetype6-dev libglib2.0-dev libcairo2-dev libicu-dev libgraphite2-dev python3 python3-pip
- run: pip3 install fonttools meson --upgrade
- run: apt update && apt install -y ninja-build binutils meson gcc g++ pkg-config ragel gtk-doc-tools libfreetype6-dev libglib2.0-dev libcairo2-dev libicu-dev libgraphite2-dev python3 python3-pip git g++-mingw-w64-i686 zip
- run: pip3 install fonttools --upgrade
- run: pip3 install git+https://github.com/mesonbuild/meson # use C linker, remove when meson 0.55 is released
- run: meson build && ninja -Cbuild test && rm -rf build
# test amalgam build
- run: meson build -Damalgam=true && ninja -Cbuild && rm -rf build
@ -236,6 +228,10 @@ jobs:
- run: meson build --unity on && ninja -Cbuild && rm -rf build
# test experimental APIs
- run: meson build -Dexperimental_api=true && ninja -Cbuild test && rm -rf build
# mingw
- run: .ci/build-win32.sh
- store_artifacts:
path: harfbuzz-win32.zip
crosscompile-notest-djgpp:
docker:
@ -279,9 +275,9 @@ workflows:
- clang-msan
- clang-tsan
- clang-ubsan
- fedora-O0-debug-outoftreebuild-mingw
- fedora-O0-debug-outoftreebuild
- meson-gcc
- meson-gcc-mingw
# crosscompiles
# they can't be test thus are without tests

View File

@ -10,7 +10,6 @@ EXTRA_DIST = \
autogen.sh \
harfbuzz.doap \
README.md \
README.mingw.md \
README.python.md \
BUILD.md \
CONFIG.md \
@ -29,10 +28,6 @@ EXTRA_DIST = \
subprojects/zlib.wrap \
meson-cc-tests/intel-atomic-primitives-test.c \
meson-cc-tests/solaris-atomic-operations.c \
mingw-configure.sh \
mingw-ldd.py \
mingw32.sh \
mingw64.sh \
$(NULL)
MAINTAINERCLEANFILES = \
@ -97,18 +92,4 @@ $(gpg_file): $(sha256_file)
release-files: $(tar_file) $(sha256_file) $(gpg_file)
dist-win:
@case $(host_triplet) in *-w64-mingw32) ;; *) echo "Error: Requires mingw build. See README.mingw.md.">&2; exit 1 ;; esac
@DIR=$(PACKAGE_TARNAME)-$(VERSION)-win`case $(host_triplet) in i686-*) echo 32 ;; x86_64-*) echo 64 ;; esac`; \
$(RM) -r $$DIR; $(MKDIR_P) $$DIR || exit 1; \
cp util/.libs/hb-{shape,view,subset}.exe $$DIR && \
$(top_srcdir)/mingw-ldd.py $$DIR/hb-view.exe | grep -v 'not found' | cut -d '>' -f 2 | xargs cp -t $$DIR && \
cp src/.libs/libharfbuzz{,-subset}-0.dll $$DIR && \
chmod a+x $$DIR/*.{exe,dll} && \
$(STRIP) $$DIR/*.{exe,dll} && \
zip -r $$DIR.zip $$DIR && \
$(RM) -r $$DIR && \
echo "$$DIR.zip is ready."
-include $(top_srcdir)/git.mk

View File

@ -9,23 +9,14 @@ steps are recommended:
2. And `mingw-w64` compiler.
With `brew` on macOS, you can have it like `brew install mingw-w64`.
On Fedora, with `dnf install mingw32-gcc-c++`, or `dnf install mingw64-gcc-c++` for the
64-bit Windows.
64-bit Windows. Use `apt install g++-mingw-w64` on Debian.
3. Install cross-compiled dependency packages. Alternatively see [^1] below.
On Fedora that would be `dnf install mingw32-glib2 mingw32-cairo mingw32-freetype`
for 32-bit, or `dnf install mingw64-glib2 mingw64-cairo mingw64-freetype` for 64-bit.
3. See how `.ci/build-win32.sh` uses meson or run that script anyway.
5. `NOCONFIGURE=1 ./autogen.sh && mkdir winbuild && cd winbuild`
Now you can use hb-shape by `(cd win32build/harfbuzz-win32 && wine hb-shape.exe)`
but if you like to shape with the Microsoft Uniscribe,
6. Run `../mingw32.sh` for 32-bit build, or `../mingw64.sh` for 64-bit. This configures
HarfBuzz for cross-compiling. It enables Uniscribe backend as well.
7. `make`
Now you can use hb-shape using `wine util/hb-shape.exe` but if you like to shape with
the Microsoft Uniscribe,
8. Bring a 32bit version of `usp10.dll` for yourself from `C:\Windows\SysWOW64\usp10.dll` of your
4. Bring a 32bit version of `usp10.dll` for yourself from `C:\Windows\SysWOW64\usp10.dll` of your
Windows installation (assuming you have a 64-bit installation, otherwise
`C:\Windows\System32\usp10.dll`) that it is not a DirectWrite proxy
([for more info](https://en.wikipedia.org/wiki/Uniscribe)).
@ -35,14 +26,6 @@ the Microsoft Uniscribe,
Put the DLL in the folder you are going to run the next command,
9. `WINEDLLOVERRIDES="usp10=n" wine util/hb-shape.exe fontname.ttf -u 0061,0062,0063 --shaper=uniscribe`
5. `WINEDLLOVERRIDES="usp10=n" wine hb-shape.exe fontname.ttf -u 0061,0062,0063 --shaper=uniscribe`
(`0061,0062,0063` means `abc`, use test/shaping/hb-unicode-decode to generate ones you need)
[^1] Download and put [this](https://drive.google.com/open?id=0B3_fQkxDZZXXbWltRGd5bjVrUDQ)
in your `~/.local/i686-w64-mingw32`. Then replace all the instances of
`/home/behdad/.local/i586-mingw32msvc` and `/home/behdad/.local/i686-w64-mingw32`
with `<$HOME>/.local/i686-w64-mingw32` on that folder.
(`<$HOME>` replace it with `/home/XXX` or `/Users/XXX` on macOS)
You shouldn't replace the instances of those inside binary files.

View File

@ -44,11 +44,7 @@ HarfBuzz release walk-through checklist:
9. Tag the release and sign it: Eg. "git tag -s 1.4.7 -m 1.4.7". Enter your
GPG password again.
10. Build win32 bundle.
a. Build Win32 binaries. See [README.mingw.md](README.mingw.md).
b. Run "make dist-win" to build Win32 bundle.
10. Build win32 bundle. See [README.mingw.md](README.mingw.md).
11. Quickly double-check the size of the .tar.xz and .zip files against their
previous releases to make sure nothing bad happened.

View File

@ -1,17 +0,0 @@
[binaries]
c = '@host@-gcc'
cpp = '@host@-g++'
ar = '@host@-ar'
ranlib = '@host@-ranlib'
strip = '@host@-strip'
windres = '@host@-windres'
pkgconfig = 'pkg-config'
[host_machine]
system = 'windows'
cpu_family = '@cpu@'
cpu = '@cpu@'
endian = 'little'
[properties]
cpp_args = ['-D_WIN32_WINNT=0x0601', '-O2', '-pipe', '-march=@arch@']

View File

@ -134,6 +134,9 @@ if cairo_dep.found()
if cpp.has_header('cairo-ft.h') and \
cpp.has_function('cairo_ft_font_face_create_for_ft_face', dependencies: cairo_dep)
cairo_ft_dep = cairo_dep
else
# Not-found dependency
cairo_ft_dep = dependency('', required: false)
endif
endif
else

View File

@ -1,28 +0,0 @@
#!/bin/sh
case $1 in
i686 | x86_64) ;;
*) echo "Usage: $0 i686|x86_64" >&2; exit 1 ;;
esac
target=$1-w64-mingw32
shift
exec "$(dirname "$0")"/configure \
--build=`../config.guess` \
--host=$target \
--prefix=$HOME/.local/$target \
CC= \
CXX= \
CPP= \
LD= \
CFLAGS="-static-libgcc" \
CXXFLAGS="-static-libgcc -static-libstdc++" \
CPPFLAGS="-I$HOME/.local/$target/include" \
LDFLAGS=-L$HOME/.local/$target/lib \
PKG_CONFIG_LIBDIR=$HOME/.local/$target/lib/pkgconfig:/usr/$target/sys-root/mingw/lib/pkgconfig/ \
PKG_CONFIG_PATH=$HOME/.local/$target/share/pkgconfig:/usr/$target/sys-root/mingw/share/pkgconfig/ \
PATH=$HOME/.local/$target/bin:/usr/$target/sys-root/mingw/bin:/usr/$target/bin:$PATH \
--without-icu \
--with-uniscribe \
"$@"

View File

@ -1,56 +0,0 @@
#!/usr/bin/env python3
# Copied from https://github.com/xantares/mingw-ldd/blob/master/mingw-ldd.py
# Modified to point to right prefix location on Fedora.
# WTFPL - Do What the Fuck You Want to Public License
import pefile
import os
import sys
def get_dependency(filename):
deps = []
pe = pefile.PE(filename)
for imp in pe.DIRECTORY_ENTRY_IMPORT:
deps.append(imp.dll.decode())
return deps
def dep_tree(root, prefix=None):
if not prefix:
arch = get_arch(root)
#print('Arch =', arch)
prefix = '/usr/'+arch+'-w64-mingw32/sys-root/mingw/bin'
#print('Using default prefix', prefix)
dep_dlls = dict()
def dep_tree_impl(root, prefix):
for dll in get_dependency(root):
if dll in dep_dlls:
continue
full_path = os.path.join(prefix, dll)
if os.path.exists(full_path):
dep_dlls[dll] = full_path
dep_tree_impl(full_path, prefix=prefix)
else:
dep_dlls[dll] = 'not found'
dep_tree_impl(root, prefix)
return (dep_dlls)
def get_arch(filename):
type2arch= {pefile.OPTIONAL_HEADER_MAGIC_PE: 'i686',
pefile.OPTIONAL_HEADER_MAGIC_PE_PLUS: 'x86_64'}
pe = pefile.PE(filename)
try:
return type2arch[pe.PE_TYPE]
except KeyError:
sys.exit ('Error: unknown architecture')
if __name__ == '__main__':
filename = sys.argv[1]
for dll, full_path in dep_tree(filename).items():
print(' ' * 7, dll, '=>', full_path)

View File

@ -1,33 +0,0 @@
#!/bin/sh
# Usage: ./mingw-meson.sh prefix host
# host being i686 or x86_64
case $2 in
i686 | x86_64) ;;
*) echo "Usage: $0 prefix i686|x86_64" >&2; exit 1 ;;
esac
cpu=$2
host=$2-w64-mingw32
if test "x$2" = "xx86_64" ; then
arch=x86-64
else
arch=i686
fi
rm -rf builddir && mkdir builddir && cd builddir && cp ../meson-mingw-cross.txt .
sed -i -e "s/@cpu_family@/$cpu/g;s/@cpu@/$cpu/g;s/@host@/$host/g;s/@arch@/$arch/g" meson-mingw-cross.txt
meson .. \
--prefix=$1 \
--libdir=lib \
--buildtype=release \
--strip \
--cross-file meson-mingw-cross.txt \
--default-library shared \
-Dgraphite=enabled
ninja
ninja install

View File

@ -1,2 +0,0 @@
#!/bin/sh
exec "$(dirname "$0")"/mingw-configure.sh i686 "$@"

View File

@ -1,2 +0,0 @@
#!/bin/sh
exec "$(dirname "$0")"/mingw-configure.sh x86_64 "$@"

View File

@ -1,5 +1,6 @@
[wrap-git]
directory=fontconfig
url=https://github.com/centricular/fontconfig.git
depth=1
push-url=git@github.com:centricular/fontconfig.git
revision=meson

View File

@ -1,5 +1,6 @@
[wrap-git]
directory=freetype2
url=https://github.com/centricular/freetype2.git
depth=1
push-url=git@github.com:centricular/freetype2.git
revision=meson

View File

@ -1,5 +1,6 @@
[wrap-git]
directory=glib
url=https://gitlab.gnome.org/GNOME/glib.git
depth=1
push-url=git@gitlab.gnome.org:GNOME/glib.git
revision=2.58.1

View File

@ -1,4 +1,5 @@
[wrap-git]
directory=libffi
url=https://github.com/centricular/libffi.git
url=https://gitlab.freedesktop.org/gstreamer/meson-ports/libffi.git
depth=1
revision=meson

View File

@ -1,4 +1,5 @@
[wrap-git]
directory=proxy-libintl
url=https://github.com/frida/proxy-libintl.git
depth=1
revision=0.1

View File

@ -1,4 +1,5 @@
[wrap-git]
directory=zlib
url=https://github.com/centricular/zlib.git
depth=1
revision=meson