add bladerf fpga images to snap (#799)

fix #798
This commit is contained in:
Dr. Johannes Pohl
2020-09-08 13:16:49 +02:00
committed by GitHub
parent 88fa644ead
commit 3cbcbf9bb3
3 changed files with 331 additions and 28 deletions

View File

@@ -9,6 +9,6 @@ cd ..
sed -i "s/version\: git/version\: $(python3 src/urh/version.py)/" snapcraft.yaml
SNAPCRAFT_BUILD_ENVIRONMENT_CPU=4 SNAPCRAFT_BUILD_ENVIRONMENT_MEMORY=6G snapcraft
SNAPCRAFT_BUILD_ENVIRONMENT_CPU=6 SNAPCRAFT_BUILD_ENVIRONMENT_MEMORY=18G snapcraft
sudo snap install --dangerous urh*.snap
urh

280
data/semwraplib.c Normal file
View File

@@ -0,0 +1,280 @@
// Source: https://github.com/snapcore/snapcraft-preloads/blob/master/semaphores/preload-semaphores.c
#ifndef _GNU_SOURCE
#define _GNU_SOURCE
#endif
/*
* $ gcc -Wall -fPIC -shared -o mylib.so ./lib.c -ldl
* $ LD_PRELOAD=./mylib.so ...
*/
#include <dlfcn.h>
#include <sys/types.h>
#include <stdio.h>
#include <semaphore.h>
#include <string.h>
#include <stdlib.h>
#include <errno.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
#include <stdarg.h>
#include <limits.h>
static sem_t *(*original_sem_open) (const char *, int, ...);
static int (*original_sem_unlink) (const char *);
// Format is: 'sem.snap.SNAP_NAME.<something>'. So: 'sem.snap.' + '.' = 10
#define MAX_NAME_SIZE NAME_MAX - 10
#define SHM_DIR "/dev/shm"
void debug(char *s, ...)
{
if (secure_getenv("SEMWRAP_DEBUG")) {
va_list va;
va_start(va, s);
fprintf(stderr, "SEMWRAP: ");
vfprintf(stderr, s, va);
va_end(va);
fprintf(stderr, "\n");
}
}
const char *get_snap_name(void)
{
const char *snapname = getenv("SNAP_INSTANCE_NAME");
if (!snapname) {
snapname = getenv("SNAP_NAME");
}
if (!snapname) {
debug("SNAP_NAME and SNAP_INSTANCE_NAME not set");
}
return snapname;
}
int rewrite(const char *snapname, const char *name, char *rewritten,
size_t rmax)
{
if (strlen(snapname) + strlen(name) > MAX_NAME_SIZE) {
errno = ENAMETOOLONG;
return -1;
}
const char *tmp = name;
if (tmp[0] == '/') {
// If specified with leading '/', just strip it to avoid
// having to mkdir(), etc
tmp = &name[1];
}
int n = snprintf(rewritten, rmax, "snap.%s.%s", snapname, tmp);
if (n < 0 || n >= rmax) {
fprintf(stderr, "snprintf truncated\n");
return -1;
}
rewritten[rmax-1] = '\0';
return 0;
}
sem_t *sem_open(const char *name, int oflag, ...)
{
mode_t mode;
unsigned int value;
debug("sem_open()");
debug("requested name: %s", name);
// lookup the libc's sem_open() if we haven't already
if (!original_sem_open) {
dlerror();
original_sem_open = dlsym(RTLD_NEXT, "sem_open");
if (!original_sem_open) {
debug("could not find sem_open in libc");
return SEM_FAILED;
}
dlerror();
}
// mode and value must be set with O_CREAT
va_list argp;
va_start(argp, oflag);
if (oflag & O_CREAT) {
mode = va_arg(argp, mode_t);
value = va_arg(argp, unsigned int);
if (value > SEM_VALUE_MAX) {
errno = EINVAL;
return SEM_FAILED;
}
}
va_end(argp);
const char *snapname = get_snap_name();
// just call libc's sem_open() if snapname not set
if (!snapname) {
if (oflag & O_CREAT) {
return original_sem_open(name, oflag, mode, value);
}
return original_sem_open(name, oflag);
}
// Format the rewritten name
char rewritten[MAX_NAME_SIZE+1];
if (rewrite(snapname, name, rewritten, MAX_NAME_SIZE + 1) != 0) {
return SEM_FAILED;
}
debug("rewritten name: %s", rewritten);
if (oflag & O_CREAT) {
// glibc's sem_open with O_CREAT will create a file in /dev/shm
// by creating a tempfile, initializing it, hardlinking it and
// unlinking the tempfile. We:
// 1. create a temporary file in /dev/shm with rewritten path
// as the template and the specified mode
// 2. initializing a sem_t with sem_init
// 3. writing the initialized sem_t to the temporary file using
// sem_open()s declared value. We used '1' for pshared since
// that is how glibc sets up a named semaphore
// 4. close the temporary file
// 5. hard link the temporary file to the rewritten path. If
// O_EXCL is not specified, ignore EEXIST and just cleanup
// as per documented behavior in 'man sem_open'. If O_EXCL
// is specified and file exists, exit with error. If link is
// successful, cleanup.
// 6. call glibc's sem_open() without O_CREAT|O_EXCL
//
// See glibc's fbtl/sem_open.c for more details
// First, calculate the requested path
char path[PATH_MAX] = { 0 };
// /sem. + '/0' = 14
int max_path_size = strlen(SHM_DIR) + strlen(rewritten) + 6;
if (max_path_size >= PATH_MAX) {
// Should never happen since PATH_MAX should be much
// larger than NAME_MAX, but be defensive.
errno = ENAMETOOLONG;
return SEM_FAILED;
}
int n = snprintf(path, max_path_size, "%s/sem.%s", SHM_DIR,
rewritten);
if (n < 0 || n >= max_path_size) {
errno = ENAMETOOLONG;
return SEM_FAILED;
}
path[max_path_size-1] = '\0';
// Then calculate the template path
char tmp[PATH_MAX] = { 0 };
n = snprintf(tmp, PATH_MAX, "%s/%s.XXXXXX", SHM_DIR,
rewritten);
if (n < 0 || n >= PATH_MAX) {
errno = ENAMETOOLONG;
return SEM_FAILED;
}
tmp[PATH_MAX-1] = '\0';
// Next, create a temporary file
int fd = mkstemp(tmp);
if (fd < 0) {
return SEM_FAILED;
}
debug("tmp name: %s", tmp);
// Update the temporary file to have the requested mode
if (fchmod(fd, mode) < 0) {
close(fd);
unlink(tmp);
return SEM_FAILED;
}
// Then write out an empty semaphore and set the initial value.
// We use '1' for pshared since that is how glibc sets up the
// semaphore (see glibc's fbtl/sem_open.c)
sem_t initsem;
sem_init(&initsem, 1, value);
if (write(fd, &initsem, sizeof(sem_t)) < 0) {
close(fd);
unlink(tmp);
return SEM_FAILED;
}
close(fd);
// Then link the file into place. If the target exists and
// O_EXCL was not specified, just cleanup and proceed to open
// the existing file as per documented behavior in 'man
// sem_open'.
int existed = 0;
if (link(tmp, path) < 0) {
// Note: snapd initially didn't allow 'l' in its
// policy so we first try with link() since it is
// race-free but fallback to rename() if necessary.
if (errno == EACCES || errno == EPERM) {
fprintf(stderr, "sem_open() wrapper: hard linking tempfile denied. Falling back to rename()\n");
if (rename(tmp, path) < 0) {
unlink(tmp);
return SEM_FAILED;
}
} else if (oflag & O_EXCL || errno != EEXIST) {
unlink(tmp);
return SEM_FAILED;
}
existed = 1;
}
unlink(tmp);
// Then call sem_open() on the created file, stripping out the
// O_CREAT|O_EXCL since we just created it
sem_t *sem = original_sem_open(rewritten,
oflag & ~(O_CREAT | O_EXCL));
if (sem == SEM_FAILED) {
if (!existed) {
unlink(path);
}
return SEM_FAILED;
}
return sem;
} else {
// without O_CREAT, just call sem_open with rewritten
return original_sem_open(rewritten, oflag);
}
return SEM_FAILED;
}
// sem_unlink
int sem_unlink(const char *name)
{
debug("sem_unlink()");
debug("requested name: %s", name);
// lookup the libc's sem_unlink() if we haven't already
if (!original_sem_unlink) {
dlerror();
original_sem_unlink = dlsym(RTLD_NEXT, "sem_unlink");
if (!original_sem_unlink) {
debug("could not find sem_unlink in libc");
return -1;
}
dlerror();
}
const char *snapname = get_snap_name();
// just call libc's sem_unlink() if snapname not set
if (!snapname) {
return original_sem_unlink(name);
}
// Format the rewritten name
char rewritten[MAX_NAME_SIZE+1];
if (rewrite(snapname, name, rewritten, MAX_NAME_SIZE + 1) != 0) {
return -1;
}
debug("rewritten name: %s", rewritten);
return original_sem_unlink(rewritten);
}

View File

@@ -44,7 +44,7 @@ plugs: # plugs for theming, font settings, cursor and to use gtk3 file chooser
apps:
urh:
adapter: full
command: snap/command-chain/alsa-launch desktop-launch snapcraft-preload $SNAP/bin/urh
command: snap/command-chain/alsa-launch desktop-launch $SNAP/bin/urh
plugs:
- desktop
- desktop-legacy
@@ -60,21 +60,14 @@ apps:
- network
environment:
QT_QPA_PLATFORMTHEME: gtk3
LD_PRELOAD: $SNAP/lib/semwraplib.so
BLADERF_SEARCH_DIR: $SNAP/bladefpgas
layout:
/usr/lib/$SNAPCRAFT_ARCH_TRIPLET/alsa-lib:
bind: $SNAP/usr/lib/$SNAPCRAFT_ARCH_TRIPLET/alsa-lib
parts:
snapcraft-preload:
source: https://github.com/sergiusens/snapcraft-preload.git
plugin: cmake
build-packages:
- on amd64:
- gcc-multilib
- g++-multilib
stage-packages: [lib32stdc++6]
alsa-mixin:
plugin: dump
source: https://github.com/diddlesnaps/snapcraft-alsa.git
@@ -85,6 +78,16 @@ parts:
- libasound2
- libasound2-plugins
semwraplib:
plugin: nil
source: data
override-build: |
snapcraftctl build
mkdir -p $SNAPCRAFT_PART_INSTALL/lib
gcc -g -O0 -Wall -Wstrict-prototypes -fPIC -shared semwraplib.c -o $SNAPCRAFT_PART_INSTALL/lib/semwraplib.so -ldl
build-packages:
- build-essential
desktop-qt5:
source: https://github.com/ubuntu/snapcraft-desktop-helpers.git
source-subdir: qt
@@ -117,36 +120,44 @@ parts:
- libxcursor1
- libxinerama1
- libxrandr2
- libasyncns0
- libatk-bridge2.0-0
- libatspi2.0-0
- libcairo-gobject2
- libepoxy0
- libflac8
- libgtk-3-0
- libogg0
- libpulse0
- libsndfile1
- libvorbis0a
- libvorbisenc2
- libwayland-cursor0
- libasyncns0
- libatk-bridge2.0-0
- libatspi2.0-0
- libcairo-gobject2
- libepoxy0
- libflac8
- libgtk-3-0
- libogg0
- libpulse0
- libsndfile1
- libvorbis0a
- libvorbisenc2
- libwayland-cursor0
- libwayland-egl1
- libodbc1
- libpq5
- libpulse-mainloop-glib0
- libspeechd2
urh:
after: [desktop-qt5, sdrplay, alsa-mixin]
plugin: python
python-version: python3
requirements: [data/requirements.txt]
source: .
override-build: |
git clone https://github.com/Nuand/bladeRF.git
cd bladeRF/host
mkdir build
cmake -DCMAKE_INSTALL_PREFIX=$SNAPCRAFT_PART_INSTALL ..
make -j$(nproc)
make install
cmake -DCMAKE_INSTALL_PREFIX=/usr ..
make install
snapcraftctl build
build-packages:
- python3
- python3-pyqt5
- libairspy-dev
- libbladerf-dev
- libhackrf-dev
- libiio-dev
- liblimesuite-dev
@@ -154,12 +165,14 @@ parts:
- libuhd-dev
- wget
- execstack
- build-essential
- cmake
- pkg-config
stage-packages:
- python3
- python3-pyqt5
- python3-pyaudio
- libairspy-dev
- libbladerf-dev
- libhackrf-dev
- libiio-dev
- liblimesuite-dev
@@ -185,3 +198,13 @@ parts:
cp x86_64/* .
ln -sf /lib/libmirsdrapi-rsp.so.2.13 /lib/libmirsdrapi-rsp.so
snapcraftctl build
bladerf-fpga:
plugin: dump
source: .
override-build: |
snapcraftctl build
wget https://www.nuand.com/fpga/v0.11.0/hostedxA4.rbf -P $SNAPCRAFT_PART_INSTALL/bladefpgas
wget https://www.nuand.com/fpga/v0.11.0/hostedxA9.rbf -P $SNAPCRAFT_PART_INSTALL/bladefpgas
wget https://www.nuand.com/fpga/v0.11.0/hostedx40.rbf -P $SNAPCRAFT_PART_INSTALL/bladefpgas
wget https://www.nuand.com/fpga/v0.11.0/hostedx115.rbf -P $SNAPCRAFT_PART_INSTALL/bladefpgas