R_X86_64_PC32 against undefined symbol `WinMain' on cygwin - c

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.

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 $# $^

Related

arm-none-gcc-ld error : cannot find the object file even though it exists with the proper path

So this is a snippet from my makefile to build my target:
#include header files directory
vpath %.h = include
vpath %.o = obj
#create a list of *.c from the source directory
SRC = $(wildcard src/*.c)
OBJ = $(SRC:src/%.c=%.o)
main.elf: $(OBJ)
$(CC) $(LDFLAGX) $(addprefix obj/,$(OBJ)) -o $#
%.o : %.c
$(CC) $(CPPFLAGS) $(CFLAGS) -c $^ -o obj/$#
my project directory is as follows:
srcdir
+---include
+---obj
\---src
Here's the output I'm getting:
arm-none-eabi-gcc -Iinclude -mcpu=cortex-m3 -mthumb -std=gnu11 -O0 -g -Wall -c src/RCC.c -o obj/RCC.o
arm-none-eabi-gcc -Iinclude -mcpu=cortex-m3 -mthumb -std=gnu11 -O0 -g -Wall -c src/SPI.c -o obj/SPI.o
arm-none-eabi-gcc -Iinclude -mcpu=cortex-m3 -mthumb -std=gnu11 -O0 -g -Wall -c src/main.c -o obj/main.o
arm-none-eabi-gcc -Iinclude -mcpu=cortex-m3 -mthumb -std=gnu11 -O0 -g -Wall -c src/startup.c -o obj/startup.o
arm-none-eabi-gcc -Iinclude -mcpu=cortex-m3 -mthumb -std=gnu11 -O0 -g -Wall -c src/timer.c -o obj/timer.o
arm-none-eabi-gcc -Iinclude -mcpu=cortex-m3 -mthumb -std=gnu11 -O0 -g -Wall -c src/usart.c -o obj/usart.o
arm-none-eabi-gcc -Xlinker -T -Xlinker lscript.ld -Xlinker -nostdlib -Xlinker -Map=main.map obj/RCC.o obj/SPI.o obj/main.o obj/startup.o obj/timer.o obj/usart.o -o main.elf
c:/program files (x86)/gnu arm embedded toolchain/9 2020-q2-update/bin/../lib/gcc/arm-none-eabi/9.3.1/../../../../arm-none-eabi/bin/ld.exe: cannot find startup.o
collect2.exe: error: ld returned 1 exit status
make.exe": *** [main.elf] Error 1
So the startup.o exists in obj/ folder and the path has also been specified in the recipe so What is going wrong here?
I have been struggling to create my own makefile due to tons of such errors and even after trying out numerous tutorials and examples which may solve a problem, another new one pops up every now and then, is there any more convenient way to build such projects that does not cause me so much trouble?

Cflags in Makefile not appearing

I have a makefile, but it seems like the cflags are only working for certain files in my program, and I am not sure why.
Here is what happens when I use make:
$ make
gcc -Wall -ansi -pedantic -g -c main.c
gcc -c fw.c
gcc -c trie.c
gcc -Wall -ansi -pedantic -g -c linked.c
gcc -Wall -ansi -pedantic -g -o fw main.o fw.o trie.o linked.o
You can see that when trying to make fw.c and trie.c it doesn't include the flags, but it does include the flags for the other files.
Here is my makefile:
CC = gcc
CFLAGS = -Wall -ansi -pedantic -g
MAIN = main
OBJS = main.o fw.o trie.o linked.o
all : $(MAIN)
$(MAIN) : $(OBJS) fw.h trie.h linked.h
$(CC) $(CFLAGS) -o fw $(OBJS)
main.o : main.c fw.h trie.h linked.h
$(CC) $(CFLAGS) -c main.c
fw.o : fw.c fw.h trie.h
$(CC) $(CGLAGS) -c fw.c
trie.o : trie.c fw.h trie.h linked.h
$(CC) $(CGLAGS) -c trie.c
linked.o : linked.c trie.h linked.h
$(CC) $(CFLAGS) -c linked.c
rm :
rm *.o $(MAIN) core
I also have an additional problem in that whenever I use make with unchanged files from the last make, it still executes this line:
$ make
gcc -Wall -ansi -pedantic -g -o fw main.o fw.o trie.o linked.o
Whereas usually, it gives me the message "nothing to be done for all". I have tried to compare this makefile to my other working makefiles, but I can't find the error(s). Where have I gone wrong?
You have typos in your Makefile:
fw.o : fw.c fw.h trie.h
$(CC) $(CGLAGS) -c fw.c
trie.o : trie.c fw.h trie.h linked.h
$(CC) $(CGLAGS) -c trie.c
Note the G. Instead, use this:
fw.o : fw.c fw.h trie.h
$(CC) $(CFLAGS) -c fw.c
trie.o : trie.c fw.h trie.h linked.h
$(CC) $(CFLAGS) -c trie.c

Makefile fails with warning message

This is a makefile that fails to link the .o files to make an executeable.
enter code here
CC = c99
CFLAGS = -g -Wall -Wextra -O0
OBJECTS = main.o getoptions.o
P = testprog
$(P): $(OBJECTS)
$(CC) $(OBJECTS) -o $(P)
main.o : main.c
$(CC) $(CFLAGS) $(OBJECTS) -c main.c
getoptions.o : getoptions.c getoptions.h
$(CC) $(CFLAGS) -c getoptions.o
I get this warning:
gcc: warning: getoptions.o: linker input file unused because linking not done
When I manually use:
c99 *.o -o testprog
linking succeeds.
Two issues here:
First, in your target for getoptions.o, you're passing getoptions.o for the -c option. You should be giving it the value of the source file getoptions.c
Second, get rid of $(OBJECTS) in the target for main.o. You don't need to pass in the object files for this step.
With those fixes you'll get a successful compilation:
c99 -g -Wall -Wextra -O0 -c main.c
c99 -g -Wall -Wextra -O0 -c getoptions.c
c99 main.o getoptions.o -o testprog
Edit:
The target line for main.o should be:
main.o : main.c getoptions.h
That way, if getoptions.h changes, main.o gets rebuilt.

Make: Totally ignoring a rule

I am trying to compile my project after adding a new source(processHandling.c) and I am getting this as a result when I 'make'
gcc -gstabs -W -Wall -std=gnu99 -c main.c
gcc -gstabs -W -Wall -std=gnu99 -c inputHandling.c
gcc -gstabs -W -Wall -std=gnu99 -c syscallsWrapper.c
gcc -gstabs -W -Wall -std=gnu99 -o myShell main.o inputHandling.o processHandling.o syscallsWrapper.o
gcc: error: processHandling.o: No such file or directory
make: *** [myShell] Error 1
This is the makefile
CC = gcc
CFLAGS = -gstabs -W -Wall -std=gnu99
myShell: main.o inputHandling.o syscallsWrapper.o
$(CC) $(CFLAGS) -o myShell main.o inputHandling.o processHandling.o syscallsWrapper.o
main.o: main.c
$(CC) $(CFLAGS) -c main.c
inputHandling.o: inputHandling.c
$(CC) $(CFLAGS) -c inputHandling.c
processHandling.o: processHandling.c
$(CC) $(CFLAGS) -c processHandling.c
syscallsWrapper.o: syscallsWrapper.c
$(CC) $(CFLAGS) -c syscallsWrapper.c
clean:
-rm myShell *.o
I tried running make with the -d flag and it seems make for some reason is totally ignoring the rule to compile processHandling.o; what could the problem be?
Also note that if I compile processHandling manually using gcc -c everything works fine.
Add processHandling.o to the dependency list for the myShell target:
myShell: main.o inputHandling.o processHandling.o syscallsWrapper.o
$(CC) $(CFLAGS) -o myShell main.o inputHandling.o processHandling.o syscallsWrapper.o
By the way, using automatic variables can help reduce the repeated file names. For example:
myShell: main.o inputHandling.o processHandling.o syscallsWrapper.o
$(CC) $(CFLAGS) -o $# $^
You need to add "processHandling.o" as a prerequisit of myShell. Otherwise when making myShell, the rule for processHandling.o will not be applied because the makefile thinks that that processHandling.o is not needed for myShell. You can simply add it like this
myShell: main.o inputHandling.o syscallsWrapper.o processHandling.o
$(CC) $(CFLAGS) -o myShell main.o inputHandling.o processHandling.o syscallsWrapper.o
Check if you really have the file processHandling.c. This error implies that the source file has not been found.

math.h linkage with file

I have a small problem, and I have tried everything to test this function, could you please help me? I need to write a C file that is called "mutual_info.c", and it needs a mathematical function. I have included the library and linked it in the makefile, but it still gives me "undefined reference to log"... my includes look like this: (I'm using Eclipse on Ubuntu)
#include <stdio.h>
#include <stdlib.h>
#include "sample.h"
#include "graph_or.h"
#include <math.h>
and my makefile looks like this:
all:
gcc -g amostra.c sample.h -o amostra.o
gcc -g graph_or.c graph_or.h -o graph_or.o
gcc -g graph_w.c graph_W.h -o graph_W.o
gcc -g mutual_info.c -o mutual_info.o -lm
clean:
rm *.o
I have absolutely no idea what is going on, I have even tried to define the LDFLAGS before the command "all" and putting it like this:
LDFLAGS= -lm
all:
gcc -g amostra.c sample.h -o amostra.o
gcc -g graph_or.c graph_or.h -o graph_or.o
gcc -g graph_w.c graph_W.h -o graph_W.o
gcc -g mutual_info.c -o mutual_info.o -lm
clean:
rm *.o
But it still won't work!! Please anyone, I need help with this! Thanks!
Let's take this in steps.
The usual way to write a makefile is to have a rule for each target, and to use prerequisites:
thing: amostra.o graph_or.o graph_w.o mutual_info.o
gcc -g amostra.o graph_or.o graph_w.o mutual_info.o -o thing -lm
mutual_info.o: mutual_info.c
gcc -g -c mutual_info.c -o mutual_info.o -lm
amostra.o: amostra.c sample.h
gcc -g -c amostra.c -o amostra.o
graph_or.o: graph_or.c graph_or.h
gcc -g -c graph_or.c -o graph_or.o
graph_w.o: graph_w.c graph_w.h
gcc -g -c graph_w.c -o graph_w.o
mutual_info.o: mutual_info.c
gcc -g -c mutual_info.c -o mutual_info.o -lm
(I have guessed that you want the executable to be called thing, and that you meant graph_w, not graph_W.)
That should work, but we can make it tidier. First we introduce automatic variables:
thing: amostra.o graph_or.o graph_w.o mutual_info.o
gcc -g $^ -o $# -lm
mutual_info.o: mutual_info.c
gcc -g -c $< -o $#
amostra.o: amostra.c sample.h
gcc -g -c $< -o $#
graph_or.o: graph_or.c graph_or.h
gcc -g -c $< -o $#
graph_w.o: graph_w.c graph_w.h
gcc -g -c $< -o $#
mutual_info.o: mutual_info.c
gcc -g -c $< -o $#
Then we see that these recipes use the same command, so we create a pattern rule:
thing: amostra.o graph_or.o graph_w.o mutual_info.o
gcc -g $^ -o $# -lm
amostra.o: sample.h
graph_or.o: graph_or.h
graph_w.o: graph_w.h
%.o: %.c
gcc -g -c $< -o $#
Give this a try and tell us if it works.
Is that a snippet from your Makefile? Hav you tried exporting LDFLAGs? I have seen this error before, but it was always fixed with the -lm flag.
gcc -lm -o blah blah.c
you need to:
gcc -c -o amostra.o amostra.c
gcc -c -o graph_or.o graph_or.c
gcc -c -o graph_w.o graph_w.c
gcc -c -o mutual_info.o mutual_info.c
gcc -o YourExecutableName amostra.o graph_or.o graph_w.o mutual_info.o -lm
Here's a generic makefile using my best guess of what you want to achieve: It compiles all *.c files in the current directory and creates a binary mutual_info.
RM := rm -f
CC := gcc
CFLAGS := -g
LDLIBS := -lm
SOURCES := $(wildcard *.c)
OBJECTS := $(SOURCES:%.c=%.o)
DEPS := $(SOURCES:%.c=%.d)
BINARY := mutual_info
FILES_TO_CLEAN := $(OBJECTS) $(DEPS)
.PHONY : all clean realclean
all : $(BINARY)
clean :
$(RM) $(FILES_TO_CLEAN)
realclean : FILES_TO_CLEAN += $(BINARY)
realclean : clean
-include $(DEPS)
$(OBJECTS) : %.o : %.c
$(CC) $(CFLAGS) -c -MMD -o $# $<
$(BINARY) : $(OBJECTS)
$(CC) -o $# $^ $(LDLIBS)
Please clarify if that's not what you want.

Resources