Skip to content

Commit a5b752b

Browse files
authored
Add experimental CI for release builds (#39)
1 parent 327b8de commit a5b752b

8 files changed

Lines changed: 132 additions & 28 deletions

File tree

.github/workflows/build-release.yml

Lines changed: 80 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,40 @@ on:
44
workflow_dispatch:
55

66
jobs:
7+
create-release:
8+
runs-on: ubuntu-slim
9+
10+
outputs:
11+
version: ${{ steps.get-version.outputs.version }}
12+
13+
steps:
14+
- name: Checkout
15+
uses: actions/checkout@v6
16+
with:
17+
# fetch full history + tags
18+
fetch-depth: 0
19+
20+
- name: Get version
21+
id: get-version
22+
run: |
23+
VERSION=$(ci/git_version.sh | xargs)
24+
echo "version=${VERSION}" >> $GITHUB_OUTPUT
25+
26+
- name: Create release
27+
env:
28+
GH_TOKEN: ${{ github.token }}
29+
VERSION: ${{ steps.get-version.outputs.version }}
30+
run: |
31+
gh release create ${VERSION} \
32+
--draft \
33+
--title "mrbind ${VERSION}"
34+
735
build-linux:
36+
needs:
37+
- create-release
838
runs-on: ${{ matrix.runner }}
939
container:
10-
image: rockylinux:8
40+
image: almalinux:8
1141
strategy:
1242
fail-fast: false
1343
matrix:
@@ -19,33 +49,68 @@ jobs:
1949
runner: ubuntu-24.04-arm
2050

2151
steps:
22-
- name: Checkout
23-
uses: action/checkout@v6
24-
25-
- name: Install build tools
52+
- name: Install tools
2653
run: |
2754
dnf install -y epel-release
55+
dnf config-manager --add-repo https://cli.github.com/packages/rpm/gh-cli.repo
2856
dnf install -y --enablerepo powertools \
29-
gcc-toolset-14 cmake ninja-build python3
57+
gcc-toolset-14 cmake ninja-build \
58+
$(: CI requirements ) \
59+
git gh unzip zip \
60+
$(: test requirements ) \
61+
gcc-c++ findutils python38-devel
3062
31-
- name: Download LLVM
63+
- name: Checkout
64+
uses: actions/checkout@v6
65+
with:
66+
submodules: true
67+
68+
- name: Fix git permissions
3269
run: |
33-
ci/download_llvm.sh 22.1.8
70+
git config --global --add safe.directory '*'
3471
35-
- name: Build libclang
72+
- name: Download and unpack LLVM
73+
env:
74+
GH_TOKEN: ${{ github.token }}
3675
run: |
37-
source /opt/rh/gcc-toolset-14/enable
38-
ci/build_llvm.sh
76+
gh release download llvm-22.1.8 --pattern "llvm-linux-$(uname -m).zip"
77+
unzip "llvm-linux-$(uname -m).zip"
78+
rm "llvm-linux-$(uname -m).zip"
3979
4080
- name: Build
4181
run: |
4282
source /opt/rh/gcc-toolset-14/enable
4383
cmake -B build -G Ninja \
44-
-D Clang_DIR=llvm-out/lib/cmake/clang \
45-
-D CMAKE_BUILD_TYPE=Release
84+
-D Clang_DIR=llvm/lib/cmake/clang \
85+
-D CMAKE_BUILD_TYPE=Release \
86+
-D MRBIND_STATIC_BUILD=ON \
87+
-D CMAKE_CXX_FLAGS="-ffunction-sections -fdata-sections" \
88+
-D CMAKE_EXE_LINKER_FLAGS="-Wl,--gc-sections -Wl,-s"
4689
cmake --build build --parallel $(nproc)
4790
48-
- name: Verify build
91+
- name: Verify binaries
4992
run: |
93+
ls -l build/mrbind*
5094
ldd build/mrbind*
51-
build/mrbind --help
95+
96+
- name: Test
97+
run: |
98+
export CLANG_RESOURCE_DIR="$(pwd)/llvm/lib/clang/22"
99+
source /opt/rh/gcc-toolset-14/enable
100+
echo g++ > examples/cxx.txt
101+
examples/c/run.sh
102+
PYTHON=python3.8 examples/python/run.sh
103+
104+
- name: Create package
105+
run: |
106+
mkdir mrbind
107+
mv build/mrbind{,_gen_c,_gen_csharp} mrbind/
108+
mv llvm/lib/clang/22 mrbind/resource-dir
109+
zip -r mrbind-linux-$(uname -m).zip mrbind/
110+
111+
- name: Upload package
112+
env:
113+
GH_TOKEN: ${{ github.token }}
114+
VERSION: ${{ needs.create-release.outputs.version }}
115+
run: |
116+
gh release upload ${VERSION} mrbind-linux-$(uname -m).zip --clobber

CMakeLists.txt

Lines changed: 27 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -23,14 +23,20 @@ if(WIN32 AND NOT MINGW)
2323
set(CMAKE_MSVC_RUNTIME_LIBRARY MultiThreaded)
2424
endif()
2525

26-
if (CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
26+
if(CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
2727
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fstandalone-debug")
2828
endif()
29+
if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
30+
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-unused-parameter -Wno-conversion -Wno-extra-semi")
31+
endif()
2932

3033
include_directories(include src)
3134
include_directories(deps/cppdecl/include)
3235

3336

37+
option(MRBIND_STATIC_BUILD "Build the parser and the generators as static binaries." OFF)
38+
39+
3440
add_library(mrbind_common STATIC
3541
src/common/command_line_args_as_utf8.cpp
3642
src/common/command_line_parser.cpp
@@ -55,7 +61,7 @@ if(MRBIND_BUILD_PARSER)
5561
src/parser/multiplex_data.cpp
5662
)
5763

58-
if (CMAKE_CXX_COMPILER_ID STREQUAL "GCC" OR CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
64+
if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU" OR CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
5965
set_source_files_properties(src/parser/disable_rtti.cpp PROPERTIES COMPILE_FLAGS -fno-rtti)
6066
endif()
6167

@@ -65,11 +71,19 @@ if(MRBIND_BUILD_PARSER)
6571

6672
target_include_directories(mrbind PRIVATE ${LLVM_INCLUDE_DIR} ${CLANG_INCLUDE_DIR})
6773

68-
# Clang lets you choose between large dynamic libraries, and fine-grained static libraries.
69-
# Those are the large dynamic ones. If they are not available for some reason,
70-
# we could switch to the static ones (probably conditionally here in CMake, by checking what's available).
71-
# See the git history to see some related static library names.
72-
target_link_libraries(mrbind PRIVATE LLVM clang-cpp)
74+
if(MRBIND_STATIC_BUILD)
75+
target_link_libraries(mrbind PRIVATE -static-libstdc++ -static-libgcc)
76+
if(NOT TARGET clangTooling)
77+
message(FATAL_ERROR "clangTooling is required for static builds")
78+
endif()
79+
target_link_libraries(mrbind PRIVATE clangTooling)
80+
else()
81+
# Clang lets you choose between large dynamic libraries, and fine-grained static libraries.
82+
# Those are the large dynamic ones. If they are not available for some reason,
83+
# we could switch to the static ones (probably conditionally here in CMake, by checking what's available).
84+
# See the git history to see some related static library names.
85+
target_link_libraries(mrbind PRIVATE LLVM clang-cpp)
86+
endif()
7387
endif()
7488

7589

@@ -123,6 +137,9 @@ if(MRBIND_BUILD_GENERATOR_C)
123137
mrbind_gen_common
124138
mrbind_c_interop
125139
)
140+
if(MRBIND_STATIC_BUILD)
141+
target_link_libraries(mrbind_gen_c PRIVATE -static-libstdc++ -static-libgcc)
142+
endif()
126143
endif()
127144

128145
if(MRBIND_BUILD_GENERATOR_CSHARP)
@@ -138,4 +155,7 @@ if(MRBIND_BUILD_GENERATOR_CSHARP)
138155
mrbind_gen_common
139156
mrbind_c_interop
140157
)
158+
if(MRBIND_STATIC_BUILD)
159+
target_link_libraries(mrbind_gen_csharp PRIVATE -static-libstdc++ -static-libgcc)
160+
endif()
141161
endif()

ci/build_llvm.sh

100755100644
Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,17 @@ SRC_DIR=${1:-llvm-src/llvm}
55
BUILD_DIR=llvm-build
66
OUT_DIR=llvm-out
77

8+
# triples may fail to be auto-detected correctly in some cases
9+
HOST_TRIPLE="$(uname -m)-unknown-linux-gnu"
10+
811
cmake -G Ninja -S "$SRC_DIR" -B "$BUILD_DIR" \
912
-DCMAKE_BUILD_TYPE=Release \
1013
-DCMAKE_INSTALL_PREFIX="$OUT_DIR" \
1114
-DCMAKE_INSTALL_LIBDIR=lib \
1215
-DLLVM_ENABLE_PROJECTS=clang \
13-
-DLLVM_TARGETS_TO_BUILD="" \
16+
-DLLVM_TARGETS_TO_BUILD="Native" \
17+
-DLLVM_HOST_TRIPLE="$HOST_TRIPLE" \
18+
-DLLVM_DEFAULT_TARGET_TRIPLE="$HOST_TRIPLE" \
1419
-DBUILD_SHARED_LIBS=OFF \
1520
-DLLVM_BUILD_LLVM_DYLIB=OFF \
1621
-DLLVM_LINK_LLVM_DYLIB=OFF \

ci/download_llvm.sh

100755100644
File mode changed.

ci/git_version.sh

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
#!/bin/sh
2+
set -e
3+
4+
if tag=$(git describe --tags --abbrev=0 --match 'v*' 2>/dev/null); then
5+
count=$(git rev-list --count "${tag}..HEAD")
6+
else
7+
# no reachable version tag, fall back to the CMake default (0.0.0).
8+
tag="v0.0.0"
9+
count=$(git rev-list --count HEAD 2>/dev/null || echo 0)
10+
fi
11+
12+
printf '%s-%s\n' "$tag" "$count"

examples/c/run.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ find input \( -name '*.h' -or -name '*.hpp' \) -printf "#include <%p>\n" >>c/out
6060
"${EXTRA_PARSER_FLAGS[@]}" \
6161
-- \
6262
-xc++-header \
63-
-resource-dir="$("$CLANG_CXX" -print-resource-dir)" \
63+
-resource-dir="${CLANG_RESOURCE_DIR:-$("$CLANG_CXX" -print-resource-dir)}" \
6464
-I. \
6565
"${EXTRA_PARSER_CXX_FLAGS[@]}"
6666

examples/csharp/run.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ find input \( -name '*.h' -or -name '*.hpp' \) -printf "#include <%p>\n" >>cshar
6565
"${EXTRA_PARSER_FLAGS[@]}" \
6666
-- \
6767
-xc++-header \
68-
-resource-dir="$("$CLANG_CXX" -print-resource-dir)" \
68+
-resource-dir="${CLANG_RESOURCE_DIR:-$("$CLANG_CXX" -print-resource-dir)}" \
6969
-I. \
7070
"${EXTRA_PARSER_CXX_FLAGS[@]}"
7171

examples/python/run.sh

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ find input \( -name '*.h' -or -name '*.hpp' \) -printf "#include <%p>\n" >>pytho
5050
"${EXTRA_PARSER_FLAGS[@]}" \
5151
-- \
5252
-xc++-header \
53-
-resource-dir="$("$CLANG_CXX" -print-resource-dir)" \
53+
-resource-dir="${CLANG_RESOURCE_DIR:-$("$CLANG_CXX" -print-resource-dir)}" \
5454
-I. \
5555
"${EXTRA_PARSER_CXX_FLAGS[@]}"
5656

@@ -62,6 +62,8 @@ if [[ ! -d python/pybind11 ]]; then
6262
(cd python/pybind11 && git checkout d2413f5bca91a2c091b9b0801e0c1b5bf089e31d)
6363
fi
6464

65+
PYTHON=${PYTHON:-python3}
66+
6567
# Compile the Python module.
6668
# Note that the output filename must match the name passed to `-DMB_PB11_MODULE_NAME=`, minus the extension.
6769
"$CLANG_CXX" \
@@ -77,8 +79,8 @@ fi
7779
-DMB_PB11_MODULE_NAME=example \
7880
-DMB_DEFINE_IMPLEMENTATION \
7981
-DPYBIND11_COMPILER_TYPE='"_mrbind_example"' -DPYBIND11_BUILD_ABI='"_mrbind_example"' \
80-
$(pkg-config --cflags python3-embed) \
82+
$(${PYTHON}-config --cflags --embed) \
8183
"${EXTRA_CXX_FLAGS[@]}"
8284

8385
# Run a test program using the Python module.
84-
PYTHONPATH=python/output python3 python/example_consumer.py
86+
PYTHONPATH=python/output $PYTHON python/example_consumer.py

0 commit comments

Comments
 (0)