Lots of errors from one library

Hi all,

I've been working on compiling Arduino sketches without using the IDE. With the generous help of people here, I've gotten in to work. But, I've run into one strange problem that's driving me nuts. I get errors from a library that I have been using for some time. Additionally, the sketch compiles just fine with the Arduino IDE.

Here is the list of errors I get when trying a CLI compile:

In file included from /usr/share/arduino-1.0.2/libraries/Flash/Flash.cpp:21:0:
/usr/share/arduino-1.0.2/libraries/Flash/Flash.h:68:22: error: ‘prog_char’ does not name a type
/usr/share/arduino-1.0.2/libraries/Flash/Flash.h:68:33: error: ISO C++ forbids declaration of ‘arr’ with no type [-fpermissive]
/usr/share/arduino-1.0.2/libraries/Flash/Flash.h:78:8: error: ‘prog_char’ does not name a type
/usr/share/arduino-1.0.2/libraries/Flash/Flash.h:90:8: error: ‘prog_char’ does not name a type
/usr/share/arduino-1.0.2/libraries/Flash/Flash.h: In member function ‘size_t _FLASH_STRING::length() const’:
/usr/share/arduino-1.0.2/libraries/Flash/Flash.h:71:20: error: ‘_arr’ was not declared in this scope
/usr/share/arduino-1.0.2/libraries/Flash/Flash.h: In member function ‘char* _FLASH_STRING::copy(char*, size_t, size_t) const’:
/usr/share/arduino-1.0.2/libraries/Flash/Flash.h:74:19: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
/usr/share/arduino-1.0.2/libraries/Flash/Flash.h:75:23: error: ‘_arr’ was not declared in this scope
/usr/share/arduino-1.0.2/libraries/Flash/Flash.h: In member function ‘char _FLASH_STRING::operator[](int) const’:
/usr/share/arduino-1.0.2/libraries/Flash/Flash.h:85:29: error: ‘_arr’ was not declared in this scope
/usr/share/arduino-1.0.2/libraries/Flash/Flash.h: At global scope:
/usr/share/arduino-1.0.2/libraries/Flash/Flash.h:179:28: error: ‘prog_char’ does not name a type
/usr/share/arduino-1.0.2/libraries/Flash/Flash.h:179:40: error: ISO C++ forbids declaration of ‘arr’ with no type [-fpermissive]
/usr/share/arduino-1.0.2/libraries/Flash/Flash.h:197:8: error: ‘prog_char’ does not name a type
/usr/share/arduino-1.0.2/libraries/Flash/Flash.h: In constructor ‘_FLASH_STRING_ARRAY::_FLASH_STRING_ARRAY(const int**, size_t)’:
/usr/share/arduino-1.0.2/libraries/Flash/Flash.h:179:61: error: class ‘_FLASH_STRING_ARRAY’ does not have any field named ‘_arr’
/usr/share/arduino-1.0.2/libraries/Flash/Flash.h: In member function ‘_FLASH_STRING _FLASH_STRING_ARRAY::operator[](int) const’:
/usr/share/arduino-1.0.2/libraries/Flash/Flash.h:186:25: error: ‘_arr’ was not declared in this scope
/usr/share/arduino-1.0.2/libraries/Flash/Flash.h: In member function ‘virtual void _FLASH_STRING_ARRAY::print(Print&) const’:
/usr/share/arduino-1.0.2/libraries/Flash/Flash.h:190:22: error: ‘_arr’ was not declared in this scope
/usr/share/arduino-1.0.2/libraries/Flash/Flash.cpp: At global scope:
/usr/share/arduino-1.0.2/libraries/Flash/Flash.cpp:23:36: error: ‘prog_char’ does not name a type
/usr/share/arduino-1.0.2/libraries/Flash/Flash.cpp:23:47: error: ISO C++ forbids declaration of ‘arr’ with no type [-fpermissive]
/usr/share/arduino-1.0.2/libraries/Flash/Flash.cpp: In constructor ‘_FLASH_STRING::_FLASH_STRING(const int*)’:
/usr/share/arduino-1.0.2/libraries/Flash/Flash.cpp:23:54: error: class ‘_FLASH_STRING’ does not have any field named ‘_arr’
make: *** [.lib/usr/share/arduino-1.0.2/libraries/Flash/Flash.cpp.o] Error 1

To avoid cluttering up the post, I'll refrain from posting other files until I have some idea WHICH ones to post (i.e. I am totally clueless as to what the error is).

I tried to Google the error messages and found references to changes in "Print.h", but these are old patches and have long since been incorporated into the current code.

Any ideas what to look for will be appreciated!

-- Roger

The prog_char declaration is in avr/pgmspace.h. Are you including this header file? Is the compiler able to find it?

PaulS:
The prog_char declaration is in avr/pgmspace.h. Are you including this header file? Is the compiler able to find it?

The pgmspace header is in the .ino file itself and in the Flash library header.

I assume the compiler can find it because there are lots of other libraries I have included in the particular program I'm trying to compile and they are all being found.

I assume the compiler can find it because there are lots of other libraries I have included in the particular program I'm trying to compile and they are all being found.

Perhaps we could have a peek at your makefile?

PaulS:
Perhaps we could have a peek at your makefile?

Certainly.....

BOARD=uno

# default arduino software directory, check software exists
ifndef ARDUINODIR

###############################################################################
#---ARDUINODIR := $(firstword $(wildcard ~/opt/arduino /usr/share/arduino))
###############################################################################
ARDUINODIR := $(firstword $(wildcard /usr/share/arduino-1.0.2))

endif
ifeq "$(wildcard $(ARDUINODIR)/hardware/arduino/boards.txt)" ""
$(error ARDUINODIR is not set correctly; arduino software not found)
endif

# default arduino version
ARDUINOCONST ?= 100

# default path for avr tools
ifndef AVRTOOLSPATH
AVRTOOLSPATH := $(subst :, , $(PATH))
AVRTOOLSPATH += $(ARDUINODIR)/hardware/tools
AVRTOOLSPATH += $(ARDUINODIR)/hardware/tools/avr/bin
endif

# auto mode?
INOFILE := $(wildcard *.ino *.pde)
ifdef INOFILE
ifneq "$(words $(INOFILE))" "1"
$(error There is more than one .pde or .ino file in this directory!)
endif

# automatically determine sources and target
TARGET := $(basename $(INOFILE))
SOURCES := $(INOFILE) \
	$(wildcard *.c *.cc *.cpp) \
	$(wildcard $(addprefix util/, *.c *.cc *.cpp)) \
	$(wildcard $(addprefix utility/, *.c *.cc *.cpp))

# automatically determine included libraries
LIBRARIES := $(filter $(notdir $(wildcard $(ARDUINODIR)/libraries/*)), \
	$(shell sed -ne "s/^ *\# *include *[<\"]\(.*\)\.h[>\"]/\1/p" $(SOURCES)))

endif

# no serial device? make a poor attempt to detect an arduino
SERIALDEVGUESS := 0
ifeq "$(SERIALDEV)" ""
SERIALDEV := $(firstword $(wildcard \
	/dev/ttyACM? /dev/ttyUSB? /dev/tty.usbserial* /dev/tty.usbmodem*))
SERIALDEVGUESS := 1
endif

# software
findsoftware = $(firstword $(wildcard $(addsuffix /$(1), $(AVRTOOLSPATH))))
CC := $(call findsoftware,avr-gcc)
CXX := $(call findsoftware,avr-g++)
LD := $(call findsoftware,avr-ld)
AR := $(call findsoftware,avr-ar)
OBJCOPY := $(call findsoftware,avr-objcopy)
AVRDUDE := $(call findsoftware,avrdude)
AVRSIZE := $(call findsoftware,avr-size)

# files
TARGET := $(if $(TARGET),$(TARGET),a.out)
OBJECTS := $(addsuffix .o, $(basename $(SOURCES)))
DEPFILES := $(patsubst %, .dep/%.dep, $(SOURCES))
ARDUINOCOREDIR := $(ARDUINODIR)/hardware/arduino/cores/arduino
ARDUINOLIB := .lib/arduino.a
ARDUINOLIBLIBSDIR := $(ARDUINODIR)/libraries
ARDUINOLIBLIBSPATH := $(foreach lib, $(LIBRARIES), \
	$(ARDUINODIR)/libraries/$(lib) $(ARDUINODIR)/libraries/$(lib)/utility )
ARDUINOLIBOBJS := $(foreach dir, $(ARDUINOCOREDIR) $(ARDUINOLIBLIBSPATH), \
	$(patsubst %, .lib/%.o, $(wildcard $(addprefix $(dir)/, *.c *.cpp))))
ifeq "$(AVRDUDECONF)" ""
ifeq "$(AVRDUDE)" "$(ARDUINODIR)/hardware/tools/avr/bin/avrdude"
AVRDUDECONF := $(ARDUINODIR)/hardware/tools/avr/etc/avrdude.conf
else
AVRDUDECONF := $(wildcard $(AVRDUDE).conf)
endif
endif

# no board?
ifndef BOARD
ifneq "$(MAKECMDGOALS)" "boards"
ifneq "$(MAKECMDGOALS)" "clean"
$(error BOARD is unset.  Type 'make boards' to see possible values)
endif
endif
endif

# obtain board parameters from the arduino boards.txt file
BOARDS_FILE := $(ARDUINODIR)/hardware/arduino/boards.txt
BOARD_BUILD_MCU := \
	$(shell sed -ne "s/$(BOARD).build.mcu=\(.*\)/\1/p" $(BOARDS_FILE))
BOARD_BUILD_FCPU := \
	$(shell sed -ne "s/$(BOARD).build.f_cpu=\(.*\)/\1/p" $(BOARDS_FILE))
BOARD_BUILD_VARIANT := \
	$(shell sed -ne "s/$(BOARD).build.variant=\(.*\)/\1/p" $(BOARDS_FILE))
BOARD_UPLOAD_SPEED := \
	$(shell sed -ne "s/$(BOARD).upload.speed=\(.*\)/\1/p" $(BOARDS_FILE))
BOARD_UPLOAD_PROTOCOL := \
	$(shell sed -ne "s/$(BOARD).upload.protocol=\(.*\)/\1/p" $(BOARDS_FILE))
BOARD_USB_VID := \
	$(shell sed -ne "s/$(BOARD).build.vid=\(.*\)/\1/p" $(BOARDS_FILE))
BOARD_USB_PID := \
	$(shell sed -ne "s/$(BOARD).build.pid=\(.*\)/\1/p" $(BOARDS_FILE))

# invalid board?
ifeq "$(BOARD_BUILD_MCU)" ""
ifneq "$(MAKECMDGOALS)" "boards"
ifneq "$(MAKECMDGOALS)" "clean"
$(error BOARD is invalid.  Type 'make boards' to see possible values)
endif
endif
endif

# flags
CPPFLAGS += -Os -Wall -fno-exceptions -ffunction-sections -fdata-sections
CPPFLAGS += -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums
CPPFLAGS += -mmcu=$(BOARD_BUILD_MCU)
CPPFLAGS += -DF_CPU=$(BOARD_BUILD_FCPU) -DARDUINO=$(ARDUINOCONST)
CPPFLAGS += -DUSB_VID=$(BOARD_USB_VID) -DUSB_PID=$(BOARD_USB_PID)
CPPFLAGS += -I. -Iutil -Iutility -I $(ARDUINOCOREDIR)
CPPFLAGS += -I $(ARDUINODIR)/hardware/arduino/variants/$(BOARD_BUILD_VARIANT)/
CPPFLAGS += $(addprefix -I $(ARDUINODIR)/libraries/, $(LIBRARIES))
CPPFLAGS += $(patsubst %, -I $(ARDUINODIR)/libraries/%/utility, $(LIBRARIES))
CPPDEPFLAGS = -MMD -MP -MF .dep/$<.dep
CPPINOFLAGS := -x c++ -include $(ARDUINOCOREDIR)/Arduino.h
AVRDUDEFLAGS += $(addprefix -C , $(AVRDUDECONF)) -DV
AVRDUDEFLAGS += -p $(BOARD_BUILD_MCU) -P $(SERIALDEV)
AVRDUDEFLAGS += -c $(BOARD_UPLOAD_PROTOCOL) -b $(BOARD_UPLOAD_SPEED)
LINKFLAGS += -Os -Wl,--gc-sections -mmcu=$(BOARD_BUILD_MCU)

# figure out which arg to use with stty (for OS X, GNU and busybox stty)
STTYFARG := $(shell stty --help 2>&1 | \
	grep -q 'illegal option' && echo -f || echo -F)

# include dependencies
ifneq "$(MAKECMDGOALS)" "clean"
-include $(DEPFILES)
endif

# default rule
.DEFAULT_GOAL := all

#_______________________________________________________________________________
#                                                                          RULES

.PHONY:	all target upload clean boards monitor size

all: target

target: $(TARGET).hex

upload: target
	@echo "\nUploading to board..."
	@test -n "$(SERIALDEV)" || { \
		echo "error: SERIALDEV could not be determined automatically." >&2; \
		exit 1; }
	@test 0 -eq $(SERIALDEVGUESS) || { \
		echo "*GUESSING* at serial device:" $(SERIALDEV); \
		echo; }
	stty $(STTYFARG) $(SERIALDEV) hupcl
	$(AVRDUDE) $(AVRDUDEFLAGS) -U flash:w:$(TARGET).hex:i

clean:
	rm -f $(OBJECTS)
	rm -f $(TARGET).elf $(TARGET).hex $(ARDUINOLIB) *~
	rm -rf .lib .dep

boards:
	@echo Available values for BOARD:
	@sed -nEe '/^#/d; /^[^.]+\.name=/p' $(BOARDS_FILE) | \
		sed -Ee 's/([^.]+)\.name=(.*)/\1            \2/' \
			-e 's/(.{12}) *(.*)/\1 \2/'

monitor:
	@test -n "$(SERIALDEV)" || { \
		echo "error: SERIALDEV could not be determined automatically." >&2; \
		exit 1; }
	@test -n `which screen` || { \
		echo "error: can't find GNU screen, you might need to install it." >&2 \
		ecit 1; }
	@test 0 -eq $(SERIALDEVGUESS) || { \
		echo "*GUESSING* at serial device:" $(SERIALDEV); \
		echo; }
	screen $(SERIALDEV)

size: $(TARGET).elf
	echo && $(AVRSIZE) --format=avr --mcu=$(BOARD_BUILD_MCU) $(TARGET).elf

# building the target

$(TARGET).hex: $(TARGET).elf
	$(OBJCOPY) -O ihex -R .eeprom $< $@

.INTERMEDIATE: $(TARGET).elf

$(TARGET).elf: $(ARDUINOLIB) $(OBJECTS)
	$(CC) $(LINKFLAGS) $(OBJECTS) $(ARDUINOLIB) -lm -o $@

%.o: %.c
	mkdir -p .dep$(dir $<)
	$(COMPILE.c) $(CPPDEPFLAGS) -o $@ $<

%.o: %.cpp
	mkdir -p .dep$(dir $<)
	$(COMPILE.cpp) $(CPPDEPFLAGS) -o $@ $<

%.o: %.cc
	mkdir -p .dep$(dir $<)
	$(COMPILE.cpp) $(CPPDEPFLAGS) -o $@ $<

%.o: %.C
	mkdir -p .dep$(dir $<)
	$(COMPILE.cpp) $(CPPDEPFLAGS) -o $@ $<

%.o: %.ino
	mkdir -p .dep$(dir $<)
	$(COMPILE.cpp) $(CPPDEPFLAGS) -o $@ $(CPPINOFLAGS) $<

%.o: %.pde
	mkdir -p .dep$(dir $<)
	$(COMPILE.cpp) $(CPPDEPFLAGS) -o $@ -x c++ -include $(ARDUINOCOREDIR)/Arduino.h $<

# building the arduino library

$(ARDUINOLIB): $(ARDUINOLIBOBJS)
	$(AR) rcs $@ $?

.lib/%.c.o: %.c
	mkdir -p $(dir $@)
	$(COMPILE.c) -o $@ $<

.lib/%.cpp.o: %.cpp
	mkdir -p $(dir $@)
	$(COMPILE.cpp) -o $@ $<

.lib/%.cc.o: %.cc
	mkdir -p $(dir $@)
	$(COMPILE.cpp) -o $@ $<

.lib/%.C.o: %.C
	mkdir -p $(dir $@)
	$(COMPILE.cpp) -o $@ $<

(I had to remove the author's info from the top because the file was larger than 9500 characters and I couldn't post it).

Honestly, I can't see why it should be a Makefile problem because all the other libraries are used and compile correctly.......

PaulS:

I assume the compiler can find it because there are lots of other libraries I have included in the particular program I'm trying to compile and they are all being found.

Perhaps we could have a peek at your makefile?

Just found something strange...... there are TWO avr-gcc toolsets on my machine. One is from the Arduino install, the other I have no idea where it came from (it's in /usr/bin/avr).

Anyway, I "removed" the non-Arduino toolset by renaming /usr/bin/avr to usr/bin/_avr (note the underscore) and NOW it all works!

What the heck is going on here?