Programs
Make7 Source Code
 previous   up   next 

Make7 is the Seed7 version of the make utility. Make is used to manage the compilation process of a program. This is done with the help of a makefile. A makefile describes the relationships among files in the program, and the commands for updating each file. In a program, typically the executable file is updated from object files, which are in turn made by compiling source files.

Make7 is designed to process makefiles from Unix and Windows make utilities. Therefore the characteristics of several make utilities can be found in make7. Make7 concentrates to provide the features of make in a portable way. Unportable features of other make utilities are left out in make7.

Usage

Make7 can be called from a command window with:

make7 [options] [targets]

Targets specifies the target rules to be processed. If no targets are specified make7 processes the first rule of the makefile. The following options are supported by make7:

-h
Write make7 usage.
-C dir
Change to dir before reading the makefile or doing anything else.
-f file
Use file as a makefile.
-i
Ignore all errors in commands executed.
-n
Print the commands that would be executed, but do not execute them.
-s
Silent operation. Do not print the commands as they are executed.

Make7 uses the option -f to determine the name of the makefile. If no -f option is present, make7 will look for the makefiles makefile, and Makefile, in that order.

Example of a make7 usage:

../prg/make7 depend

Makefile

The description of makefile properties below applies to makefiles accepted by make7. Lines starting with the number sign (#) are interpreted as comments up to the end of the line. The rules in a makefile look like:

target: dependencies ...
        commands

Target names consist of printable ASCII characters except space, tab, colon (:) and equal (=). The dependencies are a possibly empty list of target names. In the dependency list the target names are separated by spaces or tabs. The dependencies can span two or more lines, if all lines except the last end with a backslash (\). Target names in the dependency list can be quoted with double quotes ("). This allows dependency targets with spaces. Alternatively a space in a dependency target can be preceeded by a backslash (\).

Lines with commands are introduced with tabs or spaces (Historically make only allowed tabs). There can be several lines with commands (all introduced with spaces or tabs). It is also allowed to put several semicolon separated commands in a line. If the first character after the tab and space characters is a number sign (#) the command line is interpreted as comment up to the end of the line. If a command is prefixed with an at sign (@) the command is not printed, when it is executed. If a command is prefixed with a minus sign (-) possible errors of the command are ignored. Combinations of this prefixes (@- and -@) are also possible. The following built-in commands are supported:

rm    Remove files (Unix command)
del    Delete files (Dos/Windows command)
erase    Delete files (Dos/Windows command)
cp    Copy files (Unix command)
copy    Copy files (Dos/Windows command)
xcopy    Copy files and directories (Dos/Windows command)
mv    Move files (Unix command)
move    Move files (Dos/Windows command)
mkdir    Create directory(ies)
md    Create directory(ies) (Dos/Windows command)
pwd    Print current working directory
echo    Echo string(s) to standard output
cd    Change directory
make    Call make7 command
rem    Windows comment (remark) line
#    Unix comment (remark) line

The built-in commands are operating system independent, but they support only a limited set of options:

rm   -f   Ignore nonexistent files
rm   -r   Remove directories and their contents recursively
rm   -R   Remove directories and their contents recursively
del   /S   Remove directories and their contents recursively
erase   /S   Remove directories and their contents recursively
cp   -n   Do not overwrite existing files
cp   -a   Preserve mode, ownership and timestamps
cp   -p   Preserve mode, ownership and timestamps
cp   -r   Copy directories recursively
cp   -R   Copy directories recursively
copy   /Y   Overwrite existing files
xcopy   /E   Copies all subdirectories
xcopy   /O   Copies file ownership
xcopy   /Y   Overwrite existing files
mv   -n   Do not overwrite existing files
move   /Y   Overwrite existing files
mkdir   -p   Make parent directories as needed
pwd   -W   Write windows path (option is ignored)

Other commands are executed with the operating system shell. The output of a command can be redirected into a file. E.g.:

    echo "#define PATH_DELIMITER '/'" > version.h
    echo "#define USE_DIRENT" >> version.h
    echo "#define OBJECT_FILE_EXTENSION \".o\"" >> version.h
    echo "#define C_COMPILER \"$(CC)\"" >> version.h

Echo works also without quotation marks. E.g.:

    echo #define PATH_DELIMITER '\\' > version.h
    echo #define USE_DIRWIN >> version.h
    echo #define OBJECT_FILE_EXTENSION ".obj" >> version.h
    echo #define C_COMPILER "$(CC)" >> version.h

The caret can be used in unquoted strings to describe certain special characters (which would be interpreted wrongly by some make utilities):

    echo ^#define PATH_DELIMITER '\\' > version.h
    echo ^#define USE_DIRENT >> version.h
    echo ^#define OBJECT_FILE_EXTENSION ".obj" >> version.h
    echo ^#define EXECUTABLE_FILE_EXTENSION ".exe" >> version.h
    echo ^#define C_COMPILER "$(CC)" >> version.h

Echo commands are allowed to contain a backtick (`) command. E.g.:

    cd ../bin; echo "#define SEED7_LIB \"`pwd`/$(SEED7_LIB)\"" >> ../src/version.h; cd ../src
    cd ../bin; echo "#define COMP_DATA_LIB \"`pwd`/$(COMP_DATA_LIB)\"" >> ../src/version.h; cd ../src
    cd ../bin; echo "#define COMPILER_LIB \"`pwd`/$(COMPILER_LIB)\"" >> ../src/version.h; cd ../src
    cd ../lib; echo "#define SEED7_LIBRARY \"`pwd`\"" >> ../src/version.h; cd ../src

The following pattern rules are predefined, if they are not defined in the makefile:

%.o: %.c
    $(CC) -c $(CPPFLAGS) $(CFLAGS) $< -o $@
%.obj: %.c
    $(CC) -c $(CPPFLAGS) $(CFLAGS) $< -o $@

The following suffix rules are supported:

.c.o
.c.obj

Lines to define makefile macros look like:

macro=value

Macro names consist of printable ASCII characters except space, tab, closing parenthesis ()) and equal (=). The value of the macro is the string after = up to, but not including, the end of the line. Leading whitespace is not part of the value. A macro definition is:

CFLAGS = -O2 -g -Wall -Wstrict-prototypes -Winline

A macro can be used by surrounding its name with parentheses and prefixing the expression with a dollar sign ($). E.g.:

$(CFLAGS)

Macros can be used in targets, dependencies, commands or macro values. The following internal macros are predefined:

$@    The full target name of the current target
$<    The first dependency of the current rule
$?    The dependencies of the current rule without double entries
$^    The dependencies of the current rule without double entries
$+    The dependencies of the current rule
$$    The character $

There are functions that can be used to transform text:

FunctionDescriptionExampleExample result
$(strip string) Removes leading and trailing whitespace. $(strip a b c ) a b c
$(subst from,to,text) Replace from by to in text. $(subst ld,ne,old gold) one gone
$(patsubst pat,to,text) Replace words that match the pattern pat with to. $(patsubst %.c,%.o,x.c y.c) x.o y.o
$(dir names...) Extracts the directory-part of each file name in names. $(dir src/abc.c xyz) src/ ./
$(notdir names...) Extracts all but the directory-part of each file name in names. $(notdir src/abc.c xyz) abc.c xyz
$(suffix names...) Extracts the suffix of each file name in names. $(suffix s/x.c v1.0/y.c z) .c .c
$(basename names...) Extracts all but the suffix of each file name in names. $(basename s/x.c 1.0/y.c z) s/x 1.0/y z
$(addprefix pfx,names...) The prefix pfx is prepended to the front of each name. $(addprefix s/,foo bar) s/foo s/bar
$(addsuffix sfx,names...) The suffix sfx is appended to the end of each name. $(addsuffix .c,foo bar) foo.c bar.c
$(filter pat...,text) Returns all space-separated words in text that do match any of the pattern pat words. $(filter %.c,x.c y z.o) x.c
$(filter-out pat...,text) Returns all space-separated words in text that do not match any of the pattern pat words. $(filter-out %.c,x.c y z.o) y z.o
$(foreach var,list,text) Var gets all values from list in sequence and text is expanded for each of them. $(foreach d,s t,$(d)/xx) s/xx t/xx
$(wildcard pat) Create list of file names that match the pattern pat. $(wildcard dep*) depend

For the replacement function shorthands are defined:

ShorthandLong versionComment
$(var:pat=to)$(patsubst pat,to,$(var))Both pat and to contain a percent character (%).
$(var:suffix=to)$(patsubst %suffix,%to,$(var))One of suffix and to contains no percent character (%).

The conditionals ifeq, ifneq, ifdef and ifndef can be used to activate or deactivate parts of the makefile. E.g.:

ifeq ($(CC),gcc)
        $(CC) -o executable $(obj) $(gcc_libs)
else
        $(CC) -o executable $(obj) $(normal_libs)
endif

It is possible to include files into the makefile. E.g.:

ifeq (depend,$(wildcard depend))
include depend
endif

A different kind of conditional and include can be also introduced with an exclamation mark (!). E.g.:

!if exist(depend)
!include depend
!endif

Operation method

Processing a makefile starts with processing the specified target rule, or with processing the first rule if no target was specified. When a rule is processed the dependency rules are called recursively. When a rule is processed and the target file is missing the commands of the rule are executed. When a rule is processed and at least one dependency file is newer than the targed file the commands of the rule are executed.

Download

Make7 is written in the Seed7 programming language. You can download make7.exe, which is binary version of make7 for Windows. Make7 is also a part of the Seed7 package. To use make7 from the Seed7 package it is necessary to compile the Seed7 interpreter. Afterwards Make7 can be started from the directory 'seed7/prg' with:

s7 make7

Make7 can be also compiled with:

s7c make7

This creates an executable, which can be used without the 's7' interpreter.


Write make7 usage with option -h

Do make depend for Seed7

Do make for Seed7

 previous   up   next