I'm trying to learn how to use Make! So I have this simple Makefile,
all: main other
main: main.c other.o
gcc main.c -o main
echo "Compiled main.exe"
other: other.o
other.c:
touch $@
echo "int main(){return 0;}" > $@
echo "Created other.c"
other.o: other.c
gcc other.c -o other.o
echo "Compiled other.o"
clean:
rm -f main.exe other.o other.c
where everything executes as expected except at the end where a cc compile command is executed. Here is the output (I added the arrow),
> make all
touch other.c
echo "int main(){return 0;}" > other.c
echo "Created other.c"
Created other.c
gcc other.c -o other.o
echo "Compiled other.o"
Compiled other.o
gcc main.c -o main
echo "Compiled main.exe"
Compiled main.exe
cc other.o -o other <---
/usr/lib/gcc/x86_64-pc-msys/13.2.0/../../../../x86_64-pc-msys/bin/ld: other.o: in functio
n `mainCRTStartup':
/c/S/B/src/msys2-runtime/winsup/cygwin/crt0.c:20: multiple definition of `mainCRTStartup'
; /usr/lib/gcc/x86_64-pc-msys/13.2.0/../../../crt0.o:/c/S/B/src/msys2-runtime/winsup/cygw
in/crt0.c:20: first defined here
/usr/lib/gcc/x86_64-pc-msys/13.2.0/../../../../x86_64-pc-msys/bin/ld: other.o: in functio
n `mainCRTStartup':
/c/S/B/src/msys2-runtime/winsup/cygwin/crt0.c:20: multiple definition of `WinMainCRTStart
up'; /usr/lib/gcc/x86_64-pc-msys/13.2.0/../../../crt0.o:/c/S/B/src/msys2-runtime/winsup/c
ygwin/crt0.c:20: first defined here
/usr/lib/gcc/x86_64-pc-msys/13.2.0/../../../../x86_64-pc-msys/bin/ld: other.o:cygming-crt
beg:(.text+0x50): multiple definition of `__gcc_register_frame'; /usr/lib/gcc/x86_64-pc-m
sys/13.2.0/crtbegin.o:cygming-crtbeg:(.text+0x0): first defined here
/usr/lib/gcc/x86_64-pc-msys/13.2.0/../../../../x86_64-pc-msys/bin/ld: other.o:cygming-crt
beg:(.text+0x70): multiple definition of `__gcc_deregister_frame'; /usr/lib/gcc/x86_64-pc
-msys/13.2.0/crtbegin.o:cygming-crtbeg:(.text+0x20): first defined here
/usr/lib/gcc/x86_64-pc-msys/13.2.0/../../../../x86_64-pc-msys/bin/ld: other.o:cygming-crt
beg:(.data+0x0): multiple definition of `__dso_handle'; /usr/lib/gcc/x86_64-pc-msys/13.2.
0/crtbegin.o:cygming-crtbeg:(.data+0x0): first defined here
collect2: error: ld returned 1 exit status
make: *** [<builtin>: other] Error 1
Where the "<---" points to is the line in question. Why is this getting executed?
The problem is that the default program to build and link programs is cc
. And with the rule other: other.o
you tell make
to build the executable other
from the object file other.o
which it will then do using the default linker.
And the errors are because gcc other.c -o other.o
builds an executable program file named other.o
. To build an object file you need to use the -c
option.
The simple solution to all your problems, really, is to set the CC
and LD
variables, and rely on implicit rules to build your code.
Such a Makefile
could look something like this:
# Explicitly use gcc as the compiler and linker
CC = gcc
LD = gcc
# The "default" target, because the first target in the makefile
# is what make will use when no target is specified
default: main other
# Build the main executable program from the main.c source
main: main.c
# Build the other executable program from the other.c source
other: other.c
# Create the other.c source file
other.c:
echo "int main(){return 0;}" > $@
# The clean target isn't for creating a "clean" file, it's phony, fake
.PHONY: clean
clean:
-rm -f main other other.c
[Please note that you need to convert the indentation to tabs]