1#!/usr/local/bin/bash 2 3#set -x 4 5. faustpath 6. faustoptflags 7. usage.sh 8 9# Check for some common locations of the VST SDK files. This falls back to 10# /usr/local/src/vstsdk if none of these are found. In that case, or if make 11# picks the wrong location, you can also set the SDK variable explicitly. 12 13#SDK=/usr/local/src/vstsdk 14 15# Note that the paths to be searched are listed in reverse order here, so that 16# the preferred path comes *last*. 17sdkpaths="/usr/src/VST* /usr/src/vst* /usr/include/VST* /usr/include/vst* /opt/local/src/VST* /opt/local/src/vst* /opt/local/include/VST* /opt/local/include/vst* /usr/local/src/VST* /usr/local/src/vst* /usr/local/include/VST* /usr/local/include/vst* $VSTSDK" 18# This should hopefully work on *BSD, Linux and Mac OSX. 19[ -z "$SDK" ] && SDK=$(echo $sdkpaths | xargs ls -f -d 2>/dev/null | tail -n 1) 20[ -z "$SDK" ] && SDK=/usr/local/src/vstsdk 21 22# SDKSRC should point to the SDK source files (vstplugmain.cpp et al). 23# Usually these are either directly under $SDK or in the 24# public.sdk/source/vst2.x subdirectory. 25[ -z "$SDKSRC" -a -f "$SDK/vstplugmain.cpp" ] && SDKSRC="$SDK" 26[ -z "$SDKSRC" -a -f "$SDK/public.sdk/source/vst2.x/vstplugmain.cpp" ] && SDKSRC="$SDK/public.sdk/source/vst2.x" 27[ -z "$SDKSRC" ] && SDKSRC="$SDK/public.sdk/source/vst2.x" 28 29# Default qmake setup (for GUI compilation). This requires Qt4 or Qt5 (Qt5 is 30# preferred). We try to locate the qmake executable in some common locations 31# here. If this doesn't work out then you can also set the QMAKE environment 32# variable explicitly, or use one of the -qt4 and -qt5 options below. 33[ -z "$QMAKE" ] && QMAKE=$(which qmake-qt5 || which /opt/local/libexec/qt5/bin/qmake || which qmake-qt4 || which /opt/local/libexec/qt4/bin/qmake || echo qmake) 34 35# Where the Faust includes live. We assume that this is under the prefix of 36# whatever Faust binary 'which' locates. You can also specify this explicitly 37# by setting the FAUSTINC environment variable accordingly. 38# FAUSTINC is now set by faustpath 39#[ -z "$FAUSTINC" ] && FAUSTINC=$(which faust 2>/dev/null | sed -e 's?/bin/faust?/include/faust?') 40 41# Where our own Faust library files are. This may be under a different prefix 42# or not installed anywhere. We try 'ls' on faustvstqt.h in some common 43# locations here, and fall back to the current directory if the file isn't 44# found, so that you can run the script from the faust-vst source 45# directory. You can also specify this explicitly by setting the FAUSTARCH 46# environment variable accordingly. 47 48# The part below is obsolete 49# architecture location is now defined by faustpath and stored in a variable named FAUSTARCH 50#[ -z "$FAUSTLIB" ] && FAUSTLIB=$(dirname "$((ls -f /usr/share/faust/faustvstqt.h /usr/local/share/faust/faustvstqt.h /opt/local/share/faust/faustvstqt.h "$PWD/faustvstqt.h" 2>/dev/null)|tail -1)") 51#[ -z "$FAUSTLIB" ] && FAUSTLIB="$PWD" 52 53# defaults (these can be changed with the options listed below) 54FAUST_META=1 55FAUST_MIDICC=1 56FAUST_MTS=1 57FAUST_UI=0 58VOICE_CTRLS=1 59NVOICES=-1 60 61KEEP="no" 62STYLE="" 63 64PROCARCH="-fPIC" 65dllext=".so" 66CXXFLAGS="-O3 -std=c++11 -march=native -mfpmath=sse -msse -msse2 -msse3 -ffast-math -ftree-vectorize" 67 68# Darwin-specific 69#ARCH="-arch i386 -arch x86_64" 70if [[ $(uname) == Darwin || $CROSSTARGET == Darwin ]]; then 71 CXXFLAGS="-O3 -std=c++11 $ARCH -mfpmath=sse -msse -msse2 -msse3 -ffast-math -ftree-vectorize -I/opt/local/include" 72 dllext=".vst" 73fi 74 75# dispatch command arguments 76for ((i=1;i<$#+1;i++)); do 77 p=${!i} 78 if [ $p = "-help" ] || [ $p = "-h" ]; then 79 usage faust2faustvst "[options ...] <file.dsp>" 80 require VST SDK 81 echo "Compiles Faust programs to VST plugins" 82 option 83 options -osc -httpd 84 option -gui "build the plugin GUI." 85 option -keep "retain the build directory." 86 option -nometa "ignore metadata (author information etc.) from the Faust source" 87 option -nomidicc "plugin doesn't process MIDI control data." 88 option -notuning "disable the tuning control (instruments only)." 89 option -novoicectrls "no extra polyphony/tuning controls on GUI (instruments only)" 90 option "-nvoices N" "number of synth voices (instruments only; arg must be an integer)" 91 option "-qt4, -qt5" "select the GUI toolkit (requires Qt4/5; implies -gui)." 92 option "-style S" " select the stylesheet (arg must be Default, Blue, Grey or Salmon)." 93 cat <<EOF 94Environment variables: 95 FAUSTINC: specify the location of the Faust include directory 96 Default: $FAUSTINC 97 FAUSTARCH: specify the location of the Faust VST library files 98 Default: $FAUSTARCH 99 QMAKE: specify the location of the qmake binary 100 Default: $QMAKE 101 SDK: specify the location of the VST SDK 102 Default: $SDK 103 SDKSRC: specify the location of the VST SDK sources 104 Default: $SDKSRC 105EOF 106 exit 0 107 elif [ $p = "-omp" ]; then 108 : ignore 109 elif [ $p = "-icc" ]; then 110 CXX=icpc 111 CXXFLAGS="-O3 -std=c++11 -xHost -ftz -fno-alias -fp-model fast=2" 112 elif [ $p = "-osc" ]; then 113 OSCDEFS="DEFINES += OSCCTRL" 114 OSCLIBS="-lOSCFaust" 115 elif [ $p = "-httpd" ]; then 116 HTTPDEFS="DEFINES += HTTPCTRL" 117 HTTPLIBS="-lHTTPDFaust -lmicrohttpd" 118 elif [ $p = "-qrcode" ]; then # requires -httpd 119 QRDEFS="DEFINES += QRCODECTRL" 120 elif [ $p = "-nometa" ]; then 121 FAUST_META=0 122 elif [ $p = "-nomidicc" ]; then 123 FAUST_MIDICC=0 124 elif [ $p = "-notuning" ]; then 125 FAUST_MTS=0 126 elif [ $p = "-novoicectrls" ]; then 127 VOICE_CTRLS=0 128 elif [ $p = "-gui" ]; then 129 FAUST_UI=1 130 plugin_gui=yes 131 elif [ $p = "-qt4" ]; then 132 FAUST_UI=1 133 plugin_gui=yes 134 QMAKE=$(which qmake-qt4 || which /opt/local/libexec/qt4/bin/qmake || echo qmake-qt4) 135 elif [ $p = "-qt5" ]; then 136 FAUST_UI=1 137 plugin_gui=yes 138 QMAKE=$(which qmake-qt5 || which /opt/local/libexec/qt5/bin/qmake || echo qmake-qt5) 139 elif [ $p = "-nvoices" ]; then 140 (( i++ )) 141 NVOICES=${!i} 142 elif [ $p = "-arch32" ]; then 143 PROCARCH="-m32 -L/usr/lib32" 144 elif [ $p = "-arch64" ]; then 145 PROCARCH="-m64 -fPIC" 146 elif [ $p = "-osx" ]; then 147 CXXFLAGS="-O3 -std=c++11 $ARCH -mfpmath=sse -msse -msse2 -msse3 -ffast-math -ftree-vectorize -I/opt/local/include" 148 dllext=".vst" 149 elif [ $p = "-keep" ]; then 150 KEEP="yes" 151 elif [ $p = "-style" ]; then 152 (( i++ )) 153 STYLE=${!i} 154 elif [ ${p:0:1} = "-" ]; then 155 OPTIONS="$OPTIONS $p" 156 elif [[ -f "$p" ]] && [ ${p: -4} == ".dsp" ]; then 157 FILES="$FILES $p" 158 else 159 OPTIONS="$OPTIONS $p" 160 fi 161done 162 163FILES=( $FILES ) 164if [ ${#FILES[@]} = 0 ]; then 165 echo "$0: no filename specified" >&2 166 exit 1 167elif [ ${#FILES[@]} -gt 1 ]; then 168 echo "$0: multiple filenames specified" >&2 169 exit 1 170fi 171 172# Check to see whether the required include and library files are where we 173# expect them, and bail out with an error message otherwise. 174if [ ! -f "$FAUSTINC/faust/gui/QTUI.h" ]; then echo "$0: faust include files not found" >&2; exit 1; fi 175if [ ! -f "$FAUSTARCH/faustvstqt.h" ]; then echo "$0: faust-vst library files not found" >&2; exit 1; fi 176 177# Determine the Qt version so that we can pick the needed compilation options. 178QTVERSION=$($QMAKE -v 2>/dev/null | tail -1 | sed 's/.*Qt version \([0-9]\).*/\1/') 179 180QTEXTRA= 181if [ $QTVERSION = 5 ]; then 182QTEXTRA=x11extras 183fi 184 185arch=faustvst.cpp 186dspname=${FILES[0]} 187SRCDIR=$(dirname "$dspname") 188ABSDIR=$(cd $SRCDIR && pwd) 189CURDIR=$(pwd) 190 191clsname=`basename "$dspname" .dsp` 192cppname="$clsname.cpp" 193soname="$clsname$dllext" 194tmpdir=`mktemp -d /tmp/faust2faustvst.XXXXXX` 195 196RESOURCES= 197STYLE_CXXFLAGS= 198if [ -n "$STYLE" ]; then 199 RESOURCES="RESOURCES+=$FAUSTINC/faust/gui/Styles/$STYLE.qrc" 200 STYLE_CXXFLAGS="QMAKE_CXXFLAGS+=-DSTYLE=\"$STYLE\"" 201fi 202 203# now set in faustoptflags 204#CXX=g++ 205CPPFLAGS="-DFAUST_META=$FAUST_META -DFAUST_MIDICC=$FAUST_MIDICC -DFAUST_MTS=$FAUST_MTS -DFAUST_UI=$FAUST_UI -DVOICE_CTRLS=$VOICE_CTRLS -I$SDK -I$SDKSRC -D__cdecl=" 206if [ $NVOICES -ge 0 ]; then 207CPPFLAGS="$CPPFLAGS -DNVOICES=$NVOICES" 208fi 209 210# Extra SDK modules needed to build a working plugin. 211main=vstplugmain.cpp 212afx=audioeffect.cpp 213afxx=audioeffectx.cpp 214sdksrc="$SDKSRC/$main $SDKSRC/$afx $SDKSRC/$afxx" 215 216# Uncomment this to have Faust substitute the proper class name into the C++ 217# code. NOTE: This requires that the basename of the dsp file is a valid C 218# identifier, which isn't guaranteed, so we disable this by default. 219#OPTIONS="$OPTIONS -cn \"$clsname\"" 220 221# Create the temp directory. 222mkdir -p $tmpdir 223#trap "echo $0: compile error, intermediate files left in $tmpdir >&2" EXIT 224# Compile the Faust module. 225faust -i -a "$FAUSTARCH/$arch" $OPTIONS "$dspname" -o "$tmpdir/$cppname" || exit 1 226if [ -n "$plugin_gui" ]; then 227# We have to use qmake here. 228# XXXTODO: OSX support 229( 230 cd "$tmpdir" 231 $QMAKE -project -t lib -o ${clsname}.pro "CONFIG += gui plugin no_plugin_name_prefix warn_off" "QT += widgets printsupport network $QTEXTRA" "INCLUDEPATH+=$ABSDIR" "INCLUDEPATH+=$CURDIR" "INCLUDEPATH+=$FAUSTARCH" "INCLUDEPATH+=$FAUSTINC" "QMAKE_CXXFLAGS=-std=c++11 $CPPFLAGS" $STYLE_CXXFLAGS "LIBS+=$ARCHLIB $OSCLIBS $HTTPLIBS" "SOURCES+=$SDKSRC/$main $SDKSRC/$afx $SDKSRC/$afxx" "HEADERS+=$FAUSTARCH/faustvstqt.h $FAUSTINC/faust/gui/QTUI.h" $RESOURCES "$OSCDEFS" "$HTTPDEFS" "$QRDEFS" 232 $QMAKE *.pro 233 make 234) > /dev/null || exit 1 235else 236if [[ $(uname) == Darwin || $CROSSTARGET == Darwin ]]; then 237 mkdir -p $tmpdir/$soname/Contents/MacOS 238 printf '%s' 'BNDL????' > $tmpdir/$soname/Contents/PkgInfo 239 sed -e "s?@name@?$clsname?g;s?@version@?1.0.0?g" > $tmpdir/$soname/Contents/Info.plist <<EOF 240<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> 241<plist version="1.0"> 242<dict> 243 <key>CFBundleDevelopmentRegion</key> 244 <string>English</string> 245 <key>CFBundleExecutable</key> 246 <string>@name@</string> 247 <key>CFBundleIdentifier</key> 248 <string>@name@</string> 249 <key>CFBundleInfoDictionaryVersion</key> 250 <string>6.0</string> 251 <key>CFBundleName</key> 252 <string>@name@</string> 253 <key>CFBundlePackageType</key> 254 <string>BNDL</string> 255 <key>CFBundleShortVersionString</key> 256 <string>@version@</string> 257 <key>CFBundleSignature</key> 258 <string>????</string> 259 <key>CFBundleVersion</key> 260 <string>@version@</string> 261 <key>CSResourcesFileMapped</key> 262 <true/> 263</dict> 264</plist> 265EOF 266 $CXX -bundle $CXXFLAGS $FAUSTTOOLSFLAGS $PROCARCH -I"$ABSDIR" $CPPFLAGS $sdksrc "$tmpdir/$cppname" -o "$tmpdir/$soname/Contents/MacOS/$clsname" || exit 1 267else 268 $CXX -shared $CXXFLAGS $FAUSTTOOLSFLAGS $PROCARCH -I"$ABSDIR" $CPPFLAGS $sdksrc "$tmpdir/$cppname" -o "$tmpdir/$soname" || exit 1 269fi 270fi 271#trap - EXIT 272 273# copy down the plugin (bundle on OS X) 274rm -rf "$SRCDIR/$soname" 275cp -r "$tmpdir/$soname" "$SRCDIR" 276if [[ $KEEP == yes ]]; then 277 # keep the build directory 278 rm -rf "$SRCDIR/$clsname" 279 mv $tmpdir "$SRCDIR/$clsname" 280else 281 # Clean up. 282 rm -rf $tmpdir 283fi 284# Print the name of the generated plugin. 285echo "$SRCDIR/$soname;" 286