From e692ccc44ec017f79c74a9bab619019007e27cfe Mon Sep 17 00:00:00 2001 From: px4dev Date: Wed, 16 Jan 2013 21:03:27 -0800 Subject: [PATCH] Move more functionality into firmware.mk. Now we build the px4 bundles in a way that will let external builders generate them too. Pass the platform define into the firmware builder. --- Makefile | 65 ++++++------- makefiles/firmware.mk | 179 ++++++++++++++++++++++++++++++++---- makefiles/px4fmu_default.mk | 3 +- makefiles/px4io_default.mk | 1 + 4 files changed, 189 insertions(+), 59 deletions(-) diff --git a/Makefile b/Makefile index 7376d5221c..5a6ee0faec 100644 --- a/Makefile +++ b/Makefile @@ -52,45 +52,33 @@ PLATFORM_FROM_CONFIG = $(word 1,$(subst _, ,$1)) # # Built products # -FIRMWARES = $(foreach config,$(CONFIGS),$(IMAGE_DIR)/$(config).px4) -BINARIES = $(foreach config,$(CONFIGS),$(BUILD_DIR)/$(config).build/firmware.bin) +STAGED_FIRMWARES = $(foreach config,$(CONFIGS),$(IMAGE_DIR)/$(config).px4) +FIRMWARES = $(foreach config,$(CONFIGS),$(BUILD_DIR)/$(config).build/firmware.px4) # # Debugging # MQUIET = --no-print-directory #MQUIET = --print-directory -ifeq ($(V),) -Q = @ -else -Q = -endif - -all: $(FIRMWARES) -#all: $(SYMBOLS) +Q := $(if $(V),,@) +all: $(STAGED_FIRMWARES) # -# Generate FIRMWARES from BINARIES +# Copy FIRMWARES into the image directory. # -$(IMAGE_DIR)/%.px4: basepath = $(basename $(@)) -$(IMAGE_DIR)/%.px4: config = $(notdir $(basepath)) -$(IMAGE_DIR)/%.px4: platform = $(call PLATFORM_FROM_CONFIG,$(config)) -$(FIRMWARES): $(IMAGE_DIR)/%.px4: $(BUILD_DIR)/%.build/firmware.bin - @echo %% Generating $@ for $(config) - $(Q) $(MKFW) --prototype $(IMAGE_DIR)/$(platform).prototype \ - --git_identity $(PX4_BASE) \ - --image $< > $@ +$(STAGED_FIRMWARES): $(IMAGE_DIR)/%.px4: $(BUILD_DIR)/%.build/firmware.px4 + @echo %% Copying $@ + $(Q) $(COPY) $< $@ # -# Generate the firmware executable +# Generate FIRMWARES # -# XXX pick the right build tool for the host OS - force it on the generation side too. -# -$(BUILD_DIR)/%.build/firmware.bin: config = $(patsubst $(BUILD_DIR)/%.build/firmware.bin,%,$@) -$(BUILD_DIR)/%.build/firmware.bin: work_dir = $(BUILD_DIR)/$(config).build -$(BINARIES): $(BUILD_DIR)/%.build/firmware.bin: $(BUILD_DIR)/$(word 1,$(subst _, ,%)).build - @echo %% Building $(config) in $(work_dir) +$(BUILD_DIR)/%.build/firmware.px4: config = $(patsubst $(BUILD_DIR)/%.build/firmware.px4,%,$@) +$(BUILD_DIR)/%.build/firmware.px4: work_dir = $(BUILD_DIR)/$(config).build +$(FIRMWARES): $(BUILD_DIR)/%.build/firmware.px4: + @echo %%%% Building $(config) in $(work_dir) + $(Q) mkdir -p $(work_dir) $(Q) make -C $(work_dir) \ -f $(PX4_BASE)/makefiles/$(config).mk \ CONFIG=$(config) \ @@ -100,23 +88,24 @@ $(BINARIES): $(BUILD_DIR)/%.build/firmware.bin: $(BUILD_DIR)/$(word 1,$(subst _, # # Generate the config build directory. # -BUILDAREAS = $(foreach config,$(CONFIGS),$(BUILD_DIR)/$(config).build) -.PHONY: buildareas -buildareas: $(BUILDAREAS) - -$(BUILD_DIR)/%.build: config = $(notdir $(basename $@)) -$(BUILD_DIR)/%.build: platform = $(call PLATFORM_FROM_CONFIG,$(config)) -$(BUILDAREAS): $(BUILD_DIR)/%.build: - @echo %% Setting up build environment for $(config) - $(Q) mkdir -p $@ - $(Q) (cd $@ && $(RMDIR) nuttx-export && unzip -q $(ARCHIVE_DIR)/$(platform).export) +#BUILDAREAS = $(foreach config,$(CONFIGS),$(BUILD_DIR)/$(config).build) +#.PHONY: buildareas +#buildareas: $(BUILDAREAS) +# +#$(BUILD_DIR)/%.build: config = $(notdir $(basename $@)) +#$(BUILD_DIR)/%.build: platform = $(call PLATFORM_FROM_CONFIG,$(config)) +#$(BUILDAREAS): $(BUILD_DIR)/%.build: +# @echo %% Setting up build environment for $(config) +# $(Q) mkdir -p $@ +# $(Q) (cd $@ && $(RMDIR) nuttx-export && unzip -q $(ARCHIVE_DIR)/$(platform).export) # # Build the NuttX export archives. # # Note that there are no explicit dependencies extended from these # archives. If NuttX is updated, the user is expected to rebuild the -# archives/build area manually. +# archives/build area manually. Likewise, when the 'archives' target is +# invoked, all archives are always rebuilt. # # XXX Should support fetching/unpacking from a separate directory to permit # downloads of the prebuilt archives as well... @@ -196,8 +185,6 @@ endif .PHONY: clean clean: $(Q) $(RMDIR) $(BUILD_DIR)/*.build - $(Q) $(REMOVE) -f $(IMAGE_DIR)/*.bin - $(Q) $(REMOVE) -f $(IMAGE_DIR)/*.sym $(Q) $(REMOVE) -f $(IMAGE_DIR)/*.px4 $(Q) make -C $(ROMFS_SRC) -r $(MQUIET) clean diff --git a/makefiles/firmware.mk b/makefiles/firmware.mk index 3f41ec6521..1ecc7da95f 100644 --- a/makefiles/firmware.mk +++ b/makefiles/firmware.mk @@ -4,70 +4,198 @@ # Currently this assumes that we're just compiling SRCS # and then linking the whole thing together. # +# Requires: +# +# PLATFORM +# Must be set to a platform name known to the PX4 distribution. +# +# Optional: +# +# PX4_BASE: +# Points to a PX4 distribution. Normally determined based on the +# path to this file. +# +# CONFIG: +# Used to set the output filename; defaults to 'firmware'. +# +# WORK_DIR: +# Sets the directory in which the firmware will be built. Defaults +# to the directory 'build' under the directory containing the +# parent Makefile. +# + +################################################################################ +# Paths and configuration +################################################################################ # # Work out where this file is, so we can find other makefiles in the # same directory. # -# If PX4_BASE wasn't set previously, set it here now. +# If PX4_BASE wasn't set previously, work out what it should be +# and set it here now. # export PX4_MK_INCLUDE ?= $(dir $(lastword $(MAKEFILE_LIST))) ifeq ($(PX4_BASE),) export PX4_BASE := $(abspath $(PX4_MK_INCLUDE)/..) endif +$(info %% PX4_BASE $(PX4_BASE)) + +# +# If WORK_DIR is not set, create a 'build' directory next to the +# parent Makefile. +# +PARENT_MAKEFILE := $(lastword $(filter-out $(lastword $(MAKEFILE_LIST)),$(MAKEFILE_LIST))) +ifeq ($(WORK_DIR),) +export WORK_DIR := $(dir $(PARENT_MAKEFILE))/build +endif +$(info %% WORK_DIR $(WORK_DIR)) + +# +# Paths +# +export NUTTX_SRC = $(PX4_BASE)/nuttx +export NUTTX_APPS = $(PX4_BASE)/apps +export MAVLINK_SRC = $(PX4_BASE)/mavlink +export ROMFS_SRC = $(PX4_BASE)/ROMFS +export IMAGE_DIR = $(PX4_BASE)/Images +export BUILD_DIR = $(PX4_BASE)/Build +export ARCHIVE_DIR = $(PX4_BASE)/Archives + +# +# Extra tools. +# +# XXX should be in a common toolchain config somewhere. +# +MKFW = $(PX4_BASE)/Tools/px_mkfw.py +UPLOADER = $(PX4_BASE)/Tools/px_uploader.py +COPY = cp +REMOVE = rm -f +RMDIR = rm -rf + +# +# Sanity-check the PLATFORM variable and then get the platform config. +# +# The platform config in turn will fetch the toolchain configuration. +# +ifeq ($(PLATFORM),) +$(error The PLATFORM variable must be set before including firmware.mk) +endif +include $(PX4_MK_INCLUDE)/$(PLATFORM).mk + +# +# Makefile debugging. +# +Q := $(if $(V),,@) + +# +# Host-specific paths, hacks and fixups +# +SYSTYPE := $(shell uname -s) + +ifeq ($(SYSTYPE),Darwin) +# Eclipse may not have the toolchain on its path. +export PATH := $(PATH):/usr/local/bin +endif + +# +# Serial port defaults. +# +# XXX The uploader should be smarter than this. +# +ifeq ($(SYSTYPE),Darwin) +SERIAL_PORTS ?= "/dev/tty.usbmodemPX1,/dev/tty.usbmodemPX2,/dev/tty.usbmodemPX3,/dev/tty.usbmodemPX4,/dev/tty.usbmodem1,/dev/tty.usbmodem2,/dev/tty.usbmodem3,/dev/tty.usbmodem4" +endif +ifeq ($(SYSTYPE),Linux) +SERIAL_PORTS ?= "/dev/ttyACM5,/dev/ttyACM4,/dev/ttyACM3,/dev/ttyACM2,/dev/ttyACM1,/dev/ttyACM0" +endif +ifeq ($(SERIAL_PORTS),) +SERIAL_PORTS = "\\\\.\\COM32,\\\\.\\COM31,\\\\.\\COM30,\\\\.\\COM29,\\\\.\\COM28,\\\\.\\COM27,\\\\.\\COM26,\\\\.\\COM25,\\\\.\\COM24,\\\\.\\COM23,\\\\.\\COM22,\\\\.\\COM21,\\\\.\\COM20,\\\\.\\COM19,\\\\.\\COM18,\\\\.\\COM17,\\\\.\\COM16,\\\\.\\COM15,\\\\.\\COM14,\\\\.\\COM13,\\\\.\\COM12,\\\\.\\COM11,\\\\.\\COM10,\\\\.\\COM9,\\\\.\\COM8,\\\\.\\COM7,\\\\.\\COM6,\\\\.\\COM5,\\\\.\\COM4,\\\\.\\COM3,\\\\.\\COM2,\\\\.\\COM1,\\\\.\\COM0" +endif + +################################################################################ +# NuttX libraries and paths +################################################################################ + +# +# Check that the NuttX archive for the selected platform is available. +# +NUTTX_ARCHIVE := $(wildcard $(ARCHIVE_DIR)/$(PLATFORM).export) +ifeq ($(NUTTX_ARCHIVE),) +$(error The NuttX export archive for $(PLATFORM) is missing from $(ARCHIVE_DIR) - try 'make archives' in $(PX4_BASE)) +endif + +# +# The NuttX config header should always be present in the NuttX archive, and +# if it changes, everything should be rebuilt. So, use it as the trigger to +# unpack the NuttX archive. +# +NUTTX_EXPORT_DIR = $(WORK_DIR)/nuttx-export +NUTTX_CONFIG_HEADER = $(NUTTX_EXPORT_DIR)/include/nuttx/config.h # # Use the linker script from the NuttX export # -LDSCRIPT = $(WORK_DIR)/nuttx-export/build/ld.script +LDSCRIPT = $(NUTTX_EXPORT_DIR)/build/ld.script # # Add directories from the NuttX export to the relevant search paths # -INCLUDE_DIRS += $(WORK_DIR)/nuttx-export/include -LIB_DIRS += $(WORK_DIR)/nuttx-export/libs +INCLUDE_DIRS += $(NUTTX_EXPORT_DIR)/include +LIB_DIRS += $(NUTTX_EXPORT_DIR)/libs LIBS += -lapps -lnuttx +LINK_DEPS += $(wildcard $(addsuffix /*.a,$(LIB_DIRS))) + +################################################################################ +# Build rules +################################################################################ # # Things that, if they change, might affect everything # -GLOBAL_DEPS += $(MAKEFILE_LIST) +GLOBAL_DEPS += $(MAKEFILE_LIST) $(NUTTX_CONFIG_HEADER) # -# Include the platform configuration -# -include $(PX4_MK_INCLUDE)/$(PLATFORM).mk - -# -# What we're going to build +# What we're going to build. # PRODUCT_BUNDLE = $(WORK_DIR)/firmware.px4 PRODUCT_BIN = $(WORK_DIR)/firmware.bin PRODUCT_SYM = $(WORK_DIR)/firmware.sym -PRODUCTS = $(PRODUCT_BIN) $(PRODUCT_SYM) .PHONY: all -all: $(PRODUCTS) +all: $(PRODUCT_BUNDLE) # -# Rules for building objects +# Object files we will generate from sources # OBJS = $(foreach src,$(SRCS),$(WORK_DIR)/$(src).o) -$(filter %.c.o,$(OBJS)): $(WORK_DIR)/%.c.o: %.c - @echo compile $< +# +# Rules +# + +$(filter %.c.o,$(OBJS)): $(WORK_DIR)/%.c.o: %.c $(GLOBAL_DEPS) @mkdir -p $(dir $@) $(call COMPILE,$<,$@) -$(filter %.cpp.o,$(OBJS)): $(WORK_DIR)/%.cpp.o: %.cpp +$(filter %.cpp.o,$(OBJS)): $(WORK_DIR)/%.cpp.o: %.cpp $(GLOBAL_DEPS) @mkdir -p $(dir $@) $(call COMPILEXX,$<,$@) -$(filter %.S.o,$(OBJS)): $(WORK_DIR)/%.S.o: %.S +$(filter %.S.o,$(OBJS)): $(WORK_DIR)/%.S.o: %.S $(GLOBAL_DEPS) @mkdir -p $(dir $@) $(call ASSEMBLE,$<,$@) --include $(DEP_INCLUDES) +$(NUTTX_CONFIG_HEADER): $(NUTTX_ARCHIVE) + @echo %% Unpacking $(NUTTX_ARCHIVE) + $(Q) unzip -q -o -d $(WORK_DIR) $(NUTTX_ARCHIVE) + $(Q) touch $@ + +$(PRODUCT_BUNDLE): $(PRODUCT_BIN) + @echo %% Generating $@ + $(Q) $(MKFW) --prototype $(IMAGE_DIR)/$(PLATFORM).prototype \ + --git_identity $(PX4_BASE) \ + --image $< > $@ $(PRODUCT_BIN): $(PRODUCT_SYM) $(call SYM_TO_BIN,$<,$@) @@ -75,3 +203,16 @@ $(PRODUCT_BIN): $(PRODUCT_SYM) $(PRODUCT_SYM): $(OBJS) $(GLOBAL_DEPS) $(LINK_DEPS) $(call LINK,$@,$(OBJS)) +upload: $(PRODUCT_BUNDLE) $(UPLOADER) + @python -u $(UPLOADER) --port $(SERIAL_PORTS) $(PRODUCT_BUNDLE) + +clean: + @echo %% cleaning + $(Q) $(REMOVE) $(PRODUCT_BUNDLE) $(PRODUCT_BIN) $(PRODUCT_SYM) + $(Q) $(REMOVE) $(OBJS) $(DEP_INCLUDES) + $(Q) $(RMDIR) $(NUTTX_EXPORT_DIR) + +# +# DEP_INCLUDES is defined by the toolchain include in terms of $(OBJS) +# +-include $(DEP_INCLUDES) diff --git a/makefiles/px4fmu_default.mk b/makefiles/px4fmu_default.mk index 1dd3e6ab49..9bb5e09a46 100644 --- a/makefiles/px4fmu_default.mk +++ b/makefiles/px4fmu_default.mk @@ -2,6 +2,7 @@ # Makefile for the px4fmu_default configuration # +PLATFORM = px4fmu SRCS = $(PX4_BASE)/platforms/empty.c -include $(PX_4BASE)/makefiles/firmware.mk +include $(PX4_BASE)/makefiles/firmware.mk diff --git a/makefiles/px4io_default.mk b/makefiles/px4io_default.mk index 2d96fa2fba..e961e46f70 100644 --- a/makefiles/px4io_default.mk +++ b/makefiles/px4io_default.mk @@ -2,6 +2,7 @@ # Makefile for the px4io_default configuration # +PLATFORM = px4io SRCS = $(PX4_BASE)/platforms/empty.c include $(PX4_BASE)/makefiles/firmware.mk