Add better support for cross builds. (#2803)

* Add several cross compilation toolchain files.

* Make cstest compile sucessfully on targets without libyaml.

* Add cross compilation tests to CI.

* Add test for issue #2339

* Document cross compilation improvements.
This commit is contained in:
Rot127
2025-11-12 11:11:51 +00:00
committed by GitHub
parent 24a2248c1b
commit 8872be6087
18 changed files with 489 additions and 34 deletions
+178
View File
@@ -0,0 +1,178 @@
name: Cross Build Tests
on:
push:
paths-ignore:
- ".gitignore"
- "docs/**"
- "ChangeLog"
- "CREDITS.TXT"
- "COMPILE_MAKE.TXT"
- "BUILDING.md"
- "CONTRIBUTING.md"
- "LICENSE.TXT"
- "LICENSE_LLVM.TXT"
- "README.md"
- "RELEASE_NOTES"
- "SPONSORS.TXT"
- "TODO"
pull_request:
# Stop previous runs on the same branch on new push
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
env:
CI: true
UBSAN_OPTIONS: "halt_on_error=1:abort_on_error=1:print_summary=1:print_stacktrace=1"
ASAN_OPTIONS: "halt_on_error=1:abort_on_error=1:print_summary=1:print_stacktrace=1"
LSAN_OPTIONS: "halt_on_error=1:abort_on_error=1:print_summary=1:print_stacktrace=1"
jobs:
Linux:
runs-on: ${{ matrix.config.os }}
name: ${{ matrix.config.name }}
strategy:
fail-fast: false
matrix:
config:
- {
name: 'QEMU Linux s390x',
os: ubuntu-24.04,
arch: x64,
build-system: 'cmake',
diet-build: 'OFF',
build_type: 'Debug',
diet_build: false,
packages: 'gcc-s390x-linux-gnu g++-s390x-linux-gnu binutils-s390x-linux-gnu libc6-dev-s390x-cross qemu-user-static',
cross_file: 'cross_configs/linux_s390x_ubuntu24.cmake',
}
# - {
# name: 'QEMU Linux Mips 32',
# os: ubuntu-24.04,
# arch: x64,
# build-system: 'cmake',
# diet-build: 'OFF',
# build_type: 'Debug',
# diet_build: false,
# packages: 'gcc-mips-linux-gnu g++-mips-linux-gnu binutils-mips-linux-gnu libc6-dev-mips-cross qemu-user-static',
# cross_file: 'cross_configs/linux_mips_ubuntu24.cmake',
# }
- {
name: 'QEMU Linux Mips64el',
os: ubuntu-24.04,
arch: x64,
build-system: 'cmake',
diet-build: 'OFF',
build_type: 'Debug',
diet_build: false,
packages: 'gcc-mips64el-linux-gnuabi64 g++-mips64el-linux-gnuabi64 binutils-mips64el-linux-gnuabi64 libc6-dev-mips64el-cross qemu-user-static',
cross_file: 'cross_configs/linux_mips64_ubuntu24.cmake',
}
- {
name: 'QEMU Linux PPC64',
os: ubuntu-24.04,
arch: x64,
build-system: 'cmake',
diet-build: 'OFF',
build_type: 'Debug',
diet_build: false,
packages: 'gcc-powerpc64-linux-gnu g++-powerpc64-linux-gnu binutils-powerpc64-linux-gnu libc6-dev-ppc64-cross qemu-user-static',
cross_file: 'cross_configs/linux_ppc64_ubuntu24.cmake',
}
- {
name: '[BUILD ONLY] Android 35 (arm64_v8a) NDK 29',
os: ubuntu-24.04,
arch: x64,
build-system: 'cmake',
build_option: '-DANDROID_NDK=ndk/ -DANDROID_PLATFORM=android-35 -DANDROID_ABI=arm64-v8a',
diet-build: 'OFF',
build_type: 'Debug',
diet_build: false,
# QEMU alone can't emulate the binaries, because the NDK doesn't
# provide dynamic linker.
skip_tests: true,
packages: 'qemu-user-static',
ndk_version: 'r29',
cross_file: 'ndk/build/cmake/android.toolchain.cmake',
qemu: 'qemu-aarch64-static'
}
steps:
- uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.config.python-version }}
- name: Install cross build dependencies
if: ${{ matrix.config.packages != '' }}
env:
packages: ${{ matrix.config.packages }}
run: |
sudo apt-get install -y ${packages}
- name: Setup Android NDK
if: contains(matrix.config.name, 'Android')
env:
ndk_version: ${{ matrix.config.ndk_version }}
qemu: ${{ matrix.config.qemu }}
cross_file: ${{ matrix.config.cross_file }}
run: |
wget -q https://dl.google.com/android/repository/android-ndk-${ndk_version}-linux.zip
mkdir ndk
unzip -q -d ndk android-ndk-${ndk_version}-linux.zip
mv ndk/*/* ndk/
cat ndk/source.properties
- name: cmake (cross build)
env:
build_option: ${{ matrix.config.build_option }}
build_type: ${{ matrix.config.build_type }}
cross_file: ${{ matrix.config.cross_file }}
run: |
cmake -DCMAKE_BUILD_TYPE=${build_type} \
-DCAPSTONE_BUILD_STATIC_LIBS=ON \
-S . \
-DCAPSTONE_BUILD_CSTEST=ON \
-DCAPSTONE_BUILD_DIET=${diet_build} \
-DCMAKE_TOOLCHAIN_FILE=${cross_file} \
${build_option} \
-B build .
cmake --build build --config ${build_type}
- name: unit tests
if: ${{ matrix.config.skip_tests != true }}
run: |
ctest --test-dir build --output-on-failure -R unit_*
- name: "Integration tests"
if: ${{ matrix.config.skip_tests != true }}
run: |
ctest --test-dir build --output-on-failure -R integration_c_*
- name: cstest MC
if: ${{ matrix.config.skip_tests != true }}
run: |
ctest --test-dir build --output-on-failure -R MCTests
- name: cstest details
if: ${{ matrix.config.skip_tests != true }}
run: |
ctest --test-dir build --output-on-failure -R DetailTests
- name: cstest issues
if: ${{ matrix.config.skip_tests != true }}
run: |
ctest --test-dir build --output-on-failure -R IssueTests
- name: cstest features
if: ${{ matrix.config.skip_tests != true }}
run: |
ctest --test-dir build --output-on-failure -R FeaturesTests
- name: Legacy integration tests
if: ${{ matrix.config.skip_tests != true }}
run: |
ctest --test-dir build --output-on-failure -R legacy*
+36 -1
View File
@@ -92,6 +92,40 @@ By default, Capstone use system dynamic memory management, and both DIET and X86
modes are disabled. To use your own memory allocations, turn ON both DIET &
X86_REDUCE, run "cmake" with: `-DCAPSTONE_USE_SYS_DYN_MEM=0`, `-DCAPSTONE_BUILD_DIET=1`, `-DCAPSTONE_X86_REDUCE=1`
### Cross compilation
We have some example configurations for cross builds in [cross_configs](cross_configs/).
Build them with the following command (static build is of course optional):
```bash
cmake -DCMAKE_TOOLCHAIN_FILE=cross_configs/<cross_build_config>.cmake -DCAPSTONE_BUILD_STATIC_LIBS=ON -S . -B build
cmake --build build
```
See the cmake cross compilation [documentation](https://cmake.org/cmake/help/book/mastering-cmake/chapter/Cross%20Compiling%20With%20CMake.html)
for more details.
**Android**
The [Android SDK provides](https://developer.android.com/ndk/guides/cmake) a toolchain file for CMake.
It is the most reliable way to build Capstone for Android.
_Example:_
```bash
cmake -B build -DCMAKE_TOOLCHAIN_FILE=$NDK_PATH/build/cmake/android.toolchain.cmake -DANDROID_NDK=$NDK_PATH -DANDROID_ABI=arm64-v8a
cmake --build build
```
#### Test cross build with QEMU
Running the binaries with QEMU (here an example for s390x on Fedora 40)
is usually done with a command like this:
```bash
QEMU_LD_PREFIX=/usr/s390x-redhat-linux/sys-root/fc40/usr/ qemu-s390x-static ./build/cstool -d aarch64 01421bd501423bd5
```
### Developer specific options
- `CAPSTONE_DEBUG`: Change this to ON to enable extra debug assertions. Automatically enabled with `Debug` build.
@@ -106,8 +140,9 @@ X86_REDUCE, run "cmake" with: `-DCAPSTONE_USE_SYS_DYN_MEM=0`, `-DCAPSTONE_BUILD_
`cstest` is build together with Capstone by adding the flag `-DCAPSTONE_BUILD_CSTEST`.
The build requires `libyaml`. It is a fairly common package and should be provided by your package manager.
If not present it will attempt to build it from source.
_Note:_ Currently `cstest` us only supported on Linux.
_Note:_ Currently `cstest` is only tested on Linux.
If you run another operation system, please install `cstest_py`.
See `bindings/python/BUILDING.md` for instructions.
+3
View File
@@ -177,6 +177,9 @@ if(CAPSTONE_BUILD_STATIC_MSVC_RUNTIME)
set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>")
endif()
# The directory for external project patches.
set(EXTERNAL_PROJ_PATCH_DIR ${PROJECT_SOURCE_DIR}/ext_patches/)
## sources
set(SOURCES_ENGINE
cs.c
+3 -3
View File
@@ -22,11 +22,11 @@ set(CPACK_DEBIAN_PACKAGE_PRIORITY "optional")
set(CPACK_DEBIAN_PACKAGE_MULTIARCH "same")
# Determine architecture for Debian package
if(${CMAKE_SYSTEM_PROCESSOR} STREQUAL "x86_64")
if("${CMAKE_SYSTEM_PROCESSOR}" STREQUAL "x86_64")
set(CPACK_DEBIAN_PACKAGE_ARCHITECTURE "amd64")
elseif(${CMAKE_SYSTEM_PROCESSOR} STREQUAL "i386" OR ${CMAKE_SYSTEM_PROCESSOR} STREQUAL "i686")
elseif("${CMAKE_SYSTEM_PROCESSOR}" STREQUAL "i386" OR "${CMAKE_SYSTEM_PROCESSOR}" STREQUAL "i686")
set(CPACK_DEBIAN_PACKAGE_ARCHITECTURE "i386")
elseif(${CMAKE_SYSTEM_PROCESSOR} STREQUAL "arm")
elseif("${CMAKE_SYSTEM_PROCESSOR}" STREQUAL "arm")
if(CMAKE_SIZE_OF_VOID_P EQUAL 4)
set(CPACK_DEBIAN_PACKAGE_ARCHITECTURE "armhf")
else()
+5
View File
@@ -0,0 +1,5 @@
# Cross Compilation Configs
This directory holds example cross compilation configs for cmake.
Files are named like: `<targetOS>_<targetMachine>_<hostOS>.cmake`
+17
View File
@@ -0,0 +1,17 @@
# This example file is for builds on Ubunutu 24.04.
# Search for required packages (compiler + libc) with `apt search mips64`
# sudo apt install gcc-mips64el-linux-gnuabi64 g++-mips64el-linux-gnuabi64 binutils-mips64el-linux-gnuabi64 libc6-dev-mips64el-cross qemu-user-static
set(CMAKE_SYSTEM_NAME Linux)
set(CMAKE_SYSTEM_PROCESSOR mips64el)
set(CMAKE_C_COMPILER mips64el-linux-gnuabi64-gcc)
set(CMAKE_ASM_COMPILER mips64el-linux-gnuabi64-gcc)
set(CMAKE_CROSS_COMPILING 1)
set(CMAKE_SYSROOT /usr/mips64el-linux-gnuabi64/usr/)
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
set(CMAKE_CROSSCOMPILING_EMULATOR qemu-mips64el-static;-L;/usr/mips64el-linux-gnuabi64/)
+17
View File
@@ -0,0 +1,17 @@
# This example file is for builds on Ubunutu 24.04.
# Search for required packages (compiler + libc) with `apt search mips`
# sudo apt install gcc-mips-linux-gnu g++-mips-linux-gnu binutils-mips-linux-gnu libc6-dev-mips-cross qemu-user-static
set(CMAKE_SYSTEM_NAME Linux)
set(CMAKE_SYSTEM_PROCESSOR mips)
set(CMAKE_C_COMPILER mips-linux-gnu-gcc)
set(CMAKE_ASM_COMPILER mips-linux-gnu-gcc)
set(CMAKE_CROSS_COMPILING 1)
set(CMAKE_SYSROOT /usr/mips-linux-gnu/usr/)
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
set(CMAKE_CROSSCOMPILING_EMULATOR qemu-mips-static;-L;/usr/mips-linux-gnu/)
+17
View File
@@ -0,0 +1,17 @@
# This example file is for builds on Ubunutu 24.04.
# Search for required packages (compiler + libc) with `apt search PPC64`
# sudo apt install gcc-powerpc64-linux-gnu g++-powerpc64-linux-gnu binutils-powerpc64-linux-gnu libc6-dev-ppc64-cross qemu-user-static
set(CMAKE_SYSTEM_NAME Linux)
set(CMAKE_SYSTEM_PROCESSOR ppc64)
set(CMAKE_C_COMPILER powerpc64-linux-gnu-gcc)
set(CMAKE_ASM_COMPILER powerpc64-linux-gnu-gcc)
set(CMAKE_CROSS_COMPILING 1)
set(CMAKE_SYSROOT /usr/powerpc64-linux-gnu/usr)
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
set(CMAKE_CROSSCOMPILING_EMULATOR qemu-ppc64-static;-L;/usr/powerpc64-linux-gnu)
+20
View File
@@ -0,0 +1,20 @@
# This example file is for build on Fedora 42.
# Search for required packages with `dnf search s390x`
# Bug of cmake not passing sysroot early enough
# https://stackoverflow.com/questions/36195791/cmake-missing-sysroot-when-cross-compiling
set(CMAKE_C_COMPILE_OPTIONS_SYSROOT "--sysroot=")
set(CMAKE_CXX_COMPILE_OPTIONS_SYSROOT "--sysroot=")
set(CMAKE_C_COMPILER /usr/bin/s390x-linux-gnu-gcc)
set(CMAKE_ASM_COMPILER /usr/bin/s390x-linux-gnu-gcc)
set(CMAKE_CROSS_COMPILING 1)
set(CMAKE_SYSROOT /usr/s390x-redhat-linux/sys-root/fc42/)
set(CMAKE_FIND_ROOT_PATH /usr/s390x-redhat-linux/sys-root/fc42/)
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
set(CMAKE_CROSSCOMPILING_EMULATOR "qemu-s390x-static;-L;${CMAKE_SYSROOT}/usr/")
+17
View File
@@ -0,0 +1,17 @@
# This example file is for builds on Ubunutu 24.04.
# Search for required packages (compiler + libc) with `apt search s390x`
set(CMAKE_C_COMPILER /usr/bin/s390x-linux-gnu-gcc)
set(CMAKE_ASM_COMPILER /usr/bin/s390x-linux-gnu-gcc)
set(CMAKE_CROSS_COMPILING 1)
set(CMAKE_SYSTEM_NAME Linux)
set(CMAKE_SYSROOT /usr/s390x-linux-gnu/usr/)
set(CMAKE_SYSTEM_PROCESSOR "s390x")
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
set(CMAKE_CROSSCOMPILING_EMULATOR "qemu-s390x-static;-L;/usr/s390x-linux-gnu/")
+24
View File
@@ -0,0 +1,24 @@
# SPDX-FileCopyrightText: 2025 Rot127 <[email protected]>
# SPDX-License-Identifier: LGPL-3.0-only
# Requires the 32bit libc like glibc-devel.i686 libgcc.i686 (Fedora) or similar
# for other distributions.
# This example was tested on Fedora 43
# the name of the target operating system
set(CMAKE_SYSTEM_NAME Linux)
# which compilers to use for C and C++
set(CMAKE_C_COMPILER gcc)
set(CMAKE_C_FLAGS -m32)
set(CMAKE_CXX_COMPILER g++)
set(CMAKE_CXX_FLAGS -m32)
# where is the target environment located
set(CMAKE_FIND_ROOT_PATH /)
set(CMAKE_SYSTEM_PROCESSOR "i686")
# search headers and libraries in the target environment
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
+2
View File
@@ -219,12 +219,14 @@ Nonetheless, we hope this additional information is useful to you.
- Testing was re-written from scratch. Now allowing fine-grained testing of all details and is more convenient to use by contributors.
- Architecture modules from a static library, can be initialized on demand to decrease footprint (see: `cmake` option `CAPSTONE_USE_ARCH_REGISTRATION`).
- New `cmake` option to choose between fat and thin binary for Apple.
- Cross compilation support improved.
**Code quality**
- ASAN: All tests are now run with the address sanitizer enabled. This includes checking for leaks.
- Coverity code scanning workflow added and all reported bugs fixed.
- `clang-tidy` workflow added. All reported defects were fixed.
- CI runs tests for s390x, Mips, PPC, and Android targets.
### Instruction Alias
+1
View File
@@ -0,0 +1 @@
Patches for external build dependencies.
+34
View File
@@ -0,0 +1,34 @@
cmake_minimum_required(VERSION 3.15)
project(libcyaml VERSION 1.4.2 LANGUAGES C)
# Version defines
add_compile_definitions(
VERSION_MAJOR=1
VERSION_MINOR=4
VERSION_PATCH=2
)
# Set output directories
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
# Source files
set(LIBCYAML_SRC
${CMAKE_SOURCE_DIR}/src/mem.c
${CMAKE_SOURCE_DIR}/src/free.c
${CMAKE_SOURCE_DIR}/src/load.c
${CMAKE_SOURCE_DIR}/src/save.c
${CMAKE_SOURCE_DIR}/src/util.c
${CMAKE_SOURCE_DIR}/src/utf8.c
)
# Include directories
include_directories(include)
# Find libyaml
if (NOT USE_BUILT_LIBYAML)
find_library(libyaml NAMES libyaml yaml REQUIRED)
endif()
include_directories(${LIBYAML_INCLUDE_DIRS})
link_directories(${LIBYAML_LIBRARY_DIRS})
add_library(cyaml_static STATIC ${LIBCYAML_SRC})
+102 -28
View File
@@ -6,64 +6,138 @@ if(POLICY CMP0135)
endif()
include(ExternalProject)
find_library(libyaml
NAMES libyaml yaml
REQUIRED)
set(CMOCKA_LIB_FILE "${CMAKE_CURRENT_BINARY_DIR}/extern/src/cmocka_ext-build/src/libcmocka.a")
# CMocka is the unit testing library we use.
ExternalProject_Add(cmocka_ext
PREFIX extern
URL "https://cmocka.org/files/1.1/cmocka-1.1.7.tar.xz"
URL_HASH SHA256=810570eb0b8d64804331f82b29ff47c790ce9cd6b163e98d47a4807047ecad82
CONFIGURE_COMMAND cmake -DBUILD_SHARED_LIBS=OFF -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} ../cmocka_ext/
BUILD_COMMAND cmake --build . --config Release
CMAKE_ARGS
-DBUILD_SHARED_LIBS=OFF
-DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}
-DCMAKE_TOOLCHAIN_FILE=${CMAKE_TOOLCHAIN_FILE}
-DANDROID_NDK=${ANDROID_NDK}
-DANDROID_PLATFORM=${ANDROID_PLATFORM}
-DANDROID_ABI=${ANDROID_ABI}
BUILD_BYPRODUCTS "${CMOCKA_LIB_FILE}"
INSTALL_COMMAND ""
)
set(CMOCKA_INCLUDE_DIR ${CMAKE_CURRENT_BINARY_DIR}/extern/src/cmocka_ext/include)
add_library(cmocka STATIC IMPORTED)
set_target_properties(cmocka PROPERTIES IMPORTED_LOCATION "${CMOCKA_LIB_FILE}")
if ("${CMAKE_BUILD_TYPE}" STREQUAL "Debug")
set(LIBCYAML_VARIANT "debug")
# libyaml is used to parse the test files.
# Normally it can be installed via the package managers,
# but Windows and cross-compile targets might not have it.
# So it builds it optionally as well.
set(USE_BUILT_LIBYAML false)
find_library(libyaml NAMES libyaml yaml)
if (NOT libyaml)
# Build libyaml
set(USE_BUILT_LIBYAML true)
message("System libyaml: NO - Building it.")
set(LIBYAML_LIB_FILE "${CMAKE_CURRENT_BINARY_DIR}/extern/src/libyaml_ext-build/libyaml.a")
set(LIBYAML_LIBRARY_DIRS "${CMAKE_CURRENT_BINARY_DIR}/extern/src/libyaml_ext-build/")
set(LIBYAML_INCLUDE_DIRS "${CMAKE_CURRENT_BINARY_DIR}/extern/src/libyaml_ext/include")
ExternalProject_Add(libyaml_ext
PREFIX extern
URL "https://github.com/yaml/libyaml/archive/refs/tags/0.2.5.tar.gz"
URL_HASH SHA256=fa240dbf262be053f3898006d502d514936c818e422afdcf33921c63bed9bf2e
# URL "https://github.com/yaml/libyaml/archive/refs/tags/0.1.7.tar.gz"
# URL_HASH SHA256=e1884d0fa1eec8cf869ac6bebbf25391e81956aa2970267f974a9fa5e0b968e2
CMAKE_ARGS
-DCMAKE_POLICY_VERSION_MINIMUM=3.5
-DBUILD_TESTING=OFF
-DBUILD_SHARED_LIBS=OFF
-DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}
-DANDROID_NDK=${ANDROID_NDK}
-DANDROID_PLATFORM=${ANDROID_PLATFORM}
-DANDROID_ABI=${ANDROID_ABI}
-DCMAKE_TOOLCHAIN_FILE=${CMAKE_TOOLCHAIN_FILE}
BUILD_BYPRODUCTS "${LIBYAML_LIB_FILE}"
INSTALL_COMMAND ""
)
add_library(libyaml_built STATIC IMPORTED)
set_target_properties(libyaml_built PROPERTIES IMPORTED_LOCATION "${LIBYAML_LIB_FILE}")
set_target_properties(libyaml_built PROPERTIES INCLUDE_DIRECTORIES "${LIBYAML_INCLUDE_DIRS}")
set_target_properties(libyaml_built PROPERTIES LIBRARY_DIRECTORIES "${LIBYAML_LIB_DIR}")
else()
set(LIBCYAML_VARIANT "release")
message("System libyaml: YES")
endif()
set(LIBCYAML_LIB_FILE "${CMAKE_CURRENT_BINARY_DIR}/extern/src/libcyaml_ext/build/${LIBCYAML_VARIANT}/libcyaml.a")
# Libcyaml is a wrapper library around libyaml.
# It parses the yaml files so we don't have to.
# Sadly it has no CMakeLists.txt. So we patch it into.
set(LIBCYAML_INCLUDE_DIR "${CMAKE_CURRENT_BINARY_DIR}/extern/src/libcyaml_ext/include")
set(LIBCYAML_LIB_FILE "${CMAKE_CURRENT_BINARY_DIR}/extern/src/libcyaml_ext-build/lib/libcyaml_static.a")
set(LIBCYAML_LIBRARY_DIR "${CMAKE_CURRENT_BINARY_DIR}/extern/src/libcyaml_ext-build/lib/")
set(LIBCYAML_SRC_DIR "${CMAKE_CURRENT_BINARY_DIR}/extern/src/libcyaml_ext/")
ExternalProject_Add(libcyaml_ext
PREFIX extern
URL "https://github.com/tlsa/libcyaml/archive/refs/tags/v1.4.2.tar.gz"
URL_HASH SHA256=3211b2a0589ebfe02c563c96adce9246c0787be2af30353becbbd362998d16dc
CONFIGURE_COMMAND ""
BUILD_COMMAND make VARIANT=${LIBCYAML_VARIANT} PKG_CONFIG=pkg-config
PATCH_COMMAND cmake -E copy_if_different ${EXTERNAL_PROJ_PATCH_DIR}/libcyaml/CMakeLists.txt ${LIBCYAML_SRC_DIR}
CMAKE_ARGS
-DUSE_BUILT_LIBYAML=${USE_BUILT_LIBYAML}
-DLIBYAML_INCLUDE_DIRS=${LIBYAML_INCLUDE_DIRS}
-DLIBYAML_LIBRARY_DIRS=${LIBYAML_LIBRARY_DIRS}
-DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}
-DCMAKE_TOOLCHAIN_FILE=${CMAKE_TOOLCHAIN_FILE}
-DANDROID_NDK=${ANDROID_NDK}
-DANDROID_PLATFORM=${ANDROID_PLATFORM}
-DANDROID_ABI=${ANDROID_ABI}
BUILD_BYPRODUCTS "${LIBCYAML_LIB_FILE}"
BUILD_IN_SOURCE true
INSTALL_COMMAND ""
)
set(CMOCKA_INCLUDE_DIR ${CMAKE_CURRENT_BINARY_DIR}/extern/src/cmocka_ext/include)
set(LIBCYAML_INCLUDE_DIR ${CMAKE_CURRENT_BINARY_DIR}/extern/src/libcyaml_ext/include)
add_library(cmocka STATIC IMPORTED)
add_library(libcyaml STATIC IMPORTED)
set_target_properties(cmocka PROPERTIES IMPORTED_LOCATION "${CMOCKA_LIB_FILE}")
set_target_properties(libcyaml PROPERTIES IMPORTED_LOCATION "${LIBCYAML_LIB_FILE}")
add_library(libcyaml STATIC IMPORTED)
set_target_properties(libcyaml PROPERTIES IMPORTED_LOCATION "${LIBCYAML_LIB_FILE}")
set_target_properties(libcyaml PROPERTIES INCLUDE_DIRECTORIES "${LIBCYAML_INCLUDE_DIR}")
set_target_properties(libcyaml PROPERTIES LIBRARY_DIRECTORIES "${LIBCYAML_LIBRARY_DIR}")
if (USE_BUILT_LIBYAML)
add_dependencies(libcyaml libyaml_ext)
add_dependencies(libcyaml libyaml_built)
target_link_libraries(libcyaml INTERFACE libyaml_built)
else()
add_dependencies(libcyaml ${libyaml})
target_link_libraries(libcyaml INTERFACE ${libyaml})
endif()
# The final cstest binary and library.
set(CSTEST_INCLUDE_DIR ${CSTEST_DIR}/include)
file(GLOB CSTEST_SRC ${CSTEST_DIR}/src/*.c)
add_executable(cstest ${CSTEST_SRC})
add_library(libcstest STATIC ${CSTEST_SRC})
set_property(TARGET libcstest PROPERTY OUTPUT_NAME cstest)
add_dependencies(cstest cmocka_ext)
add_dependencies(cstest libcyaml_ext)
target_link_libraries(cstest PUBLIC capstone cmocka libcyaml ${libyaml})
target_link_libraries(libcstest PUBLIC capstone cmocka libcyaml ${libyaml})
add_dependencies(libcstest cmocka_ext)
add_dependencies(libcstest libcyaml_ext)
if (USE_BUILT_LIBYAML)
target_link_libraries(cstest PUBLIC capstone cmocka libcyaml libyaml_built)
target_link_libraries(libcstest PUBLIC capstone cmocka libcyaml libyaml_built)
else()
target_link_libraries(cstest PUBLIC capstone cmocka libcyaml ${libyaml})
target_link_libraries(libcstest PUBLIC capstone cmocka libcyaml ${libyaml})
endif()
target_include_directories(cstest PRIVATE
${PROJECT_SOURCE_DIR}/include>
${CSTEST_INCLUDE_DIR}
${CMOCKA_INCLUDE_DIR}
${LIBCYAML_INCLUDE_DIR}
${LIBYAML_INCLUDE_DIRS}
)
target_include_directories(libcstest PRIVATE
${PROJECT_SOURCE_DIR}/include>
${CSTEST_INCLUDE_DIR}
${CMOCKA_INCLUDE_DIR}
${LIBCYAML_INCLUDE_DIR}
${LIBYAML_INCLUDE_DIRS}
)
# Unit tests for cstest
@@ -71,20 +145,20 @@ set(CSTEST_TEST_DIR ${CSTEST_DIR}/test/)
add_subdirectory(${CSTEST_TEST_DIR})
# Test targets
add_test(MCTests
cstest ${PROJECT_SOURCE_DIR}/tests/MC
add_test(NAME MCTests
COMMAND cstest ${PROJECT_SOURCE_DIR}/tests/MC
WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}
)
add_test(DetailTests
cstest ${PROJECT_SOURCE_DIR}/tests/details
add_test(NAME DetailTests
COMMAND cstest ${PROJECT_SOURCE_DIR}/tests/details
WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}
)
add_test(IssueTests
cstest ${PROJECT_SOURCE_DIR}/tests/issues
add_test(NAME IssueTests
COMMAND cstest ${PROJECT_SOURCE_DIR}/tests/issues
WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}
)
add_test(FeaturesTests
cstest ${PROJECT_SOURCE_DIR}/tests/features
add_test(NAME FeaturesTests
COMMAND cstest ${PROJECT_SOURCE_DIR}/tests/features
WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}
)
+1 -1
View File
@@ -17,7 +17,7 @@ add_test(NAME unit_cstest
COMMAND unit_test
WORKING_DIRECTORY ${CSTEST_TEST_DIR}
)
add_test(NAME integration_cstest
add_test(NAME integration_py_cstest
COMMAND python3 ${CSTEST_TEST_DIR}/integration_tests.py cstest
WORKING_DIRECTORY ${CSTEST_TEST_DIR}
)
+1 -1
View File
@@ -28,7 +28,7 @@ add_executable(compat_header_build_test ${COMPAT_C_SRC})
add_dependencies(compat_header_build_test capstone)
target_link_libraries(compat_header_build_test PUBLIC capstone)
add_test(NAME integration_compat_headers
add_test(NAME integration_c_compat_headers
COMMAND compat_header_build_test
WORKING_DIRECTORY ${COMPAT_C_TEST_DIR}
)
+11
View File
@@ -6292,3 +6292,14 @@ test_cases:
insns:
-
asm_text: "repne movsd dword ptr es:[edi], dword ptr [esi]"
-
input:
name: "issue 2339"
bytes: [ 0x8b, 0x34, 0x82 ]
arch: "CS_ARCH_X86"
options: [ CS_MODE_64 ]
address: 0x0
expected:
insns:
-
asm_text: "mov esi, dword ptr [rdx + rax*4]"