/
build_pd_heavy.sh
executable file
·305 lines (272 loc) · 9.67 KB
/
build_pd_heavy.sh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
#!/bin/bash
# OBSOLETE: unless you have a new server offering hvcc builds you should run it locally using build_pd_hvcc.sh
# This script uploads Pd patches to Enzienaudio's server and compiles them on Bela
pdpath=
release=
NO_UPLOAD=0
WATCH=0
FORCE=0
COMMAND_ARGS=
RUN_PROJECT=1
RUN_MODE=foreground
EXPERT=0
PRE_BUILT=1
SCRIPTDIR=$(dirname "$0")
[ -z $SCRIPTDIR ] && SCRIPTDIR="./" || SCRIPTDIR=$SCRIPTDIR/
[ -z $HVRESOURCES_DIR ] && HVRESOURCES_DIR=$SCRIPTDIR/hvresources/
. $SCRIPTDIR.bela_common || { echo "You must be in Bela/scripts to run these scripts" | exit 1; }
projectpath="$SCRIPTDIR/../tmp/heavy/hvtemp/"
if [ -z "$BELA_PYTHON27" ]; then
for PY in python python2.7 ; do
$PY --version 2>&1 | grep "2\.7" >/dev/null 2>&1
if [ $? -eq 0 ]; then
BELA_PYTHON27=$PY
break;
fi;
done;
fi;
if [ -z "$BELA_PYTHON27" ]; then
echo "It looks like you might not have python2.7 installed. If you do, please specify the path
to your python2.7 executable in the environmental variable \$BELA_PYTHON27"
exit 1;
fi;
usage_brief(){
printf "Usage: $THIS_SCRIPT path/to/project "
printf '[-o] [--noupload] [-r|--release release] [--custom path]'
build_script_usage_brief
run_script_usage_brief
echo
}
usage ()
{
usage_brief
echo "
example: $THIS_SCRIPT ../projects/heavy/pd/hello-world
This program compiles a PureData patch using the online Heavy Compiler. Before using this
script you need to have set up your Enzien Audio account and familiarized yourself with the
information available here https://github.com/BelaPlatform/Bela/wiki/Running-Puredata-patches-on-Bela#heavy.
Heavy-specific options:
-r : builds against a specific Heavy release. Default is: $release (stable)
( see revision list here https://enzienaudio.com/a/releases )
--src-only : only retrieve the source files (and not the pre-built object files). With this option
selected, building the project will take longer but you can save bandwidth and tweak compiler options.
--noupload : does not use the online compiler, only compiles the current source files.
-o arg : sets the path where files returned from the online compiler are stored.
--custom arg: sets the path of C++ files to use instead of the default render.cpp
"
build_script_usage
run_script_usage
}
[ -z "$ENZIENAUDIO_COM_PATCH_NAME" ] && ENZIENAUDIO_COM_PATCH_NAME=bela
while [ -n "$1" ]
do
case $1 in
-c)
shift
COMMAND_ARGS="$1"
;;
-b)
RUN_MODE=screen
;;
-f)
RUN_MODE=foreground
;;
-s)
RUN_MODE=screenfg
;;
-n)
RUN_PROJECT=0
;;
-p)
shift
BBB_PROJECT_NAME="$1"
;;
--clean)
BBB_MAKEFILE_OPTIONS="$BBB_MAKEFILE_OPTIONS projectclean"
;;
--force)
FORCE=1
;;
-m)
shift
BBB_MAKEFILE_OPTIONS="$BBB_MAKEFILE_OPTIONS $1"
;;
--watch)
WATCH=1
;;
-o | --output )
shift
projectpath=$1
;;
-r | --release )
shift
release=$1
;;
--src-only )
PRE_BUILT=0
;;
--noupload )
NO_UPLOAD=1
;;
--custom)
shift
CUSTOM_HEAVY_SOURCE_PATH=$1
;;
--help|-h|-\?)
usage
exit
;;
-*)
echo Error: unknown option $1
usage_brief
exit 1
;;
*)
[ -z "$pdpath" ] && pdpath=$1 || {
echo "Error: too many options $pdpath $1"
usage_brief
exit 1
}
esac
shift
done
[ "$NO_UPLOAD" -eq 0 ] && [ -z "$pdpath" ] && { echo "Error: a path to the source folder should be provided"; exit 1; }
[ -z "$CUSTOM_HEAVY_SOURCE_PATH" ] && CUSTOM_HEAVY_SOURCE_PATH="$pdpath/heavy/"
[ -z $BBB_PROJECT_NAME ] && BBB_PROJECT_NAME="$(basename $(cd "$pdpath" && pwd))"
if [ -z "$release" ]
then
RELEASE_STRING=
else
RELEASE_STRING="-rr -r $release"
fi
# These files will be cleared from $projectpath before calling uploader.py
#TODO: get a reliable, exhaustive, up-to-date list.
HEAVY_FILES='Heavy* Hv*'
# The expert will have to remember to run set_date after powering up the board if needed
[ $EXPERT -eq 0 ] && check_board_alive_and_set_date
# check if project exists
[ $FORCE -eq 1 ] || check_project_exists_prompt $BBB_PROJECT_NAME
reference_time_file="$projectpath"/
#Check if rsync is available
check_rsync && RSYNC_AVAILABLE=1 || RSYNC_AVAILABLE=0
uploadBuildRun(){
if [ $NO_UPLOAD -eq 0 ]; then
# remove old static files to avoid obsolete errors
# make sure the path is not empty, so avoiding to rm -rf / by mistake
[ -z "$projectpath" ] && { echo 'ERROR: $projectpath is empty.'; exit 0; }
#empty destination folder
rm -rf "$projectpath"
#recreate the destination folder"
mkdir -p "$projectpath"
echo "Invoking the online compiler..."
if [ "$PRE_BUILT" -eq 1 ]
then
UPLOADER_EXTRA_FLAGS=--archive_only
HEAVY_JOB="bela-linux-armv7a"
else
UPLOADER_EXTRA_FLAGS=
HEAVY_JOB="c-src"
fi
# invoke the online compiler
"$BELA_PYTHON27" $HVRESOURCES_DIR/uploader.py "$pdpath"/ -n $ENZIENAUDIO_COM_PATCH_NAME -g $HEAVY_JOB -o "$projectpath" $RELEASE_STRING $UPLOADER_EXTRA_FLAGS ||\
{ echo "ERROR: an error occurred while executing the uploader.py script"; exit $?; }
fi;
echo "";
BBB_PROJECT_FOLDER=$BBB_PROJECT_HOME"/"$BBB_PROJECT_NAME #make sure there is no trailing slash here
BBB_NETWORK_TARGET_FOLDER=$BBB_ADDRESS:$BBB_PROJECT_FOLDER
# check how to copy/sync render.cpp file...
# check if custom CUSTOM_HEAVY_SOURCE_PATH folder is provided
if [ -e "$CUSTOM_HEAVY_SOURCE_PATH" ] && [ "$(ls $CUSTOM_HEAVY_SOURCE_PATH)" ]; then
echo "Custom heavy folder in use: $CUSTOM_HEAVY_SOURCE_PATH, using files in there instead of the default render.cpp:"
[ -d "$CUSTOM_HEAVY_SOURCE_PATH" ] && {
cp -v "$CUSTOM_HEAVY_SOURCE_PATH"/* "$projectpath/" || exit 1;
} || { cp -v "$CUSTOM_HEAVY_SOURCE_PATH" "$projectpath/" || exit 1; }
else
echo "Using Heavy default render.cpp"
cp "$HVRESOURCES_DIR/render.cpp" "$projectpath/" || exit 1
fi
echo "Updating files on board..."
touch $reference_time_file
MAKE_COMMAND_BASE="make --no-print-directory COMPILER=gcc QUIET=true -C $BBB_BELA_HOME PROJECT='$BBB_PROJECT_NAME'"
# Transfer the files
if [ "$PRE_BUILT" -eq 1 ]
then
ARCHIVE_NAME=archive.$HEAVY_JOB.zip
BBB_ARCHIVE_PATH=/tmp/$ARCHIVE_NAME
# copy the archive
scp "$projectpath/$ARCHIVE_NAME" $BBB_ADDRESS:$BBB_ARCHIVE_PATH
rm "$projectpath/$ARCHIVE_NAME"
ssh $BBB_ADDRESS "mkdir -p '$BBB_BELA_HOME/projects/$BBB_PROJECT_NAME' && $MAKE_COMMAND_BASE heavy-unzip-archive HEAVY_ARCHIVE=$BBB_ARCHIVE_PATH" $BBB_MAKEFILE_OPTIONS || exit 1
# in this case, most files at the destination will not exist in the
# source folder, as the latter will only contain the zip archive and
# any files (if any) from the heavy/ subfolder OR the default heavy
# render.cpp, so we avoid deleting them.
RSYNC_SHOULD_DELETE=
else
RSYNC_SHOULD_DELETE=--delete-during
fi
if [ "$RSYNC_AVAILABLE" -eq 1 ]
then
# Heavy_bela.cpp tends to hang when transferring with rsync because it
# may be very large.
# So we always use `scp` with it, also because it changes every time.
# In case we are using PRE_BUILT=1, then the file will not even exist
# (hence the [ -f ... ] below)
BIG_FILE=Heavy_$ENZIENAUDIO_COM_PATCH_NAME.cpp
rsync -acv --no-t $RSYNC_SHOULD_DELETE --exclude="$BIG_FILE" --exclude=build --exclude=$BBB_PROJECT_NAME "$projectpath"/ "$BBB_NETWORK_TARGET_FOLDER" &&\
[ $NO_UPLOAD -eq 1 ] || { [ -f "$projectpath"/$BIG_FILE ] && scp -rp "$projectpath"/$BIG_FILE $BBB_NETWORK_TARGET_FOLDER || true; } ||\
{ echo "ERROR: while synchronizing files with the BBB. Is the board connected?"; exit 1; }
else
echo "using scp..."
echo "WARNING: it is HEAVILY recommended that you install rsync on your system when building Heavy projects, in order to make the build much faster"
echo "Cleaning the destination folder..."
ssh $BBB_ADDRESS "rm -rf \"$BBB_PROJECT_FOLDER\"; mkdir -p \"$BBB_PROJECT_FOLDER\""
echo "Copying the project files"
scp -r "$projectpath"/* "$BBB_NETWORK_TARGET_FOLDER"
fi
# TODO: rsync should upload a list of modified files, so that the corresponding objects can be deleted
# TODO: this should be run only when Heavy_bela.h changes. Otherwise render is recompiled every time for no good reason
#ssh $BBB_ADDRESS "rm -rf ${BBB_PROJECT_FOLDER}/build/render.*"
#produce a list of files which content has changed (not just the date)
# remove old executable to force re-linking
#if [ $NO_UPLOAD -eq 0 ]; then
# ssh $BBB_ADDRESS "rm -rf "$BBB_PROJECT_FOLDER/$BBB_PROJECT_NAME;
#fi;
# Make new Bela executable and run
MAKE_COMMAND="$MAKE_COMMAND_BASE CL='$COMMAND_ARGS' $BBB_MAKEFILE_OPTIONS"
if [ $RUN_PROJECT -eq 0 ]
then
echo "Building project..."
ssh $BBB_ADDRESS "$MAKE_COMMAND"
else
case_run_mode
fi
} #uploadBuildRun
uploadBuildRun
if [ $WATCH -ne 0 ]; then
BACK_NO_UPLOAD=$NO_UPLOAD
while true
do
# actually we are watching multiple paths : $pdpath and $HVRESOURCES_DIR
# so that it is easier to edit hvresources code without risk of being
# overwritten, but we avoid mentioning it to the end user, otherwise they
# get confused.
echo "Waiting for changes in $pdpath, or press ctrl-c to terminate"
while sleep 1
do
folder_has_changed "$pdpath" "$reference_time_file" && {
echo "Content of $pdpath has changed"
break
}
folder_has_changed "$HVRESOURCES_DIR" "$reference_time_file" && {
echo "Content of "$HVRESOURCES_DIR" has changed"
break
}
done
echo "Files changed"
# if .pd files did not change, no point in re-uploading
folder_has_changed "$pdpath" "$reference_time_file" "\.pd" &&\
NO_UPLOAD=$BACK_NO_UPLOAD || NO_UPLOAD=1
uploadBuildRun
done
fi;