mirror of
https://github.com/kyleneideck/BackgroundMusic
synced 2025-02-26 03:47:10 +00:00
Add script that builds and installs BGMApp, BGMDriver and BGMXPCHelper
This commit is contained in:
parent
1672bb8ed0
commit
690d6221d7
5 changed files with 230 additions and 23 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -1,6 +1,7 @@
|
|||
.DS_Store
|
||||
.*.swp
|
||||
/BGMDriver/BGMDriver/quick_install.conf
|
||||
/build_and_install.log
|
||||
|
||||
# Everything below is from https://github.com/github/gitignore/blob/master/Objective-C.gitignore
|
||||
|
||||
|
|
|
@ -59,6 +59,10 @@
|
|||
- (void) initHelperConnection {
|
||||
// Note that this is called when the helper connection's interruption handler is retrying the connection after a timeout.
|
||||
[self initHelperConnectionWithErrorHandler:^(NSError* error) {
|
||||
#if !DEBUG
|
||||
#pragma unused (error)
|
||||
#endif
|
||||
|
||||
DebugMsg("BGMXPCListener::initHelperConnection: Connection error: %s", [[error description] UTF8String]);
|
||||
}];
|
||||
}
|
||||
|
|
|
@ -87,6 +87,9 @@ UInt64 WaitForBGMAppToStartOutputDevice()
|
|||
// This remote call to BGMXPCHelper will send a reply when the output device is ready to receive IO. Note that we shouldn't trust
|
||||
// the reply string.
|
||||
[[theConnection remoteObjectProxyWithErrorHandler:^(NSError* error) {
|
||||
#if !DEBUG
|
||||
#pragma unused (error)
|
||||
#endif
|
||||
DebugMsg("BGM_XPCHelper::WaitForBGMAppToStartOutputDevice: Remote call error: %s",
|
||||
[[error debugDescription] UTF8String]);
|
||||
|
||||
|
|
28
README.md
28
README.md
|
@ -46,30 +46,12 @@ Background Music Device. You can create the aggregate device using the Audio MID
|
|||
|
||||
## Install
|
||||
|
||||
No binaries yet, but building only takes a few seconds (as long as you already have Xcode installed).
|
||||
No binaries yet, but building should take less than a minute. To build and install everything, clone/download the
|
||||
project and run the `build_and_install.sh` script. Unfortunately, **it won't build if you don't have Xcode installed**
|
||||
because xcodebuild doesn't work on its own anymore.
|
||||
|
||||
- Install the virtual audio device `Background Music Device.driver` to `/Library/Audio/Plug-Ins/HAL`.
|
||||
|
||||
```shell
|
||||
sudo xcodebuild -project BGMDriver/BGMDriver.xcodeproj -target "Background Music Device" RUN_CLANG_STATIC_ANALYZER=0 DSTROOT="/" install
|
||||
```
|
||||
- Install the XPC helper.
|
||||
|
||||
```shell
|
||||
sudo xcodebuild -project BGMApp/BGMApp.xcodeproj -target BGMXPCHelper RUN_CLANG_STATIC_ANALYZER=0 DSTROOT="/" INSTALL_PATH="$(BGMApp/BGMXPCHelper/safe_install_dir.sh)" install
|
||||
```
|
||||
- Install `Background Music.app` to `/Applications` (or wherever).
|
||||
|
||||
```shell
|
||||
xcodebuild -project BGMApp/BGMApp.xcodeproj -target "Background Music" RUN_CLANG_STATIC_ANALYZER=0 DSTROOT="/" install
|
||||
```
|
||||
- Restart `coreaudiod`: <br>
|
||||
(Audio will stop working until the next step, so you might want to pause any running audio apps.)
|
||||
|
||||
```shell
|
||||
sudo launchctl kill SIGTERM system/com.apple.audio.coreaudiod
|
||||
```
|
||||
- Run `Background Music.app`.
|
||||
The script restarts the system audio process (coreaudiod) at the end of the installation, so you might want to pause any
|
||||
apps playing audio.
|
||||
|
||||
## Uninstall
|
||||
|
||||
|
|
217
build_and_install.sh
Executable file
217
build_and_install.sh
Executable file
|
@ -0,0 +1,217 @@
|
|||
#!/bin/bash
|
||||
# vim: tw=100:
|
||||
|
||||
# This file is part of Background Music.
|
||||
#
|
||||
# Background Music is free software: you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License as
|
||||
# published by the Free Software Foundation, either version 2 of the
|
||||
# License, or (at your option) any later version.
|
||||
#
|
||||
# Background Music is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with Background Music. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
#
|
||||
# build_and_install.sh
|
||||
#
|
||||
# Copyright © 2016 Kyle Neideck
|
||||
#
|
||||
# Builds and installs BGMApp, BGMDriver and BGMXPCHelper. Requires xcodebuild.
|
||||
#
|
||||
|
||||
# Safe mode
|
||||
set -euo pipefail
|
||||
IFS=$'\n\t'
|
||||
|
||||
# General error message
|
||||
set -o errtrace
|
||||
general_error() {
|
||||
echo "$(tput setaf 1)ERROR$(tput sgr0): Install script failed at line $1. This is probably a" \
|
||||
"bug in the script. Feel free to report it." >&2
|
||||
}
|
||||
trap 'general_error ${LINENO}' ERR
|
||||
|
||||
# Build for release by default.
|
||||
# TODO: Add an option to use the debug configuration?
|
||||
CONFIGURATION=Release
|
||||
#CONFIGURATION=Debug
|
||||
|
||||
# Update .gitignore if you change this.
|
||||
LOG_FILE=build_and_install.log
|
||||
|
||||
bold_face() {
|
||||
echo $(tput bold)$*$(tput sgr0)
|
||||
}
|
||||
|
||||
# Takes a PID and returns 0 if the process is running.
|
||||
is_alive() {
|
||||
kill -0 $1 > /dev/null 2>&1 && return 0 || return 1
|
||||
}
|
||||
|
||||
# Shows a "..." animation until the previous command finishes. Shows an error message and exits the
|
||||
# script if the command fails.
|
||||
#
|
||||
# Takes an optional timeout in seconds. The return value will be the exit status of the command.
|
||||
show_spinner() {
|
||||
local PREV_COMMAND_PID=$!
|
||||
|
||||
# Get the previous command as a string, with variables resolved. Assumes that if the command has
|
||||
# a child process we just want the text of the child process's command. (And that it only has
|
||||
# one child.)
|
||||
local CHILD_PID=$(pgrep -P ${PREV_COMMAND_PID} | head -n1 || echo ${PREV_COMMAND_PID})
|
||||
local PREV_COMMAND_STRING=$(ps -o command= ${CHILD_PID})
|
||||
local TIMEOUT=${1:-0}
|
||||
|
||||
(I=1;
|
||||
while (is_alive ${PREV_COMMAND_PID}) && ([[ ${TIMEOUT} -lt 1 ]] || [[ $I -lt ${TIMEOUT} ]]); do
|
||||
printf '.';
|
||||
sleep 1;
|
||||
# Erase after we've printed three dots. (\b is backspace.)
|
||||
[[ $(($I % 3)) -eq 0 ]] && printf '\b\b\b \b\b\b';
|
||||
I=$(($I + 1));
|
||||
done) &
|
||||
|
||||
set +e
|
||||
wait ${PREV_COMMAND_PID}
|
||||
local EXIT_STATUS=$?
|
||||
set -e
|
||||
|
||||
# Clean up the dots.
|
||||
printf '\b\b\b'
|
||||
|
||||
# Print an error message if the command fails.
|
||||
# (wait returns 127 if the process has already exited.)
|
||||
if [[ ${EXIT_STATUS} -ne 0 ]] && [[ ${EXIT_STATUS} -ne 127 ]]; then
|
||||
echo "$(tput setaf 1)ERROR$(tput sgr0): Build step failed. See ${LOG_FILE} for details." >&2
|
||||
echo "Failed command:" >&2
|
||||
echo " ${PREV_COMMAND_STRING}" >&2
|
||||
|
||||
exit ${EXIT_STATUS}
|
||||
fi
|
||||
|
||||
return ${EXIT_STATUS}
|
||||
}
|
||||
|
||||
# Check for xcodebuild.
|
||||
if [[ "$(which xcodebuild)" == "" ]]; then
|
||||
echo "$(tput setaf 1)ERROR$(tput sgr0): Can't find xcodebuild in your \$PATH." >&2
|
||||
echo >&2
|
||||
echo "If you have Xcode installed, you should be able to install the command line developer" \
|
||||
"tools, including xcodebuild, with" >&2
|
||||
echo " xcode-select --install" >&2
|
||||
echo "If not, you'll need to install Xcode (~9GB), because xcodebuild no longer works without" \
|
||||
"it." >&2
|
||||
|
||||
# Disable error handlers.
|
||||
trap - ERR
|
||||
set +e
|
||||
|
||||
# Check for Xcode.
|
||||
XCODE_PATH=$(which xcode-select > /dev/null && xcode-select --print-path)
|
||||
XCODE_PATH=${XCODE_PATH%/Contents/Developer}
|
||||
|
||||
if [[ "${XCODE_PATH}" == "" ]] && [[ -d /Applications/Xcode.app ]]; then
|
||||
XCODE_PATH="/Applications/Xcode.app"
|
||||
fi
|
||||
|
||||
if [[ "${XCODE_PATH}" == "" ]] && [[ -d ~/Applications/Xcode.app ]]; then
|
||||
XCODE_PATH="~/Applications/Xcode.app"
|
||||
fi
|
||||
|
||||
if [[ "${XCODE_PATH}" != "" ]]; then
|
||||
echo >&2
|
||||
echo "It looks like you have Xcode installed to ${XCODE_PATH}" >&2
|
||||
fi
|
||||
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Go to the project directory.
|
||||
cd "$( dirname "${BASH_SOURCE[0]}" )"
|
||||
|
||||
# BGMDriver
|
||||
|
||||
echo "Installing the virtual audio device $(bold_face Background Music Device.driver) to" \
|
||||
"$(bold_face /Library/Audio/Plug-Ins/HAL)." \
|
||||
| tee ${LOG_FILE}
|
||||
|
||||
sudo -v
|
||||
|
||||
# Disable the -e shell option here so we can handle the error differently.
|
||||
(set +e;
|
||||
sudo xcodebuild -project BGMDriver/BGMDriver.xcodeproj \
|
||||
-target "Background Music Device" \
|
||||
-configuration ${CONFIGURATION} \
|
||||
RUN_CLANG_STATIC_ANALYZER=0 \
|
||||
DSTROOT="/" \
|
||||
install >> ${LOG_FILE} 2>&1) &
|
||||
|
||||
show_spinner
|
||||
|
||||
# BGMXPCHelper
|
||||
|
||||
INSTALL_DIR=$(BGMApp/BGMXPCHelper/safe_install_dir.sh)
|
||||
|
||||
echo "Installing $(bold_face BGMXPCHelper.xpc) to $(bold_face ${INSTALL_DIR})." \
|
||||
| tee -a ${LOG_FILE}
|
||||
|
||||
(set +e;
|
||||
sudo xcodebuild -project BGMApp/BGMApp.xcodeproj \
|
||||
-target BGMXPCHelper \
|
||||
-configuration ${CONFIGURATION} \
|
||||
RUN_CLANG_STATIC_ANALYZER=0 \
|
||||
DSTROOT="/" \
|
||||
INSTALL_PATH="${INSTALL_DIR}" \
|
||||
install >> ${LOG_FILE} 2>&1) &
|
||||
|
||||
show_spinner
|
||||
|
||||
# BGMApp
|
||||
|
||||
echo "Installing $(bold_face Background Music.app) to $(bold_face /Applications)." \
|
||||
| tee -a ${LOG_FILE}
|
||||
|
||||
(set +e;
|
||||
sudo xcodebuild -project BGMApp/BGMApp.xcodeproj \
|
||||
-target "Background Music" \
|
||||
-configuration ${CONFIGURATION} \
|
||||
RUN_CLANG_STATIC_ANALYZER=0 \
|
||||
DSTROOT="/" \
|
||||
install >> ${LOG_FILE} 2>&1) &
|
||||
|
||||
show_spinner
|
||||
|
||||
# Fix Background Music.app owner/group.
|
||||
# (We have to run xcodebuild as root to install BGMXPCHelper because it installs to directories
|
||||
# owned by root. But that means the build directory gets created by root, and since BGMApp uses the
|
||||
# same build directory we have to run xcodebuild as root to install BGMApp as well.)
|
||||
sudo chown -R $(whoami):admin "/Applications/Background Music.app"
|
||||
|
||||
# Restart coreaudiod.
|
||||
|
||||
echo "Restarting coreaudiod to load BGMDriver." \
|
||||
| tee -a ${LOG_FILE}
|
||||
|
||||
sudo launchctl kill SIGTERM system/com.apple.audio.coreaudiod
|
||||
|
||||
# Open BGMApp.
|
||||
# I'd rather not open BGMApp here, or at least ask first, but you have to change your default audio
|
||||
# device after restarting coreaudiod and this is the easiest way.
|
||||
echo "Launching Background Music."
|
||||
|
||||
open "/Applications/Background Music.app"
|
||||
|
||||
# Wait up to 5 seconds for Background Music to start.
|
||||
(while [[ "$(ps -u $(whoami) -o ucomm= | grep 'Background Music')" == "" ]]; do
|
||||
sleep 1;
|
||||
done) &
|
||||
show_spinner 5
|
||||
|
||||
echo "Done."
|
||||
|
||||
|
Loading…
Add table
Reference in a new issue