diff --git a/Makefile b/Makefile index 93ec853a13..a8bbe84f5a 100644 --- a/Makefile +++ b/Makefile @@ -3,6 +3,8 @@ # This Makefile compiles all the objet file to ./bin/ and the resulting firmware # image in ./cfX.elf and ./cfX.bin +CRAZYFLIE_BASE ?= ./ + # Put your personal build config in tools/make/config.mk and DO NOT COMMIT IT! # Make a copy of tools/make/config.mk.example to get you started -include tools/make/config.mk @@ -29,7 +31,7 @@ LPS_TDOA3_ENABLE ?= 0 # Platform configuration handling -include current_platform.mk -include tools/make/platform.mk +include $(CRAZYFLIE_BASE)/tools/make/platform.mk CFLAGS += -DCRAZYFLIE_FW @@ -42,16 +44,16 @@ POWER_DISTRIBUTION ?= stock #OpenOCD conf RTOS_DEBUG ?= 0 -LIB = src/lib -FREERTOS = src/lib/FreeRTOS +LIB = $(CRAZYFLIE_BASE)/src/lib +FREERTOS = $(CRAZYFLIE_BASE)/src/lib/FreeRTOS ############### CPU-specific build configuration ################ ifeq ($(CPU), stm32f4) PORT = $(FREERTOS)/portable/GCC/ARM_CM4F -LINKER_DIR = tools/make/F405/linker -ST_OBJ_DIR = tools/make/F405 +LINKER_DIR = $(CRAZYFLIE_BASE)/tools/make/F405/linker +ST_OBJ_DIR = $(CRAZYFLIE_BASE)/tools/make/F405 OPENOCD_TARGET ?= target/stm32f4x_stlink.cfg @@ -60,8 +62,8 @@ OPENOCD_TARGET ?= target/stm32f4x_stlink.cfg VPATH += $(LIB)/CMSIS/STM32F4xx/Source/ VPATH += $(LIB)/STM32_USB_Device_Library/Core/src VPATH += $(LIB)/STM32_USB_OTG_Driver/src -VPATH += src/deck/api src/deck/core src/deck/drivers/src src/deck/drivers/src/test -VPATH += src/utils/src/tdoa src/utils/src/lighthouse +VPATH += $(CRAZYFLIE_BASE)/src/deck/api $(CRAZYFLIE_BASE)/src/deck/core $(CRAZYFLIE_BASE)/src/deck/drivers/src $(CRAZYFLIE_BASE)/src/deck/drivers/src/test +VPATH += $(CRAZYFLIE_BASE)/src/utils/src/tdoa $(CRAZYFLIE_BASE)/src/utils/src/lighthouse CRT0 = startup_stm32f40xx.o system_stm32f4xx.o # Add ST lib object files @@ -85,7 +87,7 @@ endif ################ Build configuration ################## # libdw dw1000 driver -VPATH += vendor/libdw1000/src +VPATH += $(CRAZYFLIE_BASE)/vendor/libdw1000/src # vl53l1 driver VPATH += $(LIB)/vl53l1/core/src @@ -108,7 +110,7 @@ CFLAGS += -DUSD_RUN_DISKIO_FUNCTION_TESTS endif # Crazyflie sources -VPATH += src/init src/hal/src src/modules/src src/utils/src src/drivers/bosch/src src/drivers/src src/platform +VPATH += $(CRAZYFLIE_BASE)/src/init $(CRAZYFLIE_BASE)/src/hal/src $(CRAZYFLIE_BASE)/src/modules/src $(CRAZYFLIE_BASE)/src/utils/src $(CRAZYFLIE_BASE)/src/drivers/bosch/src $(CRAZYFLIE_BASE)/src/drivers/src $(CRAZYFLIE_BASE)/src/platform ############### Source files configuration ################ @@ -250,20 +252,20 @@ SIZE = $(CROSS_COMPILE)size OBJCOPY = $(CROSS_COMPILE)objcopy GDB = $(CROSS_COMPILE)gdb -INCLUDES += -I$(FREERTOS)/include -I$(PORT) -Isrc -INCLUDES += -Isrc/config -Isrc/hal/interface -Isrc/modules/interface -INCLUDES += -Isrc/utils/interface -Isrc/drivers/interface -Isrc/platform -INCLUDES += -Ivendor/CMSIS/CMSIS/Include -Isrc/drivers/bosch/interface +INCLUDES += -I$(FREERTOS)/include -I$(PORT) -I$(CRAZYFLIE_BASE)/src +INCLUDES += -I$(CRAZYFLIE_BASE)/src/config -I$(CRAZYFLIE_BASE)/src/hal/interface -I$(CRAZYFLIE_BASE)/src/modules/interface +INCLUDES += -I$(CRAZYFLIE_BASE)/src/utils/interface -I$(CRAZYFLIE_BASE)/src/drivers/interface -I$(CRAZYFLIE_BASE)/src/platform +INCLUDES += -I$(CRAZYFLIE_BASE)/vendor/CMSIS/CMSIS/Include -I$(CRAZYFLIE_BASE)/src/drivers/bosch/interface INCLUDES += -I$(LIB)/STM32F4xx_StdPeriph_Driver/inc INCLUDES += -I$(LIB)/CMSIS/STM32F4xx/Include INCLUDES += -I$(LIB)/STM32_USB_Device_Library/Core/inc INCLUDES += -I$(LIB)/STM32_USB_OTG_Driver/inc -INCLUDES += -Isrc/deck/interface -Isrc/deck/drivers/interface -INCLUDES += -Isrc/utils/interface/clockCorrection -INCLUDES += -Isrc/utils/interface/tdoa -INCLUDES += -Isrc/utils/interface/lighthouse -INCLUDES += -Ivendor/libdw1000/inc +INCLUDES += -I$(CRAZYFLIE_BASE)/src/deck/interface -I$(CRAZYFLIE_BASE)/src/deck/drivers/interface +INCLUDES += -I$(CRAZYFLIE_BASE)/src/utils/interface/clockCorrection +INCLUDES += -I$(CRAZYFLIE_BASE)/src/utils/interface/tdoa +INCLUDES += -I$(CRAZYFLIE_BASE)/src/utils/interface/lighthouse +INCLUDES += -I$(CRAZYFLIE_BASE)/vendor/libdw1000/inc INCLUDES += -I$(LIB)/FatFS INCLUDES += -I$(LIB)/vl53l1 INCLUDES += -I$(LIB)/vl53l1/core/inc @@ -297,6 +299,7 @@ CFLAGS += -Wdouble-promotion ASFLAGS = $(PROCESSOR) $(INCLUDES) LDFLAGS = --specs=nosys.specs --specs=nano.specs $(PROCESSOR) -Wl,-Map=$(PROG).map,--cref,--gc-sections,--undefined=uxTopUsedPriority +LDFLAGS += -L$(CRAZYFLIE_BASE)/tools/make/F405/linker #Flags required by the ST library ifeq ($(CLOAD), 1) @@ -330,17 +333,26 @@ endif #################### Targets ############################### -all: check_submodules build +all: bin/ bin/dep bin/vendor check_submodules build build: # Each target is in a different line, so they are executed one after the other even when the processor has multiple cores (when the -j option for the make command is > 1). See: https://www.gnu.org/software/make/manual/html_node/Parallel.html - @$(MAKE) --no-print-directory clean_version - @$(MAKE) --no-print-directory compile - @$(MAKE) --no-print-directory print_version - @$(MAKE) --no-print-directory size + @$(MAKE) -f $(CRAZYFLIE_BASE)/Makefile --no-print-directory clean_version CRAZYFLIE_BASE=$(CRAZYFLIE_BASE) + @$(MAKE) -f $(CRAZYFLIE_BASE)/Makefile --no-print-directory compile CRAZYFLIE_BASE=$(CRAZYFLIE_BASE) + @$(MAKE) -f $(CRAZYFLIE_BASE)/Makefile --no-print-directory print_version CRAZYFLIE_BASE=$(CRAZYFLIE_BASE) + @$(MAKE) -f $(CRAZYFLIE_BASE)/Makefile --no-print-directory size CRAZYFLIE_BASE=$(CRAZYFLIE_BASE) compile: $(PROG).hex $(PROG).bin $(PROG).dfu +bin/: + mkdir -p bin + +bin/dep: + mkdir -p bin/dep + +bin/vendor: + mkdir -p bin/vendor + libarm_math.a: - +$(MAKE) -C tools/make/cmsis_dsp/ V=$(V) + +$(MAKE) -C $(CRAZYFLIE_BASE)/tools/make/cmsis_dsp/ CRAZYFLIE_BASE=$(abspath $(CRAZYFLIE_BASE)) PROJ_ROOT=$(CURDIR) V=$(V) clean_version: ifeq ($(SHELL),/bin/sh) @@ -350,7 +362,7 @@ endif print_version: @echo "Build for the $(PLATFORM_NAME_$(PLATFORM))!" - @$(PYTHON2) tools/make/versionTemplate.py --print-version + @$(PYTHON2) $(CRAZYFLIE_BASE)/tools/make/versionTemplate.py --crazyflie-base $(CRAZYFLIE_BASE) --print-version ifeq ($(CLOAD), 1) @echo "Crazyloader build!" endif @@ -407,9 +419,9 @@ prep: @$(CC) $(CFLAGS) -dM -E - < /dev/null check_submodules: - @$(PYTHON2) tools/make/check-for-submodules.py + @cd $(CRAZYFLIE_BASE); $(PYTHON2) tools/make/check-for-submodules.py -include tools/make/targets.mk +include $(CRAZYFLIE_BASE)/tools/make/targets.mk #include dependencies -include $(DEPS) diff --git a/docs/build_instructions.md b/docs/build_instructions.md index 8495a17061..31447ba3e7 100644 --- a/docs/build_instructions.md +++ b/docs/build_instructions.md @@ -118,6 +118,44 @@ DEBUG=1 CLOAD=0 ``` +### Out of tree build + +By setting the Makefile variable ```CRAZYFLIE_BASE```, it is possible to build the Crazyflie +from outside the project folder. This can be used to implement autonomous behaviour on +top of the Crazyflie firmware by compiling external code in the firmware from an external +repos. + +For example, if you have a deck driver file called ```push.c``` that creates a deck driver for +the deck ```bcPush```. You can create a new git repos with ```crazyflie-firmware``` clonned as +submodule and put ```push.c``` in a folder ```src```. The makefile to build a firmware starting +your deck driver automatically will be: + +```make +CRAZYFLIE_BASE=crazyflie-firmware + +CFLAGS += -DDECK_FORCE=bcPush + +VPATH += src/ + +PROJ_OBJ += push.o + +include $(CRAZYFLIE_BASE)/Makefile +``` + +Note that ```CFLAGS += -DDECK_FORCE=bcPush``` is what would normally be added to ```config.mk```. +Hence, this method also allow to create build configurations folder by building the firmware is a +separate folder with separate configurations. + +Both ```tools/make/config.mk``` and ```current_platform.mk``` are sourced from the current folder +and not from the Crazyflie firmware folder. + +Using this method it is also possible to build a clean Crazyflie firmware directly from command line: +``` +# Assuming the firmware is clonned in crazyflie-firmware/ +mkdir build && cd build +make -f ../crazyflie-firmware/Makefile CRAZYFLIE_BASE=../crazyflie-firmware +``` + # Make targets: ``` all : Shortcut for build diff --git a/tools/make/cmsis_dsp/Makefile b/tools/make/cmsis_dsp/Makefile index 03bfe2757e..58c87c99aa 100644 --- a/tools/make/cmsis_dsp/Makefile +++ b/tools/make/cmsis_dsp/Makefile @@ -1,10 +1,9 @@ include obj.mk -PROJ_ROOT=../../.. BIN=$(PROJ_ROOT)/bin/vendor PROJ_BIN=$(PROJ_ROOT)/bin -DSP_SRC=$(PROJ_ROOT)/vendor/CMSIS/CMSIS/DSP_Lib/Source -DSP_INC=$(PROJ_ROOT)/vendor/CMSIS/CMSIS/Include +DSP_SRC=$(CRAZYFLIE_BASE)/vendor/CMSIS/CMSIS/DSP_Lib/Source +DSP_INC=$(CRAZYFLIE_BASE)/vendor/CMSIS/CMSIS/Include VPATH += $(BIN) VPATH += $(DSP_SRC)/BasicMathFunctions/ diff --git a/tools/make/platform.mk b/tools/make/platform.mk index 40dbdb2b03..698417eb3a 100644 --- a/tools/make/platform.mk +++ b/tools/make/platform.mk @@ -1,8 +1,8 @@ # Platform handling # List all available platform -platforms_files = $(wildcard tools/make/platforms/*.mk) -platforms_available = $(patsubst tools/make/platforms/%.mk,%, $(platforms_files)) +platforms_files = $(wildcard $(CRAZYFLIE_BASE)/tools/make/platforms/*.mk) +platforms_available = $(patsubst $(CRAZYFLIE_BASE)/tools/make/platforms/%.mk,%, $(platforms_files)) # Find out if the requested platform exists ifeq ($(filter $(PLATFORM),$(platforms_available)),) @@ -15,7 +15,7 @@ endif # If there is no platform requested or the platform does not exist, print some help ifndef PLATFORM PLATFORM_DOC=1 -include tools/make/platforms/*.mk +include $(CRAZYFLIE_BASE)/tools/make/platforms/*.mk $(info You must provide a platform with 'make PLATFORM=') $(info Available platforms:) $(foreach plat,$(platforms_available),$(info - $(plat) : $(PLATFORM_HELP_$(plat)))) @@ -28,7 +28,7 @@ $(error Platform not defined) endif # Include the platform makefile configuration -include tools/make/platforms/$(PLATFORM).mk +include $(CRAZYFLIE_BASE)/tools/make/platforms/$(PLATFORM).mk # Write current platform in a file to make it stick for future call to make $(shell echo "PLATFORM=$(PLATFORM)" > current_platform.mk) diff --git a/tools/make/targets.mk b/tools/make/targets.mk index b3f04ebb87..a3df7de481 100644 --- a/tools/make/targets.mk +++ b/tools/make/targets.mk @@ -13,7 +13,7 @@ endif target = @$(if $(QUIET), ,echo $($1_COMMAND$(VERBOSE)) ); @$($1_COMMAND) -VTMPL_COMMAND=$(PYTHON2) tools/make/versionTemplate.py $< $@ +VTMPL_COMMAND=$(PYTHON2) $(CRAZYFLIE_BASE)/tools/make/versionTemplate.py --crazyflie-base $(CRAZYFLIE_BASE) $< $@ #$(BIN)/$(lastword $(subst /, ,$@)) VTMPL_COMMAND_SILENT=" VTMPL $@" %.c: %.vtpl @@ -50,7 +50,7 @@ $(PROG).bin: $(PROG).elf @$(if $(QUIET), ,echo $(BIN_COMMAND$(VERBOSE)) ) @$(BIN_COMMAND) -DFU_COMMAND=$(PYTHON2) tools/make/dfu-convert.py -b $(LOAD_ADDRESS):$< $@ +DFU_COMMAND=$(PYTHON2) $(CRAZYFLIE_BASE)/tools/make/dfu-convert.py -b $(LOAD_ADDRESS):$< $@ DFU_COMMAND_SILENT=" DFUse $@" $(PROG).dfu: $(PROG).bin @$(if $(QUIET), ,echo $(DFU_COMMAND$(VERBOSE)) ) diff --git a/tools/make/versionTemplate.py b/tools/make/versionTemplate.py index 5dc15c34cd..89fec21f39 100644 --- a/tools/make/versionTemplate.py +++ b/tools/make/versionTemplate.py @@ -6,6 +6,7 @@ from os import path import re import json +import argparse version = {} @@ -15,8 +16,8 @@ """ -def extract_information_from_git(): - revision = subprocess.check_output(["git", "rev-parse", "HEAD"]).strip() +def extract_information_from_git(base): + revision = subprocess.check_output(["git", "-C", base, "rev-parse", "HEAD"]).strip() version['revision'] = revision[0:12] version['irevision0'] = "0x" + revision[0:8] @@ -25,7 +26,7 @@ def extract_information_from_git(): try: identify = subprocess.check_output( - ["git", "describe", "--abbrev=12", "--tags", "HEAD"]) + ["git", "-C", base, "describe", "--abbrev=12", "--tags", "HEAD"]) identify = identify.split('-') if len(identify) > 2: @@ -48,12 +49,12 @@ def extract_information_from_git(): version['tag'] = version['tag'] + ' +' + version['local_revision'] branch = subprocess.check_output( - ["git", "rev-parse", "--abbrev-ref", "HEAD"]).strip() + ["git", "-C", base, "rev-parse", "--abbrev-ref", "HEAD"]).strip() version['branch'] = branch - subprocess.call(["git", "update-index", "-q", "--refresh"]) + subprocess.call(["git", "-C", base, "update-index", "-q", "--refresh"]) changes = subprocess.check_output( - ["git", "diff-index", "--name-only", "HEAD", "--"]).strip() + ["git", "-C", base, "diff-index", "--name-only", "HEAD", "--"]).strip() if len(changes): version['modified'] = 'true' else: @@ -96,27 +97,36 @@ def print_version(): if __name__ == "__main__": + parser = argparse.ArgumentParser() + parser.add_argument("source", help="Source template", nargs="?", default=None) + parser.add_argument("destination", help="Destination version file", nargs="?",default=None) + parser.add_argument("--crazyflie-base", help="base folder of the crazyflie firmware", + action="store", default="./") + parser.add_argument('--print-version', help="Print version and exit", + action="store_true") + args = parser.parse_args() + if extract_information_from_build_info_file(): version['source'] = "build info file" else: version['source'] = "git" - extract_information_from_git() + extract_information_from_git(args.crazyflie_base) - if len(sys.argv) == 2 and sys.argv[1] == "--print-version": + if args.print_version: print_version() sys.exit(0) - if len(sys.argv) < 3: + if not args.source or not args.destination: print("Usage:") print(" {0} ".format(sys.argv[0])) sys.exit(1) # Apply information to the file template - infile = open(sys.argv[1], 'r') - outfile = open(sys.argv[2], 'w') + infile = open(args.source, 'r') + outfile = open(args.destination, 'w') - outfile.write(header.format(sys.argv[0], sys.argv[1])) + outfile.write(header.format(sys.argv[0], args.source)) outfile.write(infile.read().format(**version)) infile.close()