Skip to content

Commit

Permalink
Add support for out of tree build (#485)
Browse files Browse the repository at this point in the history
  • Loading branch information
ataffanel committed Oct 14, 2019
1 parent e112fc3 commit d06e0d0
Show file tree
Hide file tree
Showing 6 changed files with 107 additions and 48 deletions.
66 changes: 39 additions & 27 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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

Expand All @@ -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

Expand All @@ -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
Expand All @@ -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
Expand All @@ -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 ################
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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)
Expand All @@ -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
Expand Down Expand Up @@ -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)
Expand Down
38 changes: 38 additions & 0 deletions docs/build_instructions.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
5 changes: 2 additions & 3 deletions tools/make/cmsis_dsp/Makefile
Original file line number Diff line number Diff line change
@@ -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/
Expand Down
8 changes: 4 additions & 4 deletions tools/make/platform.mk
Original file line number Diff line number Diff line change
@@ -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)),)
Expand All @@ -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=<platform>')
$(info Available platforms:)
$(foreach plat,$(platforms_available),$(info - $(plat) : $(PLATFORM_HELP_$(plat))))
Expand All @@ -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)
Expand Down
4 changes: 2 additions & 2 deletions tools/make/targets.mk
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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)) )
Expand Down
34 changes: 22 additions & 12 deletions tools/make/versionTemplate.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
from os import path
import re
import json
import argparse

version = {}

Expand All @@ -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]
Expand All @@ -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:
Expand All @@ -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:
Expand Down Expand Up @@ -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} <infile> <outfile>".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()
Expand Down

0 comments on commit d06e0d0

Please sign in to comment.