Search code examples
cmakefilecygwin

R_X86_64_PC32 against undefined symbol `WinMain' on cygwin


When I compile my code on the command line, there are no problems:

$ gcc -Wall -O2 -o mess main.c getmatrix.c toktoint.c prtmatrix.c getdist.c

But when I compile via make, it fails:

$ make clean
$ make
/usr/bin/gcc -O2 -Wall -c toktoint.c -o toktoint.o
/usr/bin/gcc -O2 -Wall -c getmatrix.c -o getmatrix.o
/usr/bin/gcc -O2 -Wall -c prtmatrix.c -o prtmatrix.o
/usr/bin/gcc -O2 -Wall -c getdist.c -o getdist.o
/usr/bin/gcc -O2 -Wall   -c -o main.o main.c
/usr/bin/gcc -O2 -Wall -o mess toktoint.o
/usr/lib/gcc/x86_64-pc-cygwin/10/../../../../x86_64-pc-cygwin/bin/ld: /usr/lib/gcc/x86_64-pc-cygwin/10/../../../../lib/libcygwin.a(libcmain.o): in function `main':
/usr/src/debug/cygwin-3.1.7-1/winsup/cygwin/lib/libcmain.c:37: undefined reference to `WinMain'
/usr/src/debug/cygwin-3.1.7-1/winsup/cygwin/lib/libcmain.c:37:(.text.startup+0x82): relocation truncated to fit: R_X86_64_PC32 against undefined symbol `WinMain'
collect2: error: ld returned 1 exit status
make: *** [Makefile:44: mess] Error 1

Here is my Makefile:

CC=/usr/bin/gcc
OPTIMIZATION=2
CFLAGS=-O$(OPTIMIZATION) -Wall
LFLAGS=
TARGET=mess
OBJECTS=toktoint.o \
    getmatrix.o \
    prtmatrix.o \
    getdist.o \
    main.o
SOURCES=toktoint.c \
    getmatrix.c \
    prtmatrix.c \
    getdist.c \
    main.c
HEADERS=getmatrix.h \
    toktoint.h \
    prtmatrix.h \
    getdist.h
all: $(TARGET)
mess: $(OBJECTS)
    $(CC) $(CFLAGS) -o $@ $<
%.o: %.c %.h
    $(CC) $(CFLAGS) -c $< -o $@
clean:
    @rm -f $(OBJECTS) $(TARGET)

I tried changing various flags, such as "-m64". And other suggestions which I found on stackoverflow, but no success.

If I compile each module on the command line, it also works:

$ make clean
$ gcc -O2 -Wall -c toktoint.c -o toktoint.o
$ gcc -O2 -Wall -c getmatrix.c -o getmatrix.o
$ gcc -O2 -Wall -c prtmatrix.c -o prtmatrix.o
$ gcc -O2 -Wall -c getdist.c -o getdist.o
$ gcc -O2 -Wall -c main.c -o main.o
$ gcc -Wall -O2 -o mess main.o getdist.o getmatrix.o prtmatrix.o toktoint.o

So it appears the problem is with make or Makefile.


Solution

  • Look at the output from make again, especially the linker line:

    /usr/bin/gcc -O2 -Wall -o mess toktoint.o
    

    It does not build with all the object files. Most notably, it misses main.o which I assume contains your main function.

    The variable $< is only

    The name of the first prerequisite

    (from this make manual, emphasis mine).

    To get all prerequisites (all object files) use $^:

    mess: $(OBJECTS)
        $(CC) $(CFLAGS) -o $@ $^