mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-08-05 23:41:44 +00:00
a91b1da28b
Build Rocky artifacts with shared IfcOpenShell libraries and keep geometry writer plugins out of executable packages while preserving them for Python packages. Generated with the assistance of an AI coding tool.
241 lines
9.6 KiB
YAML
241 lines
9.6 KiB
YAML
name: Build IfcOpenShell Linux
|
|
|
|
on:
|
|
workflow_dispatch:
|
|
|
|
jobs:
|
|
build_ifcopenshell:
|
|
runs-on: ubuntu-22.04
|
|
container: rockylinux:9
|
|
|
|
steps:
|
|
- name: Install Dependencies
|
|
run: |
|
|
dnf update -y
|
|
dnf install -y epel-release
|
|
dnf install -y gcc gcc-c++ git autoconf automake bison make zip cmake python3 python3-pip \
|
|
bzip2 patch mesa-libGL-devel libffi-devel fontconfig-devel \
|
|
sqlite-devel bzip2-devel zlib-devel openssl-devel xz-devel \
|
|
readline-devel ncurses-devel libffi-devel libuuid-devel git-lfs \
|
|
findutils xz byacc patchelf libxkbcommon-devel \
|
|
python3.11 python3.11-pip python3.11-tkinter
|
|
python3 -m pip install typing_extensions aqtinstall
|
|
git config --global --add safe.directory '*'
|
|
python3.11 -c "import tkinter; print('Tk', tkinter.TkVersion)"
|
|
|
|
- name: Install aws cli
|
|
run: |
|
|
curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip"
|
|
unzip awscliv2.zip
|
|
./aws/install
|
|
rm -rf awscliv2.zip aws
|
|
aws --version
|
|
|
|
- name: Checkout Repository
|
|
uses: actions/checkout@v6
|
|
with:
|
|
submodules: recursive
|
|
|
|
- name: Checkout Build Repository
|
|
uses: actions/checkout@v6
|
|
with:
|
|
repository: IfcOpenShell/build-outputs
|
|
path: ./build
|
|
ref: rockylinux9-x64
|
|
lfs: true
|
|
token: ${{ secrets.BUILD_REPO_TOKEN }}
|
|
|
|
- name: Unpack Dependencies
|
|
run: |
|
|
cd build
|
|
python3 ../nix/cache_dependencies.py unpack
|
|
|
|
- name: ccache
|
|
uses: hendrikmuhs/ccache-action@v1.2.22
|
|
with:
|
|
key: ubuntu-22.04-${{ runner.arch }}-rockylinux9
|
|
|
|
- name: Run Build Script
|
|
shell: bash
|
|
run: |
|
|
set -o pipefail
|
|
CXXFLAGS="-O3" CFLAGS="-O3 ${DARWIN_C_SOURCE}" ADD_COMMIT_SHA=1 BUILD_CFG=Release BUILD_BONSAIVIEWER=ON python3 ./nix/build-all.py -v --diskcleanup --shared 2>&1 | tee build.log
|
|
|
|
- name: Upload Build Logs
|
|
if: always()
|
|
uses: actions/upload-artifact@v7
|
|
with:
|
|
name: build-logs-rocky
|
|
path: |
|
|
build.log
|
|
build/*/*/logs/*.log
|
|
retention-days: 30
|
|
|
|
- name: Pack Dependencies
|
|
run: |
|
|
cd build
|
|
python3 ../nix/cache_dependencies.py pack
|
|
|
|
- name: Commit and Push Changes to Build Repository
|
|
run: |
|
|
cd build
|
|
git config user.name "IfcOpenBot"
|
|
git config user.email "ifcopenbot@ifcopenshell.org"
|
|
git add "$(find . -maxdepth 4 -name install)/*.tar.gz"
|
|
git commit -m "Update build artifacts [skip ci]" || echo "No changes to commit"
|
|
git push || true
|
|
|
|
- name: Package .zip archives
|
|
shell: bash
|
|
run: |
|
|
VERSION=v`cat VERSION`
|
|
python3.11 -m pip install "src/bonsaiviewer-autodesk[build]"
|
|
python3.11 src/bonsaiviewer-autodesk/packaging/build.py
|
|
autodesk_connector_dir="$PWD/src/bonsaiviewer-autodesk/dist/autodesk"
|
|
test -d "$autodesk_connector_dir"
|
|
|
|
cd ./build/`uname`/*/install/ifcopenshell
|
|
mkdir -p ~/output
|
|
install_root="$PWD"
|
|
QT6_VERSION="${QT6_VERSION:-6.8.3}"
|
|
|
|
if [ -z "${QT_DIR:-}" ]; then
|
|
for qt_candidate in "$(dirname "$install_root")"/qt6-${QT6_VERSION}-*/${QT6_VERSION}/*; do
|
|
if [ -d "$qt_candidate/lib" ]; then
|
|
QT_DIR="$qt_candidate"
|
|
break
|
|
fi
|
|
done
|
|
fi
|
|
|
|
ensure_soname_links() {
|
|
dest="$1"
|
|
find "$dest" -maxdepth 1 -type f -name "*.so*" | while IFS= read -r shared_object; do
|
|
soname=$(readelf -d "$shared_object" 2>/dev/null | sed -n 's/.*(SONAME).*Shared library: \[\(.*\)\].*/\1/p' | head -n 1)
|
|
[ -n "$soname" ] || continue
|
|
[ -e "$dest/$soname" ] && continue
|
|
ln -s "$(basename "$shared_object")" "$dest/$soname"
|
|
done
|
|
}
|
|
|
|
stage_runtime_payload() {
|
|
dest="$1"
|
|
include_geometry_writers="${2:-1}"
|
|
while IFS= read -r runtime_file; do
|
|
if [ "$include_geometry_writers" != "1" ] && [[ "$(basename "$runtime_file")" == ifcopenshell.geometry.writer.* ]]; then
|
|
continue
|
|
fi
|
|
cp -P "$runtime_file" "$dest/"
|
|
done < <(
|
|
for runtime_dir in "$install_root/bin" "$install_root/lib" "$install_root/lib64"; do
|
|
[ -d "$runtime_dir" ] || continue
|
|
find "$runtime_dir" \( -type f -o -type l \) \( -name "*.so" -o -name "*.so.*" -o -name "*.dylib" -o -name "*.dll" \)
|
|
done
|
|
)
|
|
ensure_soname_links "$dest"
|
|
}
|
|
|
|
stage_qt_runtime_payload() {
|
|
exe_path="$1"
|
|
dest="$2"
|
|
[ -n "${QT_DIR:-}" ] && [ -d "$QT_DIR/lib" ] || return 0
|
|
|
|
if ! LD_LIBRARY_PATH="$QT_DIR/lib:${LD_LIBRARY_PATH:-}" ldd "$exe_path" 2>/dev/null | grep -q "libQt6"; then
|
|
return 0
|
|
fi
|
|
|
|
find "$QT_DIR/lib" -maxdepth 1 \( -type f -o -type l \) -name "*.so*" -exec cp -P {} "$dest/" \;
|
|
ensure_soname_links "$dest"
|
|
|
|
if [ -d "$QT_DIR/plugins" ]; then
|
|
pushd "$QT_DIR/plugins" > /dev/null
|
|
find . \( -type f -o -type l \) -name "*.so*" | while IFS= read -r plugin_file; do
|
|
mkdir -p "$dest/plugins/$(dirname "$plugin_file")"
|
|
cp -P "$plugin_file" "$dest/plugins/$plugin_file"
|
|
done
|
|
popd > /dev/null
|
|
if [ -d "$dest/plugins" ]; then
|
|
find "$dest/plugins" -type f -name "*.so*" -exec patchelf --set-rpath '$ORIGIN/../..:$ORIGIN' {} \;
|
|
fi
|
|
fi
|
|
|
|
find "$dest" -maxdepth 1 -type f -name "*.so*" -exec patchelf --set-rpath '$ORIGIN' {} \;
|
|
|
|
printf "[Paths]\nPrefix = .\n" > "$dest/qt.conf"
|
|
}
|
|
|
|
check_runtime_dependencies() {
|
|
package_dir="$1"
|
|
missing=0
|
|
while IFS= read -r binary_file; do
|
|
readelf -h "$binary_file" >/dev/null 2>&1 || continue
|
|
if ! env -u LD_LIBRARY_PATH ldd "$binary_file" > "$package_dir/.ldd.out" 2>&1; then
|
|
echo "ldd failed for $binary_file"
|
|
cat "$package_dir/.ldd.out"
|
|
missing=1
|
|
continue
|
|
fi
|
|
if grep -q "not found" "$package_dir/.ldd.out"; then
|
|
echo "Missing runtime dependencies for $binary_file"
|
|
grep "not found" "$package_dir/.ldd.out"
|
|
missing=1
|
|
fi
|
|
done < <(find "$package_dir" -type f \( -perm /111 -o -name "*.so" -o -name "*.so.*" \))
|
|
rm -f "$package_dir/.ldd.out"
|
|
if [ "$missing" -ne 0 ]; then
|
|
echo "Runtime dependency check found issues; continuing packaging."
|
|
fi
|
|
return 0
|
|
}
|
|
|
|
ls -d python-* | while read py_version; do
|
|
postfix=`echo ${py_version: -1} | sed s/[0-9]//`
|
|
numbers=`echo $py_version | grep -oE '[0-9]+\.[0-9]+' | tr -d '.'`
|
|
py_version_major=python-${numbers}$postfix
|
|
pushd . > /dev/null
|
|
cd $py_version
|
|
if [ ! -d ifcopenshell ]; then
|
|
mkdir ../ifcopenshell_
|
|
mv * ../ifcopenshell_
|
|
mv ../ifcopenshell_ ifcopenshell
|
|
fi
|
|
[ -d ifcopenshell/__pycache__ ] && rm -rf ifcopenshell/__pycache__
|
|
find ifcopenshell -name "*.pyc" -delete
|
|
stage_runtime_payload ifcopenshell
|
|
zip -y -r -qq ifcopenshell-${py_version_major}-${VERSION}-${GITHUB_SHA:0:7}-linux64.zip ifcopenshell
|
|
mv *.zip ~/output
|
|
popd > /dev/null
|
|
done
|
|
|
|
rm -f "$install_root"/bin/*.zip
|
|
find "$install_root/bin" -maxdepth 1 -type f -perm /111 ! -name "*.zip" ! -name "*.so" ! -name "*.so.*" ! -name "*.dylib" ! -name "*.dll" | while read exe_path; do
|
|
exe=`basename "$exe_path"`
|
|
package_dir="$install_root/.package-${exe}"
|
|
rm -rf "$package_dir"
|
|
mkdir -p "$package_dir"
|
|
cp "$exe_path" "$package_dir/"
|
|
patchelf --set-rpath '$ORIGIN' "$package_dir/$exe"
|
|
stage_runtime_payload "$package_dir" 0
|
|
stage_qt_runtime_payload "$exe_path" "$package_dir"
|
|
if [ "$exe" = "BonsaiViewer" ]; then
|
|
mkdir -p "$package_dir/connectors"
|
|
cp -a "$autodesk_connector_dir" "$package_dir/connectors/"
|
|
fi
|
|
check_runtime_dependencies "$package_dir"
|
|
pushd "$package_dir" > /dev/null
|
|
zip -y -qq -r "$HOME/output/${exe}-${VERSION}-${GITHUB_SHA:0:7}-linux64.zip" .
|
|
popd > /dev/null
|
|
rm -rf "$package_dir"
|
|
done
|
|
|
|
- name: Configure AWS credentials
|
|
uses: aws-actions/configure-aws-credentials@v6
|
|
with:
|
|
aws-access-key-id: ${{ secrets.AWS_UPLOAD_ACCESS_KEY_ID }}
|
|
aws-secret-access-key: ${{ secrets.AWS_UPLOAD_SECRET_ACCESS_KEY }}
|
|
aws-region: us-east-1
|
|
|
|
- name: Upload .zip archives to S3
|
|
run: |
|
|
aws s3 cp ~/output s3://ifcopenshell-builds/ --recursive
|