Примечание: Я понимаю, что этот ответ не отвечает всем вашим требованиям, на самом деле этот подход по-прежнему требует, чтобы вы указали имена соответствующих библиотек Arduino, которые вы используете в своем проекте, а также список путей к каталогам, которые должны быть включены в проект. Однако это решение наиболее близко к вашим требованиям, о которых я мог подумать, и это может помочь кому-то еще прочитать этот вопрос в будущем.
Я использую ArduinoMakefile для этого:
- поставил Makefile.мастер в основном рабочем каталоге
- при запуске нового Arduino проекта, создать его как подкаталог в вашем рабочем пространстве
- создать один файл с расширением
.pde/.ino
содержащего setup()
и `цикл() методы
- положить оставшуюся логику в
.c/.cpp/.h/.hpp
файлы
добавить проекта Makefile тыс в наборах проект рафинированных настройки в этом подкаталоге, например:
# Your Arduino environment.
ARD_HOME = /usr/share/arduino
ARD_BIN = $(ARD_HOME)/hardware/tools/avr/bin
# Monitor Baudrate
MON_SPEED = 4800
# Board settings.
BOARD = uno
PORT = /dev/ttyACM0
PROGRAMMER = stk500v2
# Where to find header files and libraries.
INC_DIRS =
MY_LIB_DIRS =
LIBS =
LIB_DIRS = $(addprefix $(ARD_HOME)/libraries/, $(LIBS)) $(MY_LIB_DIRS)
include ../Makefile.master
компилировать и запускать с помощью make all
, make upload
, make monitor
и т.д.
Убедитесь, что у вас есть picocom установлен на ваш Unix/Linux машина (или ее эквивалент) как консольный последовательный монитор. На MAC-OS вы можете использовать экран, установив соответственно переменную MON_CMD
.
Makefile.master:
оригинальный Makefile.master была написана Alan Burlison
и модифицированы Matthieu Weber
, и могут быть найдены here.
Я сделал некоторые изменения, так что он соответствует моей конфигурации, в частности, я добавил следующие строки кода:
### DEBUG Compilation ###
ifeq ($(DEBUG), 1)
ARD_FLAGS += -DDEBUG_PROJ
C_FLAGS += -g
CXX_FLAGS += -g
else
ARD_FLAGS += -DNDEBUG_PROJ
endif
и впоследствии удалены -g
вариант из стандартных C/CXX _FLAGS
записей в Makefile.master. Таким образом, информационный символ не добавляется на выпуск кода, и только тогда, когда код компилируется с DEBUG=1
код экранируется
#ifdef DEBUG_PROJ
/* debug code here */
#endif
// or
#ifndef NDEBUG_PROJ
/* debug code here */
#endif
находит свой путь в бинарный файл, таким образом, в результате чего меньший релиз исполняемых файлов.
Здесь вы можете найти мои собственные версия Makefile.мастер:
#
# Copyright 2011 Alan Burlison, [email protected] All rights reserved.
# Subsequently modified by Matthieu Weber, [email protected]
# Subsequently modified by Patrick Trentin, [email protected]
# Use is subject to license terms.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#
# 1. Redistributions of source code must retain the above copyright notice,
# this list of conditions and the following disclaimer.
#
# 2. Redistributions in binary form must reproduce the above copyright notice,
# this list of conditions and the following disclaimer in the documentation
# and/or other materials provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY ALAN BURLISON "AS IS" AND ANY EXPRESS OR IMPLIED
# WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
# EVENT SHALL ALAN BURLISON OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
# OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
# LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
# EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
# Makefile for building Arduino projects outside of the Arduino environment
#
# This makefile should be included into a per-project Makefile of the following
# form:
#
# ----------
# BOARD = mega
# PORT = /dev/term/0
# INC_DIRS = ../common
# LIB_DIRS = ../libraries/Task ../../libraries/VirtualWire
# include ../../Makefile.master
# ----------
#
# Where:
# BOARD : Arduino board type, from $(ARD_HOME)/hardware/boards.txt
# PORT : USB port
# INC_DIRS : List pf directories containing header files
# LIB_DIRS : List of directories containing library source
#
# Before using this Makefile you can adjust the following macros to suit
# your environment, either by editing this file directly or by defining them in
# the Makefile that includes this one, in which case they will override the
# definitions below:
# ARD_REV : arduino software revision, e.g. 0017, 0018
# ARD_HOME : installation directory of the Arduino software.
# ARD_BIN : location of compiler binaries
# AVRDUDE : location of avrdude executable
# AVRDUDE_CONF : location of avrdude configuration file
# PROGRAMMER : avrdude programmer type
# MON_TERM : terminal command for serial monitor
# MON_CMD : serial monitor command
# MON_SPEED : serial monitor speed
#
# Global configuration.
ARD_REV ?= 100
ARD_HOME ?= /usr/local/arduino
ARD_BIN ?= /usr/bin
AVRDUDE ?= $(ARD_HOME)/hardware/tools/avrdude
AVRDUDE_CONF ?= $(ARD_HOME)/hardware/tools/avrdude.conf
MON_TERM ?= xterm
MON_SPEED ?= 57600
MON_CMD ?= picocom
PORT ?= $(HOME)/dev/arduino
BOARD ?= atmega328
### Nothing below here should require editing. ###
# Check for the required definitions.
ifndef BOARD
$(error $$(BOARD) not defined)
endif
ifndef PORT
$(error $$(PORT) not defined)
endif
# Version-specific settings
ARD_BOARDS = $(ARD_HOME)/hardware/arduino/boards.txt
ARD_SRC_DIR = $(ARD_HOME)/hardware/arduino/cores/arduino
ARD_MAIN = $(ARD_SRC_DIR)/main.cpp
# Standard macros.
SKETCH = $(notdir $(CURDIR))
BUILD_DIR = build
VPATH = $(LIB_DIRS)
# Macros derived from boards.txt
MCU := $(shell sed -n 's/$(BOARD)\.build\.mcu=\(.*\)/\1/p' < $(ARD_BOARDS))
F_CPU := $(shell sed -n 's/$(BOARD)\.build\.f_cpu=\(.*\)/\1/p' < $(ARD_BOARDS))
UPLOAD_SPEED := \
$(shell sed -n 's/$(BOARD)\.upload\.speed=\(.*\)/\1/p' < $(ARD_BOARDS))
PROGRAMMER := \
$(shell sed -n 's/$(BOARD)\.upload\.protocol=\(.*\)/\1/p' < $(ARD_BOARDS))
ARD_VAR := \
$(shell sed -n 's/$(BOARD)\.build\.variant=\(.*\)/\1/p' < $(ARD_BOARDS))
# More Version-specific settings
ARD_VAR_DIR = $(ARD_HOME)/hardware/arduino/variants/$(ARD_VAR)
# Build tools.
CC = $(ARD_BIN)/avr-gcc
CXX = $(ARD_BIN)/avr-g++
CXXFILT = $(ARD_BIN)/avr-c++filt
OBJCOPY = $(ARD_BIN)/avr-objcopy
OBJDUMP = $(ARD_BIN)/avr-objdump
AR = $(ARD_BIN)/avr-ar
SIZE = $(ARD_BIN)/avr-size
NM = $(ARD_BIN)/avr-nm
MKDIR = mkdir -p
RM = rm -rf
MV = mv -f
LN = ln -f
# Compiler flags.
INC_FLAGS = \
$(addprefix -I,$(INC_DIRS)) $(addprefix -I,$(LIB_DIRS)) -I$(ARD_SRC_DIR) -I$(ARD_VAR_DIR)
ARD_FLAGS = -mmcu=$(MCU) -DF_CPU=$(F_CPU) -DARDUINO=$(ARD_REV)
C_CXX_FLAGS = \
-Wall -Wextra -Wundef -Wno-unused-parameter \
-fdiagnostics-show-option -Wa,-adhlns=$(BUILD_DIR)/$*.lst
C_FLAGS = \
$(C_CXX_FLAGS) -std=gnu99 -Wstrict-prototypes -Wno-old-style-declaration
CXX_FLAGS = $(C_CXX_FLAGS)
### DEBUG Compilation ###
ifeq ($(DEBUG), 1)
ARD_FLAGS += -DDEBUG_PROJ
C_FLAGS += -g
CXX_FLAGS += -g
else
ARD_FLAGS += -DNDEBUG_PROJ
endif
# Optimiser flags.
# optimise for size, unsigned by default, pack data.
# separate sections, drop unused ones, shorten branches, jumps.
# don't inline, vectorise loops. no exceptions.
# no os preamble, use function calls in prologues.
# http://gcc.gnu.org/onlinedocs/gcc-4.3.5/gcc/
# http://www.tty1.net/blog/2008-04-29-avr-gcc-optimisations_en.html
OPT_FLAGS = \
-Os -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums \
-ffunction-sections -fdata-sections -Wl,--gc-sections,--relax \
-fno-inline-small-functions -fno-tree-scev-cprop -fno-exceptions \
-ffreestanding -mcall-prologues
# Build parameters.
IMAGE = $(BUILD_DIR)/$(SKETCH)
ARD_C_SRC = $(wildcard $(ARD_SRC_DIR)/*.c)
ARD_CXX_SRC = $(wildcard $(ARD_SRC_DIR)/*.cpp)
ARD_C_OBJ = $(patsubst %.c,%.o,$(notdir $(ARD_C_SRC)))
ARD_CXX_OBJ = $(patsubst %.cpp,%.o,$(notdir $(ARD_CXX_SRC)))
ARD_LIB = arduino
ARD_AR = $(BUILD_DIR)/lib$(ARD_LIB).a
ARD_AR_OBJ = $(ARD_AR)($(ARD_C_OBJ) $(ARD_CXX_OBJ))
ARD_LD_FLAG = -l$(ARD_LIB)
# Workaround for http://gcc.gnu.org/bugzilla/show_bug.cgi?id=34734
$(ARD_AR)(Tone.o) : CXX_FLAGS += -w
# Sketch libraries.
LIB_C_SRC = $(foreach ld,$(LIB_DIRS),$(wildcard $(ld)/*.c))
LIB_CXX_SRC = $(foreach ld,$(LIB_DIRS),$(wildcard $(ld)/*.cpp))
LIB_SRC = $(LIB_C_SRC) $(LIB_CXX_SRC)
ifneq "$(strip $(LIB_C_SRC) $(LIB_CXX_SRC))" ""
LIB_C_OBJ = $(patsubst %.c,%.o,$(notdir $(LIB_C_SRC)))
LIB_CXX_OBJ = $(patsubst %.cpp,%.o,$(notdir $(LIB_CXX_SRC)))
LIB_LIB = library
LIB_AR = $(BUILD_DIR)/lib$(LIB_LIB).a
LIB_AR_OBJ = $(LIB_AR)($(LIB_C_OBJ) $(LIB_CXX_OBJ))
LIB_LD_FLAG = -l$(LIB_LIB)
endif
# Sketch PDE source.
SKT_PDE_SRC = $(wildcard *.pde *.ino)
ifneq "$(strip $(SKT_PDE_SRC))" ""
SKT_PDE_OBJ = $(BUILD_DIR)/$(SKETCH)_pde.o
endif
# C and C++ source.
SKT_C_SRC = $(wildcard *.c)
SKT_CXX_SRC = $(wildcard *.cpp)
ifneq "$(strip $(SKT_C_SRC) $(SKT_CXX_SRC))" ""
SKT_C_OBJ = $(patsubst %.c,%.o,$(SKT_C_SRC))
SKT_CXX_OBJ = $(patsubst %.cpp,%.o,$(SKT_CXX_SRC))
SKT_LIB = sketch
SKT_AR = $(BUILD_DIR)/lib$(SKT_LIB).a
SKT_AR_OBJ = $(SKT_AR)/($(SKT_C_OBJ) $(SKT_CXX_OBJ))
SKT_LD_FLAG = -l$(SKT_LIB)
endif
# Definitions.
define run-cc
@ $(CC) $(ARD_FLAGS) $(INC_FLAGS) -M -MT '[email protected]($%)' -MF [email protected]_$*.dep $<
$(CC) -c $(C_FLAGS) $(OPT_FLAGS) $(ARD_FLAGS) $(INC_FLAGS) \
$< -o $(BUILD_DIR)/$%
@ $(AR) rc [email protected] $(BUILD_DIR)/$%
@ $(RM) $(BUILD_DIR)/$%
@ $(CXXFILT) < $(BUILD_DIR)/$*.lst > $(BUILD_DIR)/$*.lst.tmp
@ $(MV) $(BUILD_DIR)/$*.lst.tmp $(BUILD_DIR)/$*.lst
endef
define run-cxx
@ $(CXX) $(ARD_FLAGS) $(INC_FLAGS) -M -MT '[email protected]($%)' -MF [email protected]_$*.dep $<
$(CXX) -c $(CXX_FLAGS) $(OPT_FLAGS) $(ARD_FLAGS) $(INC_FLAGS) \
$< -o $(BUILD_DIR)/$%
@ $(AR) rc [email protected] $(BUILD_DIR)/$%
@ $(RM) $(BUILD_DIR)/$%
@ $(CXXFILT) < $(BUILD_DIR)/$*.lst > $(BUILD_DIR)/$*.lst.tmp
@ $(MV) $(BUILD_DIR)/$*.lst.tmp $(BUILD_DIR)/$*.lst
endef
# Rules.
.PHONY : all clean upload monitor upload_monitor
all : $(BUILD_DIR) $(IMAGE).hex
clean :
$(RM) $(BUILD_DIR)
$(BUILD_DIR) :
$(MKDIR) [email protected]
$(SKT_PDE_OBJ) : $(SKT_PDE_SRC)
if [ $(ARD_REV) -ge 100 ]; then \
echo '#include "Arduino.h"' > $(BUILD_DIR)/$(SKETCH)_pde.cpp; \
else \
echo '#include "WProgram.h"' > $(BUILD_DIR)/$(SKETCH)_pde.cpp; \
fi
echo '#include "$(SKT_PDE_SRC)"' >> $(BUILD_DIR)/$(SKETCH)_pde.cpp
$(LN) $(SKT_PDE_SRC) $(BUILD_DIR)/$(SKT_PDE_SRC)
cd $(BUILD_DIR) && $(CXX) -c $(subst build/,,$(CXX_FLAGS)) \
$(OPT_FLAGS) $(ARD_FLAGS) -I.. \
$(patsubst -I..%,-I../..%,$(INC_FLAGS)) \
$(SKETCH)_pde.cpp -o $(@F)
(%.o) : $(ARD_SRC_DIR)/%.c
$(run-cc)
(%.o) : $(ARD_SRC_DIR)/%.cpp
$(run-cxx)
(%.o) : %.c
$(run-cc)
(%.o) : %.cpp
$(run-cxx)
$(BUILD_DIR)/%.d : %.c
$(run-cc-d)
$(BUILD_DIR)/%.d : %.cpp
$(run-cxx-d)
$(IMAGE).hex : $(ARD_AR_OBJ) $(LIB_AR_OBJ) $(SKT_AR_OBJ) $(SKT_PDE_OBJ)
$(CC) $(CXX_FLAGS) $(OPT_FLAGS) $(ARD_FLAGS) -L$(BUILD_DIR) \
$(SKT_PDE_OBJ) $(SKT_LD_FLAG) $(LIB_LD_FLAG) $(ARD_LD_FLAG) -lm \
-o $(IMAGE).elf
$(OBJCOPY) -O ihex -j .eeprom --set-section-flags=.eeprom=alloc,load \
--no-change-warnings --change-section-lma .eeprom=0 $(IMAGE).elf \
$(IMAGE).eep
$(OBJCOPY) -O ihex -R .eeprom $(IMAGE).elf $(IMAGE).hex
$(OBJDUMP) -h -S $(IMAGE).elf | $(CXXFILT) -t > $(IMAGE).lst
$(SIZE) $(IMAGE).hex
upload : all
- pkill -f '$(MON_CMD).*$(PORT)'
- sleep 1
- stty -F $(PORT) hupcl
- $(AVRDUDE) -V -C$(AVRDUDE_CONF) -p$(MCU) -c$(PROGRAMMER) -P$(PORT) \
-b$(UPLOAD_SPEED) -D -Uflash:w:$(IMAGE).hex:i
monitor :
LD_LIBRARY_PATH= LD_PRELOAD= \
$(MON_TERM) -title '$(BOARD) $(PORT)' \
-e '$(MON_CMD) -b $(MON_SPEED) $(PORT)' &
upload_monitor : upload monitor
-include $(wildcard $(BUILD_DIR)/*.dep))
# vim:ft=make
Пример использования:
Учитывая реж дерево нравится следующим образом:
Base_Dir
├── Library
│ ├── Base
│ │ ├── general STM8 sources and headers
│ ├── STM8S_Discovery
│ │ └── board specific sources and headers
│ └── User
│ └── optional user library sources and headers
├── Projects
│ ├── Examples (to be filled)
│ │ └── Basic_Project
│ │ ├── config.h
│ │ ├── example.ino
│ │ └── Makefile --> should detect dependencies in ./*.c and ./*.h
...
Вы можете разместить Makefile.master
внутри Projects
, то при условии, что:
- Вам нужно только то, что находится в
Library/Base
и Library/User
для этого проекта
- Вы должны использовать LiquidCrystal Arduino библиотеки в проекте
, необходимо добавить следующее Makefile
в Basic Project
:
# Your Arduino environment.
BASE_DIR = /path/to/Base_Dir # to edit
ARD_HOME = /usr/share/arduino # to edit, maybe
ARD_BIN = $(ARD_HOME)/hardware/tools/avr/bin
# Monitor Baudrate
MON_SPEED = 4800
# Board settings.
BOARD = uno
PORT = /dev/ttyACM0
PROGRAMMER = stk500v2
# Where to find header files and libraries.
INC_DIRS =
MY_LIB_DIRS= $(BASE_DIR)/Library/Base $(BASE_DIR)/Library/User
LIBS= LiquidCrystal
LIB_DIRS = $(addprefix $(ARD_HOME)/libraries/, $(LIBS)) $(MY_LIB_DIRS)
include ../../Makefile.master
Отметьте, что common.h
должно быть автоматически обнаружено beca используйте его в .
, и нет необходимости добавлять его в INC_DIRS
.
Final Примечание: последний раз, когда я тестировала эту конфигурацию, я использовал версию 1.0.5
из Arduino исходного кода, и он работал безупречно.
Вы рассматривали загрузку другой IDE, например, Затмение на основе одного типа Simplicity Studio, строит простой проект со структурой, описанной и, видя, как IDE генерирует Makefiles? Это будет хорошей отправной точкой. –
Обратите внимание, что в среде Arduino дополнительный код, сгенерированный пользовательским интерфейсом и/или библиотеками, добавляется к пользовательскому '.ino' -коду в каждом модуле компиляции. Вы можете сделать это с помощью Makefiles, добавив дополнительный шаг к обработке. (Один из способов сделать это - создать предварительно обработанные исходные файлы в каталоге сборки, используя препроцессор, подав ему отдельные части для каждого блока компиляции.) Что вам нужно сделать здесь, это пройти весь процесс сборки вручную (и напишите об этом), включая различные варианты обработки; затем используйте это как схему для написания Makefile. –