Reputation: 301
I was compiling some C code for an assignment and I ran "make codeFile", where "codeFile" was the name of my C program, and even though I didn't have a makefile, an executable was created, and it ran and worked correctly.
Does anyone know why this worked? Why does make compile something even if I don't have a makefile? The only reference I could find was this: http://daly.axiom-developer.org/TimothyDaly_files/class5/node5.html
Upvotes: 15
Views: 12413
Reputation: 394775
Using the make command without makefiles?
make
has implicit rules that work as defaults unless you override them.
According to the make man page:
make -p -f/dev/null
will list all of the implicit rules (and relevant environment variables) without attempting to actually remake files.
To demonstrate the usage, I ran make
in Cygwin, which gave me an exe
file. Note no .c
on the name passed to make:
$ ls
hello.c
$ make hello
cc hello.c -o hello
$ ls
hello.c hello.exe
I also ran this in Ubuntu Linux, and my result was nearly the same as above, but the .exe
extension was not there, instead I had the plain hello
executable:
$ ls
hello.c hello
Step by step derivation
I believe the relevant pieces of the make implicit rules are as follows:
CC = cc
cc
is aliased to CC
LINK.c = $(CC) $(CFLAGS) $(CPPFLAGS) $(LDFLAGS) $(TARGET_ARCH)
a LINK
format is created, where the flags will be empty, and the TARGET_ARCH
variable is also empty (to allow users to set values for various target architectures.) Then we have:
%: %.c
# recipe to execute (built-in):
$(LINK.c) $^ $(LOADLIBES) $(LDLIBS) -o $@
The ^
variable is the prerequisite, hello.c
. The other variables are empty. These are followed by the -o
flag and the target name. The empty variables explain the extra spaces in the command make ran:
cc hello.c -o hello
And the %: %.c
matched the target given to make with the filename of the same target name ending in .c
, which caused the recipe to execute.
Upvotes: 7
Reputation: 1772
Make has an internal database with implicit rules. You can use make -p
to list them. Also make -d
will tell you which rules are being applied, so that would help you discover which implicit rules are being used in this case.
Upvotes: 16
Reputation: 272447
Make has several pre-defined implicit rules. In particular, in your case, it uses two such rules when trying to determine what to do for the target codeFile
:
%: %.o # Link object file
$(CC) $(LDFLAGS) n.o $(LOADLIBES) $(LDLIBS)
%.o: %.c # Compile C source code
$(CC) $(CPPFLAGS) $(CFLAGS) -c
Upvotes: 12