Mrchacha
Mrchacha

Reputation: 317

Undefined reference to main error

I'm trying to make a Makefile of the bitcount benchmark application. The original Makefile works, but I want to change the Makefile for my needs. I want to create an object file first, and then use it to create .elf and .bin files.

bitcnts: ${FILE} Makefile
    gcc -static ${FILE} -O3 -o bitcnts

But I'm getting an error saying that undefined reference to main':

/opt/riscv/bin/../lib/gcc/riscv64-unknown elf/4.9.2/../../../../riscv64-unknown-
elf/lib/soft-float/32/crt0.o: 
In function `.L0 ': (.text+0x40): undefined reference to `main'
collect2: error: ld returned 1 exit status
Makefile:23: recipe for target 'prog.elf' failed
make[1]: *** [prog.elf] Error 1

The attempted Makefile looks like this:

CROSS=riscv64-unknown-elf-
CC=$(CROSS)gcc    
LD=$(CROSS)g++
OBJCOPY=$(CROSS)objcopy
LIB_O=$(LIB)mutex.o $(LIB)wrap_malloc.o

CFLAGS_SYS=-m32 -msoft-float
LDFLAGS_SYS=-m32 -msoft-float -T$(LDFILE) -Wl,--wrap,malloc -Wl,--wrap,free -Wl,
--wrap,calloc -Wl,--wrap,realloc -Wl,--wrap,_malloc_r -Wl,--wrap,_free_r -Wl,
--wrap,_calloc_r -Wl,--wrap,_realloc_r

CFLAGS=-g $(CFLAGS_SYS) -O2 -std=gnu99 -Wall -I$(LIB) -I./
LDFLAGS=-g $(LDFLAGS_SYS)


FILE = bitcnt_1.c bitcnt_2.c bitcnt_3.c bitcnt_4.c bitcnts.c bitfiles.c 
bitstrng.c bstr_i.c

MAIN = bitcnts

.PHONY : all
all: prog.elf

prog.bin : prog.elf
   @${OBJCOPY} -R .uncached -R .tileram -O binary $< $@

prog.elf : $(MAIN).o $(LIB_O)
   @${LD} $^ -o $@ ${LDFLAGS}

$(MAIN).o : $(FILE)
   @${CC} ${CFLAGS} -c $< -o $@

.PHONY: build
build: all

And then to build:

# Build
.PHONY: bitcount-build
bitcount-build:
  @make -C $(MIBENCH)/automotive/bitcount build
# Run
.PHONY: bitcount-run
bitcount-run:
  @make -C $(MIBENCH)/automotive/bitcount run

Upvotes: 0

Views: 1277

Answers (1)

The Vee
The Vee

Reputation: 11580

This rule

$(MAIN).o : $(FILE)
   @${CC} ${CFLAGS} -c $< -o $@

expands into

bitcnts.o: bitcnt_1.c bitcnt_2.c bitcnt_3.c bitcnt_4.c bitcnts.c bitfiles.c bitstrng.c bstr_i.c
    ...-gcc [all the flags] -c bitcnt_1.c -o bitcnts.o
                               ^^^^^^^^^^ $< is this only

The other files, bitcnt_2.c, bitcnt_3.c, bitcnt_4.c, bitcnts.c, bitfiles.c, bitstrng.c, bstr_i.c, are watched for modifications but never compiler into the object and if your main() was in bitcnts.c, bitcnts.o will not contain it.

Actually, what you want to do can not be done just as easy (sorry for the previous version of my answer that was wrong). One object file comes from one translation unit (basically from one C file). So you'll have to make 8 of them. Luckily Makefiles make that not too hard either using static patterns:

OBJECTS = $(FILE:%.c=%.o)

$(OBJECTS): %.o: %.c
    @${CC} ${CFLAGS} -c $< -o $@

prog.elf : $(OBJECTS) $(LIB_O)
    @${LD} $^ -o $@ ${LDFLAGS}

Upvotes: 1

Related Questions