Update cutter-deps to QT6 (#3363)

This commit is contained in:
karliss 2024-07-26 21:53:32 +03:00 committed by GitHub
parent f69ce2577e
commit 96696444cc
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
15 changed files with 572 additions and 94 deletions

View File

@ -1,5 +1,5 @@
version: '2.4.0-git-{build}'
image: 'Visual Studio 2017'
image: 'Visual Studio 2019'
clone_depth: 1
# Build configuration
@ -9,7 +9,7 @@ configuration:
# Environment
environment:
NINJA_URL: https://github.com/ninja-build/ninja/releases/download/v1.9.0/ninja-win.zip
VSVARSALLPATH: 'C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Auxiliary\Build\vcvarsall.bat'
VSVARSALLPATH: 'C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Auxiliary\Build\vcvarsall.bat'
ARCH: x64
PYTHON: 'C:\Python36-x64'
PACKAGE_NAME: cutter-git-x64.Windows
@ -25,7 +25,6 @@ install:
- cmd: python -m pip install meson ninja
- ps: choco install winflexbison3
# Artifacts
- cmd: set "ARTIFACT_NAME=%PACKAGE_NAME%.zip"
- cmd: set "ARTIFACT_PATH=build\%ARTIFACT_NAME%"
before_build:
@ -40,6 +39,7 @@ build_script:
- cmd: "cmake
-DCMAKE_BUILD_TYPE=Release
-DCUTTER_USE_BUNDLED_RIZIN=ON
-DCUTTER_QT6=ON
-DCUTTER_ENABLE_PYTHON=ON
-DCUTTER_ENABLE_PYTHON_BINDINGS=ON
-DCUTTER_ENABLE_PACKAGING=ON

View File

@ -0,0 +1,26 @@
name: 'Build linux'
description: 'Build cutter in a docker image'
inputs:
system-deps:
description: 'Use system libraries instead of cutter-deps'
required: true
image:
description: 'Docker image'
required: true
qt-major:
description: 'Qt major version'
required: true
package:
description: 'Package appimage'
required: true
runs:
using: 'docker'
image: 'ubuntu:18.04'
entrypoint: './.github/actions/build-linux-old/entrypoint.sh'
args:
- ${{ inputs.system-deps }}
env:
package: ${{ inputs.package }}
qt_major: ${{ inputs.qt-major }}
image: ${{ inputs.image }}
system_deps: ${{ inputs.system-deps }}

206
.github/actions/build-linux-old/entrypoint.sh vendored Executable file
View File

@ -0,0 +1,206 @@
#!/bin/bash
set -euo pipefail
pwd
ls
#export TZ=UTC
#ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
apt-get -y update
# latest git and cmake
export GIT_VERSION="git-2.36.1"
export CMAKE_VERSION="3.25.3"
apt-get -y install wget libcurl4-gnutls-dev libexpat1-dev gettext libz-dev libssl-dev build-essential
wget "https://www.kernel.org/pub/software/scm/git/$GIT_VERSION.tar.gz"
tar -zxf "$GIT_VERSION.tar.gz"
# build.
#make -C "$GIT_VERSION" prefix=/usr install -j > "$GIT_VERSION/build.log"
# ensure git is installed.
#git version
wget "https://github.com/Kitware/CMake/releases/download/v$CMAKE_VERSION/cmake-$CMAKE_VERSION-linux-x86_64.sh"
bash ./cmake-$CMAKE_VERSION-linux-x86_64.sh --skip-license --prefix=/usr
# ensure cmake is installed.
cmake --version
# cleanup dev environment.
rm -rf "$GIT_VERSION.tar.gz" "$GIT_VERSION" cmake-$CMAKE_VERSION-linux-x86_64.sh
unset CMAKE_VERSION
unset GIT_VERSION
apt-get -y install libgraphviz-dev \
mesa-common-dev \
libxkbcommon-x11-dev \
ninja-build \
python3-pip \
curl \
libpcre2-dev \
libfuse2 \
pkg-config \
git
if [ "$image" = "ubuntu:18.04" ]; then
# install additional packages needed for appimage
apt-get -y install gcc-7 \
libglu1-mesa-dev \
freeglut3-dev \
mesa-common-dev \
libclang-8-dev \
llvm-8
ln -s /usr/bin/llvm-config-8 /usr/bin/llvm-config
fi
if [ "$image" = "ubuntu:18.04" ] || [ "$image" = "ubuntu:20.04" ]; then
# install additional packages needed for appimage
apt-get -y install libxcb1-dev \
libxkbcommon-dev \
libxcb-*-dev \
libegl1
fi
if [ "$image" = "ubuntu:20.04" ] && [ "$system_deps" = "false" ]; then
# install additional packages needed for appimage
apt-get -y install libclang-12-dev \
llvm-12 \
libsm6 \
libwayland-dev \
libgl1-mesa-dev
fi
if [ "$image" = "ubuntu:18.04" ] && [ "$system_deps" = "true" ]; then
apt-get -y install qt5-default \
libqt5svg5-dev \
qttools5-dev \
qttools5-dev-tools
fi
if [ "$image" = "ubuntu:22.04" ]; then
apt-get -y install libclang-12-dev \
llvm-12 \
qt6-base-dev \
qt6-tools-dev \
qt6-tools-dev-tools \
libqt6svg6-dev \
libqt6core5compat6-dev \
libqt6svgwidgets6 \
qt6-l10n-tools \
gcc-12 \
g++-12
fi
# https://github.com/rizinorg/cutter/runs/7170222817?check_suite_focus=true
python3 -m pip install meson==0.61.5
if [ "$system_deps" = "false" ]
then
CUTTER_QT="$qt_major" scripts/fetch_deps.sh
set +u # TODO: remove temp code after updating cutter_deps
. cutter-deps/env.sh
set -u
#export LD_LIBRARY_PATH="`llvm-config --libdir`:$LD_LIBRARY_PATH"
fi
#if [ "${{ matrix.cc-override }}" != "default" ]
#then
# export CC="${{matrix.cc-override}}"
# export CXX="${{matrix.cxx-override}}"
#fi
# otherwise git complains about dubious ownership, due to code being checked out outside the container with a different user
git config --global --add safe.directory /github/workspace/rizin
if [ $qt_major = 6]
then
CMAKE_QT_ARG='ON'
else
CMAKE_QT_ARG='OFF'
fi
mkdir build
cd build
if [ "$system_deps" = "false" ]
then
locale
locale -a
export LANG="C.UTF-8"
export LC_ALL="C.UTF-8"
cmake \
-G Ninja \
-DCMAKE_BUILD_TYPE=Release \
-DCUTTER_ENABLE_PYTHON=ON \
-DPython3_ROOT_DIR="$CUTTER_DEPS_PYTHON_PREFIX" \
-DCUTTER_ENABLE_PYTHON_BINDINGS=ON \
-DCUTTER_ENABLE_GRAPHVIZ=ON \
-DCUTTER_USE_BUNDLED_RIZIN=ON \
-DCUTTER_APPIMAGE_BUILD=ON \
-DCUTTER_ENABLE_PACKAGING=ON \
-DCUTTER_ENABLE_KSYNTAXHIGHLIGHTING=OFF \
-DCUTTER_ENABLE_SIGDB=ON \
-DCUTTER_ENABLE_DEPENDENCY_DOWNLOADS=ON \
-DCUTTER_PACKAGE_RZ_GHIDRA=ON \
-DCUTTER_PACKAGE_JSDEC=ON \
-DCUTTER_PACKAGE_RZ_LIBSWIFT=ON \
-DCUTTER_PACKAGE_RZ_LIBYARA=ON \
-DCUTTER_PACKAGE_RZ_SILHOUETTE=ON \
-DCMAKE_INSTALL_PREFIX=appdir/usr \
-DCMAKE_INSTALL_RPATH_USE_LINK_PATH=ON \
-DCUTTER_QT6=$CMAKE_QT_ARG \
..
else
cmake \
-G Ninja \
-DCMAKE_BUILD_TYPE=Release \
-DCUTTER_USE_BUNDLED_RIZIN=ON \
-DCUTTER_QT6=$CMAKE_QT_ARG \
..
fi
ninja
if [ "$package" = "true" ]
then
export CUTTER_VERSION=$(python ../scripts/get_version.py)
export VERSION=$CUTTER_VERSION
ninja install
if [ $qt_major == "6" ]
then
pyside_ver=6
else
pyside_ver=2
fi
"../scripts/appimage_embed_python.sh" appdir $pyside_ver
APP_PREFIX=`pwd`/appdir/usr
export LD_LIBRARY_PATH="${LD_LIBRARY_PATH:-}:$APP_PREFIX/lib/rizin/plugins"
export PATH=$PATH:${APP_PREFIX}/bin
wget -c "https://github.com/probonopd/linuxdeployqt/releases/download/continuous/linuxdeployqt-continuous-x86_64.AppImage"
chmod a+x linuxdeployqt*.AppImage
rm -fv "../cutter-deps/qt/plugins/imageformats/libqjp2.so"
if [ "$qt_major" == "5" ]; then
export APPIMAGE_FILE="Cutter-${PACKAGE_ID}-Linux-Qt5-x86_64.AppImage"
./linuxdeployqt*.AppImage --appimage-extract-and-run \
./appdir/usr/share/applications/*.desktop \
-executable=./appdir/usr/bin/python3 \
-appimage \
-no-strip -exclude-libs=libnss3.so,libnssutil3.so,libqjp2.so \
-ignore-glob=usr/lib/python3.12/**/* \
-verbose=2
else
export APPIMAGE_FILE="Cutter-${PACKAGE_ID}-Linux-x86_64.AppImage"
./linuxdeployqt*.AppImage --appimage-extract-and-run \
./appdir/usr/share/applications/*.desktop \
-executable=./appdir/usr/bin/python3 \
-appimage \
-no-strip -exclude-libs=libnss3.so,libnssutil3.so,libqjp2.so \
-exclude-libs="libwayland-client.so,libwayland-egl.so,libwayland-cursor.so" \
-ignore-glob=usr/lib/python3.12/**/* \
-extra-plugins="platforms/libqwayland-egl.so,platforms/libqwayland-generic.so,wayland-decoration-client,wayland-graphics-integration-client,wayland-shell-integration,wayland-graphics-integration-server" \
-verbose=2
fi
find ./appdir -executable -type f -exec ldd {} \; | cut -d " " -f 2-3 | sort | uniq
# find ./appdir -executable -type f -exec ldd {} \; | grep " => /usr" | cut -d " " -f 2-3 | sort | uniq
mv Cutter-*-x86_64.AppImage "$APPIMAGE_FILE"
echo PACKAGE_NAME=$APPIMAGE_FILE >> $GITHUB_ENV
echo PACKAGE_NAME=$APPIMAGE_FILE >> $GITHUB_OUTPUT
echo PACKAGE_PATH=build/$APPIMAGE_FILE >> $GITHUB_ENV
echo PACKAGE_PATH=build/$APPIMAGE_FILE >> $GITHUB_OUTPUT
echo UPLOAD_ASSET_TYPE=application/x-executable >> $GITHUB_ENV
fi

View File

@ -30,19 +30,13 @@ jobs:
name: [
linux-x86_64,
linux-x86_64-system-deps,
linux-x86_64-qt6-system-deps,
tarball
]
include:
- name: linux-x86_64-system-deps # ensure that Cutter can be built at least in basic config on Ubuntu 18.04 using sytem libraries
image: ubuntu:18.04
python-version: 3.6.x
system-deps: true
package: false
tarball: false
cc-override: '/usr/bin/gcc-7'
cxx-override: '/usr/bin/g++-7'
- name: linux-x86_64-qt6-system-deps # ensure that Cutter can be built at least in basic config on Ubuntu 22.04 using sytem libraries
- qt-major: 6
cc-override: default
cxx-override: default
- name: linux-x86_64-system-deps # ensure that Cutter can be built at least in basic config on Ubuntu 22.04 using sytem libraries
image: ubuntu:22.04
python-version: 3.10.x
system-deps: true
@ -50,14 +44,12 @@ jobs:
tarball: false
cc-override: '/usr/bin/gcc-12'
cxx-override: '/usr/bin/g++-12'
- name: linux-x86_64
image: ubuntu:18.04
- name: linux-x86_64 # main Appimage build
image: ubuntu:20.04
python-version: 3.6.x
system-deps: false
package: true
tarball: false
cc-override: default
cxx-override: default
- name: tarball
python-version: 3.6.x
image: ubuntu:20.04
@ -129,18 +121,25 @@ jobs:
apt-get -y install gcc-7 \
libglu1-mesa-dev \
freeglut3-dev \
mesa-common-dev
mesa-common-dev \
libclang-8-dev \
llvm-8
ln -s /usr/bin/llvm-config-8 /usr/bin/llvm-config
fi
if [ "${{ matrix.image }}" = "ubuntu:18.04" ] || [ "${{ matrix.image }}" = "ubuntu:20.04" ]; then
# install additional packages needed for appimage
apt-get -y install libxcb1-dev \
libxkbcommon-dev \
libxcb-*-dev \
libegl1 \
libclang-8-dev \
llvm-8
ln -s /usr/bin/llvm-config-8 /usr/bin/llvm-config
libegl1
fi
if [ "${{ matrix.image }}" = "ubuntu:20.04" ] && [ "${{ matrix.system-deps }}" = "false" ]; then
# install additional packages needed for appimage
apt-get -y install libclang-12-dev \
llvm-12 \
libsm6 \
libwayland-dev \
libgl1-mesa-dev
fi
if [ "${{ matrix.image }}" = "ubuntu:18.04" ] && [ "${{ matrix.system-deps }}" = "true" ]; then
apt-get -y install qt5-default \
@ -184,9 +183,8 @@ jobs:
run: |
if [ "${{ matrix.system-deps }}" = "false" ]
then
scripts/fetch_deps.sh
CUTTER_QT="${{ matrix.qt-major }}" scripts/fetch_deps.sh
. cutter-deps/env.sh
export PKG_CONFIG_PATH="$CUTTER_DEPS_PYTHON_PREFIX/lib/pkgconfig:${PKG_CONFIG_PATH:-}"
export LD_LIBRARY_PATH="`llvm-config --libdir`:$LD_LIBRARY_PATH"
fi
set -e #TODO: move to top once cutter-deps doesn't fail
@ -200,13 +198,15 @@ jobs:
cd build
if [ "${{ matrix.system-deps }}" = "false" ]
then
locale
locale -a
export LANG="C.UTF-8"
export LC_ALL="C.UTF-8"
cmake \
-G Ninja \
-DCMAKE_BUILD_TYPE=Release \
-DCUTTER_ENABLE_PYTHON=ON \
-DPYTHON_LIBRARY="$CUTTER_DEPS_PYTHON_PREFIX/lib/libpython3.9.so" \
-DPYTHON_INCLUDE_DIR="$CUTTER_DEPS_PYTHON_PREFIX/include/python3.9" \
-DPYTHON_EXECUTABLE="$CUTTER_DEPS_PYTHON_PREFIX/bin/python3" \
-DPython3_ROOT_DIR="$CUTTER_DEPS_PYTHON_PREFIX" \
-DCUTTER_ENABLE_PYTHON_BINDINGS=ON \
-DCUTTER_ENABLE_GRAPHVIZ=ON \
-DCUTTER_USE_BUNDLED_RIZIN=ON \
@ -222,6 +222,7 @@ jobs:
-DCUTTER_PACKAGE_RZ_SILHOUETTE=ON \
-DCMAKE_INSTALL_PREFIX=appdir/usr \
-DCMAKE_INSTALL_RPATH_USE_LINK_PATH=ON \
-DCUTTER_QT6=${{ matrix.qt-major == '6' && 'ON' || 'OFF' }} \
..
elif [ "${{ matrix.image }}" = "ubuntu:22.04" ]
then
@ -244,21 +245,35 @@ jobs:
export CUTTER_VERSION=$(python ../scripts/get_version.py)
export VERSION=$CUTTER_VERSION
ninja install
"../scripts/appimage_embed_python.sh" appdir
"../scripts/appimage_embed_python.sh" appdir ${{ matrix.qt-major == '6' && '6' || '2' }}
APP_PREFIX=`pwd`/appdir/usr
export LD_LIBRARY_PATH="$LD_LIBRARY_PATH:$APP_PREFIX/lib/rizin/plugins"
export PATH=$PATH:${APP_PREFIX}/bin
wget -c "https://github.com/probonopd/linuxdeployqt/releases/download/continuous/linuxdeployqt-continuous-x86_64.AppImage"
chmod a+x linuxdeployqt*.AppImage
rm -fv "../cutter-deps/qt/plugins/imageformats/libqjp2.so"
./linuxdeployqt*.AppImage ./appdir/usr/share/applications/*.desktop \
-executable=./appdir/usr/bin/python3 \
-appimage \
-no-strip -exclude-libs=libnss3.so,libnssutil3.so,libqjp2.so \
-ignore-glob=usr/lib/python3.9/**/* \
-verbose=2
find ./appdir -executable -type f -exec ldd {} \; | grep " => /usr" | cut -d " " -f 2-3 | sort | uniq
export APPIMAGE_FILE="Cutter-${PACKAGE_ID}-Linux-x86_64.AppImage"
if [ "${{ matrix.qt-major }}" == "5" ]; then
export APPIMAGE_FILE="Cutter-${PACKAGE_ID}-Linux-Qt5-x86_64.AppImage"
./linuxdeployqt*.AppImage ./appdir/usr/share/applications/*.desktop \
-executable=./appdir/usr/bin/python3 \
-appimage \
-no-strip -exclude-libs=libnss3.so,libnssutil3.so,libqjp2.so \
-ignore-glob=usr/lib/python3.12/**/* \
-verbose=2
else
export APPIMAGE_FILE="Cutter-${PACKAGE_ID}-Linux-x86_64.AppImage"
./linuxdeployqt*.AppImage ./appdir/usr/share/applications/*.desktop \
-executable=./appdir/usr/bin/python3 \
-appimage \
-no-strip -exclude-libs=libnss3.so,libnssutil3.so,libqjp2.so \
-exclude-libs="libwayland-client.so,libwayland-egl.so,libwayland-cursor.so" \
-ignore-glob=usr/lib/python3.12/**/* \
-extra-plugins="platforms/libqwayland-egl.so,platforms/libqwayland-generic.so,wayland-decoration-client,wayland-graphics-integration-client,wayland-shell-integration,wayland-graphics-integration-server" \
-verbose=2
fi
find ./appdir -executable -type f -exec ldd {} \; | cut -d " " -f 2-3 | sort | uniq
# find ./appdir -executable -type f -exec ldd {} \; | grep " => /usr" | cut -d " " -f 2-3 | sort | uniq
mv Cutter-*-x86_64.AppImage "$APPIMAGE_FILE"
echo PACKAGE_NAME=$APPIMAGE_FILE >> $GITHUB_ENV
echo PACKAGE_PATH=build/$APPIMAGE_FILE >> $GITHUB_ENV
@ -293,6 +308,85 @@ jobs:
asset_path: ${{ env.PACKAGE_PATH }}
asset_name: ${{ env.PACKAGE_NAME }}
asset_content_type: ${{ env.UPLOAD_ASSET_TYPE }}
build-linux-old:
name: ${{ matrix.name }}
runs-on: ubuntu-latest
strategy:
matrix:
name: [
linux-x86_64-qt5,
linux-x86_64-qt5-system-deps,
]
include:
- qt-major: 6
cc-override: default
cxx-override: default
- name: linux-x86_64-qt5-system-deps # ensure that Cutter can be built at least in basic config on Ubuntu 18.04 using sytem libraries
image: ubuntu:18.04
python-version: 3.6.x
system-deps: true
package: false
cc-override: '/usr/bin/gcc-7'
cxx-override: '/usr/bin/g++-7'
qt-major: 5
- name: linux-x86_64-qt5 # qt5 Appimage build for increased compatibility with older distros
image: ubuntu:18.04
python-version: 3.6.x
system-deps: false
package: true
qt-major: 5
# Prevent one job from pausing the rest
fail-fast: false
steps:
- uses: actions/checkout@v3
with:
submodules: recursive
persist-credentials: false
- name: Prepare package id
shell: bash
run: |
if [ "${{ startsWith(github.event.ref, 'refs/tags')}}" = "true" ]
then
PACKAGE_ID="${{ github.event.ref }}"
else
PACKAGE_ID="git-`date "+%Y-%m-%d"`-${{ format('{0}', github.sha) }}"
fi
PACKAGE_ID=${PACKAGE_ID##refs/tags/}
echo PACKAGE_ID=$PACKAGE_ID >> $GITHUB_ENV
ls -alh
who
- name: build linux
id: build
uses: ./.github/actions/build-linux-old
with:
system-deps: ${{ matrix.system-deps }}
image: ${{ matrix.image }}
qt-major: ${{ matrix.qt-major }}
package: ${{ matrix.package }}
- uses: actions/upload-artifact@v3
if: env.PACKAGE_NAME != null
with:
name: ${{ steps.build.outputs.PACKAGE_NAME }}
path: ${{ steps.build.outputs.PACKAGE_PATH }}
- name: Get release
if: github.event_name == 'push' && startsWith(github.event.ref, 'refs/tags')
id: get_release
uses: rizinorg/gha-get-release@c8074dd5d13ddd0a194d8c9205a1466973c7dc0d
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Upload release assets
if: steps.get_release.outputs.upload_url != null && env.PACKAGE_NAME != null
uses: actions/upload-release-asset@v1.0.2
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
upload_url: ${{ steps.get_release.outputs.upload_url }}
asset_path: ${{ env.PACKAGE_PATH }}
asset_name: ${{ env.PACKAGE_NAME }}
asset_content_type: ${{ env.UPLOAD_ASSET_TYPE }}
build:
name: ${{ matrix.name }}
@ -301,21 +395,24 @@ jobs:
matrix:
name: [
macos-x86_64,
macos-arm64,
windows-x86_64,
]
include:
- python-version: 3.12.x
- system-deps: false
- name: windows-x86_64
os: windows-2019
package: true
system-deps: false
python-version: 3.7.x
python-version: 3.12.x
- name: macos-x86_64
os: macos-14-large
python-version: 3.7.x
system-deps: false
os: macos-12
arch: x86_64
package: true
- name: macos-arm64
os: macos-14
arch: arm64
package: true
cc-override: default
cxx-override: default
# Prevent one job from pausing the rest
fail-fast: false
steps:
@ -334,8 +431,9 @@ jobs:
brew bundle
- name: py dependencies
run: |
python3 -m pip install -U pip==21.3.1
pip install meson==0.61.5 # https://github.com/rizinorg/cutter/runs/7170222817?check_suite_focus=true
#python3 -m pip install -U pip==21.3.1
pip install meson # ==0.61.5 # https://github.com/rizinorg/cutter/runs/7170222817?check_suite_focus=true
pip install setuptools
- name: Prepare package id
shell: bash
run: |
@ -351,19 +449,18 @@ jobs:
shell: bash
if: contains(matrix.os, 'macos')
run: |
export MACOSX_DEPLOYMENT_TARGET=10.14
export MACOSX_DEPLOYMENT_TARGET=10.15
scripts/fetch_deps.sh
source cutter-deps/env.sh
set -euo pipefail
export PATH=/usr/local/opt/llvm/bin:$PATH
mkdir build
cd build
PACKAGE_NAME=Cutter-${PACKAGE_ID}-macOS-x86_64
PACKAGE_NAME=Cutter-${PACKAGE_ID}-macOS-${{ matrix.arch }}
cmake \
-DCMAKE_BUILD_TYPE=Release \
-DPYTHON_LIBRARY="$CUTTER_DEPS_PYTHON_PREFIX/lib/libpython3.9.dylib" \
-DPYTHON_INCLUDE_DIR="$CUTTER_DEPS_PYTHON_PREFIX/include/python3.9" \
-DPYTHON_EXECUTABLE="$CUTTER_DEPS_PYTHON_PREFIX/bin/python3" \
-DPython3_ROOT_DIR="${CUTTER_DEPS_PYTHON_PREFIX}" \
-DPython_ROOT_DIR="${CUTTER_DEPS_PYTHON_PREFIX}" \
-DCUTTER_ENABLE_PYTHON=ON \
-DCUTTER_ENABLE_PYTHON_BINDINGS=ON \
-DCUTTER_USE_BUNDLED_RIZIN=ON \
@ -376,6 +473,7 @@ jobs:
-DCUTTER_PACKAGE_RZ_LIBSWIFT=ON \
-DCUTTER_PACKAGE_RZ_LIBYARA=ON \
-DCUTTER_PACKAGE_RZ_SILHOUETTE=ON \
-DCUTTER_QT6=ON \
-DCPACK_PACKAGE_FILE_NAME="$PACKAGE_NAME" \
-DCPACK_BUNDLE_APPLE_CERT_APP="-" \
.. && \
@ -420,6 +518,7 @@ jobs:
-DCUTTER_ENABLE_DEPENDENCY_DOWNLOADS=ON ^
-DCMAKE_PREFIX_PATH="%CUTTER_DEPS%\pyside" ^
-DCPACK_PACKAGE_FILE_NAME=%PACKAGE_NAME% ^
-DCUTTER_QT6=ON ^
-G Ninja ^
..
cmake --build . --config Release

2
.gitignore vendored
View File

@ -26,7 +26,7 @@ moc_*.cpp
qrc_*.cpp
moc_*.h
ui_*.h
build*/
/build*/
cmake-build-*/
/src-build/

View File

@ -93,10 +93,15 @@ endif()
find_package(${QT_PREFIX} REQUIRED COMPONENTS ${QT_COMPONENTS})
if(CUTTER_ENABLE_PYTHON)
find_package(PythonInterp REQUIRED)
find_package(PythonLibs ${CUTTER_PYTHON_MIN} REQUIRED)
if(CMAKE_VERSION VERSION_LESS "3.12.0")
find_package(PythonInterp REQUIRED)
find_package(PythonLibs ${CUTTER_PYTHON_MIN} REQUIRED)
include_directories(${PYTHON_INCLUDE_DIRS})
else()
find_package (Python3 ${CUTTER_PYTHON_MIN} REQUIRED COMPONENTS Interpreter Development)
set (PYTHON_EXECUTABLE ${Python3_EXECUTABLE})
endif()
include_directories(${PYTHON_INCLUDE_DIRS})
add_definitions(-DCUTTER_ENABLE_PYTHON)
if(CUTTER_ENABLE_PYTHON_BINDINGS)

16
dist/CMakeLists.txt vendored
View File

@ -14,9 +14,14 @@ if(WIN32)
if (CUTTER_ENABLE_DEPENDENCY_DOWNLOADS)
set(CPACK_INSTALL_SCRIPTS ${CMAKE_CURRENT_SOURCE_DIR}/WindowsBundlePython.cmake)
endif()
find_package(PythonInterp REQUIRED)
install(DIRECTORY ${CUTTER_DEPS}/pyside/lib/site-packages DESTINATION "python${PYTHON_VERSION_MAJOR}${PYTHON_VERSION_MINOR}")
install(FILES ${CUTTER_DEPS}/pyside/bin/shiboken2.abi3.dll ${CUTTER_DEPS}/pyside/bin/pyside2.abi3.dll DESTINATION .)
if(CMAKE_VERSION VERSION_LESS "3.12.0")
find_package(PythonInterp REQUIRED)
install(DIRECTORY ${CUTTER_DEPS}/pyside/lib/site-packages DESTINATION "python${PYTHON_VERSION_MAJOR}${PYTHON_VERSION_MINOR}")
else()
find_package (Python3 ${CUTTER_PYTHON_MIN} REQUIRED COMPONENTS)
install(DIRECTORY ${CUTTER_DEPS}/pyside/lib/site-packages DESTINATION "python${Python3_VERSION_MAJOR}${Python3_VERSION_MINOR}")
endif()
install(FILES ${CUTTER_DEPS}/pyside/bin/shiboken6.abi3.dll ${CUTTER_DEPS}/pyside/bin/pyside6.abi3.dll DESTINATION .)
endif()
install(SCRIPT WindowsBundleQt.cmake)
endif()
@ -104,7 +109,7 @@ if(APPLE)
if(CUTTER_PACKAGE_DEPENDENCIES AND CUTTER_ENABLE_PYTHON)
set(EMBED_PYTHON_SH "${CMAKE_CURRENT_SOURCE_DIR}/appbundle_embed_python.sh")
set(PYTHON_FRAMEWORK_DIR "${CUTTER_DEPS}/python/Python.framework")
set(PYTHON_FRAMEWORK_DIR "${CUTTER_DEPS}/python/Library/Frameworks/Python.framework")
set(PYSIDE_PREFIX "${CUTTER_DEPS}/pyside")
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/MacOSBundlePython.cmake.in"
"${CMAKE_CURRENT_BINARY_DIR}/MacOSBundlePython.cmake" @ONLY)
@ -158,6 +163,9 @@ if(CUTTER_ENABLE_DEPENDENCY_DOWNLOADS AND (NOT WIN32))
else()
set (YARA_PLUGIN_OPTIONS "")
endif()
if (CUTTER_QT6)
set (YARA_PLUGIN_OPTIONS "${YARA_PLUGIN_OPTIONS} -DCUTTER_QT6=ON")
endif()
install(CODE "
execute_process(COMMAND
\"${CMAKE_CURRENT_SOURCE_DIR}/../scripts/rz-libyara.sh\"

View File

@ -6,7 +6,7 @@ if ! [[ $# -eq 3 ]]; then
exit 1
fi
python_version=python3.9
python_version=python3.12
py_framework=$1
appbundle=$2
@ -30,21 +30,21 @@ fi
echo "Making executable $executable point to embedded Framework"
install_name_tool -change `otool -L "$executable" | sed -n "s/^[[:blank:]]*\([^[:blank:]]*Python\) (.*$/\1/p"` @executable_path/../Frameworks/Python.framework/Versions/Current/Python "$executable"
echo "Checking if PySide2 is available"
echo "Checking if PySide is available"
pyside_prefix=$(pkg-config --variable=prefix pyside2)
pyside_prefix=$(pkg-config --variable=prefix pyside6)
if [ $? -ne 0 ]; then
echo "PySide2 is not available, ignoring."
echo "PySide is not available, ignoring."
exit 0
fi
echo "PySide is at $pyside_prefix"
if [ ! -d "Versions/Current/lib/$python_version/site-packages/PySide2" ]
if [ ! -d "Versions/Current/lib/$python_version/site-packages/PySide6" ]
then
cp -va "$pyside_prefix/lib/$python_version/" "Versions/Current/lib/$python_version"
cd .. # $appbundle/Contents/Frameworks
cp -va "$pyside_prefix/lib/"*.dylib .
else
echo "site-packages/Pyside2 exists, skipping copying"
echo "site-packages/Pyside6 exists, skipping copying"
fi

View File

@ -1,13 +1,19 @@
#!/bin/bash
if ! [[ $# -eq 1 ]]; then
echo "Usage: $0 [appdir]"
set -euo pipefail
if ! [[ $# -eq 2 ]]; then
echo "Usage: $0 [appdir] [pyside_major]"
exit 1
fi
python_version=python3.9
python_prefix=$(pkg-config --variable=prefix python3)
python_version=`$python_prefix/bin/python3 --version`
python_version=${python_version##* }
python_version=python${python_version%.*}
pyside_major=$2
appdir=$1
echo "Embedding Python from prefix $python_prefix in appdir $appdir"
@ -20,11 +26,11 @@ echo "Cleaning up embedded Python"
find . | grep -E "(__pycache__|\.pyc|\.pyo$)" | xargs rm -rf
rm -r lib/$python_version/test lib/$python_version/idlelib lib/$python_version/curses lib/$python_version/lib2to3
echo "Checking if PySide2 is available"
echo "Checking if PySide is available"
pyside_prefix=$(pkg-config --variable=prefix pyside2)
pyside_prefix=$(pkg-config --variable=prefix pyside$pyside_major)
if [ $? -ne 0 ]; then
echo "PySide2 is not available, ignoring."
echo "PySide is not available, ignoring."
exit 0
fi

View File

@ -5,19 +5,27 @@ set -e
cd $(dirname "${BASH_SOURCE[0]}")/..
mkdir -p cutter-deps && cd cutter-deps
DEPS_FILE_linux_x86_64=cutter-deps-linux-x86_64.tar.gz
DEPS_SHA256_linux_x86_64=0721c85548bbcf31f6911cdb2227e5efb4a20c34262672d4cd2193db166b2f8c
DEPS_BASE_URL=https://github.com/rizinorg/cutter-deps/releases/download/v16
if [ "$CUTTER_QT" == "5" ]; then
DEPS_FILE_linux_x86_64=cutter-deps-linux-x86_64.tar.gz
DEPS_SHA256_linux_x86_64=0721c85548bbcf31f6911cdb2227e5efb4a20c34262672d4cd2193db166b2f8c
DEPS_BASE_URL=https://github.com/rizinorg/cutter-deps/releases/download/v15
else
DEPS_FILE_linux_x86_64=cutter-deps-linux-x86_64.tar.gz
DEPS_SHA256_linux_x86_64=f63c5af2d9872bc6538a94c839d6ef6645c7630c42cff30f1d9da8eefd9eb040
fi
echo $DEPS_SHA256_linux_x86_64
DEPS_FILE_macos_x86_64=cutter-deps-macos-x86_64.tar.gz
DEPS_SHA256_macos_x86_64=0a23fdec3012a8af76675d6f3ff39cf9df9b08c13d1156fb7ffcc0e495c9407f
DEPS_SHA256_macos_x86_64=bcdc214e34dc3fd720327ad42e03fe3ec996ca28a9987e99898f149a65299a8c
DEPS_FILE_macos_arm64=cutter-deps-macos-arm64.tar.gz
DEPS_SHA256_macos_arm64=f9b9a5569bd23c9b5e45836b82aba7576a5c53df4871380a55c370b9d7f88615
DEPS_SHA256_macos_arm64=aa3f5ae91b93c5176d6bd4313af0888a2b6dcdaa2ef1750dd7e2f98156882e0f
DEPS_FILE_win_x86_64=cutter-deps-win-x86_64.tar.gz
DEPS_SHA256_win_x86_64=9ab4e89732a3df0859a26fd5de6d9f3cb80106cbe2539340af831ed298625076
DEPS_SHA256_win_x86_64=710e40cf8329205d09535cc56a9fb155a56ff1a1ca112145864382fb3d4e8160
DEPS_BASE_URL=https://github.com/rizinorg/cutter-deps/releases/download/v15
ARCH=x86_64
if [ "$OS" == "Windows_NT" ]; then

View File

@ -438,7 +438,7 @@ if(CUTTER_ENABLE_PYTHON_BINDINGS)
COMMAND "${SHIBOKEN_COMMAND}" --project-file="${BINDINGS_BUILD_DIR}/bindings.txt" ${SHIBOKEN_OPTIONS} ${SHIBOKEN_EXTRA_OPTIONS}
DEPENDS "${BINDINGS_BUILD_DIR}/bindings.xml" "${BINDINGS_BUILD_DIR}/bindings.txt"
IMPLICIT_DEPENDS CXX "${CMAKE_CURRENT_SOURCE_DIR}/bindings/bindings.h"
COMMENT "Generating Python bindings with shiboken2")
COMMENT "Generating Python bindings with ${SHIBOKEN_COMMAND}")
else()
set(BINDINGS_SOURCE "")
endif()
@ -498,19 +498,24 @@ endif()
target_link_libraries(Cutter PUBLIC ${RIZIN_TARGET})
if(CUTTER_ENABLE_PYTHON)
if (WIN32)
if(CMAKE_VERSION VERSION_LESS "3.12.0")
# On windows some of the Python STABLE API functions are in seperate library
# which isn't added by CMake.
foreach(_PYTHON_LIBRARY ${PYTHON_LIBRARIES})
# Skip extra "optimized" and "debug" values that are only meant for passing to target_link_libraries()
if((NOT _PYTHON_LIBRARY STREQUAL "optimized") AND (NOT _PYTHON_LIBRARY STREQUAL "debug"))
get_filename_component(_PYTHON_LIB_DIR ${_PYTHON_LIBRARY} DIRECTORY)
message(STATUS "Add extra library dir for Python: ${_PYTHON_LIB_DIR}")
target_link_directories(Cutter PRIVATE ${_PYTHON_LIB_DIR})
endif()
endforeach()
if (WIN32)
foreach(_PYTHON_LIBRARY ${PYTHON_LIBRARIES})
# Skip extra "optimized" and "debug" values that are only meant for passing to target_link_libraries()
if((NOT _PYTHON_LIBRARY STREQUAL "optimized") AND (NOT _PYTHON_LIBRARY STREQUAL "debug"))
get_filename_component(_PYTHON_LIB_DIR ${_PYTHON_LIBRARY} DIRECTORY)
message(STATUS "Add extra library dir for Python: ${_PYTHON_LIB_DIR}")
target_link_directories(Cutter PRIVATE ${_PYTHON_LIB_DIR})
endif()
endforeach()
endif()
target_link_libraries(Cutter PRIVATE ${PYTHON_LIBRARIES})
else()
target_link_libraries(Cutter PRIVATE Python3::Python)
endif()
target_link_libraries(Cutter PRIVATE ${PYTHON_LIBRARIES})
if(CUTTER_ENABLE_PYTHON_BINDINGS)
if (CUTTER_QT6)
target_link_libraries(Cutter PRIVATE Shiboken6::libshiboken PySide6::pyside6)

View File

@ -31,9 +31,14 @@
PyErr_Print();
return QString();
}
PythonToCppFunc pythonToCpp = Shiboken::Conversions::isPythonToCppConvertible(Sbk${PYSIDE_NAME}_QtCoreTypeConverters[SBK_QSTRING_IDX], pyResult);
auto converter = Shiboken::Conversions::getConverter("str");
if (!converter) {
Shiboken::warning(PyExc_RuntimeWarning, 0, "Can't find converter for str.");
return ::QString();
}
PythonToCppFunc pythonToCpp = Shiboken::Conversions::isPythonToCppConvertible(converter, pyResult);
if (!pythonToCpp) {
Shiboken::warning(PyExc_RuntimeWarning, 2, "Invalid return value for plugin metadata VAR_NAME, expected %s, got %s.", "QString", Py_TYPE(pyResult)->tp_name);
Shiboken::warning(PyExc_RuntimeWarning, 1, "Invalid return value for plugin metadata VAR_NAME, expected str, got %s.", Py_TYPE(pyResult)->tp_name);
return ::QString();
}
QString cppResult;

View File

@ -215,7 +215,11 @@ CutterPlugin *PluginManager::loadPythonPlugin(const char *moduleName)
}
PythonToCppFunc pythonToCpp = Shiboken::Conversions::isPythonToCppPointerConvertible(
# if QT_VERSION < QT_VERSION_CHECK(6, 2, 0)
reinterpret_cast<SbkObjectType *>(SbkCutterBindingsTypes[SBK_CUTTERPLUGIN_IDX]),
# else
reinterpret_cast<PyTypeObject **>(SbkCutterBindingsTypeStructs)[SBK_CUTTERPLUGIN_IDX],
# endif
pluginObject);
if (!pythonToCpp) {
qWarning() << "Plugin's create_cutter_plugin() function did not return an instance of "

View File

@ -0,0 +1,107 @@
import cutter
from PySide2.QtCore import Qt
from PySide2.QtWidgets import QVBoxLayout, QLabel, QWidget, QSizePolicy, QPushButton
class FortuneWidget(cutter.CutterDockWidget):
def __init__(self, parent):
super(FortuneWidget, self).__init__(parent)
self.setObjectName("FancyDockWidgetFromCoolPlugin")
self.setWindowTitle("Sample Python Plugin")
content = QWidget()
self.setWidget(content)
# Create layout and label
layout = QVBoxLayout(content)
content.setLayout(layout)
self.text = QLabel(content)
self.text.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.Preferred)
self.text.setFont(cutter.Configuration.instance().getFont())
layout.addWidget(self.text)
button = QPushButton(content)
button.setText("Want a fortune?")
button.setSizePolicy(QSizePolicy.Maximum, QSizePolicy.Maximum)
button.setMaximumHeight(50)
button.setMaximumWidth(200)
layout.addWidget(button)
layout.setAlignment(button, Qt.AlignHCenter)
button.clicked.connect(self.generate_fortune)
cutter.core().seekChanged.connect(self.generate_fortune)
self.show()
def generate_fortune(self):
fortune = cutter.cmd("fortune").replace("\n", "")
res = cutter.core().cmdRaw(f"?E {fortune}")
self.text.setText(res)
class CutterSamplePlugin(cutter.CutterPlugin):
name = "Sample Plugin"
description = "A sample plugin written in python."
version = "1.2"
author = "Cutter developers"
# Override CutterPlugin methods
def __init__(self):
super(CutterSamplePlugin, self).__init__()
self.disassembly_actions = []
self.addressable_item_actions = []
self.disas_action = None
self.addr_submenu = None
self.main = None
def setupPlugin(self):
pass
def setupInterface(self, main):
# Dock widget
widget = FortuneWidget(main)
main.addPluginDockWidget(widget)
# Dissassembly context menu
menu = main.getContextMenuExtensions(cutter.MainWindow.ContextMenuType.Disassembly)
self.disas_action = menu.addAction("CutterSamplePlugin dissassembly action")
self.disas_action.triggered.connect(self.handle_disassembler_action)
self.main = main
# Context menu for tables with addressable items like Flags,Functions,Strings,Search results,...
addressable_item_menu = main.getContextMenuExtensions(cutter.MainWindow.ContextMenuType.Addressable)
self.addr_submenu = addressable_item_menu.addMenu("CutterSamplePlugin") # create submenu
adrr_action = self.addr_submenu.addAction("Action 1")
self.addr_submenu.addSeparator() # can use separator and other qt functionality
adrr_action2 = self.addr_submenu.addAction("Action 2")
adrr_action.triggered.connect(self.handle_addressable_item_action)
adrr_action2.triggered.connect(self.handle_addressable_item_action)
def terminate(self): # optional
print("CutterSamplePlugin shutting down")
if self.main:
menu = self.main.getContextMenuExtensions(cutter.MainWindow.ContextMenuType.Disassembly)
menu.removeAction(self.disas_action)
addressable_item_menu = self.main.getContextMenuExtensions(cutter.MainWindow.ContextMenuType.Addressable)
submenu_action = self.addr_submenu.menuAction()
addressable_item_menu.removeAction(submenu_action)
print("CutterSamplePlugin finished clean up")
# Plugin methods
def handle_addressable_item_action(self):
# for actions in plugin menu Cutter sets data to current item address
submenu_action = self.addr_submenu.menuAction()
cutter.message("Context menu action callback 0x{:x}".format(submenu_action.data()))
def handle_disassembler_action(self):
# for actions in plugin menu Cutter sets data to address for current dissasembly line
cutter.message("Dissasembly menu action callback 0x{:x}".format(self.disas_action.data()))
# This function will be called by Cutter and should return an instance of the plugin.
def create_cutter_plugin():
return CutterSamplePlugin()

View File

@ -1,8 +1,8 @@
import cutter
from PySide2.QtCore import Qt
from PySide2.QtWidgets import QVBoxLayout, QLabel, QWidget, QSizePolicy, QPushButton
from PySide6.QtCore import Qt
from PySide6.QtWidgets import QVBoxLayout, QLabel, QWidget, QSizePolicy, QPushButton
class FortuneWidget(cutter.CutterDockWidget):
@ -19,7 +19,6 @@ class FortuneWidget(cutter.CutterDockWidget):
content.setLayout(layout)
self.text = QLabel(content)
self.text.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.Preferred)
self.text.setFont(cutter.Configuration.instance().getFont())
layout.addWidget(self.text)
button = QPushButton(content)