Here is my Simple Makefile:
run.exe: link gcc link.o -o run link.o: main.o fun.o ld -r main.o fun.o -o link.o main.o: main.c gcc -c main.c -o main.o fun.o: functionfile.c gcc -c functionfile.c -o fun.o clean: del *.o del *.exe
The question is not really about creating `run.exe` I know several ways to create this. But while I was writing my **Makefile**, I accidently forget to write `.o` after `link` in dependency of `run.exe`( which I know when I found following error after running `make`):
gcc -c main.c -o main.o
gcc -c functionfile.c -o fun.o
ld -r main.o fun.o -o link.o
cc link.o -o link
process_begin: CreateProcess(NULL, cc link.o -o link, ...) failed.
make (e=2): The system cannot find the file specified.
<builtin>: recipe for target 'link' failed
make: *** [link] Error 2
I guess the file it is saying which it can not find is link
because it doesn't previously exists and none of Makefile commands create it. My question is if link
can not be found how the commands of targets 2,3 and 4 runs successfully and able to create respective .o
files? Why does not it return at the same time when it does not find link
i.e without executing any of the commands? Help me to sort it if my guess is correct or if it is wrong tell me the actual thing which is happening and problem too!!? And what is this recipe for target 'link' failed
as I don't have any target named link
??
1 Answer 1
The problem comes from the very first line in your Makefile
:
run.exe: link
This causes Make to try to figure out how to create link
. It knows how to build link
from link.o
, so it uses the rules provided to create link.o
, and then tries to create link
using its built-in rule, which references cc
. But you don’t have a cc.exe
command, so it fails — that’s the missing file. All this explains the "<builtin>: recipe for target 'link' failed" error message: Make failed in its attempt to create link
using a built-in rule.
To fix this, specify the correct prerequisites:
run.exe: link.o
gcc $^ -o $@
This uses automatic variables to avoid repeating information from the rule: $^
stands for "all the prerequisites" (link.o
), $@
stands for "the file name of the target" (run.exe
).
-
so, actually it could not find cc.exe. Can we create it or? And how it knows to make
link
fromlink.o
? It means file extention doesn't matter or else??John Doe– John Doe2022年11月26日 23:31:13 +00:00Commented Nov 26, 2022 at 23:31 -
File extensions do matter, and that’s what’s wrong with your Makefile. If you fix the extensions as indicated in my answer, you won’t need to create
cc.exe
because Make will stop looking for it. The link in my answer explains why Make "knows" how to buildlink
— but its knowledge isn’t great on Windows because it doesn’t know about.exe
extensions.Stephen Kitt– Stephen Kitt2022年11月27日 21:46:52 +00:00Commented Nov 27, 2022 at 21:46 -
If I named it anything instead of
link
then it does not run even single command? It means same name matters?John Doe– John Doe2022年11月27日 23:36:46 +00:00Commented Nov 27, 2022 at 23:36 -
Yes, the names matter. The name before a
:
is the file that is produced, the names after a:
are the files that are used. You want to buildrun.exe
usinglink.o
, so the rule needs to berun.exe: link.o
, and thegcc
command needs to producerun.exe
, i.e.gcc link.o -o run.exe
(orgcc $^ -o $@
using automatic variables).Stephen Kitt– Stephen Kitt2022年11月28日 05:04:46 +00:00Commented Nov 28, 2022 at 5:04 -
Specifying
link
causes commands to run because there’s alink.o
rule. Make has a built-in rule to build executables with no extension using a.o
file; in this case that’scc link.o -o link
. You’d get the same effect withmain
orfun
, since there are rules formain.o
andfun.o
. Anything else won’t trigger the built-in rule.Stephen Kitt– Stephen Kitt2022年11月28日 05:08:39 +00:00Commented Nov 28, 2022 at 5:08