diff --git a/.gitignore b/.gitignore index d9aa693f..7785dabf 100644 --- a/.gitignore +++ b/.gitignore @@ -16,6 +16,7 @@ cmd/handbindings/bindings_test/direct cmd/handbindings/bindings_test/testapp cmd/genbindings/genbindings cmd/miqt-uic/miqt-uic +cmd/miqt-rcc/miqt-rcc examples/helloworld/helloworld examples/helloworld/helloworld.exe diff --git a/README.md b/README.md index aca8488a..403c452e 100644 --- a/README.md +++ b/README.md @@ -21,8 +21,8 @@ These bindings were newly started in August 2024. The bindings are functional fo |Linux|x86_64|Static or Dynamic (.so)|✅ Works |Windows|x86_64|Static or Dynamic (.dll)|✅ Works |Android|ARM64|Dynamic (bundled in .apk package)|✅ Works -|macOS|x86_64|Static or Dynamic (.dylib)|Should work, [not tested](https://github.com/mappu/miqt/issues/2) -|macOS|ARM64|Static or Dynamic (.dylib)|Should work, [not tested](https://github.com/mappu/miqt/issues/2) +|macOS|x86_64|Static or Dynamic (.dylib)|✅ Works +|macOS|ARM64|Static or Dynamic (.dylib)|Should work, not tested ## License @@ -151,7 +151,7 @@ go build -ldflags '-s -w' *Tested with Fsu0413 Qt 5.15 / Clang 18.1 native compilation* -1. Install Go from [the official website](https://go.dev/dl/). +1. Install Go from [go.dev](https://go.dev/dl/). 2. Install some Qt toolchain and its matching GCC or Clang compiler (MSVC is not compatible with CGO). - You can use [official Qt binaries](https://www.qt.io/) or any LGPL rebuild. - Example: Download and extract the following into some shared `C:\dev\rootfs`: @@ -171,13 +171,22 @@ $env:CGO_CXXFLAGS = '-Wno-ignored-attributes -D_Bool=bool' # Clang 18 recommenda ### Windows (MSYS2) -*Tested with MSYS2 UCRT64 Qt 5.15 / GCC 14* +*Tested with MSYS2 UCRT64 Qt 5.15 / Qt 6.7 / GCC 14* + +Install MSYS2 from [msys2.org](https://www.msys2.org/). For dynamic linking: ```bash -pacman -S mingw-w64-ucrt-x86_64-{go,gcc,qt5-base,pkg-config} -GOROOT=/ucrt64/lib/go go build -ldflags "-s -w -H windowsgui" +# Install Go and C++ toolchains +pacman -S mingw-w64-ucrt-x86_64-{go,gcc,pkg-config} +export GOROOT=/ucrt64/lib/go # Needed only if this is the first time installing Go in MSYS2. Otherwise it would be automatically applied when opening a new Bash terminal. + +# Install Qt +pacman -S mingw-w64-ucrt-x86_64-qt5-base # For Qt 5 +pacman -S mingw-w64-ucrt-x86_64-qt6-base # For Qt 6 + +go build -ldflags "-s -w -H windowsgui" ``` - Note: the MSYS2 `qt5-base` package [links against `libicu`](https://github.com/msys2/MINGW-packages/blob/master/mingw-w64-qt5-base/PKGBUILD#L241), whereas the Fsu0413 Qt packages do not. When using MSYS2, your distribution size including `.dll` files will be larger. @@ -195,20 +204,52 @@ For static linking: 1. Build the necessary docker container for cross-compilation: - `docker build -t miqt/win64-cross:latest -f docker/win64-cross-go1.23-qt5.15-static.Dockerfile .` 2. Build your application: - - `docker run --rm -v $(pwd):/src -w /src miqt/win64-cross:latest go build -buildvcs=false --tags=windowsqtstatic -ldflags '-s -w -H windowsgui'` + - `docker run --rm -v $(pwd):/src -w /src miqt/win64-cross:latest go build --tags=windowsqtstatic -ldflags '-s -w -H windowsgui'` For dynamic linking: 1. Build the necessary docker container for cross-compilation: - `docker build -t miqt/win64-dynamic:latest -f docker/win64-cross-go1.23-qt5.15-dynamic.Dockerfile .` 2. Build your application: - - `docker run --rm -v $(pwd):/src -w /src miqt/win64-dynamic:latest go build -buildvcs=false -ldflags '-s -w -H windowsgui'` + - `docker run --rm -v $(pwd):/src -w /src miqt/win64-dynamic:latest go build -ldflags '-s -w -H windowsgui'` 3. Copy necessary Qt LGPL libraries and plugin files. See FAQ Q3 for advice about docker performance. To add an icon and other properties to the .exe, you can use [the go-winres tool](https://github.com/tc-hib/go-winres). See the `examples/windowsmanifest` for details. +### macOS (Homebrew) + +*Tested with macOS 12.6 "Monterey" x86_64 / Go 1.23 / Qt 5.15 / Apple Clang 14.0* + +Install Homebrew from [brew.sh](https://brew.sh/). + +For dynamic linking: + +```bash +xcode-select --install +brew install golang +brew install pkg-config +brew install qt@5 +go build -ldflags '-s -w' +``` + +Installing `qt@5` from Homebrew may be very slow if Homebrew chooses to do a from-source build instead of a binary Bottle build, particularly owing to QtWebEngine (Chromium). + +### macOS (Docker) + +*Tested with osxcross 14.5 / Go 1.19 / MacPorts Qt 5.15 / Debian Clang 14.0* + +For dynamic linking: + +1. Build the necessary docker container for cross-compilation: + - `docker build -t miqt/osxcross:latest -f docker/macos-cross-x86_64-sdk14.5-go1.19-qt5.15-dynamic.Dockerfile .` +2. Build your application: + - `docker run --rm -v $(pwd):/src -w /src miqt/osxcross:latest go build -ldflags '-s -w'` +3. Copy necessary Qt LGPL libraries and plugin files. + +See FAQ Q3 for advice about docker performance. + ### Android (Docker) *Tested with Raymii Qt 5.15 / Android SDK 31 / Android NDK 22* diff --git a/cmd/genbindings/config-allowlist.go b/cmd/genbindings/config-allowlist.go index c572cd10..4807eeeb 100644 --- a/cmd/genbindings/config-allowlist.go +++ b/cmd/genbindings/config-allowlist.go @@ -87,6 +87,7 @@ func AllowHeader(fullpath string) bool { "q20functional.h", // Qt 6 unstable header "q20iterator.h", // Qt 6 unstable header "q23functional.h", // Qt 6 unstable header + "qguiapplication_platform.h", // Qt 6 - can be built for X11 but then platform-specific code fails to build on Windows "____last____": return false } @@ -385,8 +386,6 @@ func AllowType(p CppParameter, isReturnType bool) error { "QPlatformWindow", // e.g. qwindow.h, as below "QPlatformSurface", // e.g. qsurface.h. as below "QPlatformMenu", // e.g. QMenu_PlatformMenu. Defined in the QPA, could probably expose as uintptr - "struct _XDisplay", // Qt 6 QGuiApplication_platform - "xcb_connection_t", // Qt 6 QGuiApplication_platform "QTextDocument::ResourceProvider", // Qt 6 typedef for unsupported std::function "QTransform::Affine", // Qt 6 qtransform.h - public method returning private type "____last____": diff --git a/cmd/miqt-rcc/miqt-rcc b/cmd/miqt-rcc/miqt-rcc deleted file mode 100755 index 7e956947..00000000 Binary files a/cmd/miqt-rcc/miqt-rcc and /dev/null differ diff --git a/cmd/miqt-uic/README.md b/cmd/miqt-uic/README.md index 81230bd8..5a80143d 100644 --- a/cmd/miqt-uic/README.md +++ b/cmd/miqt-uic/README.md @@ -10,7 +10,3 @@ For usage information, see the `examples/uidesigner` folder. 2. Recursively walk and emit Go code. When developing `miqt-uic`, it's useful to run Qt `uic` side-by-side, and compare the output of each program for missing attributes or assignments. - -There is a hardcoded list of known MIQT constructor functions taking single `parent *qt.QWidget` argument. -- A bash function to regenerate this list is included in `constructors.go`. It should be re-run if MIQT is updated. -- "Promoted Widget" will result in no matching found constructor function (current known issue). diff --git a/docker/android-armv8a-go1.23-qt5.15-dynamic.Dockerfile b/docker/android-armv8a-go1.23-qt5.15-dynamic.Dockerfile index 5f8f3288..8f581342 100644 --- a/docker/android-armv8a-go1.23-qt5.15-dynamic.Dockerfile +++ b/docker/android-armv8a-go1.23-qt5.15-dynamic.Dockerfile @@ -4,14 +4,21 @@ RUN wget 'https://go.dev/dl/go1.23.1.linux-amd64.tar.gz' && \ tar x -C /usr/local/ -f go1.23.1.linux-amd64.tar.gz && \ rm go1.23.1.linux-amd64.tar.gz -COPY ../cmd/android-stub-gen/android-stub-gen.sh /usr/local/bin/android-stub-gen.sh -COPY ../cmd/android-stub-gen/android-mktemplate.sh /usr/local/bin/android-mktemplate.sh +COPY cmd/android-stub-gen/android-stub-gen.sh /usr/local/bin/android-stub-gen.sh +COPY cmd/android-mktemplate/android-mktemplate.sh /usr/local/bin/android-mktemplate.sh ENV PATH=/usr/local/go/bin:/opt/cmake/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/local/Qt-5.15.13/bin:/opt/android-sdk/cmdline-tools/tools/bin:/opt/android-sdk/tools:/opt/android-sdk/tools/bin:/opt/android-sdk/platform-tools +# The pkg-config definitions were all installed with platform-specific suffixes +# (i.e. need to use Qt5Widgets_arm64-v8a instead of Qt5Widgets) +# This container is targeting armv8-a, so set up simple symlinks +RUN /bin/bash -c 'cd /usr/local/Qt-5.15.13/lib/pkgconfig ; for f in *_arm64-v8a.pc ; do cp $f "$(basename -s _arm64-v8a.pc "$f").pc"; done' + ENV CC=/opt/android-sdk/ndk/22.1.7171670/toolchains/llvm/prebuilt/linux-x86_64/bin/aarch64-linux-android30-clang ENV CXX=/opt/android-sdk/ndk/22.1.7171670/toolchains/llvm/prebuilt/linux-x86_64/bin/aarch64-linux-android30-clang++ ENV CGO_ENABLED=1 ENV GOOS=android ENV GOARCH=arm64 -ENV GOFLAGS=-buildvcs=false \ No newline at end of file +ENV GOFLAGS=-buildvcs=false +ENV PKG_CONFIG_PATH=/usr/local/Qt-5.15.13/lib/pkgconfig +ENV CGO_CXXFLAGS="-Wno-ignored-attributes -D_Bool=bool" diff --git a/docker/macos-cross-x86_64-sdk14.5-go1.19-qt5.15-dynamic.Dockerfile b/docker/macos-cross-x86_64-sdk14.5-go1.19-qt5.15-dynamic.Dockerfile new file mode 100644 index 00000000..5acbfdf2 --- /dev/null +++ b/docker/macos-cross-x86_64-sdk14.5-go1.19-qt5.15-dynamic.Dockerfile @@ -0,0 +1,47 @@ +FROM crazymax/osxcross:14.5-debian AS osxcross + +FROM debian:bookworm + +COPY --from=osxcross /osxcross /osxcross + +RUN DEBIAN_FRONTEND=noninteractive apt-get update && \ + apt-get install --no-install-recommends -qyy \ + golang-go \ + clang \ + lld \ + libc6-dev \ + openssl \ + bzip2 \ + ca-certificates \ + curl \ + pkg-config && \ + apt-get clean + +ENV PATH="/osxcross/bin:$PATH" +ENV LD_LIBRARY_PATH="/osxcross/lib:$LD_LIBRARY_PATH" + +# The oldest macOS target with a working Qt 5.15 build on macports.org is High +# Sierra (10.13) +# @ref https://ports.macports.org/port/qt5-qtbase/details/ +# +# Go 1.19 and Go 1.20 are the last versions of Go that can target macOS 10.13. +# For later versions of Go, a higher MACOSX_DEPLOYMENT_TARGET version can be set. +# @ref https://tip.golang.org/doc/go1.20#darwin +ENV MACOSX_DEPLOYMENT_TARGET=10.13 + +# Preemptively mark some dependencies as installed that don't seem to download properly +RUN /usr/bin/env UNATTENDED=1 osxcross-macports fake-install py312 py312-packaging xorg xrender + +# Install Qt 5.15 and dependencies +RUN /usr/bin/env UNATTENDED=1 osxcross-macports install qt5-qtbase + +RUN rmdir /opt/ && \ + ln -s /osxcross/macports/pkgs/opt /opt + +ENV CC=x86_64-apple-darwin23.6-clang +ENV CXX=x86_64-apple-darwin23.6-clang++ +ENV GOOS=darwin +ENV GOARCH=amd64 +ENV CGO_ENABLED=1 +ENV PKG_CONFIG_PATH=/opt/local/libexec/qt5/lib/pkgconfig/ +ENV CGO_CXXFLAGS="-Wno-ignored-attributes -D_Bool=bool" diff --git a/docker/win64-cross-go1.19-qt5.15-dynamic.Dockerfile b/docker/win64-cross-go1.19-qt5.15-dynamic.Dockerfile index 70eafde7..f555dfed 100644 --- a/docker/win64-cross-go1.19-qt5.15-dynamic.Dockerfile +++ b/docker/win64-cross-go1.19-qt5.15-dynamic.Dockerfile @@ -18,3 +18,4 @@ ENV CC=x86_64-w64-mingw32.shared-gcc ENV PKG_CONFIG=x86_64-w64-mingw32.shared-pkg-config ENV GOOS=windows ENV CGO_ENABLED=1 +ENV GOFLAGS=-buildvcs=false diff --git a/docker/win64-cross-go1.19-qt5.15-static.Dockerfile b/docker/win64-cross-go1.19-qt5.15-static.Dockerfile index 285440f0..c9f03730 100644 --- a/docker/win64-cross-go1.19-qt5.15-static.Dockerfile +++ b/docker/win64-cross-go1.19-qt5.15-static.Dockerfile @@ -18,3 +18,4 @@ ENV CC=x86_64-w64-mingw32.static-gcc ENV PKG_CONFIG=x86_64-w64-mingw32.static-pkg-config ENV GOOS=windows ENV CGO_ENABLED=1 +ENV GOFLAGS=-buildvcs=false diff --git a/docker/win64-cross-go1.23-qt5.15-dynamic.Dockerfile b/docker/win64-cross-go1.23-qt5.15-dynamic.Dockerfile index fceab4dd..867186d2 100644 --- a/docker/win64-cross-go1.23-qt5.15-dynamic.Dockerfile +++ b/docker/win64-cross-go1.23-qt5.15-dynamic.Dockerfile @@ -18,3 +18,4 @@ ENV CC=x86_64-w64-mingw32.shared-gcc ENV PKG_CONFIG=x86_64-w64-mingw32.shared-pkg-config ENV GOOS=windows ENV CGO_ENABLED=1 +ENV GOFLAGS=-buildvcs=false diff --git a/docker/win64-cross-go1.23-qt5.15-static.Dockerfile b/docker/win64-cross-go1.23-qt5.15-static.Dockerfile index 876973bd..425a2905 100644 --- a/docker/win64-cross-go1.23-qt5.15-static.Dockerfile +++ b/docker/win64-cross-go1.23-qt5.15-static.Dockerfile @@ -18,3 +18,4 @@ ENV CC=x86_64-w64-mingw32.static-gcc ENV PKG_CONFIG=x86_64-w64-mingw32.static-pkg-config ENV GOOS=windows ENV CGO_ENABLED=1 +ENV GOFLAGS=-buildvcs=false diff --git a/qt/cflags_windows.go b/qt/cflags.go similarity index 73% rename from qt/cflags_windows.go rename to qt/cflags.go index 696a7616..27de3be3 100644 --- a/qt/cflags_windows.go +++ b/qt/cflags.go @@ -2,7 +2,7 @@ package qt /* #cgo CXXFLAGS: -std=c++11 -#cgo CFLAGS: -std=gnu11 +#cgo CFLAGS: -std=gnu11 -fPIC #cgo pkg-config: Qt5Widgets */ import "C" diff --git a/qt/cflags_android.go b/qt/cflags_android.go deleted file mode 100644 index 7103b856..00000000 --- a/qt/cflags_android.go +++ /dev/null @@ -1,9 +0,0 @@ -package qt - -/* - -#cgo CXXFLAGS: -fPIC -DQT_WIDGETS_LIB -I/usr/local/Qt-5.15.13/include/QtWidgets -I/usr/local/Qt-5.15.13/include/ -I/usr/local/Qt-5.15.13/include/QtCore -DQT_GUI_LIB -I/usr/local/Qt-5.15.13/include/QtGui -DQT_CORE_LIB -#cgo LDFLAGS: /usr/local/Qt-5.15.13/lib/libQt5Widgets_arm64-v8a.so /usr/local/Qt-5.15.13/lib/libQt5Gui_arm64-v8a.so /usr/local/Qt-5.15.13/lib/libQt5Core_arm64-v8a.so /usr/local/Qt-5.15.13/lib/libQt5Svg_arm64-v8a.so /usr/local/Qt-5.15.13/lib/libQt5AndroidExtras_arm64-v8a.so - -*/ -import "C" diff --git a/qt/cflags_linux.go b/qt/cflags_linux.go deleted file mode 100644 index 51e34c25..00000000 --- a/qt/cflags_linux.go +++ /dev/null @@ -1,9 +0,0 @@ -// +build linux,!android - -package qt - -/* -#cgo CFLAGS: -fPIC -#cgo pkg-config: Qt5Widgets -*/ -import "C" diff --git a/qt/qprintsupport/cflags_linux.go b/qt/qprintsupport/cflags.go similarity index 77% rename from qt/qprintsupport/cflags_linux.go rename to qt/qprintsupport/cflags.go index ebb10b1d..94670d68 100644 --- a/qt/qprintsupport/cflags_linux.go +++ b/qt/qprintsupport/cflags.go @@ -1,5 +1,3 @@ -// +build linux,!android - package qprintsupport /* diff --git a/qt6/cflags_linux.go b/qt6/cflags.go similarity index 74% rename from qt6/cflags_linux.go rename to qt6/cflags.go index ed37ed15..72615143 100644 --- a/qt6/cflags_linux.go +++ b/qt6/cflags.go @@ -1,5 +1,3 @@ -// +build linux,!android - package qt6 /* diff --git a/qt6/gen_qguiapplication_platform.cpp b/qt6/gen_qguiapplication_platform.cpp deleted file mode 100644 index 5b9e2152..00000000 --- a/qt6/gen_qguiapplication_platform.cpp +++ /dev/null @@ -1,5 +0,0 @@ -#define WORKAROUND_INNER_CLASS_DEFINITION_QNativeInterface__QX11Application -#include -#include "gen_qguiapplication_platform.h" -#include "_cgo_export.h" - diff --git a/qt6/gen_qguiapplication_platform.go b/qt6/gen_qguiapplication_platform.go deleted file mode 100644 index d0b5b14d..00000000 --- a/qt6/gen_qguiapplication_platform.go +++ /dev/null @@ -1,42 +0,0 @@ -package qt6 - -/* - -#include "gen_qguiapplication_platform.h" -#include - -*/ -import "C" - -import ( - "unsafe" -) - -type QNativeInterface__QX11Application struct { - h *C.QNativeInterface__QX11Application -} - -func (this *QNativeInterface__QX11Application) cPointer() *C.QNativeInterface__QX11Application { - if this == nil { - return nil - } - return this.h -} - -func (this *QNativeInterface__QX11Application) UnsafePointer() unsafe.Pointer { - if this == nil { - return nil - } - return unsafe.Pointer(this.h) -} - -func newQNativeInterface__QX11Application(h *C.QNativeInterface__QX11Application) *QNativeInterface__QX11Application { - if h == nil { - return nil - } - return &QNativeInterface__QX11Application{h: h} -} - -func UnsafeNewQNativeInterface__QX11Application(h unsafe.Pointer) *QNativeInterface__QX11Application { - return newQNativeInterface__QX11Application((*C.QNativeInterface__QX11Application)(h)) -} diff --git a/qt6/gen_qguiapplication_platform.h b/qt6/gen_qguiapplication_platform.h deleted file mode 100644 index a188da7a..00000000 --- a/qt6/gen_qguiapplication_platform.h +++ /dev/null @@ -1,31 +0,0 @@ -#ifndef GEN_QGUIAPPLICATION_PLATFORM_H -#define GEN_QGUIAPPLICATION_PLATFORM_H - -#include -#include -#include - -#pragma GCC diagnostic ignored "-Wdeprecated-declarations" - -#include "../libmiqt/libmiqt.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#ifdef __cplusplus -#if defined(WORKAROUND_INNER_CLASS_DEFINITION_QNativeInterface__QX11Application) -typedef QNativeInterface::QX11Application QNativeInterface__QX11Application; -#else -class QNativeInterface__QX11Application; -#endif -#else -typedef struct QNativeInterface__QX11Application QNativeInterface__QX11Application; -#endif - - -#ifdef __cplusplus -} /* extern C */ -#endif - -#endif diff --git a/qt6/qprintsupport/cflags_linux.go b/qt6/qprintsupport/cflags.go similarity index 77% rename from qt6/qprintsupport/cflags_linux.go rename to qt6/qprintsupport/cflags.go index 970e6d4e..105919be 100644 --- a/qt6/qprintsupport/cflags_linux.go +++ b/qt6/qprintsupport/cflags.go @@ -1,5 +1,3 @@ -// +build linux,!android - package qprintsupport /*