lu6cifer
lu6cifer

Reputation: 301

Using the make command without makefiles?

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

Answers (3)

Aaron Hall
Aaron Hall

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

Jorge Núñez
Jorge Núñez

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

Oliver Charlesworth
Oliver Charlesworth

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

Related Questions