Pages: [1]   Go Down
Author Topic: command line, undefined reference to function  (Read 2248 times)
0 Members and 1 Guest are viewing this topic.
0
Offline Offline
Newbie
*
Karma: 0
Posts: 5
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hello,

I'm trying to build from the command line so that I can see the error messages when building. (I turned on verbose settings in preferences.txt, but to no avail.)
My code is separated into a couple of files for simplicity. avr_spi.h, avr_spi.c wireless.c wireless.h, CompileNRF.pde.

The avr_spi.* files contain wrapper code to write to SPI registers.
The wireless.* files contain code that use avr_spi files to talk to the wireless board I'm using: NRF24L01.
Inside CompileNRF.pde, I call wireless_init() to set up the board to receive transmission.

When I compile, I get:
...
cat CompileNRF.pde >> applet/CompileNRF.cpp
cat /Users/nate/Robots/arduino-0011//hardware/cores/arduino/main.cxx >> applet/CompileNRF.cpp
/Users/nate/Robots/arduino-0011//hardware/tools/avr/bin/avr-gcc -mmcu=atmega168 -I. -gstabs -DF_CPU=16000000 -I/Users/nate/Robots/arduino-0011//hardware/cores/arduino -Os -Wall -Wstrict-prototypes -std=gnu99  -o applet/CompileNRF.elf applet/CompileNRF.cpp -L. applet/core.a -lm
cc1plus: warning: command line option "-Wstrict-prototypes" is valid for C/ObjC but not for C++
cc1plus: warning: command line option "-std=gnu99" is valid for C/ObjC but not for C++
/var/tmp//ccCDUial.o: In function `setup':
applet/CompileNRF.cpp:23: undefined reference to `wireless_init()'

When I use avr-nm, I can see that there is a function of this name in the Text section of the wireless.o file.


I modified the Makefile SRC to include my avr_spi.c and wireless.c files.

How can  I get my main to see the wireless_init function? (short of dumping all the code into one file)

Thanks,

Nate
Logged

Paris FR
Offline Offline
Full Member
***
Karma: 0
Posts: 155
cute little geek...
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

I think your problem is that you don't explicitely compile or link all the .c or .o files. Including the .h does not imply that the .c will then be linked against the main source file. So I think your C code compiles correctly, but fails at linking.

But it's strange that you have a wireless.o file then.

(I understand you said you've added these files to the makefile, but I don't see them in the compiler call, anyway... Is this the complete output ? If so, the problem is here)

I don't know a single thing about the syntax of makefiles, but if you want, you can send me your project, I'll build it in Eclipse and return you the generated makefile if the build is successful.
« Last Edit: June 05, 2008, 03:13:43 am by tehboii » Logged

... could use some sleep

0
Offline Offline
Newbie
*
Karma: 0
Posts: 5
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi Tehboli,

I just posted the part that gives me an error.  I definitely put the new files into SRC= Makefile variable.  
When I run `make clean; make`,  I get the same error.

[ Modified... I made a mistake in my source, but I still can't find the wireless_init function]

I appreciate your offer to make the project in Eclipse.  I think I will first try to reduce this problem to a smaller one so that we can be sure of what's going on.  So maybe a few files: a.c, a.h, b.c, b.h, project.pde
Then I would really appreciate your eclipse help.

Thanks,

Nate
« Last Edit: June 05, 2008, 10:17:48 am by krazemonkey » Logged

0
Offline Offline
Newbie
*
Karma: 0
Posts: 5
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Here's my mini-project that makes the error. It would be great if you could send me an Eclipse makefile that tells me how to compile this code!

FILE: EXTERNAL_FUNCS.pde :
#include "blink_led.h"

void setup( void ){

  setup_led(); // undefined reference when built

}

void loop ( void ) {

  while(1) {
    blink_led();

  }



###################################
FILE: blink_led.h

#ifndef BLINK_LED_H
#define BLINK_LED_H

#define LED 13

void setup_led( void );
void blink_led( void );

#endif


###################################
FILE: blink_led.c
#include "blink_led.h"
#include "wiring.h"


void setup_led( void ) {
  pinMode( LED, OUTPUT);
}
void led_on( void ) {
  digitalWrite( LED, HIGH);
}

void led_off( void ) {
  digitalWrite( LED, LOW);
}

void blink_led (void ) {
  led_on();
  delay (500 );
  led_off();
  delay (500 );
}

########################################
Logged

0
Offline Offline
Newbie
*
Karma: 0
Posts: 5
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

After reading more, I think I'm supposed to put _my_ source code into the arduino libraries directory, as explained here: http://www.arduino.cc/en/Hacking/LibraryTutorial

I'll try this after work.  (and I'll look at the hardware/libraries/Makefile, too)
Logged

0
Offline Offline
Newbie
*
Karma: 0
Posts: 5
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I tried this approach to no avail....
I ended up adapting the arduino makefile and the MacPack-AVR makefile to my own purposes. I excluded the explicit suffix rules in favor of the automatic rules make provides.  


Here it is:  Makefile for multiple source files in one, non-Arduino directory.

# This file is a result of an inability to compile multiple source files with
# Arduino.
# I'm using the CFLAGS from the ARDUINO Makefile, but specifying the source as
# in the AVR-MacPack Makefile.
# I've taken out the explicit suffix rules.

MCU     = atmega168
CLOCK      = 16000000
PROGRAMMER = -p $(MCU) -c stk500v1 -b 19200 -P /dev/tty.usbserial-A6004p9I -D -V -F -C avrdude.conf
#OBJECTS    = main.o wiring.o SoftwareSerial.o ServoBoard.o
FUSES      = -U hfuse:w:0xd9:m -U lfuse:w:0x24:m
ARDUINO =  /Users/nate/Robots/arduino-0011/hardware/cores/arduino

ARDUINO_C_SRC =  $(ARDUINO)/pins_arduino.c $(ARDUINO)/wiring.c \
$(ARDUINO)/wiring_analog.c $(ARDUINO)/wiring_digital.c \
$(ARDUINO)/wiring_pulse.c $(ARDUINO)/wiring_serial.c \
$(ARDUINO)/wiring_shift.c $(ARDUINO)/WInterrupts.c

ARDUINO_CXX_SRC = $(ARDUINO)/HardwareSerial.cpp $(ARDUINO)/WMath.cpp

ARDUINO_OBJS = $(patsubst %.c,%.o,$(ARDUINO_C_SRC)) \
               $(patsubst %.cpp,%.o,$(ARDUINO_CXX_SRC))

# Pick up all .c, .cpp files in the current directory,
# turn into .o targets for Make
OBJECTS += $(patsubst %.c,%.o,$(SRCS))
OBJECTS += $(patsubst %.cpp,%.o,$(wildcard *.cpp))
OBJECTS += $(patsubst %.c,%.o,$(wildcard *.c))
OBJECTS += $(ARDUINO_OBJS)

all:      main.hex

# file targets:
main.elf: $(OBJECTS)
      $(CC) $(CFLAGS) -o main.elf $(OBJECTS)

main.hex: main.elf
      rm -f main.hex
      $(OBJCOPY) -j .text -j .data -O ihex main.elf main.hex

show_objs:
      @echo OBJS= $(OBJECTS)

flash:      all
      $(AVRDUDE) $(PROGRAMMER) -U flash:w:main.hex:i

clean:
      $(RM) $(OBJECTS) main.elf main.hex

# Compiler flag to set the C Standard level.
# c89   - "ANSI" C
# gnu89 - c89 plus GCC extensions
# c99   - ISO C99 standard (not yet fully implemented)
# gnu99 - c99 plus GCC extensions
CSTANDARD = -std=gnu99
CDEBUG = -g$(DEBUG)
CWARN = -Wall -Wstrict-prototypes
CTUNING = -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums
#CEXTRA = -Wa,-adhlns=$(<:.c=.lst)
CINCS = -I /Users/nate/Robots/arduino-0011/hardware/cores/arduino



CFLAGS =  -mmcu=$(MCU) -DF_CPU=$(CLOCK) -I.   $(CDEBUG) $(CDEFS) $(CINCS) -O$(OPT) $(CWARN) $(CSTANDARD) $(CEXTRA)
CXXFLAGS = $(CDEFS) $(CINCS) -O$(OPT)
#ASFLAGS = -Wa,-adhlns=$(<:.S=.lst),-gstabs
LDFLAGS = -lm


# Programming support using avrdude. Settings and variables.
AVRDUDE_PORT = $(PORT)
AVRDUDE_WRITE_FLASH = -U flash:w:$(TARGET).hex
AVRDUDE_FLAGS = -D -V -F -C $(INSTALL_DIR)/hardware/tools/avr/etc/avrdude.conf \
-p $(MCU) -P $(AVRDUDE_PORT) -c $(AVRDUDE_PROGRAMMER) \
-b $(UPLOAD_RATE)

# Program settings
AVR_TOOLS_PATH = /usr/local/AVRMacPack/bin/

CC = $(AVR_TOOLS_PATH)/avr-gcc
CXX = $(AVR_TOOLS_PATH)/avr-g++
OBJCOPY = $(AVR_TOOLS_PATH)/avr-objcopy
OBJDUMP = $(AVR_TOOLS_PATH)/avr-objdump
AR  = $(AVR_TOOLS_PATH)/avr-ar
SIZE = $(AVR_TOOLS_PATH)/avr-size
NM = $(AVR_TOOLS_PATH)/avr-nm
AVRDUDE = $(AVR_TOOLS_PATH)/avrdude
REMOVE = rm -f
MV = mv -f




Logged

Forum Administrator
Cambridge, MA
Offline Offline
Faraday Member
*****
Karma: 12
Posts: 3538
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

The Arduino makefile compiles your .pde file as .cpp, so if you want to link against straight C files / functions, you need to wrap them in an:

extern "C" {}

block.
Logged

Pages: [1]   Go Up
Jump to: