Last active
July 5, 2024 02:02
-
-
Save sultanqasim/765aa38fa12e099da4ac14838e9af8ae to your computer and use it in GitHub Desktop.
SigDigger build script for my unofficial branch for Mac OS (including Apple Silicon)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/sh | |
# | |
set -eux | |
BREW_PREFIX="$(brew --prefix)" | |
CPU_COUNT="$(sysctl -n hw.ncpu)" | |
QT_PATH="${HOME}/Qt/6.7.2/macos" | |
# Homebrew dependencies | |
brew update | |
brew install volk fftw libsndfile libxml2 portaudio dylibbundler | |
brew tap pothosware/homebrew-pothos | |
#brew install pothossoapy soapyairspyhf # broken build | |
brew install soapyrtlsdr soapyhackrf soapybladerf soapyairspy soapyredpitaya soapyiris limesuite soapyplutosdr | |
brew install --head soapyuhd # avoiding C++14 compilation issue, as fix hasn't yet been tagged in a release | |
# get the code | |
if [ ! -e sigutils ]; then | |
git clone -b master --recurse-submodules https://github.com/sultanqasim/sigutils.git | |
fi | |
if [ ! -e suscan ]; then | |
git clone -b master --recurse-submodules https://github.com/sultanqasim/suscan.git | |
fi | |
if [ ! -e SuWidgets ]; then | |
git clone -b develop https://github.com/sultanqasim/SuWidgets | |
fi | |
if [ ! -e SigDigger ]; then | |
git clone -b develop https://github.com/sultanqasim/SigDigger.git | |
fi | |
# prepare the deploy path | |
DEPLOYROOT="$(pwd)/deploy-root" | |
export PKG_CONFIG_PATH="$DEPLOYROOT/usr/lib/pkgconfig" | |
rm -rf "$DEPLOYROOT" | |
mkdir -p "$DEPLOYROOT" | |
# build the source dependencies | |
( | |
cd sigutils | |
rm -rf build | |
mkdir -p build | |
cd build | |
cmake .. -DCMAKE_INSTALL_PREFIX="$DEPLOYROOT/usr" -DCMAKE_SKIP_RPATH=ON -DCMAKE_SKIP_INSTALL_RPATH=ON -DCMAKE_BUILD_TYPE=Release | |
make -j${CPU_COUNT} | |
make install | |
) | |
( | |
cd suscan | |
rm -rf build | |
mkdir -p build | |
cd build | |
cmake .. -DCMAKE_INSTALL_PREFIX="$DEPLOYROOT/usr" -DCMAKE_SKIP_RPATH=ON -DCMAKE_SKIP_INSTALL_RPATH=ON -DCMAKE_PREFIX_PATH="$DEPLOYROOT/usr" -DCMAKE_BUILD_TYPE=Release | |
make -j${CPU_COUNT} | |
make install | |
) | |
( | |
cd SuWidgets | |
"${QT_PATH}/bin/qmake" SuWidgetsLib.pro PREFIX="$DEPLOYROOT/usr" "CONFIG += release" | |
make clean | |
make -j${CPU_COUNT} | |
make install | |
) | |
# build SigDigger | |
( | |
cd SigDigger | |
"${QT_PATH}/bin/qmake" SigDigger.pro PREFIX="$DEPLOYROOT/usr" SUWIDGETS_PREFIX="$DEPLOYROOT/usr" "CONFIG += release" | |
make clean | |
make -j${CPU_COUNT} | |
make install | |
) | |
# utility functions | |
function excluded() | |
{ | |
excludelist="libc++.1.dylib libSystem.B.dylib" | |
for ef in `echo $excludelist`; do | |
if [ "$ef" == "$1" ]; then | |
return 0 | |
fi | |
done | |
return 1 | |
} | |
function find_lib() | |
{ | |
SANE_DIRS="/usr/lib $BREW_PREFIX/lib $LIBPATH" | |
for i in $SANE_DIRS; do | |
if [ -f "$i/$1" ]; then | |
echo "$i/$1" | |
return 0 | |
fi | |
done | |
return 1 | |
} | |
function embed_soapysdr() | |
{ | |
SOAPYSDRVER=`pkg-config SoapySDR --modversion | sed 's/\([0-9]*\.[0-9]*\)\..*/\1/g'` | |
MODDIR="$BREW_PREFIX/lib/SoapySDR/modules$SOAPYSDRVER" | |
mkdir -p "$LIBPATH/SoapySDR/" | |
cp -RLfv "$MODDIR" "$LIBPATH/SoapySDR" | |
# rename module directory without . to make codesign friendly | |
mv "$LIBPATH/SoapySDR/modules$SOAPYSDRVER" "$LIBPATH/SoapySDR/modules" | |
# copy in all dependencies | |
for f in "$LIBPATH/SoapySDR/modules"/*; do | |
dylibbundler -cd -of -b -x "$f" -d "$LIBPATH" -p "@executable_path/../Frameworks/" | |
done | |
# fix duplicate library | |
rm "$LIBPATH/libSoapySDR.0.8.dylib" | |
ln -s "./"`basename "$LIBPATH/libSoapySDR.0.8."*".dylib"` "$LIBPATH/libSoapySDR.0.8.dylib" | |
# make sure local soapy modules are used, not homebrew ones | |
ESCAPED_BREW_PREFIX=$(printf '%s\n' "$BREW_PREFIX" | sed -e 's/[\/&]/\\&/g') | |
ZSTR=$(printf 'z%.0s' $(seq 1 ${#BREW_PREFIX})) | |
LC_ALL=C sed -e 's/'"${ESCAPED_BREW_PREFIX}"'/'"${ZSTR}"'/' "$LIBPATH/libSoapySDR.0.8."*".dylib" >_delme_soapy | |
mv _delme_soapy "$LIBPATH/libSoapySDR.0.8."*".dylib" | |
return 0 | |
} | |
function deploy_deps() | |
{ | |
embed_soapysdr | |
cp -RLfv "$BREW_PREFIX/opt/gcc/lib/gcc/current/libgcc_s.1.1.dylib" "$LIBPATH" | |
} | |
function swap_uhd() | |
{ | |
# my hacked fork of uhd with fast retuning | |
# https://github.com/sultanqasim/uhd | |
# | |
# build by running: | |
# mkdir -p uhd/host/build | |
# cd uhd/host/build | |
# cmake .. -DCMAKE_BUILD_TYPE=Release -DENABLE_SIM=OFF | |
# make -j5 | |
cp uhd/host/build/lib/libuhd.4.7.0.dylib "$LIBPATH/" | |
dylibbundler -cd -of -b -x "$LIBPATH/libuhd.4.7.0.dylib" -d "$LIBPATH" -p "@executable_path/../Frameworks/" | |
} | |
function remove_full_paths() | |
{ | |
FULLPATH="$2" | |
if [[ "$2" == *".framework"* ]]; then | |
FWNAME=`basename "$FULLPATH"` | |
RPATHNAME='@executable_path/../Frameworks/'"$FWNAME.framework/Versions/A/$FWNAME" | |
else | |
RPATHNAME='@executable_path/../Frameworks/'`basename "$FULLPATH"` | |
fi | |
install_name_tool -change "$FULLPATH" "$RPATHNAME" "$1" | |
} | |
function remove_full_path_stdin () { | |
while read line; do | |
remove_full_paths "$1" "$line" | |
done | |
} | |
function ensure_rpath() | |
{ | |
for i in "$LIBPATH"/*.dylib "$LIBPATH/SoapySDR/modules"*/*.so "$BUNDLEPATH"/Contents/MacOS/*; do | |
if ! [ -L "$i" ]; then | |
chmod u+rw "$i" | |
echo "Fixing "`basename $i`"..." | |
otool -L "$i" | grep '\t'"$BREW_PREFIX/" | tr -d '\t' | cut -f1 -d ' ' | remove_full_path_stdin "$i"; | |
otool -L "$i" | grep '\t@rpath/.*\.dylib' | tr -d '\t' | cut -f1 -d ' ' | remove_full_path_stdin "$i"; | |
fi | |
done | |
} | |
function fix_loader_path() | |
{ | |
# $1 is library name, $2 is dependency path relative to BREW_PREFIX | |
DEPNAME=`basename "$2"` | |
install_name_tool -change "@loader_path/../../../../$2" "@executable_path/../Frameworks/$DEPNAME" "$LIBPATH/$1" | |
} | |
function fix_loader_path_and_copy_lib() | |
{ | |
FILENAME=`basename "$2"` | |
fix_loader_path "$1" "$2" | |
cp -p "$BREW_PREFIX/$2" "$LIBPATH/$FILENAME" | |
} | |
function copy_su_libs() | |
{ | |
cp -fv "$DEPLOYROOT/usr/lib/libsigutils.1.dylib" "$LIBPATH" | |
cp -fv "$DEPLOYROOT/usr/lib/libsuscan.0."*.*".dylib" "$LIBPATH" | |
cp -fv "$DEPLOYROOT/usr/lib/libsuwidgets.0.dylib" "$LIBPATH" | |
} | |
function fix_sndfile() | |
{ | |
# workaround for homebrew libsndfile path issues | |
fix_loader_path_and_copy_lib "libsndfile.1.dylib" "opt/libogg/lib/libogg.0.dylib" | |
fix_loader_path_and_copy_lib "libsndfile.1.dylib" "opt/libvorbis/lib/libvorbisenc.2.dylib" | |
fix_loader_path_and_copy_lib "libsndfile.1.dylib" "opt/flac/lib/libFLAC.12.dylib" | |
fix_loader_path_and_copy_lib "libsndfile.1.dylib" "opt/opus/lib/libopus.0.dylib" | |
fix_loader_path_and_copy_lib "libsndfile.1.dylib" "opt/mpg123/lib/libmpg123.0.dylib" | |
fix_loader_path_and_copy_lib "libsndfile.1.dylib" "opt/lame/lib/libmp3lame.0.dylib" | |
fix_loader_path_and_copy_lib "libsndfile.1.dylib" "opt/libvorbis/lib/libvorbis.0.dylib" | |
} | |
function fix_plist() | |
{ | |
plutil -replace CFBundleIdentifier -string "$BUNDLEID" "$PLISTPATH" | |
plutil -replace CFBundleName -string "SigDigger" "$PLISTPATH" | |
plutil -replace CFBundleDevelopmentRegion -string "en" "$PLISTPATH" | |
} | |
function copy_usrp_fw() | |
{ | |
mkdir -p "${BUNDLEPATH}/Contents/share/uhd/images" | |
cp "${BREW_PREFIX}/share/uhd/images/usrp_b2"* "${BUNDLEPATH}/Contents/share/uhd/images/" | |
} | |
function sign_code() | |
{ | |
find "$BUNDLEPATH" -name '*.framework' -or -name '*.dylib' -or -name '*.so' | { | |
while read -r f; do | |
codesign --sign - --force --preserve-metadata=entitlements,requirements,flags,runtime "${f}" | |
done | |
} | |
codesign --sign - --force --preserve-metadata=entitlements,requirements,flags,runtime "${BUNDLEPATH}/Contents/MacOS/SigDigger" | |
codesign --sign - --force --preserve-metadata=entitlements,requirements,flags,runtime "$BUNDLEPATH" | |
} | |
function create_dmg() | |
{ | |
rm -Rfv "$STAGINGDIR" | |
mkdir -p "$STAGINGDIR" | |
cp -Rfv "$BUNDLEPATH" "$STAGINGDIR" | |
hdiutil create -verbose -volname SigDigger -srcfolder "$STAGINGDIR" -ov -format UDZO "$DMG_NAME" | |
} | |
# turn it into a complete app bundle with all libraries included | |
BUNDLEID="org.actinid.SigDigger" | |
BUNDLEPATH="$DEPLOYROOT/usr/bin/SigDigger.app" | |
PLISTPATH="$BUNDLEPATH/Contents/Info.plist" | |
RSRCPATH="$BUNDLEPATH/Contents/Resources" | |
LIBPATH="$BUNDLEPATH/Contents/Frameworks" | |
BINPATH="$BUNDLEPATH/Contents/MacOS" | |
STAGINGDIR="$DEPLOYROOT/SigDigger.dir" | |
DMG_NAME="SigDigger.dmg" | |
"${QT_PATH}/bin/macdeployqt" "$BUNDLEPATH" | |
cp -Rfv "$DEPLOYROOT/usr/share/suscan" "$RSRCPATH" | |
cp -fv "$DEPLOYROOT/usr/bin/suscli" "$BINPATH" | |
cp -fv `which SoapySDRUtil` "$BINPATH" | |
copy_su_libs | |
deploy_deps | |
swap_uhd | |
fix_sndfile | |
ensure_rpath | |
fix_plist | |
copy_usrp_fw | |
sign_code | |
create_dmg |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment