| giuliomoro@301 | 1 # Bela | 
| giuliomoro@64 | 2 # Low-latency, real-time audio and sensor processing on BeagleBone Black | 
| l@260 | 3 # (c) 2016 Andrew McPherson, Victor Zappi, Giulio Moro, Liam Donovan | 
| giuliomoro@64 | 4 # Centre for Digital Music, Queen Mary University of London | 
| giuliomoro@64 | 5 | 
| giuliomoro@64 | 6 # This Makefile is intended for use on the BeagleBone Black itself | 
| giuliomoro@64 | 7 # and not for cross-compiling | 
| giuliomoro@64 | 8 | 
| giuliomoro@386 | 9 .DEFAULT_GOAL := Bela | 
| giuliomoro@386 | 10 | 
| giuliomoro@459 | 11 NO_PROJECT_TARGETS=help coreclean distclean stop nostartup idestart idestop idestartup idenostartup connect ideconnect update checkupdate updateunsafe | 
| giuliomoro@385 | 12 NO_PROJECT_TARGETS_MESSAGE=PROJECT or EXAMPLE should be set for all targets except: $(NO_PROJECT_TARGETS) | 
| giuliomoro@424 | 13 # list of targets that automatically activate the QUIET=true flag | 
| giuliomoro@424 | 14 QUIET_TARGETS=runide | 
| giuliomoro@424 | 15 | 
| giuliomoro@385 | 16 # Type `$ make help` to get a description of the functionalities of this Makefile. | 
| giuliomoro@385 | 17 help: ## Show this help | 
| giuliomoro@385 | 18 	@echo 'Usage: make [target] CL=[command line options] [PROJECT=[projectName] | EXAMPLE=[exampleName]]' | 
| giuliomoro@386 | 19 	@printf "\n$(NO_PROJECT_TARGETS_MESSAGE)\n\n" | 
| giuliomoro@386 | 20 	@echo 'Targets: (default: $(.DEFAULT_GOAL))' | 
| giuliomoro@385 | 21 	@fgrep -h "##" $(MAKEFILE_LIST) | fgrep -v fgrep | sed -e  's/^\(.*\): .*##\(.*\)/\1:#\2/' | column -t -c 2 -s '#' | 
| l@260 | 22 | 
| giuliomoro@385 | 23 # PROJECT or EXAMPLE must be set for targets that are not included in NO_PROJECT_TARGETS | 
| giuliomoro@374 | 24 ifeq (,$(filter $(NO_PROJECT_TARGETS),$(MAKECMDGOALS))) | 
| giuliomoro@374 | 25   ifndef PROJECT | 
| giuliomoro@374 | 26     ifndef EXAMPLE | 
| giuliomoro@385 | 27       $(error $(NO_PROJECT_TARGETS_MESSAGE)) | 
| giuliomoro@374 | 28     endif | 
| giuliomoro@287 | 29   endif | 
| l@260 | 30 endif | 
| l@260 | 31 | 
| giuliomoro@374 | 32 # if we are building an example, just copy it to the projects/ folder | 
| giuliomoro@386 | 33 # and then treat it as a project | 
| giuliomoro@374 | 34 ifdef EXAMPLE | 
| giuliomoro@394 | 35   #you can alternatively specify PROJECT= along with EXAMPLE= | 
| giuliomoro@374 | 36   PROJECT?=exampleTempProject | 
| giuliomoro@374 | 37   PROJECT_DIR?=$(abspath projects/$(PROJECT)) | 
| andrewm@380 | 38   $(shell mkdir -p $(abspath projects)) | 
| giuliomoro@374 | 39   $(shell rm -rf $(PROJECT_DIR)) | 
| giuliomoro@374 | 40   $(shell cp -r examples/$(EXAMPLE) $(PROJECT_DIR)) | 
| giuliomoro@374 | 41 else | 
| giuliomoro@287 | 42   PROJECT_DIR := $(abspath projects/$(PROJECT)) | 
| giuliomoro@287 | 43 endif | 
| giuliomoro@287 | 44 | 
| giuliomoro@374 | 45 ifdef PROJECT | 
| giuliomoro@393 | 46   $(shell mkdir -p $(PROJECT_DIR)/build build/core) | 
| giuliomoro@287 | 47 endif | 
| giuliomoro@374 | 48 | 
| giuliomoro@331 | 49 OUTPUT_FILE?=$(PROJECT_DIR)/$(PROJECT) | 
| giuliomoro@331 | 50 COMMAND_LINE_OPTIONS?=$(CL) | 
| giuliomoro@446 | 51 RUN_FROM?=$(PROJECT_DIR) | 
| giuliomoro@331 | 52 RUN_COMMAND?=$(OUTPUT_FILE) $(COMMAND_LINE_OPTIONS) | 
| giuliomoro@396 | 53 RUN_IDE_COMMAND?=stdbuf -i0 -o0 -e0 $(RUN_COMMAND) | 
| giuliomoro@401 | 54 BELA_STARTUP_SCRIPT?=/root/Bela_startup.sh | 
| giuliomoro@359 | 55 BELA_AUDIO_THREAD_NAME?=bela-audio | 
| giuliomoro@377 | 56 SCREEN_NAME?=Bela | 
| giuliomoro@399 | 57 BELA_IDE_STARTUP_SCRIPT?=/root/Bela_node.sh | 
| giuliomoro@393 | 58 BELA_IDE_HOME?=/root/Bela/IDE | 
| giuliomoro@400 | 59 # A bug in this version of screen forces us to use two screen names which beginning substrings do not match (Bela, Bela-IDE would cause problems) | 
| giuliomoro@400 | 60 BELA_IDE_SCREEN_NAME?=IDE-Bela | 
| giuliomoro@440 | 61 BELA_IDE_RUN_COMMAND?=cd $(BELA_IDE_HOME) && screen -S $(BELA_IDE_SCREEN_NAME) -d -m bash -c "while true; do /usr/local/bin/node index.js; sleep 0.5; done" | 
| giuliomoro@393 | 62 BELA_IDE_STOP_COMMAND?=screen -X -S $(BELA_IDE_SCREEN_NAME) quit > /dev/null | 
| giuliomoro@374 | 63 | 
| giuliomoro@424 | 64 ifneq (,$(filter $(QUIET_TARGETS),$(MAKECMDGOALS))) | 
| giuliomoro@424 | 65   QUIET=true | 
| giuliomoro@424 | 66 endif | 
| giuliomoro@424 | 67 QUIET?=false | 
| giuliomoro@424 | 68 | 
| giuliomoro@64 | 69 RM := rm -rf | 
| giuliomoro@64 | 70 STATIC_LIBS := ./libprussdrv.a ./libNE10.a | 
| l@260 | 71 LIBS := -lrt -lnative -lxenomai -lsndfile | 
| l@260 | 72 | 
| giuliomoro@244 | 73 # refresh library cache and check if libpd is there | 
| giuliomoro@326 | 74 #TEST_LIBPD := $(shell ldconfig; ldconfig -p | grep "libpd\.so")  # safest but slower way of checking | 
| giuliomoro@326 | 75 LIBPD_PATH = /usr/lib/libpd.so | 
| giuliomoro@326 | 76 TEST_LIBPD := $(shell which $(LIBPD_PATH)) | 
| giuliomoro@326 | 77 ifneq ($(strip $(TEST_LIBPD)), ) | 
| giuliomoro@244 | 78 # if libpd is there, link it in | 
| giuliomoro@244 | 79   LIBS += -lpd -lpthread_rt | 
| giuliomoro@244 | 80 endif | 
| giuliomoro@64 | 81 | 
| giuliomoro@241 | 82 CPP_FLAGS := -O3 -march=armv7-a -mtune=cortex-a8 -mfloat-abi=hard -mfpu=neon -ftree-vectorize | 
| giuliomoro@241 | 83 C_FLAGS := $(CPP_FLAGS) | 
| giuliomoro@241 | 84 | 
| giuliomoro@241 | 85 ifndef COMPILER | 
| giuliomoro@241 | 86 # check whether clang is installed | 
| giuliomoro@385 | 87   TEST_COMPILER := $(shell which clang) | 
| giuliomoro@302 | 88   ifneq ($(strip $(TEST_COMPILER)), ) | 
| giuliomoro@385 | 89     #if it is installed, use it | 
| giuliomoro@302 | 90     COMPILER := clang | 
| giuliomoro@302 | 91   else | 
| giuliomoro@241 | 92     COMPILER := gcc | 
| giuliomoro@302 | 93   endif | 
| giuliomoro@241 | 94 endif | 
| giuliomoro@241 | 95 | 
| giuliomoro@241 | 96 ifeq ($(COMPILER), clang) | 
| giuliomoro@306 | 97   CC=clang | 
| giuliomoro@306 | 98   CXX=clang++ | 
| giuliomoro@302 | 99   CPP_FLAGS += -DNDEBUG | 
| giuliomoro@302 | 100   C_FLAGS += -DNDEBUG | 
| giuliomoro@241 | 101 else | 
| giuliomoro@241 | 102   CC=gcc | 
| giuliomoro@241 | 103   CXX=g++ | 
| giuliomoro@241 | 104   CPP_FLAGS += --fast-math | 
| giuliomoro@241 | 105   C_FLAGS += --fast-math | 
| giuliomoro@241 | 106 endif | 
| giuliomoro@241 | 107 | 
| l@260 | 108 INCLUDES := -I$(PROJECT_DIR) -I./include -I/usr/include/ne10 -I/usr/xenomai/include -I/usr/arm-linux-gnueabihf/include/xenomai/include -I/usr/arm-linux-gnueabihf/include/ne10 | 
| andrewm@68 | 109 | 
| l@260 | 110 ASM_SRCS := $(wildcard $(PROJECT_DIR)/*.S) | 
| l@260 | 111 ASM_OBJS := $(addprefix $(PROJECT_DIR)/build/,$(notdir $(ASM_SRCS:.S=.o))) | 
| l@260 | 112 ASM_DEPS := $(addprefix $(PROJECT_DIR)/build/,$(notdir $(ASM_SRCS:.S=.d))) | 
| giuliomoro@64 | 113 | 
| l@260 | 114 C_SRCS := $(wildcard $(PROJECT_DIR)/*.c) | 
| l@260 | 115 C_OBJS := $(addprefix $(PROJECT_DIR)/build/,$(notdir $(C_SRCS:.c=.o))) | 
| l@260 | 116 C_DEPS := $(addprefix $(PROJECT_DIR)/build/,$(notdir $(C_SRCS:.c=.d))) | 
| giuliomoro@64 | 117 | 
| l@260 | 118 CPP_SRCS := $(wildcard $(PROJECT_DIR)/*.cpp) | 
| l@260 | 119 CPP_OBJS := $(addprefix $(PROJECT_DIR)/build/,$(notdir $(CPP_SRCS:.cpp=.o))) | 
| l@260 | 120 CPP_DEPS := $(addprefix $(PROJECT_DIR)/build/,$(notdir $(CPP_SRCS:.cpp=.d))) | 
| giuliomoro@64 | 121 | 
| giuliomoro@383 | 122 PROJECT_OBJS = $(ASM_OBJS) $(C_OBJS) $(CPP_OBJS) | 
| giuliomoro@383 | 123 | 
| giuliomoro@301 | 124 # Core Bela sources | 
| giuliomoro@463 | 125 CORE_CPP_SRCS = $(filter-out core/default_main.cpp core/default_libpd_render.cpp, $(wildcard core/*.cpp)) | 
| giuliomoro@186 | 126 CORE_OBJS := $(addprefix build/core/,$(notdir $(CORE_CPP_SRCS:.cpp=.o))) | 
| giuliomoro@186 | 127 CORE_CPP_DEPS := $(addprefix build/core/,$(notdir $(CORE_CPP_SRCS:.cpp=.d))) | 
| giuliomoro@64 | 128 | 
| andrewm@318 | 129 CORE_ASM_SRCS := $(wildcard core/*.S) | 
| andrewm@318 | 130 CORE_ASM_OBJS := $(addprefix build/core/,$(notdir $(CORE_ASM_SRCS:.S=.o))) | 
| andrewm@318 | 131 CORE_ASM_DEPS := $(addprefix build/core/,$(notdir $(CORE_ASM_SRCS:.S=.d))) | 
| andrewm@318 | 132 | 
| andrewm@318 | 133 | 
| giuliomoro@64 | 134 # Objects for a system-supplied default main() file, if the user | 
| giuliomoro@64 | 135 # only wants to provide the render functions. | 
| giuliomoro@64 | 136 DEFAULT_MAIN_CPP_SRCS := ./core/default_main.cpp | 
| giuliomoro@64 | 137 DEFAULT_MAIN_OBJS := ./build/core/default_main.o | 
| giuliomoro@64 | 138 DEFAULT_MAIN_CPP_DEPS := ./build/core/default_main.d | 
| andrewm@68 | 139 | 
| giuliomoro@463 | 140 # Objects for a system-supplied default render() file for libpd projects, | 
| giuliomoro@463 | 141 # if the user only wants to provide the Pd files. | 
| giuliomoro@463 | 142 DEFAULT_PD_CPP_SRCS := ./core/default_libpd_render.cpp | 
| giuliomoro@463 | 143 DEFAULT_PD_OBJS := ./build/core/default_libpd_render.o | 
| giuliomoro@463 | 144 DEFAULT_PD_CPP_DEPS := ./build/core/default_libpd_render.d | 
| giuliomoro@463 | 145 | 
| giuliomoro@463 | 146 Bela: ## Builds the Bela program with all the optimizations | 
| giuliomoro@334 | 147 Bela: $(OUTPUT_FILE) | 
| giuliomoro@334 | 148 | 
| giuliomoro@301 | 149 # all = build Bela | 
| giuliomoro@334 | 150 all: ## Same as Bela | 
| andrewm@69 | 151 all: SYNTAX_FLAG := | 
| giuliomoro@301 | 152 all: Bela | 
| andrewm@68 | 153 | 
| giuliomoro@301 | 154 # debug = buildBela debug | 
| giuliomoro@334 | 155 debug: ## Same as Bela but with debug flags and no optimizations | 
| giuliomoro@209 | 156 debug: CPP_FLAGS=-g | 
| giuliomoro@209 | 157 debug: C_FLAGS=-g | 
| giuliomoro@209 | 158 debug: all | 
| giuliomoro@209 | 159 | 
| andrewm@69 | 160 # syntax = check syntax | 
| giuliomoro@334 | 161 syntax: ## Only checks syntax | 
| andrewm@69 | 162 syntax: SYNTAX_FLAG := -fsyntax-only | 
| giuliomoro@478 | 163 syntax: $(PROJECT_OBJS) | 
| andrewm@69 | 164 | 
| giuliomoro@301 | 165 # Rule for Bela core C++ files | 
| giuliomoro@64 | 166 build/core/%.o: ./core/%.cpp | 
| l@260 | 167 	@echo 'Building $(notdir $<)...' | 
| giuliomoro@386 | 168 #	@echo 'Invoking: C++ Compiler $(CXX)' | 
| l@260 | 169 	@$(CXX) $(SYNTAX_FLAG) $(INCLUDES) $(CPP_FLAGS) -Wall -c -fmessage-length=0 -U_FORTIFY_SOURCE -MMD -MP -MF"$(@:%.o=%.d)" -MT"$(@:%.o=%.d)" -o "$@" "$<" | 
| l@260 | 170 	@echo ' ...done' | 
| giuliomoro@64 | 171 	@echo ' ' | 
| andrewm@68 | 172 | 
| andrewm@318 | 173 # Rule for Bela core ASM files | 
| andrewm@318 | 174 build/core/%.o: ./core/%.S | 
| andrewm@318 | 175 	@echo 'Building $(notdir $<)...' | 
| andrewm@318 | 176 #	@echo 'Invoking: GCC Assembler' | 
| andrewm@318 | 177 	@as  -o "$@" "$<" | 
| andrewm@318 | 178 	@echo ' ...done' | 
| andrewm@318 | 179 	@echo ' ' | 
| andrewm@318 | 180 | 
| giuliomoro@64 | 181 # Rule for user-supplied C++ files | 
| l@260 | 182 $(PROJECT_DIR)/build/%.o: $(PROJECT_DIR)/%.cpp | 
| l@260 | 183 	@echo 'Building $(notdir $<)...' | 
| l@389 | 184 #	@echo 'Invoking: C++ Compiler $(CXX)' | 
| l@260 | 185 	@$(CXX) $(SYNTAX_FLAG) $(INCLUDES) $(CPP_FLAGS) -Wall -c -fmessage-length=0 -U_FORTIFY_SOURCE -MMD -MP -MF"$(@:%.o=%.d)" -MT"$(@:%.o=%.d)" -o "$@" "$<" | 
| l@260 | 186 	@echo ' ...done' | 
| giuliomoro@64 | 187 	@echo ' ' | 
| andrewm@68 | 188 | 
| giuliomoro@64 | 189 # Rule for user-supplied C files | 
| l@260 | 190 $(PROJECT_DIR)/build/%.o: $(PROJECT_DIR)/%.c | 
| l@260 | 191 	@echo 'Building $(notdir $<)...' | 
| giuliomoro@386 | 192 #	@echo 'Invoking: C Compiler $(CC)' | 
| giuliomoro@444 | 193 	@$(CC) $(SYNTAX_FLAG) $(INCLUDES) $(C_FLAGS) -Wall -c -fmessage-length=0 -U_FORTIFY_SOURCE -MMD -MP -MF"$(@:%.o=%.d)" -MT"$(@:%.o=%.d)" -o "$@" "$<" -std=c99 | 
| l@260 | 194 	@echo ' ...done' | 
| giuliomoro@64 | 195 	@echo ' ' | 
| andrewm@68 | 196 | 
| giuliomoro@64 | 197 # Rule for user-supplied assembly files | 
| l@260 | 198 $(PROJECT_DIR)/build/%.o: $(PROJECT_DIR)/%.S | 
| l@260 | 199 	@echo 'Building $(notdir $<)...' | 
| l@260 | 200 #	@echo 'Invoking: GCC Assembler' | 
| l@260 | 201 	@as  -o "$@" "$<" | 
| l@260 | 202 	@echo ' ...done' | 
| giuliomoro@64 | 203 	@echo ' ' | 
| giuliomoro@64 | 204 | 
| giuliomoro@64 | 205 # This is a nasty kludge: we want to be able to optionally link in a default | 
| giuliomoro@64 | 206 # main file if the user hasn't supplied one. We check for the presence of the main() | 
| giuliomoro@64 | 207 # function, and conditionally call one of two recursive make targets depending on whether | 
| giuliomoro@64 | 208 # we want to link in the default main file or not. The kludge is the mess of a shell script | 
| giuliomoro@64 | 209 # line below. Surely there's a better way to do this? | 
| giuliomoro@467 | 210 $(OUTPUT_FILE): $(CORE_ASM_OBJS) $(CORE_OBJS) $(PROJECT_OBJS) $(STATIC_LIBS) $(DEFAULT_MAIN_OBJS) $(DEFAULT_PD_OBJS) | 
| giuliomoro@463 | 211 	$(eval DEFAULT_MAIN_CONDITIONAL :=\ | 
| giuliomoro@463 | 212 	    $(shell bash -c '[ `nm $(PROJECT_OBJS) 2>/dev/null | grep -w T | grep -w main | wc -l` == '0' ] && echo "$(DEFAULT_MAIN_OBJS)" || : ')) | 
| giuliomoro@470 | 213 	@#If there is a .pd file AND there is no "render" symbol then link in the $(DEFAULT_PD_OBJS) | 
| giuliomoro@463 | 214 	$(eval DEFAULT_PD_CONDITIONAL :=\ | 
| giuliomoro@470 | 215 	    $(shell bash -c '{ ls $(PROJECT_DIR)/*.pd &>/dev/null && [ `nm $(PROJECT_OBJS) 2>/dev/null | grep -w T | grep "render.*BelaContext" | wc -l` -eq 0 ]; } && echo '$(DEFAULT_PD_OBJS)' || : ' )) | 
| l@387 | 216 	@echo 'Linking...' | 
| giuliomoro@478 | 217 	@$(CXX) $(SYNTAX_FLAG) -L/usr/xenomai/lib -L/usr/arm-linux-gnueabihf/lib -L/usr/arm-linux-gnueabihf/lib/xenomai -L/usr/lib/arm-linux-gnueabihf -pthread -Wpointer-arith -o "$(PROJECT_DIR)/$(PROJECT)" $(CORE_ASM_OBJS) $(CORE_OBJS) $(DEFAULT_MAIN_CONDITIONAL) $(DEFAULT_PD_CONDITIONAL) $(ASM_OBJS) $(C_OBJS) $(CPP_OBJS) $(STATIC_LIBS) $(LIBS) | 
| l@387 | 218 	@echo ' ...done' | 
| l@387 | 219 | 
| l@260 | 220 # Other Targets: | 
| giuliomoro@417 | 221 projectclean:## Remove the PROJECT's build objects & binary | 
| giuliomoro@326 | 222 	-$(RM) $(PROJECT_DIR)/build/* $(OUTPUT_FILE) | 
| giuliomoro@64 | 223 	-@echo ' ' | 
| giuliomoro@64 | 224 | 
| giuliomoro@386 | 225 clean: ## Same as projectclean | 
| giuliomoro@386 | 226 clean: projectclean | 
| giuliomoro@386 | 227 | 
| giuliomoro@386 | 228 coreclean: ## Remove the core's build objects | 
| giuliomoro@394 | 229 	-$(RM) build/core/* | 
| giuliomoro@386 | 230 | 
| giuliomoro@386 | 231 prompt: | 
| giuliomoro@386 | 232 	@printf "Warning: you are about to DELETE the projects/ folder and its content. This operation cannot be undone. Continue? (y/N) " | 
| giuliomoro@386 | 233 	@read REPLY; if [ $$REPLY !=  y ] && [ $$REPLY != Y ]; then echo "Aborting..."; exit 1; fi | 
| giuliomoro@386 | 234 | 
| giuliomoro@386 | 235 distclean: ## Restores the Bela folder to a pristine state: remove all the projects source and the built objects, including the core Bela objects. | 
| giuliomoro@386 | 236 distclean: prompt distcleannoprompt | 
| giuliomoro@386 | 237 | 
| giuliomoro@386 | 238 distcleannoprompt: ## Same as distclean, but does not prompt for confirmation. Use with care. | 
| giuliomoro@326 | 239 	-$(RM) build/source/* $(CORE_OBJS) $(CORE_CPP_DEPS) $(DEFAULT_MAIN_OBJS) $(DEFAULT_MAIN_CPP_DEPS) $(OUTPUT_FILE) | 
| giuliomoro@64 | 240 	-@echo ' ' | 
| giuliomoro@64 | 241 | 
| giuliomoro@302 | 242 runfg: run | 
| giuliomoro@334 | 243 run: ## Run PROJECT in the foreground | 
| giuliomoro@326 | 244 run: stop Bela | 
| giuliomoro@327 | 245 	@echo "Running $(RUN_COMMAND)" | 
| giuliomoro@446 | 246 	@sync& cd $(RUN_FROM) && $(RUN_COMMAND) | 
| giuliomoro@424 | 247 runide: ## Run PROJECT for IDE (foreground, no buffering) | 
| giuliomoro@424 | 248 runide: stop Bela | 
| giuliomoro@446 | 249 	@sync& cd $(RUN_FROM) && $(RUN_IDE_COMMAND) | 
| giuliomoro@334 | 250 runscreen: ## Run PROJECT in the background (detached screen) | 
| giuliomoro@302 | 251 runscreen: stop $(OUTPUT_FILE) | 
| giuliomoro@327 | 252 	@echo "Running $(RUN_COMMAND) in a screen" | 
| giuliomoro@446 | 253 	@cd $(RUN_FROM) && screen -S $(SCREEN_NAME) -d -m $(RUN_COMMAND) | 
| giuliomoro@334 | 254 runscreenfg: ## Run PROJECT in a screen in the foreground (can detach with ctrl-a ctrl-d) | 
| giuliomoro@313 | 255 runscreenfg: stop $(OUTPUT_FILE) | 
| giuliomoro@327 | 256 	@echo "Running $(RUN_COMMAND) in a screen" | 
| giuliomoro@446 | 257 	@cd $(RUN_FROM) && screen -S $(SCREEN_NAME) -m $(RUN_COMMAND) | 
| giuliomoro@313 | 258 FIFO_NAME=/tmp/belafifo | 
| giuliomoro@334 | 259 runscreenfifo: ## Same as runscreen, but stdout and stderr are piped to the foreground through a fifo | 
| giuliomoro@313 | 260 runscreenfifo: stop $(OUTPUT_FILE) | 
| giuliomoro@313 | 261 	@echo "Running $(RUN_COMMAND), piping output to $(FIFO_NAME)" | 
| giuliomoro@313 | 262 	@rm -rf $(FIFO_NAME) | 
| giuliomoro@313 | 263 	@mkfifo $(FIFO_NAME) | 
| giuliomoro@446 | 264 	@cd $(RUN_FROM) && screen -S $(SCREEN_NAME) -d -m stdbuf -e 0 -i 0 -o 0 bash -c "$(RUN_COMMAND) &>  $(FIFO_NAME)" | 
| giuliomoro@315 | 265 	@cat /tmp/belafifo | 
| giuliomoro@302 | 266 | 
| giuliomoro@331 | 267 STARTUP_COMMAND=printf "\#!/bin/sh\n\#\n\# This file is autogenerated by Bela. Do not edit!\n\necho Running Bela...\nscreen -S $(SCREEN_NAME) -d -m %s $(RUN_COMMAND) %s\n" | 
| giuliomoro@334 | 268 nostartup: ## No Bela project runs at startup | 
| giuliomoro@331 | 269 nostartup: | 
| andrewm@391 | 270 	@echo "Disabling Bela at startup..." | 
| giuliomoro@344 | 271 	@printf "#!/bin/sh\n#\n\n# This file is autogenerated by Bela. Do not edit!\n\n# Run on startup disabled -- nothing to do here\n" > $(BELA_STARTUP_SCRIPT) | 
| giuliomoro@331 | 272 | 
| giuliomoro@334 | 273 startuploop: ## Makes PROJECT run at startup and restarts it if it crashes | 
| giuliomoro@331 | 274 startuploop: Bela | 
| giuliomoro@331 | 275 	@echo "Enabling Bela at startup in a loop..." | 
| giuliomoro@331 | 276 	@$(STARTUP_COMMAND) 'bash -c "while sleep 0.5 ; do echo Running Bela...;' '; done"' > $(BELA_STARTUP_SCRIPT) | 
| giuliomoro@331 | 277 | 
| giuliomoro@334 | 278 startup: ## Makes PROJECT run at startup | 
| giuliomoro@331 | 279 startup: Bela | 
| giuliomoro@331 | 280 	@echo "Enabling Bela at startup..." | 
| giuliomoro@331 | 281 	@$(STARTUP_COMMAND) > $(BELA_STARTUP_SCRIPT) | 
| giuliomoro@426 | 282 	@chmod +x $(BELA_STARTUP_SCRIPT) | 
| giuliomoro@334 | 283 stop: ## Stops any Bela program that is currently running | 
| giuliomoro@302 | 284 stop: | 
| giuliomoro@424 | 285 	@PID=`grep $(BELA_AUDIO_THREAD_NAME) /proc/xenomai/stat | cut -d " " -f 5 | sed s/\s//g`; if [ -z $$PID ]; then [ $(QUIET) = true ] || echo "No process to kill"; else [  $(QUIET) = true  ] || echo "Killing old Bela process $$PID"; kill -2 $$PID; fi; screen -X -S $(SCREEN_NAME) quit > /dev/null; exit 0; | 
| giuliomoro@64 | 286 | 
| giuliomoro@417 | 287 connect: ## Connects to the running Bela program (if any), can detach with ctrl-a ctrl-d. | 
| giuliomoro@417 | 288 	@screen -r -S $(SCREEN_NAME) | 
| giuliomoro@417 | 289 | 
| giuliomoro@409 | 290 idestart: ## Starts the on-board IDE | 
| giuliomoro@410 | 291 idestart: idestop | 
| giuliomoro@410 | 292 	@printf "Starting IDE..." | 
| giuliomoro@410 | 293 	@$(BELA_IDE_RUN_COMMAND) | 
| giuliomoro@410 | 294 	@printf "done\n" | 
| giuliomoro@393 | 295 | 
| giuliomoro@393 | 296 idestop: ## Stops the on-board IDE | 
| giuliomoro@410 | 297 	@printf "Stopping currently running IDE..." | 
| giuliomoro@410 | 298 	@screen -X -S $(BELA_IDE_SCREEN_NAME) quit > /dev/null; exit 0; | 
| giuliomoro@410 | 299 	@printf "done\n" | 
| giuliomoro@393 | 300 | 
| giuliomoro@440 | 301 BELA_IDE_STARTUP_COMMAND=printf '\#!/bin/sh\n\#\n\# This file is autogenerated by Bela. Do not edit!\n\necho Running the Bela IDE...\n$(BELA_IDE_RUN_COMMAND)\n' > $(BELA_IDE_STARTUP_SCRIPT) | 
| giuliomoro@393 | 302 | 
| giuliomoro@399 | 303 idestartup: ## Enables the IDE at startup | 
| giuliomoro@393 | 304 	@echo "Enabling the IDE at startup" | 
| giuliomoro@414 | 305 	@$(BELA_IDE_STARTUP_COMMAND) | 
| giuliomoro@393 | 306 	@chmod +x $(BELA_IDE_STARTUP_SCRIPT) | 
| giuliomoro@393 | 307 | 
| giuliomoro@393 | 308 idenostartup: ## Disables the IDE at startup | 
| giuliomoro@393 | 309 	@echo "Disabling the IDE at startup" | 
| giuliomoro@393 | 310 	@printf "#!/bin/sh\n#\n\n# This file is autogenerated by Bela. Do not edit!\n\n# The Bela IDE is disabled on startup.\n" > $(BELA_IDE_STARTUP_SCRIPT) | 
| giuliomoro@417 | 311 | 
| giuliomoro@417 | 312 ideconnect: ## Brings in the foreground the IDE that currently is running in a screen (if any), can detach with ctrl-a ctrl-d. | 
| giuliomoro@417 | 313 	@screen -r -S $(BELA_IDE_SCREEN_NAME) | 
| giuliomoro@417 | 314 | 
| giuliomoro@448 | 315 BELA_DIR:=$(shell dirname $(realpath $(lastword $(MAKEFILE_LIST)))) | 
| giuliomoro@448 | 316 UPDATES_DIR?=/root/Bela/updates | 
| giuliomoro@453 | 317 UPDATE_SOURCE_DIR_BASE?=/tmp/belaUpdate | 
| giuliomoro@453 | 318 UPDATE_SOURCE_DIR=$(UPDATE_SOURCE_DIR_BASE)/Bela | 
| giuliomoro@448 | 319 UPDATE_REQUIRED_PATHS?=scripts include core scripts/update_board | 
| giuliomoro@453 | 320 UPDATE_BELA_PATCH?=/tmp/belaPatch | 
| giuliomoro@448 | 321 UPDATE_BELA_BACKUP?=/tmp/belaBak | 
| giuliomoro@448 | 322 UPDATE_BELA_MV_BACKUP?=/tmp/belaMvBak | 
| giuliomoro@448 | 323 | 
| giuliomoro@448 | 324 updateclean: ## Cleans the $(UPDATES_DIR) folder | 
| giuliomoro@448 | 325 	@[ -n $(UPDATE_DIR) ] && rm -rf $(UPDATE_DIR) && mkdir -p $(UPDATE_DIR) | 
| giuliomoro@448 | 326 | 
| giuliomoro@448 | 327 checkupdate: ## Unzips the zip file in $(UPDATES_DIR) and checks that it contains a valid | 
| giuliomoro@448 | 328 	# Check that exactly one zip file exists | 
| giuliomoro@448 | 329 	@cd $(UPDATES_DIR) && COUNT=`ls -l *.zip | wc -l` && [ $$COUNT -eq 1 ] && rm -rf `ls | grep -v "\.zip$$"` | 
| giuliomoro@448 | 330 	@#TODO: heuristics on available space. Use unzip -l and df | 
| giuliomoro@448 | 331 	@echo uncompressed size: `unzip -l \`ls $(UPDATES_DIR)/*.zip\` | tail -n1 | awk '{print $$1}'` | 
| giuliomoro@453 | 332 	# Delete and re-create the temp directory (first, make sure it is not an empty string!) | 
| giuliomoro@453 | 333 	@[ -n $(UPDATE_SOURCE_DIR_BASE) ] && rm -rf $(UPDATE_SOURCE_DIR_BASE) && mkdir -p $(UPDATE_SOURCE_DIR_BASE) | 
| giuliomoro@448 | 334 	# Unzip the contents to the temp folder | 
| giuliomoro@453 | 335 	@cd $(UPDATE_SOURCE_DIR_BASE) && unzip -qq $(UPDATES_DIR)/*zip | 
| giuliomoro@458 | 336 #TODO: this should not be needed. Remove comments.  Strip the top-level folder ( if there is only one ) | 
| giuliomoro@453 | 337 #@DIR=`ls -d $(UPDATE_SOURCE_DIR)` && COUNT=`echo $$DIR | wc -l` &&\ | 
| giuliomoro@448 | 338 	  [ $$COUNT -eq 1 ] && mv $(UPDATE_SOURCE_DIR)/* /tmp/supertemp && rm -rf $(UPDATE_SOURCE_DIR) && mv /tmp/supertemp $(UPDATE_SOURCE_DIR) | 
| giuliomoro@458 | 339 | 
| giuliomoro@448 | 340 	# Now actually check if some key-files and folders are there | 
| giuliomoro@448 | 341 	@cd $(UPDATE_SOURCE_DIR) && FAIL=0 && for path in $(UPDATE_REQUIRED_PATHS); do `ls $$path >/dev/null 2>&1` || { FAIL=1; break; }; done;\ | 
| giuliomoro@448 | 342 	  [ $$FAIL -eq 0 ] || { echo "$$path was not found in the zip archive. Maybe it is corrupted?"; exit 1; } | 
| giuliomoro@453 | 343 	# Success. You can continue the install with "make update" | 
| giuliomoro@448 | 344 UPDATE_LOG?=~/update.log | 
| giuliomoro@448 | 345 LOG=>> $(UPDATE_LOG) 2>&1 | 
| giuliomoro@459 | 346 updateunsafe: ## Installs the update from $(UPDATES_DIR) in a more brick-friendly way | 
| giuliomoro@459 | 347 	@echo > $(UPDATE_LOG) | 
| giuliomoro@459 | 348 	# Re-perform the check, just in case ... | 
| giuliomoro@459 | 349 	@cd $(UPDATE_SOURCE_DIR) && FAIL=0 && for path in $(UPDATE_REQUIRED_PATHS); do `ls $$path >/dev/null 2>&1` || { FAIL=1; break; }; done;\ | 
| giuliomoro@459 | 350 	  [ $$FAIL -eq 0 ] || { echo "$$path was not found in the zip archive. Maybe it is corrupted?"; exit 1; } | 
| giuliomoro@460 | 351 	@cd $(UPDATE_SOURCE_DIR)/scripts && BBB_ADDRESS=root@127.0.0.1 BBB_BELA_HOME=$(BELA_DIR) ./update_board -y --no-frills | 
| giuliomoro@459 | 352 	@screen -S update-Bela -d -m bash -c "echo Restart the IDE $(LOG) &&\ | 
| giuliomoro@459 | 353 	  $(MAKE) --no-print-directory idestart $(LOG) && echo Update succesful $(LOG);" $(LOG) | 
| giuliomoro@448 | 354 update: ## Installs the update from $(UPDATES_DIR) | 
| giuliomoro@448 | 355 update: stop | 
| giuliomoro@448 | 356 	# Truncate the log file | 
| giuliomoro@448 | 357 	@echo > $(UPDATE_LOG) | 
| giuliomoro@448 | 358 	# Re-perform the check, just in case ... | 
| giuliomoro@448 | 359 	@cd $(UPDATE_SOURCE_DIR) && FAIL=0 && for path in $(UPDATE_REQUIRED_PATHS); do `ls $$path >/dev/null 2>&1` || { FAIL=1; break; }; done;\ | 
| giuliomoro@448 | 360 	  [ $$FAIL -eq 0 ] || { echo "$$path was not found in the zip archive. Maybe it is corrupted?"; exit 1; } | 
| giuliomoro@453 | 361 	@[ -n $(UPDATE_BELA_PATCH) ] && mkdir -p $(UPDATE_BELA_PATCH) | 
| giuliomoro@448 | 362 	@#TODO: this would allow to trim trailing slashes in case we want to be safer: a="`pwd`/" ; target=${a%/} ; echo $target | 
| giuliomoro@458 | 363 	# Clean folder | 
| giuliomoro@458 | 364 	@$(MAKE) --no-print-directory coreclean | 
| giuliomoro@458 | 365 	# Duplicate the Bela folder $(BELA_DIR) to $(UPDATE_BELA_PATCH) ... | 
| giuliomoro@458 | 366 	@rsync -a --delete-during --exclude Documentation $(BELA_DIR)/ $(UPDATE_BELA_PATCH) | 
| giuliomoro@458 | 367 	# Also backing it up in $(UPDATE_BELA_BACKUP) ... | 
| giuliomoro@448 | 368 	@[ -n $(UPDATE_BELA_BACKUP) ] && mkdir -p $(UPDATE_BELA_BACKUP) | 
| giuliomoro@458 | 369 	@rsync -a --delete-during $(BELA_DIR)/ $(UPDATE_BELA_BACKUP) | 
| giuliomoro@453 | 370 	# Here's the trick: we run "update_board" ssh'ing into the BeagleBone itself! | 
| giuliomoro@453 | 371 	@cd $(UPDATE_SOURCE_DIR)/scripts && BBB_ADDRESS=root@127.0.0.1 BBB_BELA_HOME=$(UPDATE_BELA_PATCH) ./update_board -y --no-frills | 
| giuliomoro@453 | 372 	# If everything went ok, we now have the updated version of $(BELA_DIR) in $(UPDATE_BELA_PATCH) and a backup of $(BELA_DIR) in $(UPDATE_BELA_BACKUP) | 
| giuliomoro@453 | 373 	# So let's operate the magic swap. $(BELA_DIR) is moved to $(UPDATE_BELA_MV_BACKUP) and $(UPDATE_BELA_PATCH) is moved to $(BELA_DIR). | 
| giuliomoro@448 | 374 	# If something goes wrong at thie stage, you can always find your old $(BELA_DIR) folder at $(UPDATE_BELA_BACKUP) | 
| giuliomoro@448 | 375 	# The fun part is that this Makefile is moved as well... | 
| giuliomoro@448 | 376 	# We are about to kill the IDE, so just in case you are running this from within the IDE, we run the remainder of this update in a screen. | 
| giuliomoro@448 | 377 	# Output will be logged to $(UPDATE_LOG) | 
| giuliomoro@448 | 378 	@screen -S update-Bela -d -m bash -c '\ | 
| giuliomoro@448 | 379 	  [ -n $(UPDATE_BELA_MV_BACKUP) ] $(LOG) && rm -rf $(UPDATE_BELA_MV_BACKUP) $(LOG) &&\ | 
| giuliomoro@448 | 380 	  echo Kill the IDE $(LOG) && \ | 
| giuliomoro@448 | 381 	  $(MAKE) --no-print-directory idestop $(LOG) &&\ | 
| giuliomoro@453 | 382 	  mv $(BELA_DIR) $(UPDATE_BELA_MV_BACKUP) $(LOG) && mv $(UPDATE_BELA_PATCH) $(BELA_DIR) $(LOG) &&\ | 
| giuliomoro@448 | 383 	  echo Hope we are still alive here $(LOG) &&\ | 
| giuliomoro@448 | 384 	  echo Restart the IDE $(LOG) &&\ | 
| giuliomoro@448 | 385 	  make --no-print-directory -C $(BELA_DIR) idestart $(LOG) &&\ | 
| giuliomoro@448 | 386 	  echo Update succesful $(LOG); \ | 
| giuliomoro@448 | 387 	  ' $(LOG) | 
| giuliomoro@448 | 388 | 
| giuliomoro@459 | 389 .PHONY: all clean distclean help projectclean nostartup startup startuploop debug run runfg runscreen runscreenfg runscreenfifo stop idestart idestop idestartup idenostartup ideconnect connect update checkupdate updateunsafe |