在另一台电脑上搞点事情,系统是 FreeBSD 的,在编译的时候发现找不到 servo 头文件。
细看编译命令,居然是这样的。
...
-I/usr/local/arduino/libraries//usr/local/arduino/libraries
-I/home/username/sketchbook/libraries//usr/local/arduino/libraries
...
这样的 include 路径能找到头文件才怪了。一定是 mk
文件有问题。
立刻找到 CPPFLAGS
看一下是怎么包含头文件路径的。
CPPFLAGS
= -mmcu=$(MCU) -DF_CPU=$(F_CPU)
-DARDUINO=$(ARDUINO_VERSION) \
-I. -I$(ARDUINO_CORE_PATH)
-I$(ARDUINO_VAR_PATH)/$(VARIANT) \
$(SYS_INCLUDES) $(USER_INCLUDES) -g -Os -w -Wall \
-DUSB_VID=$(USB_VID) -DUSB_PID=$(USB_PID) \
-ffunction-sections -fdata-sections
找到 SYS_INCLUDES
和 USER_INCLUDES
的定义。
SYS_INCLUDES = $(patsubst %,-I%,$(SYS_LIBS))
USER_INCLUDES = $(patsubst %,-I%,$(USER_LIBS))
继续看 SYS_LIBS
和 USER_LIBS
。
SYS_LIBS = $(patsubst %,$(ARDUINO_LIB_PATH)/%,$(ARDUINO_LIBS))
USER_LIBS = $(patsubst %,$(USER_LIB_PATH)/%,$(ARDUINO_LIBS))
SYS_LIBS
和 USER_LIBS
会将 ARDUINO_LIBS
替换成 ARDUINO_LIB_PATH/ARDUINO_LIBS
和 USER_LIB_PATH/ARDUINO_LIBS
这样的形式。
再看下 ARDUINO_LIB_PATH
和 USER_LIB_PATH
的定义。
ARDUINO_LIB_PATH = $(ARDUINO_DIR)/libraries
ifndef ARDUINO_SKETCHBOOK
ARDUINO_SKETCHBOOK = $(HOME)/sketchbook
endif
ifndef USER_LIB_PATH
USER_LIB_PATH = $(ARDUINO_SKETCHBOOK)/libraries
endif
问题就在这里咯,在 Makefile 里面定义的 ARDUINO_LIBS
,根据上文SYS_INCLUDES
和 USER_INCLUDES
的定义
SYS_INCLUDES = $(patsubst %,-I%,$(SYS_LIBS))
USER_INCLUDES = $(patsubst %,-I%,$(USER_LIBS))
就会在 mk
中被替换成
-I/usr/local/arduino/libraries//usr/local/arduino/libraries
-I/home/username/sketchbook/libraries//usr/local/arduino/libraries
这个 sketchbook
什么的是为 Arduino IDE 生成的文件夹,貌似这个 mk
还是为 IDE 编写的,得改咯。
CLI 下的库文件都在 /usr/local/arduino/libraries
里面,所以直接引用这里就可以了。
我保留 mk
对于 ARDUINO_LIB_PATH
的定义,因此 SYS_LIBS
直接引用 ARDUINO_LIB_PATH
即可。但是考虑到还得在头文件加路径 (如 #include <Servo/Servo.h>
),所以加上 wildcard
,把 libraries
下的所有路径都包含进去。
SYS_LIBS = $(wildcard $(patsubst %,%/**/*,$(ARDUINO_LIBS)))
另外需要修改的地方就是对库源文件的索引。也必须加上 wildcard
,不然编译时还是找不到源文件。
LIB_C_SRCS = $(wildcard $(patsubst %,%/**/*.c,$(SYS_LIBS)))
LIB_CPP_SRCS = $(wildcard $(patsubst %,%/**/*.cpp,$(SYS_LIBS)))
另外的 USER_LIBS
说实话可以不需要。我把所有有关 USER_LIBS
的东西全部删了。不想删的话做相同处理。
接下来,还得把 /usr/local/arduino/libraries/
里的库文件,替换成 arduino
官方的,BSD 的库太老了,编译不了。官方库的链接在这里。
最后,还要在 CPPFLAGS
上添加一些参数,不然最新的官方库在编译时会找不到 CPU 架构而报错。
CPPFLAGS =
-mmcu=$(MCU) -DF_CPU=$(F_CPU) -DARDUINO=$(ARDUINO_VERSION) \
-I. -I$(ARDUINO_CORE_PATH) -I$(ARDUINO_VAR_PATH)/$(VARIANT) \
$(SYS_INCLUDES) $(USER_INCLUDES) -g -Os -w -Wall -Wextra -std=gnu++11 \
-DUSB_VID=$(USB_VID) -DUSB_PID=$(USB_PID) \
-ffunction-sections -fdata-sections -fpermissive
-DARDUINO_AVR_UNO -DARDUINO_ARCH_AVR
其中 -std=gnu++11
和 -DARDUINO_AVR_UNO -DARDUINO_ARCH_AVR
是新添加的。
折腾就是学习的过程,如果就在 Windows 上下个 IDE 什么事情都不会发生,但是错失了很多学习的机会。这次问题的解决过程让我对 Makefile 又有了更多的了解。另外解决问题的能力,又一次得到了提升。
Voila!可以好好玩耍了。