diff --git a/.ci/build-win32.sh b/.ci/build-win32.sh new file mode 100755 index 000000000..019efff6a --- /dev/null +++ b/.ci/build-win32.sh @@ -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." diff --git a/.ci/win32-cross-file.txt b/.ci/win32-cross-file.txt new file mode 100644 index 000000000..982a909b7 --- /dev/null +++ b/.ci/win32-cross-file.txt @@ -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' diff --git a/.ci/win64-cross-file.txt b/.ci/win64-cross-file.txt new file mode 100644 index 000000000..e906e085e --- /dev/null +++ b/.ci/win64-cross-file.txt @@ -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' diff --git a/.circleci/config.yml b/.circleci/config.yml index dd7bd2752..d65140b8f 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -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 diff --git a/Makefile.am b/Makefile.am index 79c271591..4a2a8c8eb 100644 --- a/Makefile.am +++ b/Makefile.am @@ -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 diff --git a/README.mingw.md b/README.mingw.md index 76d1a8754..b9943d7ae 100644 --- a/README.mingw.md +++ b/README.mingw.md @@ -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. diff --git a/RELEASING.md b/RELEASING.md index c15126a5f..a26350b36 100644 --- a/RELEASING.md +++ b/RELEASING.md @@ -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. diff --git a/meson-mingw-cross.txt b/meson-mingw-cross.txt deleted file mode 100644 index 00de34474..000000000 --- a/meson-mingw-cross.txt +++ /dev/null @@ -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@'] diff --git a/meson.build b/meson.build index 26b20b6ce..15144e9e8 100644 --- a/meson.build +++ b/meson.build @@ -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 diff --git a/mingw-configure.sh b/mingw-configure.sh deleted file mode 100755 index 3281ce382..000000000 --- a/mingw-configure.sh +++ /dev/null @@ -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 \ - "$@" diff --git a/mingw-ldd.py b/mingw-ldd.py deleted file mode 100755 index f5556ab4b..000000000 --- a/mingw-ldd.py +++ /dev/null @@ -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) - diff --git a/mingw-meson.sh b/mingw-meson.sh deleted file mode 100644 index 9e871a3d2..000000000 --- a/mingw-meson.sh +++ /dev/null @@ -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 diff --git a/mingw32.sh b/mingw32.sh deleted file mode 100755 index 77edffa98..000000000 --- a/mingw32.sh +++ /dev/null @@ -1,2 +0,0 @@ -#!/bin/sh -exec "$(dirname "$0")"/mingw-configure.sh i686 "$@" diff --git a/mingw64.sh b/mingw64.sh deleted file mode 100755 index 28724a48e..000000000 --- a/mingw64.sh +++ /dev/null @@ -1,2 +0,0 @@ -#!/bin/sh -exec "$(dirname "$0")"/mingw-configure.sh x86_64 "$@" diff --git a/subprojects/fontconfig.wrap b/subprojects/fontconfig.wrap index 083a49d6a..6b18b2b4c 100644 --- a/subprojects/fontconfig.wrap +++ b/subprojects/fontconfig.wrap @@ -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 diff --git a/subprojects/freetype2.wrap b/subprojects/freetype2.wrap index 3151539c8..7c88f89cb 100644 --- a/subprojects/freetype2.wrap +++ b/subprojects/freetype2.wrap @@ -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 diff --git a/subprojects/glib.wrap b/subprojects/glib.wrap index a23da5c2f..7a4eae175 100644 --- a/subprojects/glib.wrap +++ b/subprojects/glib.wrap @@ -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 diff --git a/subprojects/libffi.wrap b/subprojects/libffi.wrap index 3d15e2a8a..466ca81b6 100644 --- a/subprojects/libffi.wrap +++ b/subprojects/libffi.wrap @@ -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 diff --git a/subprojects/proxy-libintl.wrap b/subprojects/proxy-libintl.wrap index b53c8f7c3..5e1e19a4a 100644 --- a/subprojects/proxy-libintl.wrap +++ b/subprojects/proxy-libintl.wrap @@ -1,4 +1,5 @@ [wrap-git] directory=proxy-libintl url=https://github.com/frida/proxy-libintl.git +depth=1 revision=0.1 diff --git a/subprojects/zlib.wrap b/subprojects/zlib.wrap index de1e861e1..b62b63a66 100644 --- a/subprojects/zlib.wrap +++ b/subprojects/zlib.wrap @@ -1,4 +1,5 @@ [wrap-git] directory=zlib url=https://github.com/centricular/zlib.git +depth=1 revision=meson