0

I have some code for handling all uart related functions and operations in a .h/.c pair that I usually include in my project. I have a makefile that compiles all of my .c files into .o files then links them all to one executable. For some reason, one of my projects using this pair compiles fine but the other gives this error:

obj/fiveax.o: In function `fiveax_init':
fiveax.c:(.text+0x10): undefined reference to `uart_init'
collect2: error: ld returned 1 exit status

when trying to link to the exectutable after compiling all the .o files. I have included my makefile below, it is the same for both projects with the only difference being the appname. Makefile

    ########################################################################
####################### Makefile Template ##############################
########################################################################

# Compiler settings - Can be customized.
CC = avr-gcc
CXXFLAGS = -mmcu=atmega2560 -D BUILD=1
LDFLAGS = -Iinclude -Ilibs/FreeRTOS/include -Llibs/FreeRTOS -lfreertos
DEV = /dev/ttyUSB0
AVRCONF = -C/etc/avrdude.conf
AVRLOAD = $(AVRCONF) -v -patmega2560 -carduino -P$(DEV) -b57600 -D -Uflash:w:bin/$(APPNAME).hex:i

# Makefile settings - Can be customized.
APPNAME = FiveAx
EXT = .c
SRCDIR = src
OBJDIR = obj
INCDIR = include
DEPDIR = dep

############## Do not change anything from here downwards! #############
SRC = $(wildcard $(SRCDIR)/*$(EXT))
OBJ = $(SRC:$(SRCDIR)/%$(EXT)=$(OBJDIR)/%.o)
DEP = $(OBJ:$(OBJDIR)/%.o=$(DEPDIR)/%.d)
# UNIX-based OS variables & settings
RM = rm
DELOBJ = $(OBJ)
# Windows OS variables & settings
DEL = del
EXE = .exe
WDELOBJ = $(SRC:$(SRCDIR)/%$(EXT)=$(OBJDIR)\\%.o)

########################################################################
####################### Targets beginning here #########################
########################################################################

all: bin $(APPNAME)

# Builds the app
$(APPNAME): $(OBJ)
    $(CC) $(CXXFLAGS) -o bin/[email protected] $^ $(LDFLAGS)
    avr-objcopy -j .text -j .data -O ihex bin/$(APPNAME).elf bin/$(APPNAME).hex

bin:
    mkdir -p $@

# Creates the dependecy rules
$(DEPDIR)/%.d: $(SRCDIR)/%$(EXT)
    @$(CPP) $(CFLAGS) $< -MM -MT $(@:$(DEPDIR)/%.d=$(OBJDIR)/%.o) >$@ $(LDFLAGS)

# Includes all .h files
-include $(DEP)

# Building rule for .o files and its .c/.cpp in combination with all .h
$(OBJDIR)/%.o: $(SRCDIR)/%$(EXT)
    $(CC) $(CXXFLAGS) -o $@ -c $< $(LDFLAGS)

load: bin $(APPNAME)
    avrdude $(AVRLOAD)

################### Cleaning rules for Unix-based OS ###################
# Cleans complete project
.PHONY: clean
clean:
    $(RM) -r $(DELOBJ) $(DEP) bin

# Cleans only all files with the extension .d
.PHONY: cleandep
cleandep:
    $(RM) $(DEP)

edit: I have included the header file for uart.h in the source file. edit: I was asked for the output of the makefile

avr-gcc -mmcu=atmega2560 -D BUILD=1 -Iinclude -Ilibs/FreeRTOS/include -o obj/uart.o -c src/uart.c -Llibs/FreeRTOS -lfreertos
avr-gcc -mmcu=atmega2560 -D BUILD=1 -Iinclude -Ilibs/FreeRTOS/include -o obj/servo.o -c src/servo.c -Llibs/FreeRTOS -lfreertos
avr-gcc -mmcu=atmega2560 -D BUILD=1 -Iinclude -Ilibs/FreeRTOS/include -o obj/main.o -c src/main.c -Llibs/FreeRTOS -lfreertos
avr-gcc -mmcu=atmega2560 -D BUILD=1 -Iinclude -Ilibs/FreeRTOS/include -o obj/fiveax.o -c src/fiveax.c -Llibs/FreeRTOS -lfreertos
avr-gcc -mmcu=atmega2560 -D BUILD=1 -Iinclude -Ilibs/FreeRTOS/include -o bin/FiveAx.elf obj/uart.o obj/servo.o obj/main.o obj/fiveax.o
obj/fiveax.o: In function `fiveax_init':
fiveax.c:(.text+0x10): undefined reference to `uart_init'
collect2: error: ld returned 1 exit status
make: *** [Makefile:41: FiveAx] Error 1
8
  • Without being familiar with freertos it's hard to know what the problem is. I assume that the uart_init method should be present in the freertos library: is it there? Or is there some other library you need to link to get it? Maybe some kind of uart library? It would help if you provided more context around the error: show the command line that make printed that generated the message, and also is this the ONLY error that was shown? Were there errors before that one? Usually the first error is the most interesting. Commented Mar 27, 2022 at 19:47
  • It is not a freertos function, has nothing to do with free rtos. It is just a header and source file that I wrote for wrapping the UART functions in avr into easy to use functions. This is the only error shown. The problem is that although I can compile my sourcefile that includes my uart header file (which contains the function I am trying to call) when linking the compiled .o file, it fails. Specifically carrying out the command ``` $(CC) $(CXXFLAGS) -o bin/[email protected] $^ $(LDFLAGS)``` in the makefile Commented Mar 27, 2022 at 20:15
  • 1
    It's not the case that uart_init is not a freertos function: see: freertoshal.github.io/doxygen/group__UART.html. I don't know what you mean by "the uart header file contains the function I am trying to call". In C, a function can either be declared or defined. A header file usually declares a function: this means the compiler knows how to call it so code that invokes it will compile. However, at link time you must provide the definition of the function, which is usually contained in a source file not a header file. If you wrote uart_init, where have you defined it? Commented Mar 27, 2022 at 20:48
  • 1
    It would have been helpful if you'd provided that information in your question initially. In that case, as I asked in my first comment, you need to put the command line that make printed (the link line) into your question so we can see it. Is the uart.o present in the link line? If not, that's the problem. If it is, then there must be something about the way you're compiling uart.c that causes this issue. Also your makefile does a lot of pathname manipulation but you haven't explained where everything lives in your directories. Commented Mar 27, 2022 at 23:59
  • 1
    I should also mention, your setting of LDFLAGS is unfortunate. You should not combine compiler options like -I in the same flags variable as linker options like -L. When you compile a .o file you should include the -I options but not the -L options (usually these are placed in CPPFLAGS or just in CXXFLAGS) and when you link object files without compiling, you should provide the -L options but you don't need the -I options. I doubt this is the cause of your problem however. Commented Mar 28, 2022 at 0:01

1 Answer 1

1

It's impossible to read the information requested because it's not formatted as a code block so all the lines run together. Please use the live preview feature of the SO question editor to check that the content you're adding is readable, to save the sanity of the people trying to help you.

The link line appears to be this:

avr-gcc -mmcu=atmega2560 -D BUILD=1 -Iinclude -Ilibs/FreeRTOS/include -o bin/FiveAx.elf obj/uart.o obj/servo.o obj/main.o obj/fiveax.o

Here we can see that the library -lfreertos is not present, and also that all the object files come at the end after the flags. I don't see how this could have happened given the makefile you show above:

CXXFLAGS = -mmcu=atmega2560 -D BUILD=1
LDFLAGS = -Iinclude -Ilibs/FreeRTOS/include -Llibs/FreeRTOS -lfreertos

        $(CC) $(CXXFLAGS) -o bin/[email protected] $^ $(LDFLAGS)

so it seems that the make output here doesn't match the makefile you've shown us. Are you sure you're using that makefile?

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.