Python binding setup refactoring + cibuildwheel workflow (#2026)
* Python bindings: Make the test scripts handy for pytest * Python bindings: Update MANIFEST.in with new paths * Update .gitignore to exclude PyCharm-related files/folders * Python bindings: Update CMakeLists.txt in order to set CMAKE_OSX_ARCHITECTURES var * Python bindings: - Moved project package settings to the new TOML format - Refactored setup.py to cleanup/improve the code and make it ready for cibuildwheel - Updated README.md with the package long description part - Removed setup.cfg since universal wheel building will be deprecated soon * Python bindings: - Replaced old PyPI-publishing.yml workflow with brand-new one based on cibuildwheel - Removed old building scripts * Replaced macos-12 runner with macos-13 since it will be removed soon * Python bindings: Specify SYSTEM_VERSION_COMPAT=0 env var for macos-13 x86_64 runner as per cibuildwheel warning message * Python bindings: Enable i686 for debugging * Python bindings: Enable DEBUG flag according to the presence of tag release * Python bindings: Added matrix to cover i686 manylinux/musllinux builds * Python bindings: - Replaced macos-14 runner with macos-latest - Bumped cibuildwheel GitHub action to 2.21.3 version * Python bindings: - Adapt test_uc_ctl_tb_cache test to the recent changes - Fixed typos - PEP8 fixes * GitHub Action Workflow: Introduce BUILD_TYPE env var to select build type according to the presence of tag release --------- Co-authored-by: mio <mio@lazym.io>
This commit is contained in:
167
.github/workflows/PyPI-publishing.yml
vendored
167
.github/workflows/PyPI-publishing.yml
vendored
@@ -1,167 +0,0 @@
|
|||||||
name: PyPI 📦 Distribution
|
|
||||||
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
paths-ignore:
|
|
||||||
- ".gitignore"
|
|
||||||
- "docs/**"
|
|
||||||
- "README"
|
|
||||||
- "CREDITS.TXT"
|
|
||||||
- "COPYING_GLIB"
|
|
||||||
- "COPYING.LGPL2"
|
|
||||||
- "AUTHORS.TXT"
|
|
||||||
- "CHANGELOG"
|
|
||||||
- "COPYING"
|
|
||||||
pull_request:
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
build:
|
|
||||||
runs-on: ${{ matrix.config.os }}
|
|
||||||
name: ${{ matrix.config.name }}
|
|
||||||
strategy:
|
|
||||||
fail-fast: false
|
|
||||||
matrix:
|
|
||||||
config:
|
|
||||||
- {
|
|
||||||
os: windows-2019,
|
|
||||||
arch: x64,
|
|
||||||
python-ver: '3.8',
|
|
||||||
name: 'win_amd64'
|
|
||||||
}
|
|
||||||
- {
|
|
||||||
os: windows-2019,
|
|
||||||
arch: x32,
|
|
||||||
python-ver: '3.8',
|
|
||||||
name: 'win32'
|
|
||||||
}
|
|
||||||
- {
|
|
||||||
os: ubuntu-latest,
|
|
||||||
arch: x64,
|
|
||||||
python-ver: '3.8',
|
|
||||||
name: 'musllinux'
|
|
||||||
}
|
|
||||||
- {
|
|
||||||
os: ubuntu-latest,
|
|
||||||
arch: x64,
|
|
||||||
python-ver: '3.8',
|
|
||||||
name: 'manylinux2014_x86_64'
|
|
||||||
}
|
|
||||||
- {
|
|
||||||
os: ubuntu-latest,
|
|
||||||
arch: x32,
|
|
||||||
python-ver: '3.8',
|
|
||||||
name: 'manylinux2014_i686'
|
|
||||||
}
|
|
||||||
- {
|
|
||||||
os: ubuntu-latest,
|
|
||||||
arch: aarch64,
|
|
||||||
python-ver: '3.8',
|
|
||||||
name: 'manylinux2014_aarch64'
|
|
||||||
}
|
|
||||||
- {
|
|
||||||
os: ubuntu-latest,
|
|
||||||
arch: x64,
|
|
||||||
python-ver: '3.8',
|
|
||||||
name: 'sdist'
|
|
||||||
}
|
|
||||||
- {
|
|
||||||
os: macos-12,
|
|
||||||
arch: x86_64,
|
|
||||||
python-ver: '3.8',
|
|
||||||
name: 'macos_x86_64'
|
|
||||||
}
|
|
||||||
- {
|
|
||||||
os: macos-14,
|
|
||||||
arch: arm64,
|
|
||||||
python-ver: '3.10',
|
|
||||||
name: 'macos_arm64'
|
|
||||||
}
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v4
|
|
||||||
|
|
||||||
- name: '🛠️ Set up Python'
|
|
||||||
uses: actions/setup-python@v5
|
|
||||||
with:
|
|
||||||
python-version: ${{ matrix.config.python-ver }}
|
|
||||||
|
|
||||||
- name: '🛠️ Add msbuild to PATH'
|
|
||||||
if: contains(matrix.config.name, 'win')
|
|
||||||
uses: microsoft/setup-msbuild@v2
|
|
||||||
with:
|
|
||||||
vs-version: '16.5'
|
|
||||||
|
|
||||||
- name: '🛠️ Win MSVC 32 dev cmd setup'
|
|
||||||
if: contains(matrix.config.name, 'win32')
|
|
||||||
uses: ilammy/msvc-dev-cmd@v1
|
|
||||||
with:
|
|
||||||
arch: x86
|
|
||||||
|
|
||||||
- name: '🛠️ Win MSVC 64 dev cmd setup'
|
|
||||||
if: contains(matrix.config.name, 'win_amd64')
|
|
||||||
uses: ilammy/msvc-dev-cmd@v1
|
|
||||||
with:
|
|
||||||
arch: x64
|
|
||||||
|
|
||||||
- name: '🛠️ Win build dependencies'
|
|
||||||
if: contains(matrix.config.name, 'win')
|
|
||||||
shell: bash
|
|
||||||
run: |
|
|
||||||
choco install ninja cmake
|
|
||||||
|
|
||||||
- name: '🛠️ macOS dependencies'
|
|
||||||
if: contains(matrix.config.name, 'macos')
|
|
||||||
run: |
|
|
||||||
brew install ninja
|
|
||||||
|
|
||||||
- name: '🛠️ pip dependencies'
|
|
||||||
run: |
|
|
||||||
pip install --upgrade setuptools wheel
|
|
||||||
|
|
||||||
- name: '🚧 Build distribution'
|
|
||||||
shell: bash
|
|
||||||
run: |
|
|
||||||
if [ ${{ matrix.config.name }} == 'win32' ]; then
|
|
||||||
cd bindings/python && python setup.py build -p win32 sdist bdist_wheel -p win32
|
|
||||||
rm dist/*.tar.gz
|
|
||||||
elif [ ${{ matrix.config.name }} == 'manylinux2014_i686' ]; then
|
|
||||||
docker run --rm -v `pwd`/:/work dockcross/manylinux2014-x86 > ./dockcross
|
|
||||||
chmod +x ./dockcross
|
|
||||||
./dockcross bindings/python/build_wheel.sh
|
|
||||||
elif [ ${{ matrix.config.name }} == 'manylinux2014_aarch64' ]; then
|
|
||||||
docker run --rm -v `pwd`/:/work dockcross/manylinux2014-aarch64 > ./dockcross
|
|
||||||
chmod +x ./dockcross
|
|
||||||
./dockcross bindings/python/build_wheel.sh --plat-name manylinux2014_aarch64
|
|
||||||
elif [ ${{ matrix.config.name }} == 'manylinux2014_x86_64' ]; then
|
|
||||||
docker run --rm -v `pwd`/:/work dockcross/manylinux2014-x64 > ./dockcross
|
|
||||||
chmod +x ./dockcross
|
|
||||||
./dockcross bindings/python/build_wheel.sh
|
|
||||||
elif [ ${{ matrix.config.name }} == 'musllinux' ]; then
|
|
||||||
docker run --rm -v `pwd`:/work -w /work python:3.7-alpine sh /work/bindings/python/musl_wheel.sh
|
|
||||||
elif [ ${{ matrix.config.name }} == 'sdist' ]; then
|
|
||||||
cd bindings/python && python setup.py sdist
|
|
||||||
elif [ ${{ matrix.config.name }} == 'macos_arm64' ]; then
|
|
||||||
cd bindings/python && _PYTHON_HOST_PLATFORM="macosx-11.0-arm64" ARCHFLAGS="-arch arm64" python setup.py bdist_wheel
|
|
||||||
else
|
|
||||||
cd bindings/python && python setup.py bdist_wheel
|
|
||||||
fi
|
|
||||||
- name: '📤 Upload artifact'
|
|
||||||
uses: actions/upload-artifact@v4
|
|
||||||
with:
|
|
||||||
name: ${{ matrix.config.name }}
|
|
||||||
path: ${{ github.workspace }}/bindings/python/dist/*
|
|
||||||
|
|
||||||
publish:
|
|
||||||
needs: [build]
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
if: startsWith(github.ref, 'refs/tags')
|
|
||||||
steps:
|
|
||||||
- uses: actions/download-artifact@v4
|
|
||||||
with:
|
|
||||||
merge-multiple: true
|
|
||||||
path: dist
|
|
||||||
|
|
||||||
- name: '📦 Publish distribution to PyPI'
|
|
||||||
uses: pypa/gh-action-pypi-publish@release/v1
|
|
||||||
with:
|
|
||||||
user: __token__
|
|
||||||
password: ${{ secrets.pypi_pass }}
|
|
||||||
84
.github/workflows/build-uc2.yml
vendored
84
.github/workflows/build-uc2.yml
vendored
@@ -4,18 +4,19 @@ on:
|
|||||||
push:
|
push:
|
||||||
paths-ignore:
|
paths-ignore:
|
||||||
- ".gitignore"
|
- ".gitignore"
|
||||||
- "docs/**"
|
|
||||||
- "README"
|
|
||||||
- "CREDITS.TXT"
|
|
||||||
- "COPYING_GLIB"
|
|
||||||
- "COPYING.LGPL2"
|
|
||||||
- "AUTHORS.TXT"
|
- "AUTHORS.TXT"
|
||||||
- "CHANGELOG"
|
|
||||||
- "COPYING"
|
- "COPYING"
|
||||||
|
- "COPYING.LGPL2"
|
||||||
|
- "COPYING_GLIB"
|
||||||
|
- "CREDITS.TXT"
|
||||||
|
- "ChangeLog"
|
||||||
|
- "README.md"
|
||||||
|
- "docs/**"
|
||||||
pull_request:
|
pull_request:
|
||||||
|
|
||||||
env:
|
env:
|
||||||
CI: true
|
# Build Debug mode if not tag release
|
||||||
|
BUILD_TYPE: ${{ startsWith(github.ref, 'refs/tags') && 'Release' || 'Debug' }}
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
Windows:
|
Windows:
|
||||||
@@ -35,7 +36,6 @@ jobs:
|
|||||||
mingw: MINGW64,
|
mingw: MINGW64,
|
||||||
mingw-arch: x86_64,
|
mingw-arch: x86_64,
|
||||||
artifact: 'windows_mingw64-shared.7z',
|
artifact: 'windows_mingw64-shared.7z',
|
||||||
build_type: 'Debug',
|
|
||||||
archiver: '7z a',
|
archiver: '7z a',
|
||||||
generators: 'Ninja'
|
generators: 'Ninja'
|
||||||
}
|
}
|
||||||
@@ -49,7 +49,6 @@ jobs:
|
|||||||
mingw: MINGW64,
|
mingw: MINGW64,
|
||||||
mingw-arch: x86_64,
|
mingw-arch: x86_64,
|
||||||
artifact: 'windows_mingw64-static.7z',
|
artifact: 'windows_mingw64-static.7z',
|
||||||
build_type: 'Debug',
|
|
||||||
archiver: '7z a',
|
archiver: '7z a',
|
||||||
generators: 'Ninja'
|
generators: 'Ninja'
|
||||||
}
|
}
|
||||||
@@ -63,7 +62,6 @@ jobs:
|
|||||||
# mingw: MINGW32,
|
# mingw: MINGW32,
|
||||||
# mingw-arch: i686,
|
# mingw-arch: i686,
|
||||||
# artifact: 'windows_mingw32.7z',
|
# artifact: 'windows_mingw32.7z',
|
||||||
# build_type: 'Debug',
|
|
||||||
# archiver: '7z a',
|
# archiver: '7z a',
|
||||||
# generators: 'Ninja'
|
# generators: 'Ninja'
|
||||||
# }
|
# }
|
||||||
@@ -77,7 +75,6 @@ jobs:
|
|||||||
# mingw: MINGW32,
|
# mingw: MINGW32,
|
||||||
# mingw-arch: i686,
|
# mingw-arch: i686,
|
||||||
# artifact: 'windows_mingw32.7z',
|
# artifact: 'windows_mingw32.7z',
|
||||||
# build_type: 'Debug',
|
|
||||||
# archiver: '7z a',
|
# archiver: '7z a',
|
||||||
# generators: 'Ninja'
|
# generators: 'Ninja'
|
||||||
# }
|
# }
|
||||||
@@ -90,7 +87,6 @@ jobs:
|
|||||||
msvc-arch: x64,
|
msvc-arch: x64,
|
||||||
artifact: 'windows_msvc64_shared.7z',
|
artifact: 'windows_msvc64_shared.7z',
|
||||||
shared: 'yes',
|
shared: 'yes',
|
||||||
build_type: 'Debug',
|
|
||||||
archiver: '7z a',
|
archiver: '7z a',
|
||||||
generators: 'Visual Studio 16 2019'
|
generators: 'Visual Studio 16 2019'
|
||||||
}
|
}
|
||||||
@@ -103,7 +99,6 @@ jobs:
|
|||||||
msvc-arch: x86,
|
msvc-arch: x86,
|
||||||
artifact: 'windows_msvc32_shared.7z',
|
artifact: 'windows_msvc32_shared.7z',
|
||||||
shared: 'yes',
|
shared: 'yes',
|
||||||
build_type: 'Debug',
|
|
||||||
archiver: '7z a',
|
archiver: '7z a',
|
||||||
generators: 'Visual Studio 16 2019'
|
generators: 'Visual Studio 16 2019'
|
||||||
}
|
}
|
||||||
@@ -116,7 +111,6 @@ jobs:
|
|||||||
msvc-arch: x64,
|
msvc-arch: x64,
|
||||||
artifact: 'windows_msvc64_static.7z',
|
artifact: 'windows_msvc64_static.7z',
|
||||||
shared: 'no',
|
shared: 'no',
|
||||||
build_type: 'Debug',
|
|
||||||
archiver: '7z a',
|
archiver: '7z a',
|
||||||
generators: 'Visual Studio 16 2019'
|
generators: 'Visual Studio 16 2019'
|
||||||
}
|
}
|
||||||
@@ -129,7 +123,6 @@ jobs:
|
|||||||
msvc-arch: x86,
|
msvc-arch: x86,
|
||||||
artifact: 'windows_msvc32_static.7z',
|
artifact: 'windows_msvc32_static.7z',
|
||||||
shared: 'no',
|
shared: 'no',
|
||||||
build_type: 'Debug',
|
|
||||||
archiver: '7z a',
|
archiver: '7z a',
|
||||||
generators: 'Visual Studio 16 2019'
|
generators: 'Visual Studio 16 2019'
|
||||||
}
|
}
|
||||||
@@ -171,13 +164,13 @@ jobs:
|
|||||||
cmake \
|
cmake \
|
||||||
-S . \
|
-S . \
|
||||||
-B . \
|
-B . \
|
||||||
-DCMAKE_BUILD_TYPE=${{ matrix.config.build_type }} \
|
-DCMAKE_BUILD_TYPE=${{ env.BUILD_TYPE }} \
|
||||||
-G "${{ matrix.config.generators }}" \
|
-G "${{ matrix.config.generators }}" \
|
||||||
-DCMAKE_INSTALL_PREFIX:PATH=instdir \
|
-DCMAKE_INSTALL_PREFIX:PATH=instdir \
|
||||||
-DBUILD_SHARED_LIBS=${{ matrix.config.shared }}
|
-DBUILD_SHARED_LIBS=${{ matrix.config.shared }}
|
||||||
cmake --build . --config ${{ matrix.config.build_type }}
|
cmake --build . --config ${{ env.BUILD_TYPE }}
|
||||||
cmake --install . --strip --config ${{ matrix.config.build_type }}
|
cmake --install . --strip --config ${{ env.BUILD_TYPE }}
|
||||||
ctest -VV -C ${{ matrix.config.build_type }}
|
ctest -VV -C ${{ env.BUILD_TYPE }}
|
||||||
mv Debug instdir
|
mv Debug instdir
|
||||||
|
|
||||||
- name: '🛠️ Win MSVC 32 setup'
|
- name: '🛠️ Win MSVC 32 setup'
|
||||||
@@ -198,13 +191,13 @@ jobs:
|
|||||||
-S . \
|
-S . \
|
||||||
-B . \
|
-B . \
|
||||||
-A "win32" \
|
-A "win32" \
|
||||||
-DCMAKE_BUILD_TYPE=${{ matrix.config.build_type }} \
|
-DCMAKE_BUILD_TYPE=${{ env.BUILD_TYPE }} \
|
||||||
-G "${{ matrix.config.generators }}" \
|
-G "${{ matrix.config.generators }}" \
|
||||||
-DCMAKE_INSTALL_PREFIX:PATH=instdir \
|
-DCMAKE_INSTALL_PREFIX:PATH=instdir \
|
||||||
-DBUILD_SHARED_LIBS=${{ matrix.config.shared }}
|
-DBUILD_SHARED_LIBS=${{ matrix.config.shared }}
|
||||||
cmake --build . --config ${{ matrix.config.build_type }}
|
cmake --build . --config ${{ env.BUILD_TYPE }}
|
||||||
cmake --install . --strip --config ${{ matrix.config.build_type }}
|
cmake --install . --strip --config ${{ env.BUILD_TYPE }}
|
||||||
ctest -VV -C ${{ matrix.config.build_type }}
|
ctest -VV -C ${{ env.BUILD_TYPE }}
|
||||||
mv Debug instdir
|
mv Debug instdir
|
||||||
|
|
||||||
- name: '🚧 Win MINGW build'
|
- name: '🚧 Win MINGW build'
|
||||||
@@ -226,14 +219,14 @@ jobs:
|
|||||||
cmake \
|
cmake \
|
||||||
-S . \
|
-S . \
|
||||||
-B . \
|
-B . \
|
||||||
-DCMAKE_BUILD_TYPE=${{ matrix.config.build_type }} \
|
-DCMAKE_BUILD_TYPE=${{ env.BUILD_TYPE }} \
|
||||||
-G "${{ matrix.config.generators }}" \
|
-G "${{ matrix.config.generators }}" \
|
||||||
-DCMAKE_INSTALL_PREFIX:PATH=instdir \
|
-DCMAKE_INSTALL_PREFIX:PATH=instdir \
|
||||||
-DCMAKE_C_FLAGS:STRING="-static" \
|
-DCMAKE_C_FLAGS:STRING="-static" \
|
||||||
-DBUILD_SHARED_LIBS=${{ matrix.config.shared }}
|
-DBUILD_SHARED_LIBS=${{ matrix.config.shared }}
|
||||||
cmake --build . --config ${{ matrix.config.build_type }}
|
cmake --build . --config ${{ env.BUILD_TYPE }}
|
||||||
cmake --install . --strip
|
cmake --install . --strip
|
||||||
ctest -VV -C ${{ matrix.config.build_type }}
|
ctest -VV -C ${{ env.BUILD_TYPE }}
|
||||||
|
|
||||||
- name: '📦 Pack artifact'
|
- name: '📦 Pack artifact'
|
||||||
if: always()
|
if: always()
|
||||||
@@ -258,26 +251,24 @@ jobs:
|
|||||||
matrix:
|
matrix:
|
||||||
config:
|
config:
|
||||||
- {
|
- {
|
||||||
os: macos-12, # x64
|
os: macos-13, # x64
|
||||||
arch: x64,
|
arch: x64,
|
||||||
python-arch: x64,
|
python-arch: x64,
|
||||||
python-ver: '3.8',
|
python-ver: '3.8',
|
||||||
name: 'macos-x64 cmake shared',
|
name: 'macos-x64 cmake shared',
|
||||||
shared: 'yes',
|
shared: 'yes',
|
||||||
artifact: 'macos-x64-cmake-shared-x64.7z',
|
artifact: 'macos-x64-cmake-shared-x64.7z',
|
||||||
build_type: 'Debug',
|
|
||||||
archiver: '7za a',
|
archiver: '7za a',
|
||||||
generators: 'Ninja'
|
generators: 'Ninja'
|
||||||
}
|
}
|
||||||
- {
|
- {
|
||||||
os: macos-12,
|
os: macos-13,
|
||||||
arch: x64,
|
arch: x64,
|
||||||
python-arch: x64,
|
python-arch: x64,
|
||||||
python-ver: '3.8',
|
python-ver: '3.8',
|
||||||
name: 'macos-x64 cmake static',
|
name: 'macos-x64 cmake static',
|
||||||
shared: 'no',
|
shared: 'no',
|
||||||
artifact: 'macos-x64-cmake-static-x64.7z',
|
artifact: 'macos-x64-cmake-static-x64.7z',
|
||||||
build_type: 'Debug',
|
|
||||||
archiver: '7za a',
|
archiver: '7za a',
|
||||||
generators: 'Ninja'
|
generators: 'Ninja'
|
||||||
}
|
}
|
||||||
@@ -289,7 +280,6 @@ jobs:
|
|||||||
name: 'macos-arm64 cmake shared',
|
name: 'macos-arm64 cmake shared',
|
||||||
shared: 'yes',
|
shared: 'yes',
|
||||||
artifact: 'macos-arm64-cmake-shared-x64.7z',
|
artifact: 'macos-arm64-cmake-shared-x64.7z',
|
||||||
build_type: 'Debug',
|
|
||||||
archiver: '7za a',
|
archiver: '7za a',
|
||||||
generators: 'Ninja'
|
generators: 'Ninja'
|
||||||
}
|
}
|
||||||
@@ -301,18 +291,16 @@ jobs:
|
|||||||
name: 'macos-arm64 cmake static',
|
name: 'macos-arm64 cmake static',
|
||||||
shared: 'no',
|
shared: 'no',
|
||||||
artifact: 'macos-arm64-cmake-static-x64.7z',
|
artifact: 'macos-arm64-cmake-static-x64.7z',
|
||||||
build_type: 'Debug',
|
|
||||||
archiver: '7za a',
|
archiver: '7za a',
|
||||||
generators: 'Ninja'
|
generators: 'Ninja'
|
||||||
}
|
}
|
||||||
- {
|
- {
|
||||||
os: macos-12,
|
os: macos-13,
|
||||||
arch: x86_64,
|
arch: x86_64,
|
||||||
python-arch: x86_64,
|
python-arch: x86_64,
|
||||||
python-ver: '3.8',
|
python-ver: '3.8',
|
||||||
name: 'android cmake',
|
name: 'android cmake',
|
||||||
artifact: 'Android-x86_64.7z',
|
artifact: 'Android-x86_64.7z',
|
||||||
build_type: 'Debug',
|
|
||||||
archiver: '7za a',
|
archiver: '7za a',
|
||||||
generators: 'Ninja'
|
generators: 'Ninja'
|
||||||
}
|
}
|
||||||
@@ -337,13 +325,13 @@ jobs:
|
|||||||
cmake \
|
cmake \
|
||||||
-S . \
|
-S . \
|
||||||
-B . \
|
-B . \
|
||||||
-DCMAKE_BUILD_TYPE=${{ matrix.config.build_type }} \
|
-DCMAKE_BUILD_TYPE=${{ env.BUILD_TYPE }} \
|
||||||
-G "${{ matrix.config.generators }}" \
|
-G "${{ matrix.config.generators }}" \
|
||||||
-DCMAKE_INSTALL_PREFIX:PATH=instdir \
|
-DCMAKE_INSTALL_PREFIX:PATH=instdir \
|
||||||
-DBUILD_SHARED_LIBS=${{ matrix.config.shared }}
|
-DBUILD_SHARED_LIBS=${{ matrix.config.shared }}
|
||||||
cmake --build . --config ${{ matrix.config.build_type }}
|
cmake --build . --config ${{ env.BUILD_TYPE }}
|
||||||
cmake --install . --strip
|
cmake --install . --strip
|
||||||
ctest -VV -C ${{ matrix.config.build_type }}
|
ctest -VV -C ${{ env.BUILD_TYPE }}
|
||||||
|
|
||||||
# - name: Setup tmate session
|
# - name: Setup tmate session
|
||||||
# if: ${{ failure() }}
|
# if: ${{ failure() }}
|
||||||
@@ -364,10 +352,10 @@ jobs:
|
|||||||
-DOLP_SDK_BUILD_EXAMPLES=ON \
|
-DOLP_SDK_BUILD_EXAMPLES=ON \
|
||||||
-S . \
|
-S . \
|
||||||
-B . \
|
-B . \
|
||||||
-DCMAKE_BUILD_TYPE=${{ matrix.config.build_type }} \
|
-DCMAKE_BUILD_TYPE=${{ env.BUILD_TYPE }} \
|
||||||
-G "${{ matrix.config.generators }}" \
|
-G "${{ matrix.config.generators }}" \
|
||||||
-DCMAKE_INSTALL_PREFIX:PATH=instdir
|
-DCMAKE_INSTALL_PREFIX:PATH=instdir
|
||||||
cmake --build . --config ${{ matrix.config.build_type }}
|
cmake --build . --config ${{ env.BUILD_TYPE }}
|
||||||
cmake --install . --strip
|
cmake --install . --strip
|
||||||
|
|
||||||
- name: '🚧 AVD Cache'
|
- name: '🚧 AVD Cache'
|
||||||
@@ -436,7 +424,6 @@ jobs:
|
|||||||
name: 'ubuntu-x64 cmake shared',
|
name: 'ubuntu-x64 cmake shared',
|
||||||
shared: 'yes',
|
shared: 'yes',
|
||||||
artifact: 'ubuntu-cmake-shared-x64.7z',
|
artifact: 'ubuntu-cmake-shared-x64.7z',
|
||||||
build_type: 'Debug',
|
|
||||||
archiver: '7z a',
|
archiver: '7z a',
|
||||||
generators: 'Ninja'
|
generators: 'Ninja'
|
||||||
}
|
}
|
||||||
@@ -448,7 +435,6 @@ jobs:
|
|||||||
name: 'ubuntu-x86 cmake shared',
|
name: 'ubuntu-x86 cmake shared',
|
||||||
shared: 'yes',
|
shared: 'yes',
|
||||||
artifact: 'ubuntu-cmake-shared-x86.7z',
|
artifact: 'ubuntu-cmake-shared-x86.7z',
|
||||||
build_type: 'Debug',
|
|
||||||
archiver: '7z a',
|
archiver: '7z a',
|
||||||
generators: 'Ninja'
|
generators: 'Ninja'
|
||||||
}
|
}
|
||||||
@@ -460,7 +446,6 @@ jobs:
|
|||||||
name: 'ubuntu-x64 cmake static',
|
name: 'ubuntu-x64 cmake static',
|
||||||
shared: 'no',
|
shared: 'no',
|
||||||
artifact: 'ubuntu-cmake-static-x64.7z',
|
artifact: 'ubuntu-cmake-static-x64.7z',
|
||||||
build_type: 'Debug',
|
|
||||||
archiver: '7z a',
|
archiver: '7z a',
|
||||||
generators: 'Ninja'
|
generators: 'Ninja'
|
||||||
}
|
}
|
||||||
@@ -472,7 +457,6 @@ jobs:
|
|||||||
name: 'ubuntu-x86 cmake static',
|
name: 'ubuntu-x86 cmake static',
|
||||||
shared: 'no',
|
shared: 'no',
|
||||||
artifact: 'ubuntu-cmake-static-x86.7z',
|
artifact: 'ubuntu-cmake-static-x86.7z',
|
||||||
build_type: 'Debug',
|
|
||||||
archiver: '7z a',
|
archiver: '7z a',
|
||||||
generators: 'Ninja'
|
generators: 'Ninja'
|
||||||
}
|
}
|
||||||
@@ -483,7 +467,6 @@ jobs:
|
|||||||
python-ver: '3.8',
|
python-ver: '3.8',
|
||||||
name: 'ubuntu-aarch64 cmake',
|
name: 'ubuntu-aarch64 cmake',
|
||||||
artifact: 'ubuntu-cmake-aarch64.7z',
|
artifact: 'ubuntu-cmake-aarch64.7z',
|
||||||
build_type: 'Debug',
|
|
||||||
archiver: '7z a',
|
archiver: '7z a',
|
||||||
generators: 'Ninja',
|
generators: 'Ninja',
|
||||||
distro: ubuntu20.04
|
distro: ubuntu20.04
|
||||||
@@ -495,7 +478,6 @@ jobs:
|
|||||||
python-ver: '3.8',
|
python-ver: '3.8',
|
||||||
name: 'ubuntu-ppc64le cmake',
|
name: 'ubuntu-ppc64le cmake',
|
||||||
artifact: 'ubuntu-cmake-ppc64le.7z',
|
artifact: 'ubuntu-cmake-ppc64le.7z',
|
||||||
build_type: 'Debug',
|
|
||||||
archiver: '7z a',
|
archiver: '7z a',
|
||||||
generators: 'Ninja',
|
generators: 'Ninja',
|
||||||
distro: ubuntu20.04
|
distro: ubuntu20.04
|
||||||
@@ -526,13 +508,13 @@ jobs:
|
|||||||
cmake \
|
cmake \
|
||||||
-S . \
|
-S . \
|
||||||
-B . \
|
-B . \
|
||||||
-DCMAKE_BUILD_TYPE=${{ matrix.config.build_type }} \
|
-DCMAKE_BUILD_TYPE=${{ env.BUILD_TYPE }} \
|
||||||
-G "${{ matrix.config.generators }}" \
|
-G "${{ matrix.config.generators }}" \
|
||||||
-DCMAKE_INSTALL_PREFIX:PATH=instdir \
|
-DCMAKE_INSTALL_PREFIX:PATH=instdir \
|
||||||
-DBUILD_SHARED_LIBS=${{ matrix.config.shared }}
|
-DBUILD_SHARED_LIBS=${{ matrix.config.shared }}
|
||||||
cmake --build . --config ${{ matrix.config.build_type }}
|
cmake --build . --config ${{ env.BUILD_TYPE }}
|
||||||
cmake --install . --strip
|
cmake --install . --strip
|
||||||
ctest -VV -C ${{ matrix.config.build_type }}
|
ctest -VV -C ${{ env.BUILD_TYPE }}
|
||||||
|
|
||||||
- name: '🚧 Linux ppc64le/aarch64 build'
|
- name: '🚧 Linux ppc64le/aarch64 build'
|
||||||
if: contains(matrix.config.arch, 'ppc64le') || contains(matrix.config.arch, 'aarch64')
|
if: contains(matrix.config.arch, 'ppc64le') || contains(matrix.config.arch, 'aarch64')
|
||||||
@@ -553,12 +535,12 @@ jobs:
|
|||||||
cmake \
|
cmake \
|
||||||
-S . \
|
-S . \
|
||||||
-B . \
|
-B . \
|
||||||
-DCMAKE_BUILD_TYPE=${{ matrix.config.build_type }} \
|
-DCMAKE_BUILD_TYPE=${{ env.BUILD_TYPE }} \
|
||||||
-G "${{ matrix.config.generators }}" \
|
-G "${{ matrix.config.generators }}" \
|
||||||
-DCMAKE_INSTALL_PREFIX:PATH=/instdir
|
-DCMAKE_INSTALL_PREFIX:PATH=/instdir
|
||||||
cmake --build . --config ${{ matrix.config.build_type }}
|
cmake --build . --config ${{ env.BUILD_TYPE }}
|
||||||
cmake --install . --strip
|
cmake --install . --strip
|
||||||
ctest -VV -C ${{ matrix.config.build_type }}
|
ctest -VV -C ${{ env.BUILD_TYPE }}
|
||||||
|
|
||||||
- name: '📦 Pack artifact'
|
- name: '📦 Pack artifact'
|
||||||
if: always()
|
if: always()
|
||||||
|
|||||||
360
.github/workflows/build-wheels-publish.yml
vendored
Normal file
360
.github/workflows/build-wheels-publish.yml
vendored
Normal file
@@ -0,0 +1,360 @@
|
|||||||
|
name: Build wheels with cibuildwheel
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
paths-ignore:
|
||||||
|
- ".gitignore"
|
||||||
|
- "AUTHORS.TXT"
|
||||||
|
- "COPYING"
|
||||||
|
- "COPYING.LGPL2"
|
||||||
|
- "COPYING_GLIB"
|
||||||
|
- "CREDITS.TXT"
|
||||||
|
- "ChangeLog"
|
||||||
|
- "README.md"
|
||||||
|
- "docs/**"
|
||||||
|
pull_request:
|
||||||
|
|
||||||
|
env:
|
||||||
|
# Enable DEBUG flag if not tag release
|
||||||
|
UNICORN_DEBUG: ${{ startsWith(github.ref, 'refs/tags') && '0' || '1' }}
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
# job to be executed for every push - testing purpose
|
||||||
|
build_wheels_python38_only:
|
||||||
|
name: Building on ${{ matrix.os }} - ${{ matrix.arch }} ${{ matrix.cibw_build }}
|
||||||
|
runs-on: ${{ matrix.os }}
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
include:
|
||||||
|
# NOTE: aarch64 builds are super slow due to QEMU emulation. Making this to parallelize and speed up workflow
|
||||||
|
# i686 - manylinux
|
||||||
|
- { os: ubuntu-latest, arch: i686, cibw_build: 'cp38-manylinux' }
|
||||||
|
# i686 - musllinux
|
||||||
|
- { os: ubuntu-latest, arch: i686, cibw_build: 'cp38-musllinux' }
|
||||||
|
# x86_64 - manylinux
|
||||||
|
- { os: ubuntu-latest, arch: x86_64, cibw_build: 'cp38-manylinux' }
|
||||||
|
# x86_64 - musllinux
|
||||||
|
- { os: ubuntu-latest, arch: x86_64, cibw_build: 'cp38-musllinux' }
|
||||||
|
# aarch64 - manylinux
|
||||||
|
- { os: ubuntu-latest, arch: aarch64, cibw_build: 'cp38-manylinux' }
|
||||||
|
# aarch64 - musllinux
|
||||||
|
- { os: ubuntu-latest, arch: aarch64, cibw_build: 'cp38-musllinux' }
|
||||||
|
- { os: macos-13, arch: x86_64, cibw_build: '' }
|
||||||
|
- { os: macos-latest, arch: arm64, cibw_build: '' }
|
||||||
|
- { os: windows-2019, arch: AMD64, cibw_build: '' }
|
||||||
|
- { os: windows-2019, arch: x86, cibw_build: '' }
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: '🛠️ Add msbuild to PATH'
|
||||||
|
if: runner.os == 'Windows'
|
||||||
|
uses: microsoft/setup-msbuild@v2
|
||||||
|
with:
|
||||||
|
vs-version: '16.5'
|
||||||
|
|
||||||
|
- name: '🛠️ Win build dependencies'
|
||||||
|
if: runner.os == 'Windows'
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
choco install ninja cmake
|
||||||
|
|
||||||
|
- name: '🛠️ macOS dependencies'
|
||||||
|
if: runner.os == 'macOS'
|
||||||
|
run: |
|
||||||
|
brew install ninja
|
||||||
|
|
||||||
|
# https://cibuildwheel.pypa.io/en/stable/faq/#macos-building-cpython-38-wheels-on-arm64
|
||||||
|
- uses: actions/setup-python@v5
|
||||||
|
if: runner.os == 'macOS' && runner.arch == 'ARM64'
|
||||||
|
with:
|
||||||
|
python-version: 3.8
|
||||||
|
|
||||||
|
- name: '🛠️ Win MSVC 32 dev cmd setup'
|
||||||
|
if: runner.os == 'Windows' && matrix.arch == 'x86'
|
||||||
|
uses: ilammy/msvc-dev-cmd@v1
|
||||||
|
with:
|
||||||
|
arch: x86
|
||||||
|
|
||||||
|
- name: '🛠️ Win MSVC 64 dev cmd setup'
|
||||||
|
if: runner.os == 'Windows' && matrix.arch == 'AMD64'
|
||||||
|
uses: ilammy/msvc-dev-cmd@v1
|
||||||
|
with:
|
||||||
|
arch: x64
|
||||||
|
|
||||||
|
- name: '🛠️ Set up QEMU'
|
||||||
|
if: runner.os == 'Linux'
|
||||||
|
uses: docker/setup-qemu-action@v3
|
||||||
|
|
||||||
|
- name: '🚧 cibuildwheel run - Linux'
|
||||||
|
if: matrix.os == 'ubuntu-latest'
|
||||||
|
uses: pypa/cibuildwheel@v2.21.3
|
||||||
|
env:
|
||||||
|
CIBW_BUILD_FRONTEND: build
|
||||||
|
CIBW_BUILD: ${{ matrix.cibw_build }}*
|
||||||
|
CIBW_ARCHS: ${{ matrix.arch }}
|
||||||
|
CIBW_ENVIRONMENT: DEBUG=${{ env.UNICORN_DEBUG }}
|
||||||
|
CIBW_ENVIRONMENT_PASS_LINUX: DEBUG
|
||||||
|
CIBW_TEST_REQUIRES: pytest
|
||||||
|
CIBW_TEST_COMMAND: pytest {package}/tests
|
||||||
|
with:
|
||||||
|
package-dir: bindings/python
|
||||||
|
output-dir: wheelhouse
|
||||||
|
|
||||||
|
- name: '🚧 cibuildwheel run - Windows'
|
||||||
|
if: matrix.os == 'windows-2019'
|
||||||
|
uses: pypa/cibuildwheel@v2.21.3
|
||||||
|
env:
|
||||||
|
CIBW_BUILD_FRONTEND: build
|
||||||
|
CIBW_BUILD: 'cp38*'
|
||||||
|
CIBW_ARCHS: ${{ matrix.arch }}
|
||||||
|
CIBW_ENVIRONMENT: DEBUG=${{ env.UNICORN_DEBUG }}
|
||||||
|
CIBW_TEST_REQUIRES: pytest
|
||||||
|
CIBW_TEST_COMMAND: pytest {package}/tests
|
||||||
|
with:
|
||||||
|
package-dir: bindings/python
|
||||||
|
output-dir: wheelhouse
|
||||||
|
|
||||||
|
- name: '🚧 cibuildwheel run - MacOS x86_84'
|
||||||
|
if: matrix.os == 'macos-13'
|
||||||
|
uses: pypa/cibuildwheel@v2.21.3
|
||||||
|
env:
|
||||||
|
CIBW_BUILD_FRONTEND: build
|
||||||
|
CIBW_BUILD: 'cp38*'
|
||||||
|
CIBW_ENVIRONMENT: SYSTEM_VERSION_COMPAT=0 DEBUG=${{ env.UNICORN_DEBUG }}
|
||||||
|
CIBW_TEST_REQUIRES: pytest
|
||||||
|
CIBW_TEST_COMMAND: pytest {package}/tests
|
||||||
|
with:
|
||||||
|
package-dir: bindings/python
|
||||||
|
output-dir: wheelhouse
|
||||||
|
|
||||||
|
- name: '🚧 cibuildwheel run - MacOS arm64'
|
||||||
|
if: matrix.os == 'macos-latest'
|
||||||
|
uses: pypa/cibuildwheel@v2.21.3
|
||||||
|
env:
|
||||||
|
CIBW_BUILD_FRONTEND: build
|
||||||
|
CIBW_BUILD: 'cp38*'
|
||||||
|
CIBW_ENVIRONMENT: DEBUG=${{ env.UNICORN_DEBUG }}
|
||||||
|
CIBW_TEST_REQUIRES: pytest
|
||||||
|
CIBW_TEST_COMMAND: pytest {package}/tests
|
||||||
|
# https://github.com/pypa/cibuildwheel/pull/1169
|
||||||
|
CIBW_TEST_SKIP: "cp38-macosx_*:arm64"
|
||||||
|
with:
|
||||||
|
package-dir: bindings/python
|
||||||
|
output-dir: wheelhouse
|
||||||
|
|
||||||
|
# we re-tag cp38 wheel (just an old one) with py2 tag. Hacky but it works...
|
||||||
|
- name: '🚧 Python 2.7 wheels re-tagging - Windows'
|
||||||
|
if: matrix.os == 'windows-2019'
|
||||||
|
run: |
|
||||||
|
python -m pip install -U pip wheel && Get-ChildItem -Path wheelhouse/ -Filter *cp38*.whl | Foreach-Object {
|
||||||
|
python -m wheel tags --python-tag='py2' --abi-tag=none $_.FullName
|
||||||
|
}
|
||||||
|
- name: '🚧 Python 2.7 wheels re-tagging - Non-Windows'
|
||||||
|
if: matrix.os != 'windows-2019'
|
||||||
|
env:
|
||||||
|
PIP_BREAK_SYSTEM_PACKAGES: 1
|
||||||
|
run: |
|
||||||
|
python3 -m pip install -U pip wheel && python3 -m wheel tags --python-tag='py2' --abi-tag=none wheelhouse/*cp38*.whl
|
||||||
|
|
||||||
|
- uses: actions/upload-artifact@v4
|
||||||
|
with:
|
||||||
|
name: cibw-wheels-${{ matrix.os }}-${{ strategy.job-index }}
|
||||||
|
path: ./wheelhouse/*.whl
|
||||||
|
|
||||||
|
# Job to be executed to build all wheels for all platforms/architectures/python versions only for tag release
|
||||||
|
build_wheels_all_versions:
|
||||||
|
name: Building on ${{ matrix.os }} - ${{ matrix.arch }} ${{ matrix.cibw_build }}
|
||||||
|
runs-on: ${{ matrix.os }}
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
include:
|
||||||
|
# NOTE: aarch64 builds are super slow due to QEMU emulation. Making this to parallelize and speed up workflow
|
||||||
|
# i686 - manylinux
|
||||||
|
- { os: ubuntu-latest, arch: i686, cibw_build: 'cp37-manylinux' }
|
||||||
|
- { os: ubuntu-latest, arch: i686, cibw_build: 'cp39-manylinux' }
|
||||||
|
- { os: ubuntu-latest, arch: i686, cibw_build: 'cp310-manylinux' }
|
||||||
|
- { os: ubuntu-latest, arch: i686, cibw_build: 'cp311-manylinux' }
|
||||||
|
- { os: ubuntu-latest, arch: i686, cibw_build: 'cp312-manylinux' }
|
||||||
|
- { os: ubuntu-latest, arch: i686, cibw_build: 'cp313-manylinux' }
|
||||||
|
# i686 - musllinux
|
||||||
|
- { os: ubuntu-latest, arch: i686, cibw_build: 'cp37-musllinux' }
|
||||||
|
- { os: ubuntu-latest, arch: i686, cibw_build: 'cp39-musllinux' }
|
||||||
|
- { os: ubuntu-latest, arch: i686, cibw_build: 'cp310-musllinux' }
|
||||||
|
- { os: ubuntu-latest, arch: i686, cibw_build: 'cp311-musllinux' }
|
||||||
|
- { os: ubuntu-latest, arch: i686, cibw_build: 'cp312-musllinux' }
|
||||||
|
- { os: ubuntu-latest, arch: i686, cibw_build: 'cp313-musllinux' }
|
||||||
|
# x86_64 - manylinux
|
||||||
|
- { os: ubuntu-latest, arch: x86_64, cibw_build: 'cp37-manylinux' }
|
||||||
|
- { os: ubuntu-latest, arch: x86_64, cibw_build: 'cp39-manylinux' }
|
||||||
|
- { os: ubuntu-latest, arch: x86_64, cibw_build: 'cp310-manylinux' }
|
||||||
|
- { os: ubuntu-latest, arch: x86_64, cibw_build: 'cp311-manylinux' }
|
||||||
|
- { os: ubuntu-latest, arch: x86_64, cibw_build: 'cp312-manylinux' }
|
||||||
|
- { os: ubuntu-latest, arch: x86_64, cibw_build: 'cp313-manylinux' }
|
||||||
|
# x86_64 - musllinux
|
||||||
|
- { os: ubuntu-latest, arch: x86_64, cibw_build: 'cp37-musllinux' }
|
||||||
|
- { os: ubuntu-latest, arch: x86_64, cibw_build: 'cp39-musllinux' }
|
||||||
|
- { os: ubuntu-latest, arch: x86_64, cibw_build: 'cp310-musllinux' }
|
||||||
|
- { os: ubuntu-latest, arch: x86_64, cibw_build: 'cp311-musllinux' }
|
||||||
|
- { os: ubuntu-latest, arch: x86_64, cibw_build: 'cp312-musllinux' }
|
||||||
|
- { os: ubuntu-latest, arch: x86_64, cibw_build: 'cp313-musllinux' }
|
||||||
|
# aarch64 - manylinux
|
||||||
|
- { os: ubuntu-latest, arch: aarch64, cibw_build: 'cp37-manylinux' }
|
||||||
|
- { os: ubuntu-latest, arch: aarch64, cibw_build: 'cp39-manylinux' }
|
||||||
|
- { os: ubuntu-latest, arch: aarch64, cibw_build: 'cp310-manylinux' }
|
||||||
|
- { os: ubuntu-latest, arch: aarch64, cibw_build: 'cp311-manylinux' }
|
||||||
|
- { os: ubuntu-latest, arch: aarch64, cibw_build: 'cp312-manylinux' }
|
||||||
|
- { os: ubuntu-latest, arch: aarch64, cibw_build: 'cp313-manylinux' }
|
||||||
|
# aarch64 - musllinux
|
||||||
|
- { os: ubuntu-latest, arch: aarch64, cibw_build: 'cp37-musllinux' }
|
||||||
|
- { os: ubuntu-latest, arch: aarch64, cibw_build: 'cp39-musllinux' }
|
||||||
|
- { os: ubuntu-latest, arch: aarch64, cibw_build: 'cp310-musllinux' }
|
||||||
|
- { os: ubuntu-latest, arch: aarch64, cibw_build: 'cp311-musllinux' }
|
||||||
|
- { os: ubuntu-latest, arch: aarch64, cibw_build: 'cp312-musllinux' }
|
||||||
|
- { os: ubuntu-latest, arch: aarch64, cibw_build: 'cp313-musllinux' }
|
||||||
|
- { os: macos-13, arch: x86_64, cibw_build: '' }
|
||||||
|
- { os: macos-latest, arch: arm64, cibw_build: '' }
|
||||||
|
- { os: windows-2019, arch: AMD64, cibw_build: '' }
|
||||||
|
- { os: windows-2019, arch: x86, cibw_build: '' }
|
||||||
|
if: startsWith(github.ref, 'refs/tags')
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: '🛠️ Add msbuild to PATH'
|
||||||
|
if: runner.os == 'Windows'
|
||||||
|
uses: microsoft/setup-msbuild@v2
|
||||||
|
with:
|
||||||
|
vs-version: '16.5'
|
||||||
|
|
||||||
|
- name: '🛠️ Win build dependencies'
|
||||||
|
if: runner.os == 'Windows'
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
choco install ninja cmake
|
||||||
|
|
||||||
|
- name: '🛠️ macOS dependencies'
|
||||||
|
if: runner.os == 'macOS'
|
||||||
|
run: |
|
||||||
|
brew install ninja
|
||||||
|
|
||||||
|
- name: '🛠️ Win MSVC 32 dev cmd setup'
|
||||||
|
if: runner.os == 'Windows' && matrix.arch == 'x86'
|
||||||
|
uses: ilammy/msvc-dev-cmd@v1
|
||||||
|
with:
|
||||||
|
arch: x86
|
||||||
|
|
||||||
|
- name: '🛠️ Win MSVC 64 dev cmd setup'
|
||||||
|
if: runner.os == 'Windows' && matrix.arch == 'AMD64'
|
||||||
|
uses: ilammy/msvc-dev-cmd@v1
|
||||||
|
with:
|
||||||
|
arch: x64
|
||||||
|
|
||||||
|
- name: '🛠️ Set up QEMU'
|
||||||
|
if: runner.os == 'Linux'
|
||||||
|
uses: docker/setup-qemu-action@v3
|
||||||
|
|
||||||
|
- name: '🚧 cibuildwheel run - Linux'
|
||||||
|
if: matrix.os == 'ubuntu-latest'
|
||||||
|
uses: pypa/cibuildwheel@v2.21.3
|
||||||
|
env:
|
||||||
|
CIBW_BUILD_FRONTEND: build
|
||||||
|
CIBW_BUILD: ${{ matrix.cibw_build }}*
|
||||||
|
CIBW_ARCHS: ${{ matrix.arch }}
|
||||||
|
CIBW_ENVIRONMENT: DEBUG=${{ env.UNICORN_DEBUG }}
|
||||||
|
CIBW_ENVIRONMENT_PASS_LINUX: DEBUG
|
||||||
|
CIBW_TEST_REQUIRES: pytest
|
||||||
|
CIBW_TEST_COMMAND: pytest {package}/tests
|
||||||
|
with:
|
||||||
|
package-dir: bindings/python
|
||||||
|
output-dir: wheelhouse
|
||||||
|
|
||||||
|
- name: '🚧 cibuildwheel run - Windows'
|
||||||
|
if: matrix.os == 'windows-2019'
|
||||||
|
uses: pypa/cibuildwheel@v2.21.3
|
||||||
|
env:
|
||||||
|
CIBW_BUILD_FRONTEND: build
|
||||||
|
CIBW_SKIP: '*36* *38*'
|
||||||
|
CIBW_BUILD: 'cp*'
|
||||||
|
CIBW_ENVIRONMENT: DEBUG=${{ env.UNICORN_DEBUG }}
|
||||||
|
CIBW_ARCHS: ${{ matrix.arch }}
|
||||||
|
CIBW_TEST_REQUIRES: pytest
|
||||||
|
CIBW_TEST_COMMAND: pytest {package}/tests
|
||||||
|
with:
|
||||||
|
package-dir: bindings/python
|
||||||
|
output-dir: wheelhouse
|
||||||
|
|
||||||
|
- name: '🚧 cibuildwheel run - MacOS x86_84'
|
||||||
|
if: matrix.os == 'macos-13'
|
||||||
|
uses: pypa/cibuildwheel@v2.21.3
|
||||||
|
env:
|
||||||
|
CIBW_BUILD_FRONTEND: build
|
||||||
|
CIBW_SKIP: '*36* *38*'
|
||||||
|
CIBW_BUILD: 'cp*'
|
||||||
|
CIBW_ENVIRONMENT: DEBUG=${{ env.UNICORN_DEBUG }}
|
||||||
|
CIBW_TEST_REQUIRES: pytest
|
||||||
|
CIBW_TEST_COMMAND: pytest {package}/tests
|
||||||
|
with:
|
||||||
|
package-dir: bindings/python
|
||||||
|
output-dir: wheelhouse
|
||||||
|
|
||||||
|
- name: '🚧 cibuildwheel run - MacOS arm64'
|
||||||
|
if: matrix.os == 'macos-latest'
|
||||||
|
uses: pypa/cibuildwheel@v2.21.3
|
||||||
|
env:
|
||||||
|
CIBW_BUILD_FRONTEND: build
|
||||||
|
CIBW_SKIP: '*36* *37* *38*'
|
||||||
|
CIBW_BUILD: 'cp*'
|
||||||
|
CIBW_ENVIRONMENT: DEBUG=${{ env.UNICORN_DEBUG }}
|
||||||
|
CIBW_TEST_REQUIRES: pytest
|
||||||
|
CIBW_TEST_COMMAND: pytest {package}/tests
|
||||||
|
with:
|
||||||
|
package-dir: bindings/python
|
||||||
|
output-dir: wheelhouse
|
||||||
|
|
||||||
|
- uses: actions/upload-artifact@v4
|
||||||
|
with:
|
||||||
|
name: cibw-wheels-${{ matrix.os }}-${{ strategy.job-index }}
|
||||||
|
path: ./wheelhouse/*.whl
|
||||||
|
|
||||||
|
make_sdist:
|
||||||
|
name: Make SDist
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
fetch-depth: 0 # Optional, use if you use setuptools_scm
|
||||||
|
submodules: true # Optional, use if you have submodules
|
||||||
|
|
||||||
|
- name: Build SDist
|
||||||
|
run: |
|
||||||
|
cd bindings/python
|
||||||
|
python3 -m pip install -U pip build
|
||||||
|
python3 -m build --sdist
|
||||||
|
|
||||||
|
- uses: actions/upload-artifact@v4
|
||||||
|
with:
|
||||||
|
path: bindings/python/dist/*.tar.gz
|
||||||
|
|
||||||
|
publish:
|
||||||
|
needs: [ build_wheels_python38_only, build_wheels_all_versions, make_sdist ]
|
||||||
|
environment: pypi
|
||||||
|
permissions:
|
||||||
|
id-token: write
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
if: startsWith(github.ref, 'refs/tags')
|
||||||
|
steps:
|
||||||
|
- uses: actions/download-artifact@v4
|
||||||
|
with:
|
||||||
|
merge-multiple: true
|
||||||
|
path: dist
|
||||||
|
|
||||||
|
- name: Show downloaded artifacts
|
||||||
|
run: ls -laR dist
|
||||||
|
|
||||||
|
- name: '📦 Publish distribution to PyPI'
|
||||||
|
uses: pypa/gh-action-pypi-publish@release/v1
|
||||||
|
with:
|
||||||
|
user: __token__
|
||||||
|
password: ${{ secrets.pypi_pass }}
|
||||||
6
.gitignore
vendored
6
.gitignore
vendored
@@ -91,3 +91,9 @@ cmocka/
|
|||||||
zig-cache/
|
zig-cache/
|
||||||
zig-out/
|
zig-out/
|
||||||
.cache
|
.cache
|
||||||
|
|
||||||
|
##################
|
||||||
|
## PyCharm Project
|
||||||
|
##################
|
||||||
|
|
||||||
|
.idea/
|
||||||
|
|||||||
@@ -30,6 +30,24 @@ if(APPLE AND NOT CMAKE_C_COMPILER)
|
|||||||
set(CMAKE_C_COMPILER "/usr/bin/cc")
|
set(CMAKE_C_COMPILER "/usr/bin/cc")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
# Source: https://github.com/capstone-engine/capstone/blob/next/CMakeLists.txt
|
||||||
|
# If building for OSX it's best to allow CMake to handle building both architectures
|
||||||
|
if(APPLE)
|
||||||
|
# The cibuildwheel on Github Actions sets this env variable
|
||||||
|
# with the architecture flags it wants to build for.
|
||||||
|
if(DEFINED ENV{ARCHFLAGS})
|
||||||
|
if("$ENV{ARCHFLAGS}" STREQUAL "-arch arm64 -arch x86_64")
|
||||||
|
set(CMAKE_OSX_ARCHITECTURES "x86_64;arm64")
|
||||||
|
elseif("$ENV{ARCHFLAGS}" STREQUAL "-arch arm64")
|
||||||
|
set(CMAKE_OSX_ARCHITECTURES "arm64")
|
||||||
|
elseif("$ENV{ARCHFLAGS}" STREQUAL "-arch x86_64")
|
||||||
|
set(CMAKE_OSX_ARCHITECTURES "x86_64")
|
||||||
|
endif()
|
||||||
|
else()
|
||||||
|
set(CMAKE_OSX_ARCHITECTURES "x86_64;arm64")
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
|
||||||
# Detect if unicorn is compiled as the top-level project
|
# Detect if unicorn is compiled as the top-level project
|
||||||
set(PROJECT_IS_TOP_LEVEL OFF)
|
set(PROJECT_IS_TOP_LEVEL OFF)
|
||||||
if(CMAKE_CURRENT_SOURCE_DIR STREQUAL CMAKE_SOURCE_DIR)
|
if(CMAKE_CURRENT_SOURCE_DIR STREQUAL CMAKE_SOURCE_DIR)
|
||||||
|
|||||||
@@ -1,4 +1,9 @@
|
|||||||
recursive-include src *
|
recursive-include src *
|
||||||
recursive-include prebuilt *
|
recursive-include prebuilt *
|
||||||
include LICENSE.TXT
|
graft unicorn/lib
|
||||||
include README.TXT
|
graft unicorn/include
|
||||||
|
global-include *.a
|
||||||
|
global-include *.so.2
|
||||||
|
global-include *.*lib
|
||||||
|
global-include *.dll
|
||||||
|
global-include *.h
|
||||||
|
|||||||
@@ -1,3 +1,21 @@
|
|||||||
|
# Unicorn
|
||||||
|
|
||||||
|
Unicorn is a lightweight, multi-platform, multi-architecture CPU emulator framework
|
||||||
|
based on [QEMU](http://qemu.org).
|
||||||
|
|
||||||
|
Unicorn offers some unparalleled features:
|
||||||
|
|
||||||
|
- Multi-architecture: ARM, ARM64 (ARMv8), M68K, MIPS, PowerPC, RISCV, SPARC, S390X, TriCore and X86 (16, 32, 64-bit)
|
||||||
|
- Clean/simple/lightweight/intuitive architecture-neutral API
|
||||||
|
- Implemented in pure C language, with bindings for Crystal, Clojure, Visual Basic, Perl, Rust, Ruby, Python, Java, .NET, Go, Delphi/Free Pascal, Haskell, Pharo, and Lua.
|
||||||
|
- Native support for Windows & *nix (with Mac OSX, Linux, *BSD & Solaris confirmed)
|
||||||
|
- High performance via Just-In-Time compilation
|
||||||
|
- Support for fine-grained instrumentation at various levels
|
||||||
|
- Thread-safety by design
|
||||||
|
- Distributed under free software license GPLv2
|
||||||
|
|
||||||
|
Further information is available at http://www.unicorn-engine.org
|
||||||
|
|
||||||
# Python Bindings for Unicorn
|
# Python Bindings for Unicorn
|
||||||
|
|
||||||
Originally written by Nguyen Anh Quynh, polished and redesigned by elicn, maintained by all community contributors.
|
Originally written by Nguyen Anh Quynh, polished and redesigned by elicn, maintained by all community contributors.
|
||||||
|
|||||||
@@ -1,15 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
set -e -x
|
|
||||||
|
|
||||||
cd bindings/python
|
|
||||||
|
|
||||||
# Compile wheels
|
|
||||||
python3.7 setup.py bdist_wheel $@
|
|
||||||
cd dist
|
|
||||||
|
|
||||||
# We can't repair an aarch64 wheel on x64 hosts
|
|
||||||
# https://github.com/pypa/auditwheel/issues/244
|
|
||||||
if [[ ! "$*" =~ "aarch64" ]];then
|
|
||||||
auditwheel repair *.whl
|
|
||||||
mv -f wheelhouse/*.whl .
|
|
||||||
fi
|
|
||||||
@@ -1,9 +0,0 @@
|
|||||||
#!/bin/sh
|
|
||||||
|
|
||||||
# TODO: use cibuildwheel
|
|
||||||
apk update
|
|
||||||
apk add gcc make cmake pkgconfig linux-headers git musl-dev patchelf
|
|
||||||
|
|
||||||
python3 -m pip install -U pip setuptools auditwheel
|
|
||||||
|
|
||||||
cd bindings/python && python3 setup.py bdist_wheel && auditwheel repair dist/*.whl && mv -f wheelhouse/*.whl ./dist/
|
|
||||||
40
bindings/python/pyproject.toml
Normal file
40
bindings/python/pyproject.toml
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
[build-system]
|
||||||
|
requires = ["setuptools", "build", "wheel"]
|
||||||
|
build-backend = "setuptools.build_meta"
|
||||||
|
|
||||||
|
[project]
|
||||||
|
name = "unicorn"
|
||||||
|
version = "2.1.1"
|
||||||
|
requires-python = ">= 2.7, != 3.0.*, != 3.1.*, != 3.2.*, != 3.3.*, != 3.4.*, != 3.5.*, != 3.6.*"
|
||||||
|
authors = [
|
||||||
|
{ name = "Nguyen Anh Quynh", email = "quynh@gmail.com" },
|
||||||
|
]
|
||||||
|
description = "Unicorn CPU emulator engine"
|
||||||
|
readme = "README.md"
|
||||||
|
keywords = ["emulation", "qemu", "unicorn"]
|
||||||
|
classifiers = [
|
||||||
|
'License :: OSI Approved :: BSD License',
|
||||||
|
'Programming Language :: Python :: 2.7',
|
||||||
|
'Programming Language :: Python :: 3.7',
|
||||||
|
'Programming Language :: Python :: 3.8',
|
||||||
|
'Programming Language :: Python :: 3.9',
|
||||||
|
'Programming Language :: Python :: 3.10',
|
||||||
|
'Programming Language :: Python :: 3.11',
|
||||||
|
'Programming Language :: Python :: 3.12',
|
||||||
|
'Programming Language :: Python :: 3.13',
|
||||||
|
]
|
||||||
|
|
||||||
|
[project.urls]
|
||||||
|
Homepage = "http://www.unicorn-engine.org"
|
||||||
|
Repository = "https://github.com/unicorn-engine/unicorn"
|
||||||
|
"Bug Tracker" = "https://github.com/unicorn-engine/unicorn/issues"
|
||||||
|
Changelog = "https://github.com/unicorn-engine/unicorn/blob/master/ChangeLog"
|
||||||
|
|
||||||
|
[project.optional-dependencies]
|
||||||
|
test = [
|
||||||
|
"pytest",
|
||||||
|
"pytest-cov",
|
||||||
|
]
|
||||||
|
|
||||||
|
[tool.setuptools.packages.find]
|
||||||
|
include = ["unicorn*"]
|
||||||
@@ -1,31 +0,0 @@
|
|||||||
#!/bin/sh
|
|
||||||
|
|
||||||
python3 ./sample_arm.py
|
|
||||||
echo "=========================="
|
|
||||||
python3 ./sample_armeb.py
|
|
||||||
echo "=========================="
|
|
||||||
python3 ./sample_arm64.py
|
|
||||||
echo "=========================="
|
|
||||||
python3 ./sample_arm64eb.py
|
|
||||||
echo "=========================="
|
|
||||||
python3 ./sample_m68k.py
|
|
||||||
echo "=========================="
|
|
||||||
python3 ./sample_mips.py
|
|
||||||
echo "=========================="
|
|
||||||
python3 ./sample_ppc.py
|
|
||||||
echo "=========================="
|
|
||||||
python3 ./sample_riscv.py
|
|
||||||
echo "=========================="
|
|
||||||
python3 ./sample_s390x.py
|
|
||||||
echo "=========================="
|
|
||||||
python3 ./sample_sparc.py
|
|
||||||
echo "=========================="
|
|
||||||
python3 ./sample_tricore.py
|
|
||||||
echo "=========================="
|
|
||||||
python3 ./sample_x86.py
|
|
||||||
echo "=========================="
|
|
||||||
python3 ./shellcode.py
|
|
||||||
echo "=========================="
|
|
||||||
python3 ./sample_ctl.py
|
|
||||||
echo "=========================="
|
|
||||||
python3 ./sample_network_auditing.py
|
|
||||||
@@ -1,2 +0,0 @@
|
|||||||
[bdist_wheel]
|
|
||||||
universal=1
|
|
||||||
@@ -1,29 +1,19 @@
|
|||||||
#!/usr/bin/env python
|
|
||||||
# Python binding for Unicorn engine. Nguyen Anh Quynh <aquynh@gmail.com>
|
# Python binding for Unicorn engine. Nguyen Anh Quynh <aquynh@gmail.com>
|
||||||
|
|
||||||
from __future__ import print_function
|
|
||||||
import glob
|
import glob
|
||||||
import logging
|
import logging
|
||||||
import os
|
import os
|
||||||
import subprocess
|
|
||||||
import shutil
|
|
||||||
import sys
|
|
||||||
import platform
|
import platform
|
||||||
import setuptools
|
import shutil
|
||||||
|
import subprocess
|
||||||
|
import sys
|
||||||
from setuptools import setup
|
from setuptools import setup
|
||||||
from sysconfig import get_platform
|
|
||||||
from setuptools.command.build import build
|
from setuptools.command.build import build
|
||||||
from setuptools.command.sdist import sdist
|
from setuptools.command.sdist import sdist
|
||||||
from setuptools.command.bdist_egg import bdist_egg
|
from setuptools.command.bdist_egg import bdist_egg
|
||||||
|
|
||||||
log = logging.getLogger(__name__)
|
log = logging.getLogger(__name__)
|
||||||
|
|
||||||
SYSTEM = sys.platform
|
|
||||||
|
|
||||||
# sys.maxint is 2**31 - 1 on both 32 and 64 bit mingw
|
|
||||||
IS_64BITS = platform.architecture()[0] == '64bit'
|
|
||||||
|
|
||||||
# are we building from the repository or from a source distribution?
|
# are we building from the repository or from a source distribution?
|
||||||
ROOT_DIR = os.path.dirname(os.path.realpath(__file__))
|
ROOT_DIR = os.path.dirname(os.path.realpath(__file__))
|
||||||
LIBS_DIR = os.path.join(ROOT_DIR, 'unicorn', 'lib')
|
LIBS_DIR = os.path.join(ROOT_DIR, 'unicorn', 'lib')
|
||||||
@@ -32,29 +22,28 @@ SRC_DIR = os.path.join(ROOT_DIR, 'src')
|
|||||||
UC_DIR = SRC_DIR if os.path.exists(SRC_DIR) else os.path.join(ROOT_DIR, '../..')
|
UC_DIR = SRC_DIR if os.path.exists(SRC_DIR) else os.path.join(ROOT_DIR, '../..')
|
||||||
BUILD_DIR = os.path.join(UC_DIR, 'build_python')
|
BUILD_DIR = os.path.join(UC_DIR, 'build_python')
|
||||||
|
|
||||||
VERSION = "2.1.1"
|
if sys.platform == 'darwin':
|
||||||
|
|
||||||
if SYSTEM == 'darwin':
|
|
||||||
LIBRARY_FILE = "libunicorn.2.dylib"
|
LIBRARY_FILE = "libunicorn.2.dylib"
|
||||||
STATIC_LIBRARY_FILE = "libunicorn.a"
|
STATIC_LIBRARY_FILE = "libunicorn.a"
|
||||||
elif SYSTEM in ('win32', 'cygwin'):
|
elif sys.platform in ('win32', 'cygwin'):
|
||||||
LIBRARY_FILE = "unicorn.dll"
|
LIBRARY_FILE = "unicorn.dll"
|
||||||
STATIC_LIBRARY_FILE = "unicorn.lib"
|
STATIC_LIBRARY_FILE = "unicorn.lib"
|
||||||
else:
|
else:
|
||||||
LIBRARY_FILE = "libunicorn.so.2"
|
LIBRARY_FILE = "libunicorn.so.2"
|
||||||
STATIC_LIBRARY_FILE = "libunicorn.a"
|
STATIC_LIBRARY_FILE = "libunicorn.a"
|
||||||
|
|
||||||
|
|
||||||
def clean_bins():
|
def clean_bins():
|
||||||
shutil.rmtree(LIBS_DIR, ignore_errors=True)
|
shutil.rmtree(LIBS_DIR, ignore_errors=True)
|
||||||
shutil.rmtree(HEADERS_DIR, ignore_errors=True)
|
shutil.rmtree(HEADERS_DIR, ignore_errors=True)
|
||||||
|
|
||||||
|
|
||||||
def copy_sources():
|
def copy_sources():
|
||||||
"""Copy the C sources into the source directory.
|
"""
|
||||||
|
Copy the C sources into the source directory.
|
||||||
This rearranges the source files under the python distribution
|
This rearranges the source files under the python distribution
|
||||||
directory.
|
directory.
|
||||||
"""
|
"""
|
||||||
src = []
|
|
||||||
|
|
||||||
shutil.rmtree(SRC_DIR, ignore_errors=True)
|
shutil.rmtree(SRC_DIR, ignore_errors=True)
|
||||||
os.mkdir(SRC_DIR)
|
os.mkdir(SRC_DIR)
|
||||||
|
|
||||||
@@ -68,15 +57,14 @@ def copy_sources():
|
|||||||
shutil.copytree(os.path.join(ROOT_DIR, '../../cmake'), os.path.join(SRC_DIR, 'cmake/'))
|
shutil.copytree(os.path.join(ROOT_DIR, '../../cmake'), os.path.join(SRC_DIR, 'cmake/'))
|
||||||
|
|
||||||
try:
|
try:
|
||||||
# remove site-specific configuration file
|
# remove site-specific configuration file, might not exist
|
||||||
# might not exist
|
|
||||||
os.remove(os.path.join(SRC_DIR, 'qemu/config-host.mak'))
|
os.remove(os.path.join(SRC_DIR, 'qemu/config-host.mak'))
|
||||||
except OSError:
|
except OSError:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
src = []
|
||||||
src.extend(glob.glob(os.path.join(ROOT_DIR, "../../*.[ch]")))
|
src.extend(glob.glob(os.path.join(ROOT_DIR, "../../*.[ch]")))
|
||||||
src.extend(glob.glob(os.path.join(ROOT_DIR, "../../*.mk")))
|
src.extend(glob.glob(os.path.join(ROOT_DIR, "../../*.mk")))
|
||||||
|
|
||||||
src.extend(glob.glob(os.path.join(ROOT_DIR, "../../LICENSE*")))
|
src.extend(glob.glob(os.path.join(ROOT_DIR, "../../LICENSE*")))
|
||||||
src.extend(glob.glob(os.path.join(ROOT_DIR, "../../README.md")))
|
src.extend(glob.glob(os.path.join(ROOT_DIR, "../../README.md")))
|
||||||
src.extend(glob.glob(os.path.join(ROOT_DIR, "../../*.TXT")))
|
src.extend(glob.glob(os.path.join(ROOT_DIR, "../../*.TXT")))
|
||||||
@@ -87,6 +75,7 @@ def copy_sources():
|
|||||||
log.info("%s -> %s" % (filename, outpath))
|
log.info("%s -> %s" % (filename, outpath))
|
||||||
shutil.copy(filename, outpath)
|
shutil.copy(filename, outpath)
|
||||||
|
|
||||||
|
|
||||||
def build_libraries():
|
def build_libraries():
|
||||||
"""
|
"""
|
||||||
Prepare the unicorn directory for a binary distribution or installation.
|
Prepare the unicorn directory for a binary distribution or installation.
|
||||||
@@ -94,7 +83,6 @@ def build_libraries():
|
|||||||
|
|
||||||
Will use a src/ dir if one exists in the current directory, otherwise assumes it's in the repo
|
Will use a src/ dir if one exists in the current directory, otherwise assumes it's in the repo
|
||||||
"""
|
"""
|
||||||
cwd = os.getcwd()
|
|
||||||
clean_bins()
|
clean_bins()
|
||||||
os.mkdir(HEADERS_DIR)
|
os.mkdir(HEADERS_DIR)
|
||||||
os.mkdir(LIBS_DIR)
|
os.mkdir(LIBS_DIR)
|
||||||
@@ -102,158 +90,84 @@ def build_libraries():
|
|||||||
# copy public headers
|
# copy public headers
|
||||||
shutil.copytree(os.path.join(UC_DIR, 'include', 'unicorn'), os.path.join(HEADERS_DIR, 'unicorn'))
|
shutil.copytree(os.path.join(UC_DIR, 'include', 'unicorn'), os.path.join(HEADERS_DIR, 'unicorn'))
|
||||||
|
|
||||||
# check if a prebuilt library exists
|
# check if a prebuilt library exists and if so, use it instead of building
|
||||||
# if so, use it instead of building
|
|
||||||
if os.path.exists(os.path.join(ROOT_DIR, 'prebuilt', LIBRARY_FILE)):
|
if os.path.exists(os.path.join(ROOT_DIR, 'prebuilt', LIBRARY_FILE)):
|
||||||
shutil.copy(os.path.join(ROOT_DIR, 'prebuilt', LIBRARY_FILE), LIBS_DIR)
|
shutil.copy(os.path.join(ROOT_DIR, 'prebuilt', LIBRARY_FILE), LIBS_DIR)
|
||||||
if STATIC_LIBRARY_FILE is not None and os.path.exists(os.path.join(ROOT_DIR, 'prebuilt', STATIC_LIBRARY_FILE)):
|
if STATIC_LIBRARY_FILE is not None and os.path.exists(os.path.join(ROOT_DIR, 'prebuilt', STATIC_LIBRARY_FILE)):
|
||||||
shutil.copy(os.path.join(ROOT_DIR, 'prebuilt', STATIC_LIBRARY_FILE), LIBS_DIR)
|
shutil.copy(os.path.join(ROOT_DIR, 'prebuilt', STATIC_LIBRARY_FILE), LIBS_DIR)
|
||||||
return
|
return
|
||||||
|
|
||||||
# otherwise, build!!
|
# otherwise, build
|
||||||
os.chdir(UC_DIR)
|
|
||||||
|
|
||||||
try:
|
|
||||||
subprocess.check_call(['msbuild', '/help'])
|
|
||||||
except:
|
|
||||||
has_msbuild = False
|
|
||||||
else:
|
|
||||||
has_msbuild = True
|
|
||||||
|
|
||||||
if has_msbuild and SYSTEM == 'win32':
|
|
||||||
plat = 'Win32' if platform.architecture()[0] == '32bit' else 'x64'
|
|
||||||
conf = 'Debug' if os.getenv('DEBUG', '') else 'Release'
|
|
||||||
if not os.path.exists(BUILD_DIR):
|
if not os.path.exists(BUILD_DIR):
|
||||||
os.mkdir(BUILD_DIR)
|
os.mkdir(BUILD_DIR)
|
||||||
|
|
||||||
subprocess.check_call(['cmake', '-B', BUILD_DIR, '-G', "Visual Studio 16 2019", "-A", plat, "-DCMAKE_BUILD_TYPE=" + conf])
|
has_msbuild = shutil.which('msbuild') is not None
|
||||||
subprocess.check_call(['msbuild', 'unicorn.sln', '-m', '-p:Platform=' + plat, '-p:Configuration=' + conf], cwd=BUILD_DIR)
|
conf = 'Debug' if int(os.getenv('DEBUG', 0)) else 'Release'
|
||||||
|
|
||||||
|
if has_msbuild and sys.platform == 'win32':
|
||||||
|
plat = 'Win32' if platform.architecture()[0] == '32bit' else 'x64'
|
||||||
|
|
||||||
|
subprocess.check_call(['cmake', '-B', BUILD_DIR, '-G', "Visual Studio 16 2019", "-A", plat,
|
||||||
|
"-DCMAKE_BUILD_TYPE=" + conf], cwd=UC_DIR)
|
||||||
|
subprocess.check_call(['msbuild', 'unicorn.sln', '-m', '-p:Platform=' + plat, '-p:Configuration=' + conf],
|
||||||
|
cwd=BUILD_DIR)
|
||||||
|
|
||||||
obj_dir = os.path.join(BUILD_DIR, conf)
|
obj_dir = os.path.join(BUILD_DIR, conf)
|
||||||
shutil.copy(os.path.join(obj_dir, LIBRARY_FILE), LIBS_DIR)
|
shutil.copy(os.path.join(obj_dir, LIBRARY_FILE), LIBS_DIR)
|
||||||
shutil.copy(os.path.join(BUILD_DIR, STATIC_LIBRARY_FILE), LIBS_DIR)
|
shutil.copy(os.path.join(BUILD_DIR, STATIC_LIBRARY_FILE), LIBS_DIR)
|
||||||
else:
|
else:
|
||||||
# platform description refs at https://docs.python.org/2/library/sys.html#sys.platform
|
|
||||||
if not os.path.exists(BUILD_DIR):
|
|
||||||
os.mkdir(BUILD_DIR)
|
|
||||||
conf = 'Debug' if os.getenv('DEBUG', '') else 'Release'
|
|
||||||
|
|
||||||
cmake_args = ["cmake", '-B', BUILD_DIR, '-S', UC_DIR, "-DCMAKE_BUILD_TYPE=" + conf]
|
cmake_args = ["cmake", '-B', BUILD_DIR, '-S', UC_DIR, "-DCMAKE_BUILD_TYPE=" + conf]
|
||||||
if os.getenv("TRACE", ""):
|
if os.getenv("TRACE"):
|
||||||
cmake_args += ["-DUNICORN_TRACER=on"]
|
cmake_args += ["-DUNICORN_TRACER=on"]
|
||||||
subprocess.check_call(cmake_args)
|
subprocess.check_call(cmake_args, cwd=UC_DIR)
|
||||||
os.chdir(BUILD_DIR)
|
|
||||||
threads = os.getenv("THREADS", "4")
|
threads = os.getenv("THREADS", "4")
|
||||||
subprocess.check_call(["cmake", "--build", ".", "-j" + threads])
|
subprocess.check_call(["cmake", "--build", ".", "-j" + threads], cwd=BUILD_DIR)
|
||||||
|
|
||||||
shutil.copy(LIBRARY_FILE, LIBS_DIR)
|
shutil.copy(os.path.join(BUILD_DIR, LIBRARY_FILE), LIBS_DIR)
|
||||||
shutil.copy(STATIC_LIBRARY_FILE, LIBS_DIR)
|
shutil.copy(os.path.join(BUILD_DIR, STATIC_LIBRARY_FILE), LIBS_DIR)
|
||||||
|
|
||||||
os.chdir(cwd)
|
|
||||||
|
|
||||||
|
|
||||||
class custom_sdist(sdist):
|
class CustomSDist(sdist):
|
||||||
def run(self):
|
def run(self):
|
||||||
clean_bins()
|
clean_bins()
|
||||||
copy_sources()
|
copy_sources()
|
||||||
return sdist.run(self)
|
return super().run()
|
||||||
|
|
||||||
class custom_build(build):
|
|
||||||
|
class CustomBuild(build):
|
||||||
def run(self):
|
def run(self):
|
||||||
if 'LIBUNICORN_PATH' in os.environ:
|
if 'LIBUNICORN_PATH' in os.environ:
|
||||||
log.info("Skipping building C extensions since LIBUNICORN_PATH is set")
|
log.info("Skipping building C extensions since LIBUNICORN_PATH is set")
|
||||||
else:
|
else:
|
||||||
log.info("Building C extensions")
|
log.info("Building C extensions")
|
||||||
build_libraries()
|
build_libraries()
|
||||||
return build.run(self)
|
return super().run()
|
||||||
|
|
||||||
class custom_bdist_egg(bdist_egg):
|
|
||||||
|
class CustomBDistEgg(bdist_egg):
|
||||||
def run(self):
|
def run(self):
|
||||||
self.run_command('build')
|
self.run_command('build')
|
||||||
return bdist_egg.run(self)
|
return super().run()
|
||||||
|
|
||||||
def dummy_src():
|
|
||||||
return []
|
|
||||||
|
|
||||||
cmdclass = {}
|
cmdclass = {'build': CustomBuild, 'sdist': CustomSDist, 'bdist_egg': CustomBDistEgg}
|
||||||
cmdclass['build'] = custom_build
|
|
||||||
cmdclass['sdist'] = custom_sdist
|
|
||||||
cmdclass['bdist_egg'] = custom_bdist_egg
|
|
||||||
|
|
||||||
if 'bdist_wheel' in sys.argv and '--plat-name' not in sys.argv:
|
|
||||||
idx = sys.argv.index('bdist_wheel') + 1
|
|
||||||
sys.argv.insert(idx, '--plat-name')
|
|
||||||
name = get_platform()
|
|
||||||
if 'linux' in name:
|
|
||||||
# linux_* platform tags are disallowed because the python ecosystem is fubar
|
|
||||||
# linux builds should be built in the centos 5 vm for maximum compatibility
|
|
||||||
# see https://github.com/pypa/manylinux
|
|
||||||
# see also https://github.com/angr/angr-dev/blob/master/bdist.sh
|
|
||||||
sys.argv.insert(idx + 1, 'manylinux1_' + platform.machine())
|
|
||||||
elif 'mingw' in name:
|
|
||||||
if IS_64BITS:
|
|
||||||
sys.argv.insert(idx + 1, 'win_amd64')
|
|
||||||
else:
|
|
||||||
sys.argv.insert(idx + 1, 'win32')
|
|
||||||
else:
|
|
||||||
# https://www.python.org/dev/peps/pep-0425/
|
|
||||||
sys.argv.insert(idx + 1, name.replace('.', '_').replace('-', '_'))
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
from setuptools.command.develop import develop
|
from setuptools.command.develop import develop
|
||||||
class custom_develop(develop):
|
|
||||||
|
|
||||||
|
class CustomDevelop(develop):
|
||||||
def run(self):
|
def run(self):
|
||||||
log.info("Building C extensions")
|
log.info("Building C extensions")
|
||||||
build_libraries()
|
build_libraries()
|
||||||
return develop.run(self)
|
return super().run()
|
||||||
|
|
||||||
cmdclass['develop'] = custom_develop
|
|
||||||
|
cmdclass['develop'] = CustomDevelop
|
||||||
except ImportError:
|
except ImportError:
|
||||||
print("Proper 'develop' support unavailable.")
|
print("Proper 'develop' support unavailable.")
|
||||||
|
|
||||||
def join_all(src, files):
|
|
||||||
return tuple(os.path.join(src, f) for f in files)
|
|
||||||
|
|
||||||
long_desc = '''
|
|
||||||
Unicorn is a lightweight, multi-platform, multi-architecture CPU emulator framework
|
|
||||||
based on [QEMU](http://qemu.org).
|
|
||||||
|
|
||||||
Unicorn offers some unparalleled features:
|
|
||||||
|
|
||||||
- Multi-architecture: ARM, ARM64 (ARMv8), M68K, MIPS, PowerPC, RISCV, SPARC, S390X, TriCore and X86 (16, 32, 64-bit)
|
|
||||||
- Clean/simple/lightweight/intuitive architecture-neutral API
|
|
||||||
- Implemented in pure C language, with bindings for Crystal, Clojure, Visual Basic, Perl, Rust, Ruby, Python, Java, .NET, Go, Delphi/Free Pascal, Haskell, Pharo, and Lua.
|
|
||||||
- Native support for Windows & *nix (with Mac OSX, Linux, *BSD & Solaris confirmed)
|
|
||||||
- High performance via Just-In-Time compilation
|
|
||||||
- Support for fine-grained instrumentation at various levels
|
|
||||||
- Thread-safety by design
|
|
||||||
- Distributed under free software license GPLv2
|
|
||||||
|
|
||||||
Further information is available at http://www.unicorn-engine.org
|
|
||||||
'''
|
|
||||||
|
|
||||||
setup(
|
setup(
|
||||||
provides=['unicorn'],
|
|
||||||
packages=setuptools.find_packages(include=["unicorn", "unicorn.*"]),
|
|
||||||
name='unicorn',
|
|
||||||
version=VERSION,
|
|
||||||
author='Nguyen Anh Quynh',
|
|
||||||
author_email='aquynh@gmail.com',
|
|
||||||
description='Unicorn CPU emulator engine',
|
|
||||||
long_description=long_desc,
|
|
||||||
long_description_content_type="text/markdown",
|
|
||||||
url='http://www.unicorn-engine.org',
|
|
||||||
classifiers=[
|
|
||||||
'License :: OSI Approved :: BSD License',
|
|
||||||
'Programming Language :: Python :: 2',
|
|
||||||
'Programming Language :: Python :: 3',
|
|
||||||
],
|
|
||||||
requires=['ctypes'],
|
|
||||||
cmdclass=cmdclass,
|
cmdclass=cmdclass,
|
||||||
zip_safe=False,
|
has_ext_modules=lambda: True, # It's not a Pure Python wheel
|
||||||
include_package_data=True,
|
|
||||||
is_pure=False,
|
|
||||||
package_data={
|
|
||||||
'unicorn': ['unicorn/py.typed', 'lib/*', 'include/unicorn/*']
|
|
||||||
}
|
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -6,7 +6,6 @@ from __future__ import print_function
|
|||||||
from unicorn import *
|
from unicorn import *
|
||||||
from unicorn.arm_const import *
|
from unicorn.arm_const import *
|
||||||
|
|
||||||
|
|
||||||
# code to be emulated
|
# code to be emulated
|
||||||
ARM_CODE = b"\x37\x00\xa0\xe3\x03\x10\x42\xe0" # mov r0, #0x37; sub r1, r2, r3
|
ARM_CODE = b"\x37\x00\xa0\xe3\x03\x10\x42\xe0" # mov r0, #0x37; sub r1, r2, r3
|
||||||
THUMB_CODE = b"\x83\xb0" # sub sp, #0xc
|
THUMB_CODE = b"\x83\xb0" # sub sp, #0xc
|
||||||
@@ -98,6 +97,7 @@ def test_thumb():
|
|||||||
except UcError as e:
|
except UcError as e:
|
||||||
print("ERROR: %s" % e)
|
print("ERROR: %s" % e)
|
||||||
|
|
||||||
|
|
||||||
def test_read_sctlr():
|
def test_read_sctlr():
|
||||||
print("Read SCTLR")
|
print("Read SCTLR")
|
||||||
try:
|
try:
|
||||||
@@ -118,6 +118,7 @@ def test_read_sctlr():
|
|||||||
except UcError as e:
|
except UcError as e:
|
||||||
print("ERROR: %s" % e)
|
print("ERROR: %s" % e)
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
test_arm()
|
test_arm()
|
||||||
print("=" * 26)
|
print("=" * 26)
|
||||||
@@ -6,7 +6,6 @@ from __future__ import print_function
|
|||||||
from unicorn import *
|
from unicorn import *
|
||||||
from unicorn.arm64_const import *
|
from unicorn.arm64_const import *
|
||||||
|
|
||||||
|
|
||||||
# code to be emulated
|
# code to be emulated
|
||||||
ARM64_CODE = b"\xab\x05\x00\xb8\xaf\x05\x40\x38" # str x11, [x13]; ldrb x15, [x13]
|
ARM64_CODE = b"\xab\x05\x00\xb8\xaf\x05\x40\x38" # str x11, [x13]; ldrb x15, [x13]
|
||||||
|
|
||||||
@@ -85,6 +84,7 @@ def test_arm64_read_sctlr():
|
|||||||
except UcError as e:
|
except UcError as e:
|
||||||
print("ERROR: %s" % e)
|
print("ERROR: %s" % e)
|
||||||
|
|
||||||
|
|
||||||
def test_arm64_hook_mrs():
|
def test_arm64_hook_mrs():
|
||||||
def _hook_mrs(uc, reg, cp_reg, _):
|
def _hook_mrs(uc, reg, cp_reg, _):
|
||||||
print(f">>> Hook MRS instruction: reg = 0x{reg:x}(UC_ARM64_REG_X2) cp_reg = {cp_reg}")
|
print(f">>> Hook MRS instruction: reg = 0x{reg:x}(UC_ARM64_REG_X2) cp_reg = {cp_reg}")
|
||||||
@@ -116,6 +116,7 @@ def test_arm64_hook_mrs():
|
|||||||
except UcError as e:
|
except UcError as e:
|
||||||
print("ERROR: %s" % e)
|
print("ERROR: %s" % e)
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
test_arm64()
|
test_arm64()
|
||||||
print("=" * 26)
|
print("=" * 26)
|
||||||
@@ -7,7 +7,6 @@ from __future__ import print_function
|
|||||||
from unicorn import *
|
from unicorn import *
|
||||||
from unicorn.arm64_const import *
|
from unicorn.arm64_const import *
|
||||||
|
|
||||||
|
|
||||||
# code to be emulated
|
# code to be emulated
|
||||||
ARM64_CODE = b"\xab\x05\x00\xb8\xaf\x05\x40\x38" # str x11, [x13]; ldrb x15, [x13]
|
ARM64_CODE = b"\xab\x05\x00\xb8\xaf\x05\x40\x38" # str x11, [x13]; ldrb x15, [x13]
|
||||||
|
|
||||||
@@ -5,7 +5,6 @@ from __future__ import print_function
|
|||||||
from unicorn import *
|
from unicorn import *
|
||||||
from unicorn.arm_const import *
|
from unicorn.arm_const import *
|
||||||
|
|
||||||
|
|
||||||
# code to be emulated
|
# code to be emulated
|
||||||
ARM_CODE = b"\xe3\xa0\x00\x37\xe0\x42\x10\x03" # mov r0, #0x37; sub r1, r2, r3
|
ARM_CODE = b"\xe3\xa0\x00\x37\xe0\x42\x10\x03" # mov r0, #0x37; sub r1, r2, r3
|
||||||
THUMB_CODE = b"\xb0\x83" # sub sp, #0xc
|
THUMB_CODE = b"\xb0\x83" # sub sp, #0xc
|
||||||
@@ -6,6 +6,7 @@ from unicorn import *
|
|||||||
from unicorn.x86_const import *
|
from unicorn.x86_const import *
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
|
|
||||||
|
|
||||||
def test_uc_ctl_read():
|
def test_uc_ctl_read():
|
||||||
uc = Uc(UC_ARCH_X86, UC_MODE_32)
|
uc = Uc(UC_ARCH_X86, UC_MODE_32)
|
||||||
|
|
||||||
@@ -21,6 +22,7 @@ def test_uc_ctl_read():
|
|||||||
|
|
||||||
print(f">>> arch={arch} mode={mode} page size={page_size} timeout={timeout}")
|
print(f">>> arch={arch} mode={mode} page size={page_size} timeout={timeout}")
|
||||||
|
|
||||||
|
|
||||||
def time_emulation(uc, start, end):
|
def time_emulation(uc, start, end):
|
||||||
n = datetime.now()
|
n = datetime.now()
|
||||||
|
|
||||||
@@ -28,6 +30,7 @@ def time_emulation(uc, start, end):
|
|||||||
|
|
||||||
return (datetime.now() - n).total_seconds() * 1e6
|
return (datetime.now() - n).total_seconds() * 1e6
|
||||||
|
|
||||||
|
|
||||||
def test_uc_ctl_tb_cache():
|
def test_uc_ctl_tb_cache():
|
||||||
# Initialize emulator in X86-32bit mode
|
# Initialize emulator in X86-32bit mode
|
||||||
uc = Uc(UC_ARCH_X86, UC_MODE_32)
|
uc = Uc(UC_ARCH_X86, UC_MODE_32)
|
||||||
@@ -36,7 +39,7 @@ def test_uc_ctl_tb_cache():
|
|||||||
# Fill the code buffer with NOP.
|
# Fill the code buffer with NOP.
|
||||||
code = b"\x90" * 8 * 512
|
code = b"\x90" * 8 * 512
|
||||||
|
|
||||||
print("Controling the TB cache in a finer granularity by uc_ctl.")
|
print("Controlling the TB cache in a finer granularity by uc_ctl.")
|
||||||
|
|
||||||
uc.mem_map(addr, 0x10000)
|
uc.mem_map(addr, 0x10000)
|
||||||
|
|
||||||
@@ -49,7 +52,7 @@ def test_uc_ctl_tb_cache():
|
|||||||
# Now we request cache for all TBs.
|
# Now we request cache for all TBs.
|
||||||
for i in range(8):
|
for i in range(8):
|
||||||
tb = uc.ctl_request_cache(addr + i * 512)
|
tb = uc.ctl_request_cache(addr + i * 512)
|
||||||
print(f">>> TB is cached at {hex(tb.pc)} which has {tb.icount} instructions with {tb.size} bytes")
|
print(f">>> TB is cached at {hex(tb[0])} which has {tb[1]} instructions with {tb[2]} bytes")
|
||||||
|
|
||||||
# Do emulation with all TB cached.
|
# Do emulation with all TB cached.
|
||||||
cached = time_emulation(uc, addr, addr + len(code))
|
cached = time_emulation(uc, addr, addr + len(code))
|
||||||
@@ -62,12 +65,15 @@ def test_uc_ctl_tb_cache():
|
|||||||
|
|
||||||
print(f">>> Run time: First time {standard}, Cached: {cached}, Cached evicted: {evicted}")
|
print(f">>> Run time: First time {standard}, Cached: {cached}, Cached evicted: {evicted}")
|
||||||
|
|
||||||
|
|
||||||
def trace_new_edge(uc, cur, prev, data):
|
def trace_new_edge(uc, cur, prev, data):
|
||||||
print(f">>> Getting a new edge from {hex(prev.pc + prev.size - 1)} to {hex(cur.pc)}")
|
print(f">>> Getting a new edge from {hex(prev.pc + prev.size - 1)} to {hex(cur.pc)}")
|
||||||
|
|
||||||
|
|
||||||
def trace_tcg_sub(uc, address, arg1, arg2, size, data):
|
def trace_tcg_sub(uc, address, arg1, arg2, size, data):
|
||||||
print(f">>> Get a tcg sub opcode at {hex(address)} with args: {arg1} and {arg2}")
|
print(f">>> Get a tcg sub opcode at {hex(address)} with args: {arg1} and {arg2}")
|
||||||
|
|
||||||
|
|
||||||
def test_uc_ctl_exits():
|
def test_uc_ctl_exits():
|
||||||
uc = Uc(UC_ARCH_X86, UC_MODE_32)
|
uc = Uc(UC_ARCH_X86, UC_MODE_32)
|
||||||
addr = 0x1000
|
addr = 0x1000
|
||||||
@@ -98,7 +104,7 @@ def test_uc_ctl_exits():
|
|||||||
|
|
||||||
uc.ctl_set_exits(exits)
|
uc.ctl_set_exits(exits)
|
||||||
|
|
||||||
# This should stop at ADDRESS + 6 and increase eax, even thouhg we don't provide an exit.
|
# This should stop at ADDRESS + 6 and increase eax, even though we don't provide an exit.
|
||||||
uc.emu_start(addr, 0)
|
uc.emu_start(addr, 0)
|
||||||
|
|
||||||
eax = uc.reg_read(UC_X86_REG_EAX)
|
eax = uc.reg_read(UC_X86_REG_EAX)
|
||||||
@@ -106,7 +112,7 @@ def test_uc_ctl_exits():
|
|||||||
|
|
||||||
print(f">>> eax = {hex(eax)} and ebx = {hex(ebx)} after the first emulation")
|
print(f">>> eax = {hex(eax)} and ebx = {hex(ebx)} after the first emulation")
|
||||||
|
|
||||||
# This should stop at ADDRESS + 8, even thouhg we don't provide an exit.
|
# This should stop at ADDRESS + 8, even though we don't provide an exit.
|
||||||
uc.emu_start(addr, 0)
|
uc.emu_start(addr, 0)
|
||||||
|
|
||||||
eax = uc.reg_read(UC_X86_REG_EAX)
|
eax = uc.reg_read(UC_X86_REG_EAX)
|
||||||
@@ -114,6 +120,7 @@ def test_uc_ctl_exits():
|
|||||||
|
|
||||||
print(f">>> eax = {hex(eax)} and ebx = {hex(ebx)} after the first emulation")
|
print(f">>> eax = {hex(eax)} and ebx = {hex(ebx)} after the first emulation")
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
test_uc_ctl_read()
|
test_uc_ctl_read()
|
||||||
print("=" * 32)
|
print("=" * 32)
|
||||||
@@ -6,7 +6,6 @@ from __future__ import print_function
|
|||||||
from unicorn import *
|
from unicorn import *
|
||||||
from unicorn.m68k_const import *
|
from unicorn.m68k_const import *
|
||||||
|
|
||||||
|
|
||||||
# code to be emulated
|
# code to be emulated
|
||||||
M68K_CODE = b"\x76\xed" # movq #-19, %d3
|
M68K_CODE = b"\x76\xed" # movq #-19, %d3
|
||||||
# memory address where emulation starts
|
# memory address where emulation starts
|
||||||
@@ -6,7 +6,6 @@ from __future__ import print_function
|
|||||||
from unicorn import *
|
from unicorn import *
|
||||||
from unicorn.mips_const import *
|
from unicorn.mips_const import *
|
||||||
|
|
||||||
|
|
||||||
# code to be emulated
|
# code to be emulated
|
||||||
MIPS_CODE_EB = b"\x34\x21\x34\x56" # ori $at, $at, 0x3456;
|
MIPS_CODE_EB = b"\x34\x21\x34\x56" # ori $at, $at, 0x3456;
|
||||||
MIPS_CODE_EL = b"\x56\x34\x21\x34" # ori $at, $at, 0x3456;
|
MIPS_CODE_EL = b"\x56\x34\x21\x34" # ori $at, $at, 0x3456;
|
||||||
@@ -3,10 +3,11 @@
|
|||||||
# Nguyen Tan Cong <shenlongbk@gmail.com>
|
# Nguyen Tan Cong <shenlongbk@gmail.com>
|
||||||
|
|
||||||
from __future__ import print_function
|
from __future__ import print_function
|
||||||
from unicorn import *
|
import pytest
|
||||||
from unicorn.x86_const import *
|
|
||||||
import struct
|
import struct
|
||||||
import uuid
|
import uuid
|
||||||
|
from unicorn import *
|
||||||
|
from unicorn.x86_const import *
|
||||||
|
|
||||||
SIZE_REG = 4
|
SIZE_REG = 4
|
||||||
SOCKETCALL_MAX_ARGS = 3
|
SOCKETCALL_MAX_ARGS = 3
|
||||||
@@ -360,6 +361,7 @@ def hook_intr(uc, intno, user_data):
|
|||||||
print_sockcall(msg)
|
print_sockcall(msg)
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize("code", [X86_SEND_ETCPASSWD, X86_BIND_TCP, X86_REVERSE_TCP, X86_REVERSE_TCP_2])
|
||||||
# Test X86 32 bit
|
# Test X86 32 bit
|
||||||
def test_i386(code):
|
def test_i386(code):
|
||||||
global fd_chains
|
global fd_chains
|
||||||
@@ -1,12 +1,10 @@
|
|||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
# Sample code for PPC of Unicorn. Nguyen Anh Quynh <aquynh@gmail.com>
|
# Sample code for PPC of Unicorn. Nguyen Anh Quynh <aquynh@gmail.com>
|
||||||
#
|
|
||||||
|
|
||||||
from __future__ import print_function
|
from __future__ import print_function
|
||||||
from unicorn import *
|
from unicorn import *
|
||||||
from unicorn.ppc_const import *
|
from unicorn.ppc_const import *
|
||||||
|
|
||||||
|
|
||||||
# code to be emulated
|
# code to be emulated
|
||||||
PPC_CODE = b"\x7F\x46\x1A\x14" # add r26, r6, r3
|
PPC_CODE = b"\x7F\x46\x1A\x14" # add r26, r6, r3
|
||||||
# memory address where emulation starts
|
# memory address where emulation starts
|
||||||
@@ -62,4 +60,3 @@ def test_ppc():
|
|||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
test_ppc()
|
test_ppc()
|
||||||
|
|
||||||
@@ -1,12 +1,10 @@
|
|||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
# Sample code for RISCV of Unicorn. Nguyen Anh Quynh <aquynh@gmail.com>
|
# Sample code for RISCV of Unicorn. Nguyen Anh Quynh <aquynh@gmail.com>
|
||||||
#
|
|
||||||
|
|
||||||
from __future__ import print_function
|
from __future__ import print_function
|
||||||
from unicorn import *
|
from unicorn import *
|
||||||
from unicorn.riscv_const import *
|
from unicorn.riscv_const import *
|
||||||
|
|
||||||
|
|
||||||
'''
|
'''
|
||||||
$ cstool riscv64 1305100093850502
|
$ cstool riscv64 1305100093850502
|
||||||
0 13 05 10 00 addi a0, zero, 1
|
0 13 05 10 00 addi a0, zero, 1
|
||||||
@@ -68,4 +66,3 @@ def test_riscv():
|
|||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
test_riscv()
|
test_riscv()
|
||||||
|
|
||||||
@@ -60,4 +60,3 @@ def test_s390x():
|
|||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
test_s390x()
|
test_s390x()
|
||||||
|
|
||||||
@@ -4,6 +4,7 @@
|
|||||||
# KaiJern Lau <kj@theshepherdlab.io>
|
# KaiJern Lau <kj@theshepherdlab.io>
|
||||||
|
|
||||||
from __future__ import print_function
|
from __future__ import print_function
|
||||||
|
import pytest
|
||||||
from unicorn import *
|
from unicorn import *
|
||||||
from unicorn.x86_const import *
|
from unicorn.x86_const import *
|
||||||
|
|
||||||
@@ -44,6 +45,7 @@ X86_CODE64 = b"\x48\x31\xff\x57\x57\x5e\x5a\x48\xbf\x2f\x2f\x62\x69\x6e\x2f\x73\
|
|||||||
# memory address where emulation starts
|
# memory address where emulation starts
|
||||||
ADDRESS = 0x1000000
|
ADDRESS = 0x1000000
|
||||||
|
|
||||||
|
|
||||||
# callback for tracing instructions
|
# callback for tracing instructions
|
||||||
def hook_code(uc, address, size, user_data):
|
def hook_code(uc, address, size, user_data):
|
||||||
print(">>> Tracing instruction at 0x%x, instruction size = 0x%x" % (address, size))
|
print(">>> Tracing instruction at 0x%x, instruction size = 0x%x" % (address, size))
|
||||||
@@ -59,6 +61,7 @@ def hook_code(uc, address, size, user_data):
|
|||||||
def hook_block(uc, address, size, user_data):
|
def hook_block(uc, address, size, user_data):
|
||||||
print(">>> Tracing basic block at 0x%x, block size = 0x%x" % (address, size))
|
print(">>> Tracing basic block at 0x%x, block size = 0x%x" % (address, size))
|
||||||
|
|
||||||
|
|
||||||
def read_string(uc, address):
|
def read_string(uc, address):
|
||||||
ret = ""
|
ret = ""
|
||||||
c = uc.mem_read(address, 1)[0]
|
c = uc.mem_read(address, 1)[0]
|
||||||
@@ -70,6 +73,7 @@ def read_string(uc, address):
|
|||||||
read_bytes += 1
|
read_bytes += 1
|
||||||
return ret
|
return ret
|
||||||
|
|
||||||
|
|
||||||
# callback for tracing Linux interrupt
|
# callback for tracing Linux interrupt
|
||||||
def hook_intr(uc, intno, user_data):
|
def hook_intr(uc, intno, user_data):
|
||||||
# only handle Linux syscall
|
# only handle Linux syscall
|
||||||
@@ -112,6 +116,7 @@ def hook_syscall32(mu, user_data):
|
|||||||
print(">>> got SYSCALL with EAX = 0x%x" % (eax))
|
print(">>> got SYSCALL with EAX = 0x%x" % (eax))
|
||||||
mu.emu_stop()
|
mu.emu_stop()
|
||||||
|
|
||||||
|
|
||||||
def hook_syscall64(mu, user_data):
|
def hook_syscall64(mu, user_data):
|
||||||
rax = mu.reg_read(UC_X86_REG_RAX)
|
rax = mu.reg_read(UC_X86_REG_RAX)
|
||||||
rdi = mu.reg_read(UC_X86_REG_RDI)
|
rdi = mu.reg_read(UC_X86_REG_RDI)
|
||||||
@@ -128,6 +133,9 @@ def hook_syscall64(mu, user_data):
|
|||||||
|
|
||||||
mu.emu_stop()
|
mu.emu_stop()
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize("mode,code",
|
||||||
|
[(UC_MODE_32, X86_CODE32_SELF), (UC_MODE_32, X86_CODE32), (UC_MODE_64, X86_CODE64)])
|
||||||
# Test X86 32 bit
|
# Test X86 32 bit
|
||||||
def test_i386(mode, code):
|
def test_i386(mode, code):
|
||||||
if mode == UC_MODE_32:
|
if mode == UC_MODE_32:
|
||||||
@@ -171,6 +179,7 @@ def test_i386(mode, code):
|
|||||||
except UcError as e:
|
except UcError as e:
|
||||||
print("ERROR: %s" % e)
|
print("ERROR: %s" % e)
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
test_i386(UC_MODE_32, X86_CODE32_SELF)
|
test_i386(UC_MODE_32, X86_CODE32_SELF)
|
||||||
print("=" * 20)
|
print("=" * 20)
|
||||||
@@ -6,7 +6,6 @@ from __future__ import print_function
|
|||||||
from unicorn import *
|
from unicorn import *
|
||||||
from unicorn.sparc_const import *
|
from unicorn.sparc_const import *
|
||||||
|
|
||||||
|
|
||||||
# code to be emulated
|
# code to be emulated
|
||||||
SPARC_CODE = b"\x86\x00\x40\x02" # add %g1, %g2, %g3;
|
SPARC_CODE = b"\x86\x00\x40\x02" # add %g1, %g2, %g3;
|
||||||
# memory address where emulation starts
|
# memory address where emulation starts
|
||||||
@@ -1,9 +1,9 @@
|
|||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
|
|
||||||
'''
|
"""
|
||||||
Created for Unicorn Engine by Eric Poole <eric.poole@aptiv.com>, 2022
|
Created for Unicorn Engine by Eric Poole <eric.poole@aptiv.com>, 2022
|
||||||
Copyright 2022 Aptiv
|
Copyright 2022 Aptiv
|
||||||
'''
|
"""
|
||||||
|
|
||||||
from __future__ import print_function
|
from __future__ import print_function
|
||||||
from unicorn import *
|
from unicorn import *
|
||||||
@@ -14,14 +14,17 @@ TRICORE_CODE = b"\x82\x11\xbb\x00\x00\x08" # mov d0, #0x1; mov.u d0, #0x8000
|
|||||||
# memory address where emulation starts
|
# memory address where emulation starts
|
||||||
ADDRESS = 0x10000
|
ADDRESS = 0x10000
|
||||||
|
|
||||||
|
|
||||||
# callback for tracing basic blocks
|
# callback for tracing basic blocks
|
||||||
def hook_block(uc, address, size, user_data):
|
def hook_block(uc, address, size, user_data):
|
||||||
print(">>> Tracing basic block at 0x%x, block size = 0x%x" % (address, size))
|
print(">>> Tracing basic block at 0x%x, block size = 0x%x" % (address, size))
|
||||||
|
|
||||||
|
|
||||||
# callback for tracing instructions
|
# callback for tracing instructions
|
||||||
def hook_code(uc, address, size, user_data):
|
def hook_code(uc, address, size, user_data):
|
||||||
print(">>> Tracing instruction at 0x%x, instruction size = 0x%x" % (address, size))
|
print(">>> Tracing instruction at 0x%x, instruction size = 0x%x" % (address, size))
|
||||||
|
|
||||||
|
|
||||||
# Test TriCore
|
# Test TriCore
|
||||||
def test_tricore():
|
def test_tricore():
|
||||||
print("Emulate TriCore code")
|
print("Emulate TriCore code")
|
||||||
@@ -53,5 +56,6 @@ def test_tricore():
|
|||||||
except UcError as e:
|
except UcError as e:
|
||||||
print("ERROR: %s" % e)
|
print("ERROR: %s" % e)
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
test_tricore()
|
test_tricore()
|
||||||
@@ -2,9 +2,9 @@
|
|||||||
# Sample code for X86 of Unicorn. Nguyen Anh Quynh <aquynh@gmail.com>
|
# Sample code for X86 of Unicorn. Nguyen Anh Quynh <aquynh@gmail.com>
|
||||||
|
|
||||||
from __future__ import print_function
|
from __future__ import print_function
|
||||||
|
import pickle
|
||||||
from unicorn import *
|
from unicorn import *
|
||||||
from unicorn.x86_const import *
|
from unicorn.x86_const import *
|
||||||
import pickle
|
|
||||||
|
|
||||||
X86_CODE32 = b"\x41\x4a\x66\x0f\xef\xc1" # INC ecx; DEC edx; PXOR xmm0, xmm1
|
X86_CODE32 = b"\x41\x4a\x66\x0f\xef\xc1" # INC ecx; DEC edx; PXOR xmm0, xmm1
|
||||||
X86_CODE32_LOOP = b"\x41\x4a\xeb\xfe" # INC ecx; DEC edx; JMP self-loop
|
X86_CODE32_LOOP = b"\x41\x4a\xeb\xfe" # INC ecx; DEC edx; JMP self-loop
|
||||||
@@ -33,6 +33,7 @@ def hook_code(uc, address, size, user_data):
|
|||||||
eflags = uc.reg_read(UC_X86_REG_EFLAGS)
|
eflags = uc.reg_read(UC_X86_REG_EFLAGS)
|
||||||
print(">>> --- EFLAGS is 0x%x" % eflags)
|
print(">>> --- EFLAGS is 0x%x" % eflags)
|
||||||
|
|
||||||
|
|
||||||
def hook_code64(uc, address, size, user_data):
|
def hook_code64(uc, address, size, user_data):
|
||||||
print(">>> Tracing instruction at 0x%x, instruction size = 0x%x" % (address, size))
|
print(">>> Tracing instruction at 0x%x, instruction size = 0x%x" % (address, size))
|
||||||
rip = uc.reg_read(UC_X86_REG_RIP)
|
rip = uc.reg_read(UC_X86_REG_RIP)
|
||||||
@@ -232,6 +233,7 @@ def test_i386_invalid_mem_read():
|
|||||||
except UcError as e:
|
except UcError as e:
|
||||||
print("ERROR: %s" % e)
|
print("ERROR: %s" % e)
|
||||||
|
|
||||||
|
|
||||||
def test_i386_jump():
|
def test_i386_jump():
|
||||||
print("Emulate i386 code with jump")
|
print("Emulate i386 code with jump")
|
||||||
try:
|
try:
|
||||||
@@ -322,6 +324,7 @@ def test_i386_invalid_mem_write():
|
|||||||
except UcError as e:
|
except UcError as e:
|
||||||
print("ERROR: %s" % e)
|
print("ERROR: %s" % e)
|
||||||
|
|
||||||
|
|
||||||
def test_i386_jump_invalid():
|
def test_i386_jump_invalid():
|
||||||
print("Emulate i386 code that jumps to invalid memory")
|
print("Emulate i386 code that jumps to invalid memory")
|
||||||
try:
|
try:
|
||||||
@@ -359,6 +362,7 @@ def test_i386_jump_invalid():
|
|||||||
except UcError as e:
|
except UcError as e:
|
||||||
print("ERROR %s" % e)
|
print("ERROR %s" % e)
|
||||||
|
|
||||||
|
|
||||||
def test_i386_loop():
|
def test_i386_loop():
|
||||||
print("Emulate i386 code that loop forever")
|
print("Emulate i386 code that loop forever")
|
||||||
try:
|
try:
|
||||||
@@ -387,6 +391,7 @@ def test_i386_loop():
|
|||||||
except UcError as e:
|
except UcError as e:
|
||||||
print("ERROR: %s" % e)
|
print("ERROR: %s" % e)
|
||||||
|
|
||||||
|
|
||||||
# Test X86 32 bit with IN/OUT instruction
|
# Test X86 32 bit with IN/OUT instruction
|
||||||
def test_i386_inout():
|
def test_i386_inout():
|
||||||
print("Emulate i386 code with IN/OUT instructions")
|
print("Emulate i386 code with IN/OUT instructions")
|
||||||
@@ -474,6 +479,7 @@ def test_i386_context_save():
|
|||||||
except UcError as e:
|
except UcError as e:
|
||||||
print("ERROR: %s" % e)
|
print("ERROR: %s" % e)
|
||||||
|
|
||||||
|
|
||||||
def test_x86_64():
|
def test_x86_64():
|
||||||
print("Emulate x86_64 code")
|
print("Emulate x86_64 code")
|
||||||
try:
|
try:
|
||||||
@@ -631,14 +637,17 @@ def test_x86_16():
|
|||||||
except UcError as e:
|
except UcError as e:
|
||||||
print("ERROR: %s" % e)
|
print("ERROR: %s" % e)
|
||||||
|
|
||||||
|
|
||||||
def mmio_read_cb(uc, offset, size, data):
|
def mmio_read_cb(uc, offset, size, data):
|
||||||
print(f">>> Read IO memory at offset {hex(offset)} with {hex(size)} bytes and return 0x19260817")
|
print(f">>> Read IO memory at offset {hex(offset)} with {hex(size)} bytes and return 0x19260817")
|
||||||
|
|
||||||
return 0x19260817
|
return 0x19260817
|
||||||
|
|
||||||
|
|
||||||
def mmio_write_cb(uc, offset, size, value, data):
|
def mmio_write_cb(uc, offset, size, value, data):
|
||||||
print(f">>> Write value {hex(value)} to IO memory at offset {hex(offset)} with {hex(size)} bytes")
|
print(f">>> Write value {hex(value)} to IO memory at offset {hex(offset)} with {hex(size)} bytes")
|
||||||
|
|
||||||
|
|
||||||
def test_i386_mmio():
|
def test_i386_mmio():
|
||||||
print("Test i386 IO memory")
|
print("Test i386 IO memory")
|
||||||
try:
|
try:
|
||||||
@@ -664,6 +673,7 @@ def test_i386_mmio():
|
|||||||
except UcError as e:
|
except UcError as e:
|
||||||
print("ERROR: %s" % e)
|
print("ERROR: %s" % e)
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
test_x86_16()
|
test_x86_16()
|
||||||
test_i386()
|
test_i386()
|
||||||
Reference in New Issue
Block a user