Skip to content

Commit

Permalink
Initial Makefile commit
Browse files Browse the repository at this point in the history
  • Loading branch information
blckmn committed Dec 21, 2017
1 parent 25f9e7c commit 1517d2a
Show file tree
Hide file tree
Showing 10 changed files with 563 additions and 0 deletions.
374 changes: 374 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,374 @@
###############################################################################
# "THE BEER-WARE LICENSE" (Revision 42):
# <[email protected]> wrote this file. As long as you retain this notice you
# can do whatever you want with this stuff. If we meet some day, and you think
# this stuff is worth it, you can buy me a beer in return
###############################################################################
#
# Makefile for building the betaflight-esc firmware.
#
# Invoke this with 'make help' to see the list of supported targets.
#
###############################################################################


# Things that the user might override on the commandline
#

# The target to build, see VALID_TARGETS below
TARGET ?= FISHDRONE_ESC

# Compile-time options
OPTIONS ?=

# Debugger optons, must be empty or GDB
DEBUG ?=

# Insert the debugging hardfault debugger
# releases should not be built with this flag as it does not disable pwm output
DEBUG_HARDFAULTS ?=

# Serial port/Device for flashing
SERIAL_DEVICE ?= $(firstword $(wildcard /dev/ttyUSB*) no-port-found)

# Flash size (KB). Some low-end chips actually have more flash than advertised, use this to override.
FLASH_SIZE ?=


###############################################################################
# Things that need to be maintained as the source changes
#

# Working directories
ROOT := $(patsubst %/,%,$(dir $(lastword $(MAKEFILE_LIST))))
SRC_DIR := $(ROOT)/src/main
OBJECT_DIR := $(ROOT)/obj/main
BIN_DIR := $(ROOT)/obj
CMSIS_DIR := $(ROOT)/lib/main/CMSIS
INCLUDE_DIRS := $(SRC_DIR) \
$(ROOT)/src/main/target
LINKER_DIR := $(ROOT)/src/link

## V : Set verbosity level based on the V= parameter
## V=0 Low
## V=1 High
include $(ROOT)/make/build_verbosity.mk

# developer preferences, edit these at will, they'll be gitignored
-include $(ROOT)/make/local.mk

# configure some directories that are relative to wherever ROOT_DIR is located
ifndef TOOLS_DIR
TOOLS_DIR := $(ROOT)/tools
endif
BUILD_DIR := $(ROOT)/build
DL_DIR := $(ROOT)/downloads

export RM := rm

# default xtal value for targets
HSE_VALUE ?= 8000000

# used for turning on features
FEATURES =

include $(ROOT)/make/targets.mk

REVISION := $(shell git log -1 --format="%h")

FW_VER_MAJOR := $(shell grep " FW_VERSION_MAJOR" src/main/build/version.h | awk '{print $$3}' )
FW_VER_MINOR := $(shell grep " FW_VERSION_MINOR" src/main/build/version.h | awk '{print $$3}' )
FW_VER_PATCH := $(shell grep " FW_VERSION_PATCH" src/main/build/version.h | awk '{print $$3}' )

FW_VER := $(FW_VER_MAJOR).$(FW_VER_MINOR).$(FW_VER_PATCH)

# Search path for sources
VPATH := $(SRC_DIR):$(SRC_DIR)/startup

CSOURCES := $(shell find $(SRC_DIR) -name '*.c')

LD_FLAGS :=

#
# Default Tool options - can be overridden in {mcu}.mk files.
#
ifeq ($(DEBUG),GDB)
OPTIMISE_DEFAULT := -Og

LTO_FLAGS := $(OPTIMISE_DEFAULT)
DEBUG_FLAGS = -ggdb3 -DDEBUG
else
OPTIMISATION_BASE := -flto -fuse-linker-plugin -ffast-math
OPTIMISE_DEFAULT := -O2
OPTIMISE_SPEED := -Ofast
OPTIMISE_SIZE := -Os

LTO_FLAGS := $(OPTIMISATION_BASE) $(OPTIMISE_SPEED)
endif

VPATH := $(VPATH):$(ROOT)/make/mcu
VPATH := $(VPATH):$(ROOT)/make

# start specific includes
include $(ROOT)/make/mcu/$(TARGET_MCU).mk

# Configure default flash sizes for the targets (largest size specified gets hit first) if flash not specified already.
ifeq ($(FLASH_SIZE),)
ifneq ($(TARGET_FLASH),)
FLASH_SIZE := $(TARGET_FLASH)
else
$(error FLASH_SIZE not configured for target $(TARGET))
endif
endif

DEVICE_FLAGS := $(DEVICE_FLAGS) -DFLASH_SIZE=$(FLASH_SIZE)

ifneq ($(HSE_VALUE),)
DEVICE_FLAGS := $(DEVICE_FLAGS) -DHSE_VALUE=$(HSE_VALUE)
endif

TARGET_DIR = $(ROOT)/src/main/target/$(BASE_TARGET)
TARGET_DIR_SRC = $(notdir $(wildcard $(TARGET_DIR)/*.c))

ifeq ($(OPBL),yes)
TARGET_FLAGS := -DOPBL $(TARGET_FLAGS)
.DEFAULT_GOAL := binary
else
.DEFAULT_GOAL := hex
endif

INCLUDE_DIRS := $(INCLUDE_DIRS) \
$(TARGET_DIR)

VPATH := $(VPATH):$(TARGET_DIR)

include $(ROOT)/make/source.mk

###############################################################################
# Things that might need changing to use different tools
#

# Find out if ccache is installed on the system
CCACHE := ccache
RESULT = $(shell (which $(CCACHE) > /dev/null 2>&1; echo $$?) )
ifneq ($(RESULT),0)
CCACHE :=
endif

ARM_SDK_PREFIX ?= arm-none-eabi-

# Tool names
CROSS_CC := $(CCACHE) $(ARM_SDK_PREFIX)gcc
CROSS_CXX := $(CCACHE) $(ARM_SDK_PREFIX)g++
CROSS_GDB := $(ARM_SDK_PREFIX)gdb
OBJCOPY := $(ARM_SDK_PREFIX)objcopy
OBJDUMP := $(ARM_SDK_PREFIX)objdump
SIZE := $(ARM_SDK_PREFIX)size

#
# Tool options.
#
CC_DEBUG_OPTIMISATION := $(OPTIMISE_DEFAULT)
CC_DEFAULT_OPTIMISATION := $(OPTIMISATION_BASE) $(OPTIMISE_DEFAULT)
CC_SPEED_OPTIMISATION := $(OPTIMISATION_BASE) $(OPTIMISE_SPEED)
CC_SIZE_OPTIMISATION := $(OPTIMISATION_BASE) $(OPTIMISE_SIZE)

CFLAGS += $(ARCH_FLAGS) \
$(addprefix -D,$(OPTIONS)) \
$(addprefix -I,$(INCLUDE_DIRS)) \
$(DEBUG_FLAGS) \
-std=gnu99 \
-Wall -Wextra -Wunsafe-loop-optimizations -Wdouble-promotion \
-ffunction-sections \
-fdata-sections \
-pedantic \
$(DEVICE_FLAGS) \
-DUSE_STDPERIPH_DRIVER \
-D$(TARGET) \
$(TARGET_FLAGS) \
-D'__FORKNAME__="$(FORKNAME)"' \
-D'__TARGET__="$(TARGET)"' \
-D'__REVISION__="$(REVISION)"' \
-save-temps=obj \
-MMD -MP \
$(EXTRA_FLAGS)

ASFLAGS = $(ARCH_FLAGS) \
-x assembler-with-cpp \
$(addprefix -I,$(INCLUDE_DIRS)) \
-MMD -MP

ifeq ($(LD_FLAGS),)
LD_FLAGS = -lm \
-nostartfiles \
--specs=nano.specs \
-lc \
-lnosys \
$(ARCH_FLAGS) \
$(LTO_FLAGS) \
$(DEBUG_FLAGS) \
-static \
-Wl,-gc-sections,-Map,$(TARGET_MAP) \
-Wl,-L$(LINKER_DIR) \
-Wl,--cref \
-Wl,--no-wchar-size-warning \
-T$(LD_SCRIPT)
endif

###############################################################################
# No user-serviceable parts below
###############################################################################

CPPCHECK = cppcheck $(CSOURCES) --enable=all --platform=unix64 \
--std=c99 --inline-suppr --quiet --force \
$(addprefix -I,$(INCLUDE_DIRS)) \
-I/usr/include -I/usr/include/linux

#
# Things we will build
#
TARGET_BIN = $(BIN_DIR)/$(FORKNAME)_$(FW_VER)_$(TARGET).bin
TARGET_HEX = $(BIN_DIR)/$(FORKNAME)_$(FW_VER)_$(TARGET).hex
TARGET_ELF = $(OBJECT_DIR)/$(FORKNAME)_$(TARGET).elf
TARGET_LST = $(OBJECT_DIR)/$(FORKNAME)_$(TARGET).lst
TARGET_OBJS = $(addsuffix .o,$(addprefix $(OBJECT_DIR)/$(TARGET)/,$(basename $(SRC))))
TARGET_DEPS = $(addsuffix .d,$(addprefix $(OBJECT_DIR)/$(TARGET)/,$(basename $(SRC))))
TARGET_MAP = $(OBJECT_DIR)/$(FORKNAME)_$(TARGET).map


CLEAN_ARTIFACTS := $(TARGET_BIN)
CLEAN_ARTIFACTS += $(TARGET_HEX)
CLEAN_ARTIFACTS += $(TARGET_ELF) $(TARGET_OBJS) $(TARGET_MAP)
CLEAN_ARTIFACTS += $(TARGET_LST)

# Make sure build date and revision is updated on every incremental build
$(OBJECT_DIR)/$(TARGET)/build/version.o : $(SRC)

# List of buildable ELF files and their object dependencies.
# It would be nice to compute these lists, but that seems to be just beyond make.

$(TARGET_LST): $(TARGET_ELF)
$(V0) $(OBJDUMP) -S --disassemble $< > $@

$(TARGET_HEX): $(TARGET_ELF)
$(V0) $(OBJCOPY) -O ihex --set-start 0x8000000 $< $@

$(TARGET_BIN): $(TARGET_ELF)
$(V0) $(OBJCOPY) -O binary $< $@

$(TARGET_ELF): $(TARGET_OBJS)
$(V1) echo Linking $(TARGET)
$(V1) $(CROSS_CC) -o $@ $^ $(LD_FLAGS)
$(V0) $(SIZE) $(TARGET_ELF)

# Compile
ifeq ($(DEBUG),GDB)
$(OBJECT_DIR)/$(TARGET)/%.o: %.c
$(V1) mkdir -p $(dir $@)
$(V1) echo "%% (debug) $(notdir $<)" "$(STDOUT)" && \
$(CROSS_CC) -c -o $@ $(CFLAGS) $(CC_DEBUG_OPTIMISATION) $<
else
$(OBJECT_DIR)/$(TARGET)/%.o: %.c
$(V1) mkdir -p $(dir $@)
$(V1) $(if $(findstring $(subst ./src/main/,,$<),$(SPEED_OPTIMISED_SRC)), \
echo "%% (speed optimised) $(notdir $<)" "$(STDOUT)" && \
$(CROSS_CC) -c -o $@ $(CFLAGS) $(CC_SPEED_OPTIMISATION) $<, \
$(if $(findstring $(subst ./src/main/,,$<),$(SIZE_OPTIMISED_SRC)), \
echo "%% (size optimised) $(notdir $<)" "$(STDOUT)" && \
$(CROSS_CC) -c -o $@ $(CFLAGS) $(CC_SIZE_OPTIMISATION) $<, \
echo "%% $(notdir $<)" "$(STDOUT)" && \
$(CROSS_CC) -c -o $@ $(CFLAGS) $(CC_DEFAULT_OPTIMISATION) $<))
endif

# Assemble
$(OBJECT_DIR)/$(TARGET)/%.o: %.s
$(V1) mkdir -p $(dir $@)
$(V1) echo "%% $(notdir $<)" "$(STDOUT)"
$(V1) $(CROSS_CC) -c -o $@ $(ASFLAGS) $<

$(OBJECT_DIR)/$(TARGET)/%.o: %.S
$(V1) mkdir -p $(dir $@)
$(V1) echo "%% $(notdir $<)" "$(STDOUT)"
$(V1) $(CROSS_CC) -c -o $@ $(ASFLAGS) $<


## all : Build all targets (excluding unsupported)
all: $(SUPPORTED_TARGETS)

## official : Build all official (travis) targets
official: $(OFFICIAL_TARGETS)

$(VALID_TARGETS):
$(V0) @echo "Building $@" && \
$(MAKE) binary hex TARGET=$@ && \
echo "Building $@ succeeded."

$(SKIP_TARGETS):
$(MAKE) TARGET=$@

CLEAN_TARGETS = $(addprefix clean_,$(VALID_TARGETS) $(SKIP_TARGETS) )
TARGETS_CLEAN = $(addsuffix _clean,$(VALID_TARGETS) $(SKIP_TARGETS) )

## clean : clean up temporary / machine-generated files
clean:
$(V0) @echo "Cleaning $(TARGET)"
$(V0) rm -f $(CLEAN_ARTIFACTS)
$(V0) rm -rf $(OBJECT_DIR)/$(TARGET)
$(V0) @echo "Cleaning $(TARGET) succeeded."

## clean_test : clean up temporary / machine-generated files (tests)
clean_test:
$(V0) cd src/test && $(MAKE) clean || true

## clean_<TARGET> : clean up one specific target
$(CLEAN_TARGETS):
$(V0) $(MAKE) -j TARGET=$(subst clean_,,$@) clean

## <TARGET>_clean : clean up one specific target (alias for above)
$(TARGETS_CLEAN):
$(V0) $(MAKE) -j TARGET=$(subst _clean,,$@) clean

## clean_all : clean all valid targets
clean_all: $(CLEAN_TARGETS)

## all_clean : clean all valid targets (alias for above)
all_clean: $(TARGETS_CLEAN)

binary:
$(V0) $(MAKE) -j $(TARGET_BIN)

hex:
$(V0) $(MAKE) -j $(TARGET_HEX)

# mkdirs
$(BUILD_DIR):
mkdir -p $@

## version : print firmware version
version:
@echo $(FW_VER)

## help : print this help message and exit
help:
$(V0) @echo ""
$(V0) @echo "Makefile for the $(FORKNAME) firmware"
$(V0) @echo ""
$(V0) @echo "Usage:"
$(V0) @echo " make [V=<verbosity>] [TARGET=<target>] [OPTIONS=\"<options>\"]"
$(V0) @echo "Or:"
$(V0) @echo " make <target> [V=<verbosity>] [OPTIONS=\"<options>\"]"
$(V0) @echo ""
$(V0) @echo "Valid TARGET values are: $(VALID_TARGETS)"
$(V0) @echo ""


## targets : print a list of all valid target platforms (for consumption by scripts)
targets:
$(V0) @echo "Valid targets: $(VALID_TARGETS)"
$(V0) @echo "Target: $(TARGET)"

# rebuild everything when makefile changes
$(TARGET_OBJS) : Makefile

# include auto-generated dependencies
-include $(TARGET_DEPS)
21 changes: 21 additions & 0 deletions make/build_verbosity.mk
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@


## V : Set verbosity level based on the V= parameter
## V=0 Low
## V=1 High
export AT := @

ifndef V
export V0 :=
export V1 := $(AT)
export STDOUT :=
else ifeq ($(V), 0)
export V0 := $(AT)
export V1 := $(AT)
export STDOUT:= "> /dev/null"
export MAKE := $(MAKE) --no-print-directory
else ifeq ($(V), 1)
export V0 :=
export V1 :=
export STDOUT :=
endif
1 change: 1 addition & 0 deletions make/local.mk
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
GCC_REQUIRED_VERSION := 6.3.1
Loading

0 comments on commit 1517d2a

Please sign in to comment.