Skip to content

Commit

Permalink
Need to ask about capstone.pc, softlink, and documents. But the main …
Browse files Browse the repository at this point in the history
…thing is working as intended
  • Loading branch information
AndrewQuijano committed Nov 10, 2024
1 parent 729f6f6 commit abeb90e
Show file tree
Hide file tree
Showing 8 changed files with 210 additions and 15 deletions.
2 changes: 2 additions & 0 deletions libcapstone-dev/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
*.deb
*.txt
61 changes: 61 additions & 0 deletions libcapstone-dev/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
ARG VERSION=""
ARG LIBCAPSTONE_NAME=""

# Assume this is run from capstone/debian directory
# Run in the root of the repo
# docker build -f ./debian/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 your 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"
RUN cmake -B build -DCMAKE_BUILD_TYPE=Release -DCAPSTONE_BUILD_SHARED_LIBS=1
RUN cmake --build build

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

# Run cmake install, by default everything goes into /usr/local
RUN cmake --install build

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

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

# Copy /usr/local/include/capstone/ to /package-root/usr/local/include/capstone/ and all other cases
RUN cp -r /usr/local/include/capstone/* /package-root/usr/include/capstone/
RUN cp -r /usr/local/lib/pkgconfig/capstone* /package-root/usr/lib/x86_64-linux-gnu/pkgconfig/
RUN cp -r /usr/local/lib/libcapstone.a /package-root/usr/lib/x86_64-linux-gnu/
# Need libcapstone.a too

# Create DEBIAN directory and control file
COPY ./libcapstone-dev/control /package-root/DEBIAN/control

# Update capstone.pc file with the correct version and remove archs field
# Update control file with the correct version
# TODO, I think pkgconfig needs to point from /usr/local to /usr?
ARG VERSION
ARG LIBCAPSTONE_NAME
RUN sed -i "s/^Version:.*/Version: ${VERSION}/" /package-root/DEBIAN/control
RUN sed -i "s/^Version:.*/Version: ${VERSION}/" /package-root/usr/lib/x86_64-linux-gnu/pkgconfig/capstone.pc
RUN sed -i "s/Depends: <libcapstone-name> (= <version-placeholder>)/Depends: ${LIBCAPSTONE_NAME} (= ${VERSION})/" /package-root/DEBIAN/control
RUN sed -i "/^archs=/d" /package-root/usr/lib/x86_64-linux-gnu/pkgconfig/capstone.pc

# Build the package
RUN fakeroot dpkg-deb --build /package-root /libcapstone-dev.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"
59 changes: 59 additions & 0 deletions libcapstone-dev/check_capstone.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
#!/bin/bash

# Usage: ./check_capstone_pc.sh <path_to_deb_file> <expected_version>

DEB_FILE=$1
EXPECTED_VERSION=$2

# 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"

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

# Check if the version follows the format X.Y.Z, e. g. 1.5.1 or 1.9.1
if [[ ! "$EXPECTED_VERSION" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
echo "ERROR: Version must be in the format X.Y.Z"
exit 1
fi

# Path to the capstone.pc file
CAPSTONE_PC="$TEMP_DIR/usr/lib/x86_64-linux-gnu/pkgconfig/capstone.pc"

# Check if the capstone.pc file exists
if [[ ! -f "$CAPSTONE_PC" ]]; then
echo "capstone.pc file not found in the package!"
rm -rf "$TEMP_DIR"
exit 1
fi

# Check the version in the capstone.pc file
ACTUAL_VERSION=$(grep "^Version:" "$CAPSTONE_PC" | awk '{print $2}')
if [[ "$ACTUAL_VERSION" != "$EXPECTED_VERSION" ]]; then
echo "Version mismatch! Expected: $EXPECTED_VERSION, Found: $ACTUAL_VERSION"
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

echo "libcapstone-dev.deb file is correct."
rm -rf "$TEMP_DIR"
exit 0
20 changes: 20 additions & 0 deletions libcapstone-dev/control
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
Package: libcapstone-dev
Version: <version-placeholder>
Architecture: amd64
Priority: optional
Section: universe/libdevel
Source: capstone
Origin: Ubuntu
Maintainer: Ubuntu Developers <[email protected]>
Original-Maintainer: Debian Security Tools <[email protected]>
Bugs: https://bugs.launchpad.net/ubuntu/+filebug
Installed-Size: 8255 kB
Depends: <libcapstone-name> (= <version-placeholder>)
Homepage: https://www.capstone-engine.org/
Download-Size: 795 kB
APT-Sources: http://archive.ubuntu.com/ubuntu jammy/universe amd64 Packages
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.
58 changes: 58 additions & 0 deletions libcapstone-dev/setup.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
# !/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 ./debian folder
if [[ $(basename "$PWD") != "libcapstone-dev" ]]; then
echo "ERROR: Script must be run from the ./libcapstone-dev 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 X.Y.Z, e. g. 1.5.1 or 1.9.1
if [[ ! "$version" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
echo "ERROR: Version must be in the format X.Y.Z"
exit 1
fi

# Extract the major version
major_version=$(echo "$version" | cut -d. -f1)
# Create the variable with the major version
libcapstone_name="libcapstone${major_version}"

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

# Copy deb file out of container to host
docker run --rm -v $(pwd):/out packager bash -c "cp /libcapstone-dev.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
19 changes: 7 additions & 12 deletions libcapstone/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -22,32 +22,27 @@ RUN cmake -B build -DCMAKE_BUILD_TYPE=Release -DCAPSTONE_BUILD_SHARED_LIBS=1
RUN cmake --build build

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

# Run cmake install, by default everything goes into /usr/local
RUN cmake --install build

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

# Make directories as needed
ARG LIBCAPSTONE_NAME
RUN mkdir -p /package-root/usr/lib/x86_64-linux-gnu/
RUN mkdir -p /package-root/usr/share/doc/${LIBCAPSTONE_NAME}

# TODO: at the moment, I get /usr/local/lib/libcapstone.so.6.0
# My question is, where is the .so.6.0 being populated? Should a fix be made to only have a .5, .6, etc?
# With that said, I will have to assume the version based as an argument is correct in populating the control file

# Copy files to the package root
RUN cp -r /usr/local/lib/libcapstone* /package-root/usr/lib/x86_64-linux-gnu/
RUN cp -r /usr/local/lib/libcapstone.so* /package-root/usr/lib/x86_64-linux-gnu/
# RUN cp /usr/share/doc/${LIBCAPSTONE_NAME}

# Check if there is exactly one file in /package-root/usr/local/lib and rename it
RUN files=$(ls /package-root/usr/lib/x86_64-linux-gnu/libcapstone*.so) && \
if [ $(echo "$files" | wc -l) -eq 1 ]; then \
mv $files /package-root/usr/lib/x86_64-linux-gnu/${LIBCAPSTONE_NAME}.so; \
else \
echo "Error: Expected exactly one file in /package-root/usr/local/lib, found $(echo "$files" | wc -l)"; \
exit 1; \
fi

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

Expand Down
2 changes: 1 addition & 1 deletion libcapstone/control
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
Package: libcapstone<major-version-placeholder>
Version: <version-placeholder>
Architecture: all
Architecture: amd64
Priority: optional
Section: universe/libs
Source: capstone
Expand Down
4 changes: 2 additions & 2 deletions libcapstone/setup.sh
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,6 @@ docker run --rm -v $(pwd):/out packager bash -c "cp /${libcapstone_name}.deb /ou
mv ${libcapstone_name}.deb ${libcapstone_name}_${version}_amd64.deb

# 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"
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

0 comments on commit abeb90e

Please sign in to comment.