Mail Archives: djgpp/1997/08/09/10:38:49

From: "John M. Aldrich" <fighteer AT cs DOT com>
Newsgroups: comp.os.msdos.djgpp
Subject: Re: Using makefile
Date: Fri, 08 Aug 1997 11:52:00 +0000
Organization: Two pounds of chaos and a pinch of salt
Lines: 231
Message-ID: <>
References: <01bca409$36c25e60$2809a8c0 AT jarrod>
Reply-To: fighteer AT cs DOT com
Mime-Version: 1.0
To: djgpp AT delorie DOT com
DJ-Gateway: from newsgroup comp.os.msdos.djgpp

This is a multi-part message in MIME format.

Content-Type: text/plain; charset=us-ascii
Content-Transfer-Encoding: 7bit

Jarrod Koh wrote:
> Can someone tell me how to use the makefile under MSDOS?
> i.e. the exact command and switches(if any)

With a properly written makefile, using it is as simple as changing to
the appropriate directory and typing "make".  This requires, of course,
that you have make.exe installed (it's in v2gnu/ and in your
PATH (before any copies of make.exe installed by other compilers, like

Actually writing a makefile is a simple task once you learn how. 
Basically, you list the target files (the ones you are trying to make),
the files that the targets depend on, and the commands necessary to turn
the latter into the former.  Make does the rest.  You can also define
and use variables, create "phony" targets, include or exclude portions
of the makefile, and run various functions to manipulate variables and
data.  The information is all in the documentation for make, which I
suggest you read.

I have written a generously commented sample makefile to help users come
to terms with the power of GNU Make.  I am attaching it to this message;
it's not large.


| John M. Aldrich, aka Fighteer I |     mailto:fighteer AT cs DOT com      |
| Proud owner of what might one   |    |
| day be a spectacular MUD...     | Plan: To make Bill Gates suffer |

Content-Type: text/plain; charset=us-ascii; name="Makefile.tst"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline; filename="Makefile.tst"

# Sample Makefile to illustrate basic use of GNU Make

# This is a comment.

# Start by defining necessary variables.  Variables can be used for
# anything, and can be overridden on the command line.
# A variable definition begins at the left margin, and is of the syntax:
#  VARIABLE = value
# Capitalization is unimportant, but Make is case sensitive, so it is
# customary to make most variables in all caps.

# It is customary to start with the names of all the programs your
# makefile will require.  You should always try to stick to the standard
# naming conventions so that other people can understand your makefiles.

CC = gcc
AR = ar
RM = rm -f

# Now define the various flags that will be passed to the compiler
# at different stages.  Empty definitions are fine; and are often useful
# as a reminder for things that can be added later if needed.

LIBS = -lmylib

CFLAGS = -Wall -O2 -g $(DEBUG) $(PROF)
SFLAGS = -Wall -g $(DEBUG) $(PROF)

# Use backslashes to "escape" the end of line character, allowing you
# to spread a long line over multiple lines.
OFILES = main.o \
         files.o \
         parser.o \
         display.o \
         input.o \

LIBFILES = graph1.o \
           graph2.o \
           initgr.o \

DIST = myprog.exe \
       myprog.doc \
       readme.txt \

# To tell Make what files to compile and how to compile them, you now define
# a series of "rules".  Each rule specifies one or more files that Make will
# try to create using the set of commands specified.  Each rule may also
# specify one or more "dependencies".  A dependency is something that the
# target file(s) needs in order to be compiled.  To build a target, Make
# first checks to see if all of its dependencies are up to date.  If not, it
# will attempt to resolve these dependencies before compiling the current
# target.  If all the dependencies of a given target are up to date and no
# dependency is newer than the target, that rule will not be run.
# The first target in a makefile serves as the default target if no target
# is specified on the command line.  A target does not have to be the name
# of a file; if it is not then it will always be run.  Under GNU, "all" is
# the traditional default target name.
# Rule syntax:
#  	  [COMMAND(s)]
# Commands _must_ be prefixed with a tab character.  Some editors replace
# tabs with 8 spaces, but this will cause make to generate a "Missing
# separator" error.  There are various tricks for various editors to make
# them not do this.

# Target "all" depends on myprog.exe and has no commands.
all : myprog.exe

# The '$@' in this rule is an automatic variable which is resolved to
# the target of the current rule.  So, $@ will become 'myprog.exe' when
# the rule is run.
myprog.exe : libmylib.a $(OFILES)
	$(CC) $(LFLAGS) -o $@ $(OFILES) $(LIBS)

# Sometimes you will want just an image without producing an executable.
# In this case, just type "make myprog" and this rule will be run.
myprog : libmylib.a $(OFILES)
	$(CC) $(LFLAGS) -o $@ $(OFILES) $(LIBS)

# Now, the rule to make libmylib.a
# The '$^' automatic variable evaluates to _all_ the dependencies of the
# given target.
libmylib.a : $(LIBFILES)
	$(AR) rvs $@ $^

# Now we will define pattern rules to make all of a given kind of file.
# Pattern rules say, "For all target files matching this pattern, and
# for which a dependency exists with the indicated pattern, use this
# rule to create them."

# The below rule tells Make how to turn .c files into .o files.
# '$<' is an automatic variable which evaluates to the FIRST dependency
# of the current target.
%.o : %.c
	$(CC) -c $(CFLAGS) $<

# This rule performs a similar task for .S files.
%.o : %.S
	$(CC) -c $(SFLAGS) $<

# Now, we will define some additional rules, called "phony" rules.
# This is because the targets of these rules are not actual files that
# need to be created, but extra functions of the makefile.  The "all" rule
# above is an example of a phony rule.  This works because if the target
# "file" of a a rule does not exist, the rule will always be run.  GNU Make
# takes this a step further by allowing you to explicity specify a rule
# as phony.  Thus, even if a file should exist that has the same name as
# the target, the rule will still be run.  This is done with the ".PHONY"
# special target.

.PHONY : all clean extraclean install dist

# The 'clean' rule is traditionally used to remove any extra files that
# are built as a standard part of a program's compilation, but aren't
# needed to run it.
# Here is also one of the traditional problems with makefiles that are
# created based on a Unix toolset:  the below command will not work
# if you change the definition of $(RM) to "del", because MS-DOS del
# cannot accept multiple arguments.  For maximum portability, the
# below line should be split into two separate commands.
clean :
	$(RM) *.o *.d

# 'extraclean' takes 'clean' a step further by removing all files that
# can be recreated by the makefile.  See the note above about rm vs. del.
extraclean : clean
	$(RM) myprog myprog.exe libmylib.a

# 'install' is the traditional name for a rule that moves all files to
# the place they need to be to run.
install : myprog.exe
	update myprog.exe c:/djgpp/bin
	update myprog.doc c:/djgpp/doc

# 'dist' is the traditional name for the rule to create a distribution
# form of your program.  I like to create a variable specifying all the
# distribution files, and using it as a dependency to the 'dist' command.
# You can take this even farther and make the zipfile an actual rule just
# like the program, and make 'dist' specify that rule as a dependency.
# This would have the added advantage of only rebuilding the zipfile if
# any distribution files are changed.
dist : $(DIST)
	zip $^

# The final portion of a traditional makefile specifies additional
# dependencies of the program files.  Actually, this sometimes goes at the
# end and sometimes between the variable definitions and the first real
# rules.  If a rule specifies an existing file as target but contains
# no commands, it is not considered for the 'default' rule that gets
# evaluated first.

# What the following rules say is that if any of the indicated dependencies
# have been modified, the indicated file should be considered not up to date.
$(OFILES) : myprog.h
files.o : files.h
display.o : display.h
input.o : input.h files.h

# An additional feature of gcc is the ability to automatically generate
# files listing all the dependencies of a given target file.  This is
# done by passing the "-MD" switch to gcc.  If you choose to do this,
# you should include the following section in your makefile.  This also
# illustrates some of the additional sophistication available to you in
# GNU Make, such as makefile directives, functions, etc.
# Hint:  To easily add -MD to your gcc command line, just add it to
# the CFLAGS and SFLAGS variables above.
DEPS := $(wildcard *.d)
ifneq ($(DEPS),)
include $(DEPS)


- Raw text -

  webmaster     delorie software   privacy  
  Copyright 2019   by DJ Delorie     Updated Jul 2019