Skip to content

Commit

Permalink
Start creating Debian Package, will test with PANDA
Browse files Browse the repository at this point in the history
  • Loading branch information
AndrewQuijano committed Dec 6, 2024
1 parent 0206235 commit 7a62be2
Show file tree
Hide file tree
Showing 10 changed files with 245 additions and 21 deletions.
52 changes: 33 additions & 19 deletions .github/workflows/build_release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,33 @@ jobs:
name: build
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
with:
submodules: true

- name: Make setup.sh and check_capstone.sh are executable
run: |
chmod +x ./packages/deb/setup.sh
chmod +x ./packages/deb/check_capstone.sh
- name: Build Debian Package
working-directory: ./packages/deb
run: ./setup.sh ${{ github.event.release.tag_name }}

- name: Run sanity checks on the Debian package
working-directory: ./packages/deb
run: |
./check_capstone.sh ./libcapstone-dev_${{ github.event.release.tag_name }}_amd64.deb
- name: Upload debian package to release
uses: softprops/action-gh-release@v2
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
tag_name: ${{ github.event.release.tag_name }}
files: |
./packages/deb/*.deb
- name: archive
id: archive
run: |
Expand All @@ -27,24 +50,15 @@ jobs:
TARBALL=$PKGNAME.tar.xz
tar cJf $TARBALL $PKGNAME
sha256sum $TARBALL > $SHASUM
echo "::set-output name=tarball::$TARBALL"
echo "::set-output name=shasum::$SHASUM"
- name: upload tarball
uses: actions/upload-release-asset@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
upload_url: ${{ github.event.release.upload_url }}
asset_path: ./${{ steps.archive.outputs.tarball }}
asset_name: ${{ steps.archive.outputs.tarball }}
asset_content_type: application/gzip

- name: upload shasum
uses: actions/upload-release-asset@v1
echo "tarball=$TARBALL" >> $GITHUB_OUTPUT
echo "shasum=$SHASUM" >> $GITHUB_OUTPUT
- name: Upload tarball and shasum to release
uses: softprops/action-gh-release@v2
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
upload_url: ${{ github.event.release.upload_url }}
asset_path: ./${{ steps.archive.outputs.shasum }}
asset_name: ${{ steps.archive.outputs.shasum }}
asset_content_type: text/plain
tag_name: ${{ github.event.release.tag_name }}
files: |
${{ steps.archive.outputs.tarball }}
${{ steps.archive.outputs.shasum }}
2 changes: 1 addition & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -731,7 +731,7 @@ source_group("Include\\TriCore" FILES ${HEADERS_TRICORE})
## installation
if(CAPSTONE_INSTALL)
include(GNUInstallDirs)

install(FILES ${HEADERS_COMMON} DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/capstone)

# Support absolute installation paths (discussion: https://github.com/NixOS/nixpkgs/issues/144170)
Expand Down
1 change: 0 additions & 1 deletion capstone.pc.in
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,3 @@ URL: https://www.capstone-engine.org/
archive=${libdir}/libcapstone.a
Libs: -L${libdir} -lcapstone
Cflags: -I${includedir}/capstone
archs=@CAPSTONE_ARCHITECTURES@
2 changes: 2 additions & 0 deletions packages/deb/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
*.deb
*.txt
69 changes: 69 additions & 0 deletions packages/deb/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
ARG VERSION=""

# Run in the root of the repo
# docker build -f ./packages/deb/Dockerfile -t packager .
FROM debian:bookworm-slim

# Install necessary tools for packaging
RUN apt-get -qq update && \
DEBIAN_FRONTEND=noninteractive apt-get -qq install -y \
fakeroot dpkg-dev dos2unix cmake

# Copy project files into the container
RUN mkdir /capstone
COPY . /capstone
WORKDIR /capstone/

# Using cmake, see BUILDING.md file
# For debug build change "Release" to "Debug"
ARG VERSION
RUN cmake -B build -DCMAKE_BUILD_TYPE=Release -DBUILD_SHARED_LIBS=1 -DPROJECT_VERSION=${VERSION} -DCMAKE_INSTALL_PREFIX=/usr
RUN cmake --build build

# List files before cmake install
# RUN find / -type f > /before-install.txt

# Make directories as needed
RUN mkdir -p /package-root/usr/include/capstone/
RUN mkdir -p /package-root/usr/lib/pkgconfig/
RUN mkdir -p /package-root/usr/bin/
RUN mkdir -p /package-root/usr/share/doc/libcapstone-dev

# Run cmake install
RUN cmake --install build --prefix /package-root/usr/

# List files after cmake install
# RUN find / -type f > /after-install.txt

# Create DEBIAN directory and control file
COPY ./packages/deb/control /package-root/DEBIAN/control

# Copy documentation over
COPY ./ChangeLog /package-root/usr/share/doc/libcapstone-dev
COPY ./CREDITS.TXT /package-root/usr/share/doc/libcapstone-dev
COPY ./HACK.TXT /package-root/usr/share/doc/libcapstone-dev
COPY ./LICENSE.TXT /package-root/usr/share/doc/libcapstone-dev
COPY ./README.md /package-root/usr/share/doc/libcapstone-dev
COPY ./RELEASE_NOTES /package-root/usr/share/doc/libcapstone-dev
COPY ./SPONSORS.TXT /package-root/usr/share/doc/libcapstone-dev

# Generate MD5 checksums for all files and save to DEBIAN/md5sums
RUN cd /package-root && \
find . -type f ! -path './DEBIAN/*' -exec md5sum {} + | sed 's| \./| |' > /package-root/DEBIAN/md5sums

# Update capstone.pc file with the correct version and remove archs field
# Update control file with the correct version
ARG VERSION
# Calculate the installed size and update the control file in a single RUN command
RUN INSTALLED_SIZE=$(du -sk /package-root | cut -f1) && \
sed -i "s/^Installed-Size:.*/Installed-Size: ${INSTALLED_SIZE}/" /package-root/DEBIAN/control
RUN sed -i "s/^Version:.*/Version: ${VERSION}/" /package-root/DEBIAN/control

# Add triggers script to run ldconfig after installation
COPY ./packages/deb/triggers /package-root/DEBIAN/triggers

# Build the package
RUN fakeroot dpkg-deb --build /package-root /libcapstone-dev_${VERSION}_amd64.deb

# The user can now extract the .deb file from the container with something like
# docker run --rm -v $(pwd):/out packager bash -c "cp /libcapstone-dev.deb /out"
7 changes: 7 additions & 0 deletions packages/deb/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
Incomplete Debian package implementation.
It can be used to generate an easily installable Capstone, but misses a lot of
mandatory things to add it in the Debian repos (`debian/control` is incomplete, no dependencies added etc.).

You can build the package by dispatching the `Build Debian Package` workflow or executing the commands in the `Dockerfile`.
It assumes the current commit is tagged and `"$(git describe --tags --abbrev=0)"` returns a valid version number.
The package is uploaded as artifact.
46 changes: 46 additions & 0 deletions packages/deb/check_capstone.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
#!/bin/bash
set -eu

# Usage: ./check_capstone_pc.sh <path_to_deb_file>

DEB_FILE=$1

# Check if the deb file exists
if [[ ! -f "$DEB_FILE" ]]; then
echo "Debian package file not found!"
exit 1
fi

# Create a temporary directory to extract the deb file
TEMP_DIR=$(mktemp -d)

# Extract the deb file
dpkg-deb -x "$DEB_FILE" "$TEMP_DIR"

# Check if the capstone.pc file exists
CAPSTONE_PC="$TEMP_DIR/usr/lib/x86_64-linux-gnu/pkgconfig/capstone.pc"
if [[ ! -f "$CAPSTONE_PC" ]]; then
echo "capstone.pc file not found in the package!"
rm -rf "$TEMP_DIR"
exit 1
fi

# Check if libcapstone.a is included in the package
LIBCAPSTONE_A="$TEMP_DIR/usr/lib/x86_64-linux-gnu/libcapstone.a"
if [[ ! -f "$LIBCAPSTONE_A" ]]; then
echo "libcapstone.a not found in the package!"
rm -rf "$TEMP_DIR"
exit 1
fi

# Check if libcapstone.so is included in the package
LIBCAPSTONE_SO="$TEMP_DIR/usr/lib/x86_64-linux-gnu/libcapstone.so"
if [[ ! -f "$LIBCAPSTONE_SO" ]]; then
echo "libcapstone.so not found in the package!"
rm -rf "$TEMP_DIR"
exit 1
fi

echo "libcapstone-dev.deb file is correct."
rm -rf "$TEMP_DIR"
exit 0
32 changes: 32 additions & 0 deletions packages/deb/control
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
Package: libcapstone-dev
Source: capstone
Version: <version-placeholder>
Architecture: amd64
Maintainer: Rot127 <[email protected]>
Original-Maintainer: Debian Security Tools <[email protected]>
Installed-Size: <size-in-kb>
Depends: libc6 (>= 2.2.5)
Section: libdevel
Priority: optional
Multi-Arch: same
Homepage: https://www.capstone-engine.org/
Description: lightweight multi-architecture disassembly framework - devel files
Capstone is a lightweight multi-platform, multi-architecture disassembly
framework.
.
These are the development headers and libraries.
Features:
- Support hardware architectures: ARM, ARM64 (aka ARMv8), Mips, PowerPC &
Intel.
- Clean/simple/lightweight/intuitive architecture-neutral API.
- Provide details on disassembled instructions (called "decomposer" by some
others).
- Provide some semantics of the disassembled instruction, such as list of
implicit registers read & written.
- Implemented in pure C language, with bindings for Java, OCaml and Python
ready to use and Ruby, C#, GO & Vala available on git repos.
- Native support for Windows & *nix (with OS X, Linux, *BSD & Solaris
confirmed).
- Thread-safe by design.
- Special support for embedding into firmware or OS kernel.
- Distributed under the open source BSD license.
53 changes: 53 additions & 0 deletions packages/deb/setup.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
# !/bin/bash
set -eu

# Function to get the current Ubuntu version
get_os_version() {
lsb_release -i -s 2>/dev/null
}

# Check if the script is running in the ./packages/deb folder
if [[ $(basename "$PWD") != "deb" ]]; then
echo "ERROR: Script must be run from the ./deb directory"
exit 1
fi

OS_VERSION=$(get_os_version)
if [[ "$OS_VERSION" != "Ubuntu" && "$OS_VERSION" != "Debian" ]]; then
echo "ERROR: OS is not Ubuntu or Debian and unsupported"
exit 1
fi

# Get the version number as an input
# Check if version argument is provided
if [[ $# -ne 1 ]]; then
echo "ERROR: Version argument is required"
exit 1
fi

# Get the version number as an input
version=$1

# Remove leading 'v' if present, e. g. v1.5.1 -> 1.5.1
if [[ "$version" =~ ^v[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
version=${version:1}
fi

# Check if the version follows the format for Debian Packages
if [[ ! "$version" =~ ^[0-9]+(.[0-9]+)*(-[A-Za-z0-9]+)?$ ]]; then
echo "ERROR: Version must be in a valid Debian package format"
exit 1
fi

# Now build the packager container from that
pushd ../../
docker build -f ./packages/deb/Dockerfile -t packager --build-arg VERSION="${version}" .
popd

# Copy deb file out of container to host
docker run --rm -v $(pwd):/out packager bash -c "cp /*.deb /out"

# Check which files existed before and after 'make install' was executed.
# docker run --rm -v $(pwd):/out packager bash -c "cp /before-install.txt /out"
# docker run --rm -v $(pwd):/out packager bash -c "cp /after-install.txt /out"
# diff before-install.txt after-install.txt
2 changes: 2 additions & 0 deletions packages/deb/triggers
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# Trigger ldconfig after install
activate-noawait ldconfig

0 comments on commit 7a62be2

Please sign in to comment.