embedXcode: Link Error using an Arduino library (Servo.h) within a header file For various reasons, I am moving from the Arduino IDE to Xcode using the embedXcode plugin. The code in question compiles and uploads fine from the Arduino IDE, so I think the issue is related to library definitions in embedXcode. The board I am using is an Arduino Mega 2560 (actually it is a Freetronics EtherMega).

The error thrown is:

Command /Applications/Xcode.app/Contents/Developer/usr/bin/make failed with exit code 2


More specifically:

    5.3-LINK                    Builds/embeddedcomputing.elf

/Applications/Arduino.app/Contents/Java/hardware/tools/avr/bin/avr-g++ -o Builds/embeddedcomputing.elf Builds/main.cpp.o Builds/embeddedcomputing.a -Os -w -mmcu=atmega2560 -Wl,--gc-sections  -LBuilds -lm
Builds/main.cpp.o: In function `Robot::Robot()':
main.cpp:(.text._ZN5RobotC2Ev[Robot::Robot()]+0x5e): undefined reference to `Servo::Servo()'
Builds/main.cpp.o: In function `Robot::begin()':
main.cpp:(.text._ZN5Robot5beginEv[Robot::begin()]+0x5a): undefined reference to `Servo::attach(int)'
main.cpp:(.text._ZN5Robot5beginEv[Robot::begin()]+0x64): undefined reference to `Servo::write(int)'
main.cpp:(.text._ZN5Robot5beginEv[Robot::begin()]+0xea): undefined reference to `Servo::write(int)'
main.cpp:(.text._ZN5Robot5beginEv[Robot::begin()]+0x112): undefined reference to `Servo::write(int)'
main.cpp:(.text._ZN5Robot5beginEv[Robot::begin()]+0x132): undefined reference to `Servo::write(int)'
Builds/embeddedcomputing.a(HB25MotorControl.cpp.o): In function `HB25MotorControl::HB25MotorControl(unsigned char)':
HB25MotorControl.cpp:(.text._ZN16HB25MotorControlC2Eh+0x14): undefined reference to `Servo::Servo()'
Builds/embeddedcomputing.a(HB25MotorControl.cpp.o): In function `HB25MotorControl::begin()':
HB25MotorControl.cpp:(.text._ZN16HB25MotorControl5beginEv+0x42): undefined reference to `Servo::attach(int, int, int)'
HB25MotorControl.cpp:(.text._ZN16HB25MotorControl5beginEv+0x58): undefined reference to `Servo::writeMicroseconds(int)'
Builds/embeddedcomputing.a(HB25MotorControl.cpp.o): In function `HB25MotorControl::stop()':
HB25MotorControl.cpp:(.text._ZN16HB25MotorControl4stopEv+0x12): undefined reference to `Servo::writeMicroseconds(int)'
Builds/embeddedcomputing.a(HB25MotorControl.cpp.o): In function `HB25MotorControl::moveAtSpeed(int)':
HB25MotorControl.cpp:(.text._ZN16HB25MotorControl11moveAtSpeedEi+0x44): undefined reference to `Servo::writeMicroseconds(int)'
collect2: error: ld returned 1 exit status
make: *** [Builds/embeddedcomputing.elf] Error 1
Command /Applications/Xcode.app/Contents/Developer/usr/bin/make failed with exit code 2


Robot.h contains a robot class which defines a Servo (for a turret) and two HB-25 MotorControl objects (which control the drive motors). The HB25MotorControl is a custom library that I have written for the Parallax HB-25 Motor Controller. It also uses the Servo library.

To answer the obvious questions:


Yes I have #include &lt;Servo.h&gt; in my HB25MotorControl library. You
can see the library code by following the link above. It is also
included in the main sketch.  
I have compiled, linked and uploaded other sketches which use Arduino and custom libraries in Xcode using the embedXcode plugin.
My embedXcode Makefile definitions include
    the Servo library and the HB25MotorControl library. See extract
    below.


APP_LIBS_LIST = Wire Servo SoftwareSerial

USER_LIBS_LIST = NewPing Time DS3232RTC HB25MotorControl

Any suggestions on how to fix this error and get my code to build in Xcode would be greatly appreciated.
I ended up contacting the developer of the embedXcode plugin. He was very helpful and provided the fix within a day. The cause of the issue is apparently the Arduino IDE has changed its library structure in the latest release.

The next version of embedXcode (release 4.1.4.) will include a fix for this, however if you can't wait until then you need to open ArduinoAVR_165.mk (located in the Makefiles group in Xcode) in your project and add the following line:

avr165_20 += $(foreach dir,$(APP_LIB_PATH),$(patsubst %,$(dir)/%/src/$(BUILD_CORE),$(APP_LIBS_LIST)))


After you add this line, the file should look like this:

# Two locations for Arduino libraries
#
APP_LIB_PATH = $(APPLICATION_PATH)/libraries
APP_LIB_PATH += $(APPLICATION_PATH)/hardware/arduino/$(BUILD_CORE)/libraries

avr165_20 = $(foreach dir,$(APP_LIB_PATH),$(patsubst %,$(dir)/%,$(APP_LIBS_LIST)))
avr165_20 += $(foreach dir,$(APP_LIB_PATH),$(patsubst %,$(dir)/%/utility,$(APP_LIBS_LIST)))
avr165_20 += $(foreach dir,$(APP_LIB_PATH),$(patsubst %,$(dir)/%/src,$(APP_LIBS_LIST)))
avr165_20 += $(foreach dir,$(APP_LIB_PATH),$(patsubst %,$(dir)/%/src/utility,$(APP_LIBS_LIST)))
avr165_20 += $(foreach dir,$(APP_LIB_PATH),$(patsubst %,$(dir)/%/src/$(BUILD_CORE),$(APP_LIBS_LIST)))
avr165_20 += $(foreach dir,$(APP_LIB_PATH),$(patsubst %,$(dir)/%/src/arch/$(BUILD_CORE),$(APP_LIBS_LIST)))


Note that each project has its own ArduinoAVR_165.mk file, so you will have to make this change in each project until you update to the new release.