-
Notifications
You must be signed in to change notification settings - Fork 55
refactor: replace private access hacks with accessor pattern #315
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,73 @@ | ||
| # SPDX-FileCopyrightText: 2026 UnionTech Software Technology Co., Ltd. | ||
| # | ||
| # SPDX-License-Identifier: LGPL-3.0-or-later | ||
|
|
||
| name: Build qt5integration on Arch Linux | ||
|
|
||
| on: | ||
| push: | ||
|
|
||
| pull_request: | ||
|
|
||
| jobs: | ||
| container: | ||
| runs-on: ubuntu-latest | ||
| container: archlinux:latest | ||
| steps: | ||
| - name: Initialize pacman and system update | ||
| run: | | ||
| pacman-key --init | ||
| pacman --noconfirm --noprogressbar -Syu | ||
|
|
||
| - name: Install base build tools | ||
| run: | | ||
| pacman -S --noconfirm --noprogressbar base-devel git cmake ninja pkgconf | ||
|
|
||
| - name: Install qt5integration system dependencies | ||
| run: | | ||
| pacman -S --noconfirm --noprogressbar \ | ||
| qt5-base qt5-tools qt5-svg qt5-x11extras \ | ||
| qt5-wayland qt5-imageformats \ | ||
| extra-cmake-modules \ | ||
| gtest \ | ||
| libqtxdg xcb-util-renderutil \ | ||
| fontconfig libglvnd mtdev libxrender \ | ||
| icu uchardet dbus spdlog gsettings-qt \ | ||
| libxext libxi cups startup-notification systemd xcb-util \ | ||
| librsvg libraw kwayland \ | ||
| dtkcommon dtklog \ | ||
| treeland-protocols dtkcore dtkgui dtkwidget | ||
|
|
||
| - uses: actions/checkout@v4 | ||
| with: | ||
| fetch-depth: 0 | ||
|
|
||
| - name: Configure and build qt5integration | ||
| run: | | ||
| cmake -B build \ | ||
| -GNinja \ | ||
| -DCMAKE_INSTALL_PREFIX=/usr \ | ||
| -DCMAKE_INSTALL_LIBDIR=lib \ | ||
| -DCMAKE_BUILD_TYPE=Release \ | ||
| -DDTK5=ON | ||
| cmake --build build -j$(nproc) | ||
| echo "✅ qt5integration built successfully!" | ||
|
|
||
| - name: Install qt5integration to staging directory | ||
| run: | | ||
| DESTDIR=/tmp/qt5integration-install cmake --install build | ||
| echo "Total: $(find /tmp/qt5integration-install -type f | wc -l) files" | ||
|
|
||
| - name: Create installation package | ||
| run: | | ||
| tar -czf /tmp/qt5integration-archlinux-$(date +%Y%m%d-%H%M%S).tar.gz -C /tmp/qt5integration-install . | ||
| ls -la /tmp/qt5integration-archlinux-*.tar.gz | ||
|
|
||
| - name: Upload qt5integration Arch Linux build artifacts | ||
| if: ${{ !env.ACT }} | ||
| uses: actions/upload-artifact@v4 | ||
| with: | ||
| name: qt5integration-archlinux-build | ||
| path: "/tmp/qt5integration-archlinux-*.tar.gz" | ||
| if-no-files-found: error | ||
| retention-days: 30 | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,119 @@ | ||
| # SPDX-FileCopyrightText: 2026 UnionTech Software Technology Co., Ltd. | ||
| # | ||
| # SPDX-License-Identifier: LGPL-3.0-or-later | ||
|
|
||
| name: Build qt5integration on Deepin crimson | ||
|
|
||
| on: | ||
| push: | ||
|
|
||
| pull_request: | ||
|
|
||
| jobs: | ||
| container: | ||
| runs-on: ubuntu-latest | ||
| container: linuxdeepin/deepin:crimson | ||
| steps: | ||
| - uses: actions/checkout@v4 | ||
|
|
||
| - name: Setup apt sources and build tools | ||
| run: | | ||
| set -euxo pipefail | ||
| echo "deb [trusted=yes] http://mirrors.kernel.org/deepin/beige/ crimson main commercial community" > /etc/apt/sources.list | ||
| echo "deb-src [trusted=yes] http://mirrors.kernel.org/deepin/beige/ crimson main commercial community" >> /etc/apt/sources.list | ||
| rm -rf /etc/apt/sources.list.d | ||
|
Comment on lines
+21
to
+24
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The Deepin crimson repository does not distribute a GPG signing key publicly, so |
||
| apt-get update | ||
| apt-get install -y devscripts equivs git | ||
|
|
||
| - name: Build and install dtkcommon from source | ||
| run: | | ||
| set -euxo pipefail | ||
| cd /tmp | ||
| git clone --depth=1 https://github.com/linuxdeepin/dtkcommon.git | ||
| cd dtkcommon | ||
| mk-build-deps --install --remove --tool='apt-get -o Debug::pkgProblemResolver=yes --no-install-recommends --yes' debian/control | ||
| dpkg-buildpackage -uc -us -b | ||
| dpkg -i ../*.deb 2>/dev/null || apt-get install -f -y | ||
| echo "✅ dtkcommon installed" | ||
|
|
||
| - name: Build and install dtklog from source | ||
| run: | | ||
| set -euxo pipefail | ||
| cd /tmp | ||
| git clone --depth=1 https://github.com/linuxdeepin/dtklog.git | ||
| cd dtklog | ||
| mk-build-deps --install --remove --tool='apt-get -o Debug::pkgProblemResolver=yes --no-install-recommends --yes' debian/control | ||
| dpkg-buildpackage -uc -us -b -Pnodtk6 | ||
| dpkg -i ../*.deb 2>/dev/null || apt-get install -f -y | ||
| echo "✅ dtklog installed" | ||
|
|
||
| - name: Build and install treeland-protocols from source | ||
| run: | | ||
| set -euxo pipefail | ||
| apt-get install -y --allow-unauthenticated wlr-protocols || true | ||
| cd /tmp | ||
| git clone --depth=1 https://github.com/linuxdeepin/treeland-protocols.git | ||
| cd treeland-protocols | ||
| mk-build-deps --install --remove --tool='apt-get -o Debug::pkgProblemResolver=yes --no-install-recommends --yes' debian/control | ||
| dpkg-buildpackage -uc -us -b | ||
| dpkg -i ../*.deb 2>/dev/null || apt-get install -f -y | ||
| echo "✅ treeland-protocols installed" | ||
|
|
||
| - name: Build and install dtkcore from source | ||
| run: | | ||
| set -euxo pipefail | ||
| cd /tmp | ||
| git clone --depth=1 https://github.com/linuxdeepin/dtkcore.git | ||
| cd dtkcore | ||
| mk-build-deps --install --remove --tool='apt-get -o Debug::pkgProblemResolver=yes --no-install-recommends --yes' debian/control | ||
| dpkg-buildpackage -uc -us -b -Pnodtk6 | ||
| dpkg -i ../*.deb 2>/dev/null || apt-get install -f -y | ||
| echo "✅ dtkcore installed" | ||
|
|
||
| - name: Build and install dtkgui from source | ||
| run: | | ||
| set -euxo pipefail | ||
| cd /tmp | ||
| git clone --depth=1 https://github.com/linuxdeepin/dtkgui.git | ||
| cd dtkgui | ||
| mk-build-deps --install --remove --tool='apt-get -o Debug::pkgProblemResolver=yes --no-install-recommends --yes' debian/control | ||
| dpkg-buildpackage -uc -us -b -Pnodtk6 | ||
| dpkg -i ../*.deb 2>/dev/null || apt-get install -f -y | ||
| echo "✅ dtkgui installed" | ||
|
|
||
| - name: Build and install dtkwidget from source | ||
| run: | | ||
| set -euxo pipefail | ||
| cd /tmp | ||
| git clone --depth=1 https://github.com/linuxdeepin/dtkwidget.git | ||
| cd dtkwidget | ||
| mk-build-deps --install --remove --tool='apt-get -o Debug::pkgProblemResolver=yes --no-install-recommends --yes' debian/control | ||
| dpkg-buildpackage -uc -us -b -Pnodtk6 | ||
| dpkg -i ../*.deb 2>/dev/null || apt-get install -f -y | ||
| echo "✅ dtkwidget installed" | ||
|
|
||
| - name: Install qt5integration build dependencies | ||
| run: | | ||
| set -euxo pipefail | ||
| mk-build-deps --install --remove --tool='apt-get -o Debug::pkgProblemResolver=yes --no-install-recommends --yes' debian/control | ||
|
|
||
| - name: Build qt5integration deb packages | ||
| run: | | ||
| set -euxo pipefail | ||
| dpkg-buildpackage -uc -us -b -Pnodtk6 | ||
| echo "✅ qt5integration deb packages built successfully!" | ||
| ls -la ../ | ||
|
|
||
| - name: Collect deb artifacts | ||
| run: | | ||
| mkdir -p dist | ||
| mv ../*.deb dist/ | ||
| ls -la dist | ||
|
|
||
| - name: Upload qt5integration deb packages as artifacts | ||
| uses: actions/upload-artifact@v4 | ||
| with: | ||
| name: qt5integration-deepin-deb-packages | ||
| path: dist/*.deb | ||
| if-no-files-found: error | ||
| retention-days: 30 | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,79 @@ | ||
| // SPDX-FileCopyrightText: 2026 UnionTech Software Technology Co., Ltd. | ||
| // SPDX-License-Identifier: LGPL-3.0-or-later | ||
|
|
||
| #pragma once | ||
|
|
||
| #include <QtCore/qcompilerdetection.h> | ||
|
Check warning on line 6 in platformthemeplugin/dprivateaccessor_p.h
|
||
|
|
||
| // Private member accessor using the explicit template instantiation technique. | ||
| // | ||
| // C++ Standard [temp.explicit]/12 states: | ||
| // "The usual access checking rules do not apply to names used to | ||
| // specify explicit instantiation definitions." | ||
| // | ||
| // This allows passing pointers to private/protected data members and | ||
| // member functions as template arguments in explicit instantiations, | ||
| // bypassing normal access control — without modifying the class definition | ||
| // and without the UB caused by "#define private public". | ||
| // | ||
| // NOTE: The friend declaration must live inside the Tag struct so the friend | ||
| // function is findable via ADL when calling get(TagName{}). | ||
|
|
||
| QT_WARNING_PUSH | ||
| QT_WARNING_DISABLE_GCC("-Wnon-template-friend") | ||
|
|
||
| template<typename Tag> | ||
| struct Qt5IntegrationPrivateAccessor | ||
|
zccrs marked this conversation as resolved.
|
||
| { | ||
| using MemberPtr = typename Tag::MemberPtr; | ||
| friend MemberPtr get(Tag) noexcept; | ||
| }; | ||
|
|
||
| template<typename Tag, typename Tag::MemberPtr Ptr> | ||
| struct Qt5IntegrationPrivateAccessorImpl : Qt5IntegrationPrivateAccessor<Tag> | ||
| { | ||
| friend typename Tag::MemberPtr get(Tag) noexcept { return Ptr; } | ||
| }; | ||
|
|
||
| QT_WARNING_POP | ||
|
|
||
| // Non-static data member access | ||
| // Usage: D_PRIVATE_MEMBER(obj, TagName{}) → gives the member value (copy/ref) | ||
| // Usage: &D_PRIVATE_MEMBER(obj, TagName{}) → gives address of member | ||
| #define D_DECLARE_PRIVATE_MEMBER(TagName, ClassName, MemberName, MemberType) \ | ||
| struct TagName { \ | ||
| using MemberPtr = MemberType ClassName::*; \ | ||
| friend MemberPtr get(TagName) noexcept; \ | ||
| }; \ | ||
| template struct Qt5IntegrationPrivateAccessorImpl<TagName, &ClassName::MemberName> | ||
|
|
||
| // Trampoline: ensures get(tag) is called from a context with no class-scope | ||
| // get() member that might suppress ADL (C++ [basic.lookup.argdep] para 3). | ||
| namespace dtk_private_detail { | ||
| template<typename Tag> | ||
| inline typename Tag::MemberPtr access(Tag t) noexcept { return get(t); } | ||
| } | ||
|
|
||
| #define D_PRIVATE_MEMBER(obj, tag) ((obj).*dtk_private_detail::access(tag)) | ||
|
|
||
| // Non-static member function call | ||
| // Usage: D_PRIVATE_CALL(obj, TagName{}, arg1, arg2) | ||
| #define D_DECLARE_PRIVATE_FUNCTION(TagName, ClassName, FuncName, RetType, ...) \ | ||
| struct TagName { \ | ||
| using MemberPtr = RetType (ClassName::*)(__VA_ARGS__); \ | ||
| friend MemberPtr get(TagName) noexcept; \ | ||
| }; \ | ||
| template struct Qt5IntegrationPrivateAccessorImpl<TagName, &ClassName::FuncName> | ||
|
|
||
| #define D_PRIVATE_CALL(obj, tag, ...) ((obj).*dtk_private_detail::access(tag))(__VA_ARGS__) | ||
|
|
||
| // Static data member access | ||
| // get(TagName{}) returns MemberType*, so D_PRIVATE_STATIC_MEMBER dereferences it | ||
| #define D_DECLARE_PRIVATE_STATIC_MEMBER(TagName, ClassName, MemberName, MemberType) \ | ||
| struct TagName { \ | ||
| using MemberPtr = MemberType*; \ | ||
| friend MemberPtr get(TagName) noexcept; \ | ||
| }; \ | ||
| template struct Qt5IntegrationPrivateAccessorImpl<TagName, &ClassName::MemberName> | ||
|
|
||
| #define D_PRIVATE_STATIC_MEMBER(tag) (*dtk_private_detail::access(tag)) | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Arch Linux is a rolling release; pinning to a timestamped image causes partial-upgrade breakage (pacman does not support partial upgrades).
archlinux:latestensures a consistent package state, which is the correct approach for Arch CI.