ci: Build UHD DEBs with B310 support

Add nib310rio-dev to the Debian build dependencies so the UHD package
build fails if the B310 userspace header is unavailable instead of
silently disabling B300 support.

The Ubuntu installer pipeline downloads the nib310rio Debian package
artifact and exposes it to pbuilder as a local apt repository. This lets
pbuilder satisfy the new dependency inside the clean build root where
CMake checks for nib310rio/nib310rio.h.
This commit is contained in:
Virendra Kakade 2026-09-10 18:26:51 -05:00 committed by mkoop-ni
parent 0d7ed3b1a4
commit eb785ff23b
6 changed files with 68 additions and 12 deletions

View File

@ -42,7 +42,7 @@ jobs:
timeoutInMinutes: 120 timeoutInMinutes: 120
variables: variables:
# Need to use list format to support inclusion of variable groups. # Need to use list format to support inclusion of variable groups.
# Variable group used by .ci/templates/steps-windows-sbom.yml@ettus-rts # Variable group used by .ci/templates/steps-windows-sbom.yml@ettus-rts
- group: meta-ettus-vars - group: meta-ettus-vars
# Variable group needed for code signing (signtool-p4-path) # Variable group needed for code signing (signtool-p4-path)
- ${{ if eq(parameters.toolset, 'msbuild') }}: - ${{ if eq(parameters.toolset, 'msbuild') }}:
@ -102,9 +102,9 @@ jobs:
# Job uses template which causes self checkout to result in different values # Job uses template which causes self checkout to result in different values
# for $(Build.SourcesDirectory) due to single vs multiple repositories use. # for $(Build.SourcesDirectory) due to single vs multiple repositories use.
# Switching to use manual path definition $(Pipeline.Workspace)/s/<RepoName> # Switching to use manual path definition $(Pipeline.Workspace)/s/<RepoName>
# for consistent behavior to avoid # for consistent behavior to avoid
# $(Pipeline.Workspace)/s vs $(Pipeline.Workspace)/s/<RepoName>). # $(Pipeline.Workspace)/s vs $(Pipeline.Workspace)/s/<RepoName>).
# Custom path now includes <RepoName>, which is now hardcoded, rather than # Custom path now includes <RepoName>, which is now hardcoded, rather than
# use name from git repo (avoids problem when building from public uhd repo). # use name from git repo (avoids problem when building from public uhd repo).
# Checkout path needs to be defined relative to $(Pipeline.Workspace). # Checkout path needs to be defined relative to $(Pipeline.Workspace).
- checkout: self - checkout: self
@ -139,7 +139,7 @@ jobs:
- ${{ if parameters.create_sbom }}: - ${{ if parameters.create_sbom }}:
- template: .ci/templates/steps-linux-sbom.yml@ettus-rts - template: .ci/templates/steps-linux-sbom.yml@ettus-rts
parameters: parameters:
toolset: ${{ parameters.toolset }} toolset: ${{ parameters.toolset }}
installer: ${{ parameters.installer }} installer: ${{ parameters.installer }}
sbomComponentList: 'uhd libuhd libboost libusb' sbomComponentList: 'uhd libuhd libboost libusb'
buildOSName: $(buildOSName) buildOSName: $(buildOSName)
@ -148,16 +148,18 @@ jobs:
uhdInstallerDir: $(Build.BinariesDirectory)/uhddev-installer uhdInstallerDir: $(Build.BinariesDirectory)/uhddev-installer
releaseBinaries: ${{ parameters.releaseBinaries }} releaseBinaries: ${{ parameters.releaseBinaries }}
- ${{ if eq(parameters.toolset, 'ubuntu_deb') }}: - ${{ if eq(parameters.toolset, 'ubuntu_deb') }}:
- template: steps-install-nib310rio-dev.yml
- template: steps-build-uhd-installer-ubuntu-deb.yml - template: steps-build-uhd-installer-ubuntu-deb.yml
parameters: parameters:
uhdSrcDir: $(uhdSrcDir) uhdSrcDir: $(uhdSrcDir)
uhdInstallerDir: $(Build.BinariesDirectory)/uhddev-installer uhdInstallerDir: $(Build.BinariesDirectory)/uhddev-installer
ubuntuReleaseName: $(ubuntuReleaseName) ubuntuReleaseName: $(ubuntuReleaseName)
nib310rioDebPackageDir: $(Pipeline.Workspace)/nib310rio_kernel_packages/nib310rio-deb-packages
cmake_args: ${{ parameters.cmake_args }} cmake_args: ${{ parameters.cmake_args }}
- ${{ if parameters.create_sbom }}: - ${{ if parameters.create_sbom }}:
- template: .ci/templates/steps-linux-sbom.yml@ettus-rts - template: .ci/templates/steps-linux-sbom.yml@ettus-rts
parameters: parameters:
toolset: ${{ parameters.toolset }} toolset: ${{ parameters.toolset }}
installer: ${{ parameters.installer }} installer: ${{ parameters.installer }}
sbomComponentList: 'uhd libuhd' sbomComponentList: 'uhd libuhd'
buildOSName: $(buildOSName) buildOSName: $(buildOSName)

View File

@ -8,13 +8,25 @@ parameters:
- name: cmake_args - name: cmake_args
type: string type: string
default: " " default: " "
- name: nib310rioDebPackageDir
type: string
default: ""
steps: steps:
- script: | - script: |
set -euo pipefail
sudo pbuilder create --debootstrapopts --variant=buildd --distribution ${{ parameters.ubuntuReleaseName }} sudo pbuilder create --debootstrapopts --variant=buildd --distribution ${{ parameters.ubuntuReleaseName }}
displayName: Setup pbuilder displayName: Setup pbuilder
- script: | - script: |
set -euo pipefail
mkdir -p ${{ parameters.uhdInstallerDir }} mkdir -p ${{ parameters.uhdInstallerDir }}
cd ${{ parameters.uhdSrcDir }} cd ${{ parameters.uhdSrcDir }}
python3 tools/debs/uhd_ubuntu_deb.py ${{ parameters.ubuntuReleaseName }} --buildpath ${{ parameters.uhdInstallerDir }} pbuilder_args=()
if [[ -n "${{ parameters.nib310rioDebPackageDir }}" ]]; then
pushd "${{ parameters.nib310rioDebPackageDir }}"
dpkg-scanpackages . /dev/null | gzip -9c > Packages.gz
popd
pbuilder_args+=(--pbuilder-extra-apt-repo "${{ parameters.nib310rioDebPackageDir }}")
fi
python3 tools/debs/uhd_ubuntu_deb.py ${{ parameters.ubuntuReleaseName }} --buildpath ${{ parameters.uhdInstallerDir }} "${pbuilder_args[@]}"
displayName: Build dsc and debs displayName: Build dsc and debs

View File

@ -16,6 +16,7 @@ Build-Depends: cmake,
protobuf-compiler, protobuf-compiler,
protobuf-compiler-grpc, protobuf-compiler-grpc,
libncurses-dev, libncurses-dev,
nib310rio-dev [linux-any],
libusb-1.0-0-dev [linux-any hurd-i386], libusb-1.0-0-dev [linux-any hurd-i386],
pkgconf, pkgconf,
python3-dev, python3-dev,

View File

@ -16,6 +16,7 @@ Build-Depends: cmake,
protobuf-compiler, protobuf-compiler,
protobuf-compiler-grpc, protobuf-compiler-grpc,
libncurses-dev, libncurses-dev,
nib310rio-dev [linux-any],
libusb-1.0-0-dev [linux-any hurd-i386], libusb-1.0-0-dev [linux-any hurd-i386],
libusb2-dev [kfreebsd-any], libusb2-dev [kfreebsd-any],
pkgconf, pkgconf,

View File

@ -16,6 +16,7 @@ Build-Depends: cmake,
protobuf-compiler, protobuf-compiler,
protobuf-compiler-grpc, protobuf-compiler-grpc,
libncurses-dev, libncurses-dev,
nib310rio-dev [linux-any],
libusb-1.0-0-dev [linux-any hurd-i386], libusb-1.0-0-dev [linux-any hurd-i386],
libusb2-dev [kfreebsd-any], libusb2-dev [kfreebsd-any],
pkgconf, pkgconf,

View File

@ -16,9 +16,11 @@ import pathlib
import re import re
import shlex import shlex
import shutil import shutil
import stat
import subprocess import subprocess
import sys import sys
import tarfile import tarfile
import tempfile
supported_ubuntu_releases = ["jammy", "noble", "plucky", "resolute"] supported_ubuntu_releases = ["jammy", "noble", "plucky", "resolute"]
tar_command = "tar --exclude='.git*' --exclude='./debian' --exclude='*.swp' --exclude='./fpga/usrp1' --exclude='./fpga/usrp2' --exclude='./fpga/usrp3/top/b200' --exclude='./fpga/usrp3/top/b2xxmini' --exclude='./fpga/usrp3/lib/*_200' --exclude='build' --exclude='./images/*.pyc' --exclude='./images/uhd-*' --exclude='tags' --exclude='.ci' --exclude='.clang*' -cJf {}/uhd_{}.orig.tar.xz ." tar_command = "tar --exclude='.git*' --exclude='./debian' --exclude='*.swp' --exclude='./fpga/usrp1' --exclude='./fpga/usrp2' --exclude='./fpga/usrp3/top/b200' --exclude='./fpga/usrp3/top/b2xxmini' --exclude='./fpga/usrp3/lib/*_200' --exclude='build' --exclude='./images/*.pyc' --exclude='./images/uhd-*' --exclude='tags' --exclude='.ci' --exclude='.clang*' -cJf {}/uhd_{}.orig.tar.xz ."
@ -114,14 +116,45 @@ def main(args):
if not args.nobuild: if not args.nobuild:
print("Building deb with dsc using pbuilder for {}".format(args.release)) print("Building deb with dsc using pbuilder for {}".format(args.release))
os.mkdir(args.buildpath + "/result") os.mkdir(args.buildpath + "/result")
result = subprocess.run( pbuilder_command = [
shlex.split( "sudo",
"sudo pbuilder build --buildresult ./result uhd_{}-0ubuntu1~{}1.dsc".format( "pbuilder",
uhd_version, args.release "build",
"--buildresult",
"./result",
]
# --othermirror is silently ignored by "pbuilder build" (it only applies
# to "pbuilder create"/"update --override-config"), so a local apt repo
# for extra build-deps has to be added via a hook script instead. The D
# hook runs after bind mounts are active but before build-deps are
# resolved, which is the documented place to call apt-get update.
if args.pbuilder_extra_apt_repo:
repo_dir = os.path.abspath(args.pbuilder_extra_apt_repo)
hook_dir = tempfile.mkdtemp(prefix="uhd-pbuilder-hooks-")
hook_path = os.path.join(hook_dir, "D50uhd_local_apt_repo")
with open(hook_path, "w") as hook_file:
hook_file.write(
"#!/bin/bash\n"
"set -euo pipefail\n"
"echo 'deb [trusted=yes] file:{repo_dir} ./' "
"> /etc/apt/sources.list.d/uhd-local-extra.list\n"
"apt-get update\n".format(repo_dir=repo_dir)
) )
), os.chmod(
cwd=args.buildpath, hook_path, os.stat(hook_path).st_mode | stat.S_IXUSR | stat.S_IXGRP | stat.S_IXOTH
)
pbuilder_command.extend(
[
"--bindmounts",
repo_dir,
"--hookdir",
hook_dir,
]
)
pbuilder_command.append(
"uhd_{}-0ubuntu1~{}1.dsc".format(uhd_version, args.release)
) )
result = subprocess.run(pbuilder_command, cwd=args.buildpath)
if result.returncode: if result.returncode:
print("pbuilder failed") print("pbuilder failed")
sys.exit(result.returncode) sys.exit(result.returncode)
@ -159,6 +192,12 @@ if __name__ == "__main__":
required=True, required=True,
help="Output path for build files. " "Will get nuked before creating packages.", help="Output path for build files. " "Will get nuked before creating packages.",
) )
parser.add_argument(
"--pbuilder-extra-apt-repo",
type=str,
default="",
help="Extra apt repository path to bind mount into pbuilder and use for build dependencies.",
)
parser.add_argument( parser.add_argument(
"release", "release",
type=str, type=str,