Skip to content

Commit ea42c28

Browse files
Creating a functional Debian Package for Capstone v5 (#2569)
1 parent 8455b3c commit ea42c28

File tree

12 files changed

+294
-80
lines changed

12 files changed

+294
-80
lines changed

.gitattributes

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,4 @@
11
/arch/**/*.inc linguist-language=C
2+
3+
# Ensure shell scripts have LF line endings
4+
*.sh text eol=lf

.github/workflows/build_release.yml

Lines changed: 33 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,33 @@ jobs:
1111
name: build
1212
runs-on: ubuntu-latest
1313
steps:
14-
- uses: actions/checkout@v3
14+
- uses: actions/checkout@v4
1515
with:
1616
submodules: true
1717

18+
- name: Make setup.sh and check_capstone.sh are executable
19+
run: |
20+
chmod +x ./packages/deb/setup.sh
21+
chmod +x ./packages/deb/check_capstone.sh
22+
23+
- name: Build Debian Package
24+
working-directory: ./packages/deb
25+
run: ./setup.sh ${{ github.event.release.tag_name }}
26+
27+
- name: Run sanity checks on the Debian package
28+
working-directory: ./packages/deb
29+
run: |
30+
./check_capstone.sh ./libcapstone-dev_${{ github.event.release.tag_name }}_amd64.deb
31+
32+
- name: Upload debian package to release
33+
uses: softprops/action-gh-release@v2
34+
env:
35+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
36+
with:
37+
tag_name: ${{ github.event.release.tag_name }}
38+
files: |
39+
./packages/deb/*.deb
40+
1841
- name: archive
1942
id: archive
2043
run: |
@@ -27,24 +50,15 @@ jobs:
2750
TARBALL=$PKGNAME.tar.xz
2851
tar cJf $TARBALL $PKGNAME
2952
sha256sum $TARBALL > $SHASUM
30-
echo "::set-output name=tarball::$TARBALL"
31-
echo "::set-output name=shasum::$SHASUM"
32-
- name: upload tarball
33-
uses: actions/upload-release-asset@v1
34-
env:
35-
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
36-
with:
37-
upload_url: ${{ github.event.release.upload_url }}
38-
asset_path: ./${{ steps.archive.outputs.tarball }}
39-
asset_name: ${{ steps.archive.outputs.tarball }}
40-
asset_content_type: application/gzip
41-
42-
- name: upload shasum
43-
uses: actions/upload-release-asset@v1
53+
echo "tarball=$TARBALL" >> $GITHUB_OUTPUT
54+
echo "shasum=$SHASUM" >> $GITHUB_OUTPUT
55+
56+
- name: Upload tarball and shasum to release
57+
uses: softprops/action-gh-release@v2
4458
env:
4559
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
4660
with:
47-
upload_url: ${{ github.event.release.upload_url }}
48-
asset_path: ./${{ steps.archive.outputs.shasum }}
49-
asset_name: ${{ steps.archive.outputs.shasum }}
50-
asset_content_type: text/plain
61+
tag_name: ${{ github.event.release.tag_name }}
62+
files: |
63+
${{ steps.archive.outputs.tarball }}
64+
${{ steps.archive.outputs.shasum }}

CMakeLists.txt

Lines changed: 50 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,16 @@ cmake_policy(SET CMP0042 NEW)
2121
# Enable support for MSVC_RUNTIME_LIBRARY
2222
cmake_policy(SET CMP0091 NEW)
2323

24-
project(capstone
25-
VERSION 5.0.3
26-
)
24+
# Check if VERSION is provided externally, otherwise default to 5.0.3
25+
if(NOT DEFINED PROJECT_VERSION)
26+
set(PROJECT_VERSION "5.0.3")
27+
endif()
28+
29+
# Extract the major, minor, and patch versions
30+
string(REGEX MATCH "^[0-9]+\\.[0-9]+\\.[0-9]+" PROJECT_VERSION_BASE ${PROJECT_VERSION})
31+
32+
# Set the project version without the pre-release identifier
33+
project(capstone VERSION ${PROJECT_VERSION_BASE})
2734

2835
if (MSVC)
2936
add_compile_options(/W1 /w14189)
@@ -35,7 +42,8 @@ endif()
3542
# to configure the options specify them in in the command line or change them in the cmake UI.
3643
# Don't edit the makefile!
3744
option(BUILD_SHARED_LIBS "Build shared library" OFF)
38-
option(CAPSTONE_BUILD_STATIC_RUNTIME "Embed static runtime" ${BUILD_SHARED_LIBS})
45+
option(BUILD_STATIC_LIBS "Build static library" ON)
46+
option(BUILD_STATIC_RUNTIME "Embed static MSVC runtime (Windows only). Always set if BUILD_SHARED_LIBS=ON" ${BUILD_SHARED_LIBS})
3947
option(CAPSTONE_BUILD_MACOS_THIN "Disable universal2 builds on macOS" OFF)
4048
option(CAPSTONE_BUILD_DIET "Build diet library" OFF)
4149
option(CAPSTONE_BUILD_TESTS "Build tests" ${PROJECT_IS_TOP_LEVEL})
@@ -46,6 +54,10 @@ option(CAPSTONE_ARCHITECTURE_DEFAULT "Whether architectures are enabled by defau
4654
option(CAPSTONE_DEBUG "Whether to enable extra debug assertions" OFF)
4755
option(CAPSTONE_INSTALL "Generate install target" ${PROJECT_IS_TOP_LEVEL})
4856

57+
if (NOT BUILD_SHARED_LIBS AND NOT BUILD_STATIC_LIBS)
58+
FATAL_ERROR("BUILD_SHARED_LIBS and BUILD_STATIC_LIBS are both unset. Nothing to build.")
59+
endif()
60+
4961
set(SUPPORTED_ARCHITECTURES ARM ARM64 M68K MIPS PPC SPARC SYSZ XCORE X86 TMS320C64X M680X EVM MOS65XX WASM BPF RISCV SH TRICORE)
5062
set(SUPPORTED_ARCHITECTURE_LABELS ARM ARM64 M68K MIPS PowerPC Sparc SystemZ XCore x86 TMS320C64x M680x EVM MOS65XX WASM BPF RISCV SH TriCore)
5163

@@ -109,7 +121,7 @@ if(CAPSTONE_DEBUG)
109121
endif()
110122

111123
# Force static runtime libraries
112-
if(CAPSTONE_BUILD_STATIC_RUNTIME)
124+
if(BUILD_STATIC_RUNTIME)
113125
set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>")
114126
endif()
115127

@@ -631,19 +643,33 @@ set(ALL_HEADERS
631643
set_property(GLOBAL PROPERTY VERSION ${PROJECT_VERSION})
632644

633645
## targets
634-
add_library(capstone ${ALL_SOURCES} ${ALL_HEADERS})
635-
add_library(capstone::capstone ALIAS capstone)
646+
add_library(capstone OBJECT ${ALL_SOURCES} ${ALL_HEADERS})
647+
set_property(TARGET capstone PROPERTY C_STANDARD 99)
636648
target_include_directories(capstone PUBLIC
637649
$<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/include>
638650
)
639-
set_property(TARGET capstone PROPERTY C_STANDARD 99)
651+
if(BUILD_STATIC_LIBS)
652+
add_library(capstone_static STATIC $<TARGET_OBJECTS:capstone>)
653+
# Use normal capstone name. Otherwise we get libcapstone_static.a
654+
set_target_properties(capstone_static PROPERTIES OUTPUT_NAME "capstone")
655+
target_include_directories(capstone_static PUBLIC
656+
$<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/include>
657+
)
658+
endif()
640659

641660
if(BUILD_SHARED_LIBS)
642-
target_compile_definitions(capstone PUBLIC CAPSTONE_SHARED)
643-
set_target_properties(capstone PROPERTIES
661+
set_property(TARGET capstone PROPERTY POSITION_INDEPENDENT_CODE 1)
662+
add_library(capstone_shared SHARED $<TARGET_OBJECTS:capstone>)
663+
# Use normal capstone name. Otherwise we get libcapstone_shared.so
664+
set_target_properties(capstone_shared PROPERTIES OUTPUT_NAME "capstone")
665+
set_target_properties(capstone_shared PROPERTIES
644666
VERSION ${PROJECT_VERSION}
645667
SOVERSION ${PROJECT_VERSION_MAJOR}
646668
)
669+
target_include_directories(capstone_shared PUBLIC
670+
$<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/include>
671+
)
672+
target_compile_definitions(capstone PUBLIC CAPSTONE_SHARED)
647673
endif()
648674

649675
if(CAPSTONE_BUILD_TESTS)
@@ -712,7 +738,6 @@ source_group("Include\\TriCore" FILES ${HEADERS_TRICORE})
712738
## installation
713739
if(CAPSTONE_INSTALL)
714740
include(GNUInstallDirs)
715-
716741
install(FILES ${HEADERS_COMMON} DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/capstone)
717742

718743
# Support absolute installation paths (discussion: https://github.com/NixOS/nixpkgs/issues/144170)
@@ -753,12 +778,20 @@ if(CAPSTONE_INSTALL)
753778
DESTINATION ${CAPSTONE_CMAKE_CONFIG_INSTALL_DIR}
754779
)
755780

756-
install(TARGETS capstone
757-
EXPORT capstone-targets
758-
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
759-
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
760-
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
761-
INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
781+
if(BUILD_SHARED_LIBS)
782+
set(LIB_INSTALL_TARGETS capstone_shared)
783+
endif()
784+
785+
if (BUILD_STATIC_LIBS)
786+
set(LIB_INSTALL_TARGETS ${LIB_INSTALL_TARGETS} capstone_static)
787+
endif()
788+
789+
install(TARGETS ${LIB_INSTALL_TARGETS}
790+
EXPORT capstone-targets
791+
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
792+
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
793+
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
794+
INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
762795
)
763796

764797
install(EXPORT capstone-targets

bindings/python/setup.py

Lines changed: 3 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -62,15 +62,12 @@
6262
if SYSTEM == 'darwin':
6363
VERSIONED_LIBRARY_FILE = "libcapstone.{PKG_MAJOR}.dylib".format(**VERSION_DATA)
6464
LIBRARY_FILE = "libcapstone.dylib"
65-
STATIC_LIBRARY_FILE = 'libcapstone.a'
6665
elif SYSTEM in ('win32', 'cygwin'):
6766
VERSIONED_LIBRARY_FILE = "capstone.dll"
6867
LIBRARY_FILE = "capstone.dll"
69-
STATIC_LIBRARY_FILE = None
7068
else:
7169
VERSIONED_LIBRARY_FILE = "libcapstone.so.{PKG_MAJOR}".format(**VERSION_DATA)
7270
LIBRARY_FILE = "libcapstone.so"
73-
STATIC_LIBRARY_FILE = 'libcapstone.a'
7471

7572
def clean_bins():
7673
shutil.rmtree(LIBS_DIR, ignore_errors=True)
@@ -124,12 +121,9 @@ def build_libraries():
124121
shutil.copytree(os.path.join(BUILD_DIR, 'include', 'capstone'), os.path.join(HEADERS_DIR, 'capstone'))
125122

126123
# if prebuilt libraries are available, use those and cancel build
127-
if os.path.exists(os.path.join(ROOT_DIR, 'prebuilt', LIBRARY_FILE)) and \
128-
(not STATIC_LIBRARY_FILE or os.path.exists(os.path.join(ROOT_DIR, 'prebuilt', STATIC_LIBRARY_FILE))):
124+
if os.path.exists(os.path.join(ROOT_DIR, 'prebuilt', LIBRARY_FILE)):
129125
logger.info('Using prebuilt libraries')
130126
shutil.copy(os.path.join(ROOT_DIR, 'prebuilt', LIBRARY_FILE), LIBS_DIR)
131-
if STATIC_LIBRARY_FILE is not None:
132-
shutil.copy(os.path.join(ROOT_DIR, 'prebuilt', STATIC_LIBRARY_FILE), LIBS_DIR)
133127
return
134128

135129
os.chdir(BUILD_DIR)
@@ -145,19 +139,15 @@ def build_libraries():
145139
os.chdir("build")
146140
print("Build Directory: {}\n".format(os.getcwd()))
147141
# Only build capstone.dll / libcapstone.dylib
148-
if SYSTEM == "win32":
149-
os.system('cmake -DCMAKE_BUILD_TYPE=Release -DBUILD_SHARED_LIBS=ON -DCAPSTONE_BUILD_TESTS=OFF -DCAPSTONE_BUILD_CSTOOL=OFF -G "NMake Makefiles" ..')
142+
if SYSTEM in ('win32', 'cygwin'):
143+
os.system('cmake -DCMAKE_BUILD_TYPE=Release -DBUILD_SHARED_LIBS=ON -DBUILD_STATIC_LIBS=OFF -DCAPSTONE_BUILD_TESTS=OFF -DCAPSTONE_BUILD_CSTOOL=OFF -G "NMake Makefiles" ..')
150144
else:
151145
os.system('cmake -DCMAKE_BUILD_TYPE=Release -DBUILD_SHARED_LIBS=ON -DCAPSTONE_BUILD_TESTS=OFF -DCAPSTONE_BUILD_CSTOOL=OFF -G "Unix Makefiles" ..')
152146
os.system("cmake --build .")
153147
else: # Unix incl. cygwin
154148
os.system("CAPSTONE_BUILD_CORE_ONLY=yes bash ./make.sh")
155149

156150
shutil.copy(VERSIONED_LIBRARY_FILE, os.path.join(LIBS_DIR, LIBRARY_FILE))
157-
158-
# only copy static library if it exists (it's a build option)
159-
if STATIC_LIBRARY_FILE and os.path.exists(STATIC_LIBRARY_FILE):
160-
shutil.copy(STATIC_LIBRARY_FILE, LIBS_DIR)
161151
os.chdir(cwd)
162152

163153

capstone.pc.in

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,4 +10,3 @@ URL: https://www.capstone-engine.org/
1010
archive=${libdir}/libcapstone.a
1111
Libs: -L${libdir} -lcapstone
1212
Cflags: -I${includedir}/capstone
13-
archs=@CAPSTONE_ARCHITECTURES@

nmake.bat

Lines changed: 0 additions & 30 deletions
This file was deleted.

packages/deb/.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
*.deb
2+
*.txt

packages/deb/Dockerfile

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
# SPDX-License-Identifier: MIT
2+
# Copyright (C) 2024 Andrew Quijano
3+
# Contact: andrewquijano92@gmail.com
4+
ARG VERSION=""
5+
6+
# Run in the root of the repo
7+
# docker build -f ./packages/deb/Dockerfile -t packager .
8+
FROM debian:bookworm-slim
9+
10+
# Install necessary tools for packaging
11+
RUN apt-get -qq update && \
12+
DEBIAN_FRONTEND=noninteractive apt-get -qq install -y \
13+
fakeroot dpkg-dev dos2unix cmake
14+
15+
# Copy project files into the container
16+
RUN mkdir /capstone
17+
COPY . /capstone
18+
WORKDIR /capstone/
19+
20+
# Using cmake, see BUILDING.md file
21+
# For debug build change "Release" to "Debug"
22+
ARG VERSION
23+
RUN cmake -B build -DCMAKE_BUILD_TYPE=Release -DBUILD_SHARED_LIBS=1 -DPROJECT_VERSION=${VERSION} -DCMAKE_INSTALL_PREFIX=/usr
24+
RUN cmake --build build
25+
26+
# List files before cmake install
27+
# RUN find / -type f > /before-install.txt
28+
29+
# Make directories as needed
30+
RUN mkdir -p /package-root/usr/include/capstone/
31+
RUN mkdir -p /package-root/usr/lib/pkgconfig/
32+
RUN mkdir -p /package-root/usr/bin/
33+
RUN mkdir -p /package-root/usr/share/doc/libcapstone-dev
34+
35+
# Run cmake install
36+
RUN cmake --install build --prefix /package-root/usr/
37+
38+
# List files after cmake install
39+
# RUN find / -type f > /after-install.txt
40+
41+
# Create DEBIAN directory and control file
42+
COPY ./packages/deb/control /package-root/DEBIAN/control
43+
44+
# Copy documentation over
45+
COPY ./ChangeLog /package-root/usr/share/doc/libcapstone-dev
46+
COPY ./CREDITS.TXT /package-root/usr/share/doc/libcapstone-dev
47+
COPY ./HACK.TXT /package-root/usr/share/doc/libcapstone-dev
48+
COPY ./LICENSE.TXT /package-root/usr/share/doc/libcapstone-dev
49+
COPY ./README.md /package-root/usr/share/doc/libcapstone-dev
50+
COPY ./SPONSORS.TXT /package-root/usr/share/doc/libcapstone-dev
51+
52+
# Generate MD5 checksums for all files and save to DEBIAN/md5sums
53+
RUN cd /package-root && \
54+
find . -type f ! -path './DEBIAN/*' -exec md5sum {} + | sed 's| \./| |' > /package-root/DEBIAN/md5sums
55+
56+
# Update control file with the correct information
57+
ARG VERSION
58+
RUN INSTALLED_SIZE=$(du -sk /package-root | cut -f1) && \
59+
sed -i "s/^Installed-Size:.*/Installed-Size: ${INSTALLED_SIZE}/" /package-root/DEBIAN/control
60+
RUN sed -i "s/^Version:.*/Version: ${VERSION}/" /package-root/DEBIAN/control
61+
62+
# Add triggers script to run ldconfig after installation
63+
COPY ./packages/deb/triggers /package-root/DEBIAN/triggers
64+
65+
# Build the package
66+
RUN fakeroot dpkg-deb --build /package-root /libcapstone-dev_${VERSION}_amd64.deb
67+
68+
# The user can now extract the .deb file from the container with something like
69+
# docker run --rm -v $(pwd):/out packager bash -c "cp /libcapstone-dev.deb /out"

0 commit comments

Comments
 (0)