Search code examples
cmakefilegtk

C/GTK - Makefile error: undefined reference to main when invoking make


I am trying to write a Makefile with a C file that utilizes GTK3.0 but I am running into the following:

/usr/bin/ld: /usr/lib/gcc/x86_64-pc-linux-gnu/11.2.0/../../../../lib/Scrt1.o: in function `_start':
(.text+0x1b): undefined reference to `main'
collect2: error: ld returned 1 exit status
make: *** [makefile:13: sudoku] Error 1

Here is the Makefile:

CC := gcc
PKGCONFIG = $(shell which pkg-config)
CFLAGS = $(shell $(PKGCONFIG) --cflags gtk+-3.0)
LIBS = $(shell $(PKGCONFIG) --libs gtk+-3.0)

SRC = src/sudoku.c
OBJS = bin/sudoku.o

$(OBJS): $(SRC)
    $(CC) -c $(CFLAGS) -o $(OBJS) $(SRC)

sudoku: $(OBJS)
    $(CC) -o $(OBJS) $(LIBS)

.PHONY: clean

clean:
    rm -f $(OBJS)
    rm -f sudoku

Not entirely sure what is the problem here. According to some solutions online, the source code may not have a main function but a main function is clearly defined in my src/sudoku.c file.

Another issue is that the sudoku.o file is placed incorrectly into the same directory that the makefile is in (I want it to be placed into the bin directory).


Solution

  • This rule:

    sudoku: $(OBJS)
        $(CC) -o $(OBJS) $(LIBS)
    

    is wrong, because you have omitted the argument to the -o compiler option. As a result, the first (and in this case, only) file among those designated by $(OBJS) is taken as the name of the output file instead of one to include in the link. You presumably wanted this, instead:

    sudoku: $(OBJS)
        $(CC) -o $@ $(OBJS) $(LIBS)
    

    ($@ expands to the name of the target being built).

    Additionally, although this rule will work well enough when there is only one source file:

    $(OBJS): $(SRC)
        $(CC) -c $(CFLAGS) -o $(OBJS) $(SRC)
    

    , it will break if there are two or more. I would actually remove it altogether, as it does not do anything that make's built-in rule for constructing object files from C source files doesn't also do.