Skip to content

Commit 7e52f1e

Browse files
committed
Add cross build CI workflow.
1 parent 446750f commit 7e52f1e

File tree

10 files changed

+238
-28
lines changed

10 files changed

+238
-28
lines changed

.github/workflows/CrossBuilds.yml

Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
name: Cross Build Tests
2+
on:
3+
push:
4+
paths-ignore:
5+
- ".gitignore"
6+
- "docs/**"
7+
- "ChangeLog"
8+
- "CREDITS.TXT"
9+
- "COMPILE_MAKE.TXT"
10+
- "BUILDING.md"
11+
- "CONTRIBUTING.md"
12+
- "LICENSE.TXT"
13+
- "LICENSE_LLVM.TXT"
14+
- "README.md"
15+
- "RELEASE_NOTES"
16+
- "SPONSORS.TXT"
17+
- "TODO"
18+
pull_request:
19+
20+
# Stop previous runs on the same branch on new push
21+
concurrency:
22+
group: ${{ github.workflow }}-${{ github.ref }}
23+
cancel-in-progress: true
24+
25+
env:
26+
CI: true
27+
UBSAN_OPTIONS: "halt_on_error=1:abort_on_error=1:print_summary=1:print_stacktrace=1"
28+
ASAN_OPTIONS: "halt_on_error=1:abort_on_error=1:print_summary=1:print_stacktrace=1"
29+
LSAN_OPTIONS: "halt_on_error=1:abort_on_error=1:print_summary=1:print_stacktrace=1"
30+
31+
jobs:
32+
Linux:
33+
runs-on: ${{ matrix.config.os }}
34+
name: ${{ matrix.config.name }}
35+
strategy:
36+
fail-fast: false
37+
matrix:
38+
config:
39+
- {
40+
name: 'QEMU Linux s390x',
41+
os: ubuntu-24.04,
42+
arch: x64,
43+
build-system: 'cmake',
44+
diet-build: 'OFF',
45+
build_type: 'Debug',
46+
diet_build: false,
47+
packages: 'gcc-s390x-linux-gnu g++-s390x-linux-gnu binutils-s390x-linux-gnu libc6-dev-s390x-cross qemu-user-static',
48+
cross_file: 'cross_configs/linux_s390x_ubuntu24.cmake',
49+
}
50+
51+
steps:
52+
- uses: actions/checkout@v4
53+
54+
- name: Set up Python
55+
uses: actions/setup-python@v5
56+
with:
57+
python-version: ${{ matrix.config.python-version }}
58+
59+
- name: Install cross build dependencies
60+
env:
61+
packages: ${{ matrix.config.packages }}
62+
run: |
63+
sudo apt-get install -y ${packages}
64+
65+
- name: cmake (cross build)
66+
env:
67+
build_option: ${{ matrix.config.build_option }}
68+
build_type: ${{ matrix.config.build_type }}
69+
cross_file: ${{ matrix.config.cross_file }}
70+
run: |
71+
cmake -DCMAKE_BUILD_TYPE=${build_type} \
72+
-DCAPSTONE_BUILD_STATIC_LIBS=ON \
73+
-S . \
74+
-DCAPSTONE_BUILD_CSTEST=ON \
75+
-DCAPSTONE_BUILD_DIET=${diet_build} \
76+
-DCMAKE_TOOLCHAIN_FILE=${cross_file} \
77+
${build_option} \
78+
-B build .
79+
cmake --build build --config ${build_type}
80+
81+
- name: unit tests
82+
if: startsWith(matrix.config.build-system, 'cmake')
83+
run: |
84+
ctest --test-dir build --output-on-failure -R unit_*
85+
86+
- name: "Integration tests"
87+
if: startsWith(matrix.config.build-system, 'cmake') && matrix.config.diet-build == 'OFF'
88+
run: |
89+
ctest --test-dir build --output-on-failure -R integration_*
90+
91+
- name: cstest MC
92+
if: startsWith(matrix.config.build-system, 'cmake')
93+
run: |
94+
ctest --test-dir build --output-on-failure -R MCTests
95+
96+
- name: cstest details
97+
if: startsWith(matrix.config.build-system, 'cmake')
98+
run: |
99+
ctest --test-dir build --output-on-failure -R DetailTests
100+
101+
- name: cstest issues
102+
if: startsWith(matrix.config.build-system, 'cmake')
103+
run: |
104+
ctest --test-dir build --output-on-failure -R IssueTests
105+
106+
- name: cstest features
107+
if: startsWith(matrix.config.build-system, 'cmake')
108+
run: |
109+
ctest --test-dir build --output-on-failure -R FeaturesTests
110+
111+
- name: Legacy integration tests
112+
if: startsWith(matrix.config.build-system, 'cmake')
113+
run: |
114+
ctest --test-dir build --output-on-failure -R legacy*

BUILDING.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -140,8 +140,9 @@ QEMU_LD_PREFIX=/usr/s390x-redhat-linux/sys-root/fc40/usr/ qemu-s390x-static ./bu
140140
`cstest` is build together with Capstone by adding the flag `-DCAPSTONE_BUILD_CSTEST`.
141141

142142
The build requires `libyaml`. It is a fairly common package and should be provided by your package manager.
143+
If not present it will attempt to build it from source.
143144

144-
_Note:_ Currently `cstest` us only supported on Linux.
145+
_Note:_ Currently `cstest` is only tested on Linux.
145146

146147
If you run another operation system, please install `cstest_py`.
147148
See `bindings/python/BUILDING.md` for instructions.

CMakeLists.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -177,6 +177,9 @@ if(CAPSTONE_BUILD_STATIC_MSVC_RUNTIME)
177177
set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>")
178178
endif()
179179

180+
# The directory for external project patches.
181+
set(EXTERNAL_PROJ_PATCH_DIR ${PROJECT_SOURCE_DIR}/ext_patches/)
182+
180183
## sources
181184
set(SOURCES_ENGINE
182185
cs.c

cross_configs/README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
11
# Cross Compilation Configs
22

33
This directory holds example cross compilation configs for cmake.
4+
5+
Files are named like: `<targetOS>_<targetMachine>_<hostOS>.cmake`
File renamed without changes.
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
# This example file is for builds on Ubunutu 24.04.
2+
# Search for required packages (compiler + libc) with `apt search s390x`
3+
set(CMAKE_C_COMPILER /usr/bin/s390x-linux-gnu-gcc)
4+
set(CMAKE_ASM_COMPILER /usr/bin/s390x-linux-gnu-gcc)
5+
set(CMAKE_CROSS_COMPILING 1)
6+
7+
set(CMAKE_SYSTEM_NAME Linux)
8+
9+
set(CMAKE_SYSROOT /)
10+
11+
set(CMAKE_SYSTEM_PROCESSOR "s390x")
12+
13+
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
14+
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
15+
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
16+
17+
set(CMAKE_CROSSCOMPILING_EMULATOR "qemu-s390x-static;-L;/usr/s390x-linux-gnu/usr/")

docs/cs_v6_release_guide.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -219,12 +219,14 @@ Nonetheless, we hope this additional information is useful to you.
219219
- Testing was re-written from scratch. Now allowing fine-grained testing of all details and is more convenient to use by contributors.
220220
- Architecture modules from a static library, can be initialized on demand to decrease footprint (see: `cmake` option `CAPSTONE_USE_ARCH_REGISTRATION`).
221221
- New `cmake` option to choose between fat and thin binary for Apple.
222+
- Cross compilation support improved.
222223

223224
**Code quality**
224225

225226
- ASAN: All tests are now run with the address sanitizer enabled. This includes checking for leaks.
226227
- Coverity code scanning workflow added and all reported bugs fixed.
227228
- `clang-tidy` workflow added. All reported defects were fixed.
229+
- CI runs tests for s390x big endian target.
228230

229231
### Instruction Alias
230232

ext_patches/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Patches for external build dependencies.
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
cmake_minimum_required(VERSION 3.15)
2+
project(libcyaml VERSION 1.4.2 LANGUAGES C)
3+
4+
# Version defines
5+
add_compile_definitions(
6+
VERSION_MAJOR=1
7+
VERSION_MINOR=4
8+
VERSION_PATCH=2
9+
)
10+
11+
# Set output directories
12+
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
13+
14+
# Source files
15+
set(LIBCYAML_SRC
16+
${CMAKE_SOURCE_DIR}/src/mem.c
17+
${CMAKE_SOURCE_DIR}/src/free.c
18+
${CMAKE_SOURCE_DIR}/src/load.c
19+
${CMAKE_SOURCE_DIR}/src/save.c
20+
${CMAKE_SOURCE_DIR}/src/util.c
21+
${CMAKE_SOURCE_DIR}/src/utf8.c
22+
)
23+
24+
# Include directories
25+
include_directories(include)
26+
27+
# Find libyaml
28+
if (NOT USE_BUILT_LIBYAML)
29+
find_library(libyaml NAMES libyaml yaml REQUIRED)
30+
endif()
31+
include_directories(${LIBYAML_INCLUDE_DIRS})
32+
link_directories(${LIBYAML_LIBRARY_DIRS})
33+
34+
add_library(cyaml_static STATIC ${LIBCYAML_SRC})

suite/cstest/CMakeLists.txt

Lines changed: 63 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -8,90 +8,126 @@ endif()
88
include(ExternalProject)
99
set(CMOCKA_LIB_FILE "${CMAKE_CURRENT_BINARY_DIR}/extern/src/cmocka_ext-build/src/libcmocka.a")
1010

11+
# CMocka is the unit testing library we use.
1112
ExternalProject_Add(cmocka_ext
1213
PREFIX extern
1314
URL "https://cmocka.org/files/1.1/cmocka-1.1.7.tar.xz"
1415
URL_HASH SHA256=810570eb0b8d64804331f82b29ff47c790ce9cd6b163e98d47a4807047ecad82
15-
CONFIGURE_COMMAND cmake -DBUILD_SHARED_LIBS=OFF -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} ../cmocka_ext/
16-
BUILD_COMMAND cmake --build . --config Release
16+
CMAKE_ARGS
17+
-DBUILD_SHARED_LIBS=OFF
18+
-DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}
19+
-DCMAKE_TOOLCHAIN_FILE=${CMAKE_TOOLCHAIN_FILE}
1720
BUILD_BYPRODUCTS "${CMOCKA_LIB_FILE}"
1821
INSTALL_COMMAND ""
1922
)
23+
set(CMOCKA_INCLUDE_DIR ${CMAKE_CURRENT_BINARY_DIR}/extern/src/cmocka_ext/include)
24+
add_library(cmocka STATIC IMPORTED)
25+
set_target_properties(cmocka PROPERTIES IMPORTED_LOCATION "${CMOCKA_LIB_FILE}")
2026

21-
set(use_built_libyaml false)
27+
# libyaml is used to parse the test files.
28+
# Normally it can be installed via the package managers,
29+
# but Windows and cross-compile targets might not have it.
30+
# So it builds it optionally as well.
31+
set(USE_BUILT_LIBYAML false)
2232
find_library(libyaml NAMES libyaml yaml)
23-
2433
if (NOT libyaml)
2534
# Build libyaml
26-
set(use_built_libyaml true)
35+
set(USE_BUILT_LIBYAML true)
2736
message("System libyaml: NO - Building it.")
28-
set(LIBYAML_LIB_FILE "${CMAKE_CURRENT_BINARY_DIR}/extern/src/libyaml_ext/src/.libs/libyaml.a")
37+
set(LIBYAML_LIB_FILE "${CMAKE_CURRENT_BINARY_DIR}/extern/src/libyaml_ext-build/libyaml.a")
38+
set(LIBYAML_LIBRARY_DIRS "${CMAKE_CURRENT_BINARY_DIR}/extern/src/libyaml_ext-build/")
39+
set(LIBYAML_INCLUDE_DIRS "${CMAKE_CURRENT_BINARY_DIR}/extern/src/libyaml_ext/include")
2940
ExternalProject_Add(libyaml_ext
3041
PREFIX extern
3142
URL "https://github.com/yaml/libyaml/archive/refs/tags/0.2.5.tar.gz"
3243
URL_HASH SHA256=fa240dbf262be053f3898006d502d514936c818e422afdcf33921c63bed9bf2e
33-
CMAKE_ARGS -DCMAKE_POLICY_VERSION_MINIMUM=3.5 -DBUILD_TESTING=OFF
44+
# URL "https://github.com/yaml/libyaml/archive/refs/tags/0.1.7.tar.gz"
45+
# URL_HASH SHA256=e1884d0fa1eec8cf869ac6bebbf25391e81956aa2970267f974a9fa5e0b968e2
46+
CMAKE_ARGS
47+
-DCMAKE_POLICY_VERSION_MINIMUM=3.5
48+
-DBUILD_TESTING=OFF
49+
-DBUILD_SHARED_LIBS=OFF
50+
-DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}
51+
-DCMAKE_TOOLCHAIN_FILE=${CMAKE_TOOLCHAIN_FILE}
3452
BUILD_BYPRODUCTS "${LIBYAML_LIB_FILE}"
35-
BUILD_IN_SOURCE true
3653
INSTALL_COMMAND ""
3754
)
38-
set(LIBYAML_INCLUDE_DIR ${CMAKE_CURRENT_BINARY_DIR}/extern/src/libyaml_ext/include)
3955
add_library(libyaml_built STATIC IMPORTED)
4056
set_target_properties(libyaml_built PROPERTIES IMPORTED_LOCATION "${LIBYAML_LIB_FILE}")
57+
set_target_properties(libyaml_built PROPERTIES INCLUDE_DIRECTORIES "${LIBYAML_INCLUDE_DIRS}")
58+
set_target_properties(libyaml_built PROPERTIES LIBRARY_DIRECTORIES "${LIBYAML_LIB_DIR}")
4159
else()
4260
message("System libyaml: YES")
4361
endif()
4462

45-
if ("${CMAKE_BUILD_TYPE}" STREQUAL "Debug")
46-
set(LIBCYAML_VARIANT "debug")
47-
else()
48-
set(LIBCYAML_VARIANT "release")
49-
endif()
63+
# Libcyaml is a wrapper library around libyaml.
64+
# It parses the yaml files so we don't have to.
65+
# Sadly it has no CMakeLists.txt. So we patch it into.
66+
set(LIBCYAML_INCLUDE_DIR "${CMAKE_CURRENT_BINARY_DIR}/extern/src/libcyaml_ext/include")
5067

51-
set(LIBCYAML_LIB_FILE "${CMAKE_CURRENT_BINARY_DIR}/extern/src/libcyaml_ext/build/${LIBCYAML_VARIANT}/libcyaml.a")
68+
set(LIBCYAML_LIB_FILE "${CMAKE_CURRENT_BINARY_DIR}/extern/src/libcyaml_ext-build/lib/libcyaml_static.a")
69+
set(LIBCYAML_LIBRARY_DIR "${CMAKE_CURRENT_BINARY_DIR}/extern/src/libcyaml_ext-build/lib/")
70+
set(LIBCYAML_SRC_DIR "${CMAKE_CURRENT_BINARY_DIR}/extern/src/libcyaml_ext/")
5271
ExternalProject_Add(libcyaml_ext
5372
PREFIX extern
5473
URL "https://github.com/tlsa/libcyaml/archive/refs/tags/v1.4.2.tar.gz"
5574
URL_HASH SHA256=3211b2a0589ebfe02c563c96adce9246c0787be2af30353becbbd362998d16dc
56-
CONFIGURE_COMMAND ""
57-
BUILD_COMMAND make VARIANT=${LIBCYAML_VARIANT} PKG_CONFIG=pkg-config
75+
PATCH_COMMAND cmake -E copy_if_different ${EXTERNAL_PROJ_PATCH_DIR}/libcyaml/CMakeLists.txt ${LIBCYAML_SRC_DIR}
76+
CMAKE_ARGS
77+
-DUSE_BUILT_LIBYAML=${USE_BUILT_LIBYAML}
78+
-DLIBYAML_INCLUDE_DIRS=${LIBYAML_INCLUDE_DIRS}
79+
-DLIBYAML_LIBRARY_DIRS=${LIBYAML_LIBRARY_DIRS}
80+
-DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}
81+
-DCMAKE_TOOLCHAIN_FILE=${CMAKE_TOOLCHAIN_FILE}
5882
BUILD_BYPRODUCTS "${LIBCYAML_LIB_FILE}"
59-
BUILD_IN_SOURCE true
6083
INSTALL_COMMAND ""
6184
)
62-
set(CMOCKA_INCLUDE_DIR ${CMAKE_CURRENT_BINARY_DIR}/extern/src/cmocka_ext/include)
63-
set(LIBCYAML_INCLUDE_DIR ${CMAKE_CURRENT_BINARY_DIR}/extern/src/libcyaml_ext/include)
64-
add_library(cmocka STATIC IMPORTED)
85+
6586
add_library(libcyaml STATIC IMPORTED)
66-
set_target_properties(cmocka PROPERTIES IMPORTED_LOCATION "${CMOCKA_LIB_FILE}")
6787
set_target_properties(libcyaml PROPERTIES IMPORTED_LOCATION "${LIBCYAML_LIB_FILE}")
88+
set_target_properties(libcyaml PROPERTIES INCLUDE_DIRECTORIES "${LIBCYAML_INCLUDE_DIR}")
89+
set_target_properties(libcyaml PROPERTIES LIBRARY_DIRECTORIES "${LIBCYAML_LIBRARY_DIR}")
90+
if (USE_BUILT_LIBYAML)
91+
add_dependencies(libcyaml libyaml_ext)
92+
add_dependencies(libcyaml ${libyaml_built})
93+
target_link_libraries(libcyaml PUBLIC ${libyaml_built})
94+
else()
95+
add_dependencies(libcyaml ${libyaml})
96+
target_link_libraries(libcyaml INTERFACE ${libyaml})
97+
endif()
6898

99+
# The final cstest binary and library.
69100
set(CSTEST_INCLUDE_DIR ${CSTEST_DIR}/include)
70101
file(GLOB CSTEST_SRC ${CSTEST_DIR}/src/*.c)
71102
add_executable(cstest ${CSTEST_SRC})
72103
add_library(libcstest STATIC ${CSTEST_SRC})
104+
73105
add_dependencies(cstest cmocka_ext)
74106
add_dependencies(cstest libcyaml_ext)
75-
if (use_built_libyaml)
76-
target_link_libraries(cstest PUBLIC capstone cmocka libcyaml ${libyaml_built})
77-
target_link_libraries(libcstest PUBLIC capstone cmocka libcyaml ${libyaml_built})
107+
add_dependencies(libcstest cmocka_ext)
108+
add_dependencies(libcstest libcyaml_ext)
109+
110+
if (USE_BUILT_LIBYAML)
111+
target_link_libraries(cstest PUBLIC capstone cmocka libcyaml libyaml_built)
112+
target_link_libraries(libcstest PUBLIC capstone cmocka libcyaml libyaml_built)
78113
else()
79114
target_link_libraries(cstest PUBLIC capstone cmocka libcyaml ${libyaml})
80115
target_link_libraries(libcstest PUBLIC capstone cmocka libcyaml ${libyaml})
81116
endif()
117+
82118
target_include_directories(cstest PRIVATE
83119
${PROJECT_SOURCE_DIR}/include>
84120
${CSTEST_INCLUDE_DIR}
85121
${CMOCKA_INCLUDE_DIR}
86122
${LIBCYAML_INCLUDE_DIR}
87-
${LIBYAML_INCLUDE_DIR}
123+
${LIBYAML_INCLUDE_DIRS}
88124
)
89125
target_include_directories(libcstest PRIVATE
90126
${PROJECT_SOURCE_DIR}/include>
91127
${CSTEST_INCLUDE_DIR}
92128
${CMOCKA_INCLUDE_DIR}
93129
${LIBCYAML_INCLUDE_DIR}
94-
${LIBYAML_INCLUDE_DIR}
130+
${LIBYAML_INCLUDE_DIRS}
95131
)
96132

97133
# Unit tests for cstest

0 commit comments

Comments
 (0)