char *a_dir; /* directory in which it resides */
struct idf *a_idf; /* its idf-structure */
struct file_list *a_next; /* next in list */
+ char a_notfound; /* could not open ... */
};
#define f_walk(list, ctrl) \
#define f_filename(a) ((a)->a_filename)
#define f_idf(a) ((a)->a_idf)
#define f_dir(a) ((a)->a_dir)
+#define f_notfound(a) ((a)->a_notfound)
/* $Header$ */
#include <em_path.h>
+#include <alloc.h>
+#include "main.h"
static char lib_dir[128] = EM_DIR;
+static struct liblist {
+ int libno;
+ struct liblist *libnext;
+} *lblist;
+
+int
is_library_dir(d)
char *d;
{
"system" definition modules. Return 1 if it is, 0 otherwise.
*/
- return strcmp(lib_dir, d) == 0;
+ register struct liblist *p = lblist;
+
+ while (p) {
+ if (! strcmp(DEFPATH[p->libno], d)) return 1;
+ p = p->libnext;
+ }
+ return 0;
}
init_lib()
extern char *strcat();
strcat(lib_dir, "/lib/m2");
- AddInclDir(lib_dir);
+ AddLibDir(lib_dir);
+}
+
+set_libdir(n)
+{
+ register struct liblist *p =
+ (struct liblist *) Malloc(sizeof(struct liblist));
+
+ p->libnext = lblist;
+ p->libno = n;
+ lblist = p;
}
.SH NAME
m2mm \- Modula-2 makefile generator
.SH SYNOPSIS
-\fBm2mm\fP [ \fB-I\fPdir \fB-M\fPflags \fB-C\fPcompiler \fB-S\fPsuffix ] file ...
+\fBm2mm\fP [ \fB-I\fPdir \fB-L\fPdir \fB-l\fPlibrary \fB-M\fPflags \fB-C\fPcompiler \fB-S\fPsuffix ] file ...
.SH DESCRIPTION
.I M2mm
is a makefile generator and fast syntax checker for Modula-2 programs.
.IR make (1)
without an argument will make all these programs.
.PP
-In the makefile, the variables \fBMOD\fP, \fBM2FLAGS\fP, \fBIFLAGS\fP, and
+In the makefile, the variables \fBMOD\fP, \fBM2FLAGS\fP, \fBIFLAGS\fP, \fBLIBS\fP, and
\fBSUFFIX\fP will be defined.
The generated rules have the following form:
.DS
Add \fIdir\fP to the list of directories where definition modules are
looked for. Also add the flag to \fBIFLAGS\fP.
The default value for \fBIFLAGS\fP is empty.
+.IP \fB-L\fP\fIdir\fP
+Add \fIdir\fP to the list of directories where definition modules are
+looked for. Also add the corresponding \fB-I\fP flag to \fBIFLAGS\fP.
+The difference with the \fB-I\fP flag is, that the \fB-L\fP directories are considered
+interfaces to libraries, and thus no rules are generated using or creating
+object files for modules found in these directories. Instead, the user is
+expected to add a library to the \fBLIBS\fP macro, using the \fB-l\fP flag.
.IP \fB-M\fP\fIflags\fP
Set \fBM2FLAGS\fP to \fIflags\fP.
.IP \fB-C\fP\fIcompiler\fP
Set \fBMOD\fP to \fIcompiler\fP.
The default value for \fBMOD\fP is "ack" (for the time being).
+.IP \fB-l\fP\fIlibrary\fP
+Add \fIlibrary\fP to the \fBLIBS\fP macro. This macro is initially empty,
+and is passed to the loader.
.IP \fB-S\fPsuffix
Set \fBSUFFIX\fP to \fIsuffix\fP.
The default suffix is "o".
char *mflags = "";
char *compiler = "ack";
char *suff = "o";
+char *llibs = 0;
main(argc, argv)
register char **argv;
for (i = 1; i < nDEF; i++) {
print(" -I%s", DEFPATH[i]);
}
- print("\nM2FLAGS = %s\nMOD = %s\nSUFFIX = %s\n", mflags, compiler, suff);
+ print("\nM2FLAGS = %s\nMOD = %s\nSUFFIX = %s\nLIBS = %s\n", mflags, compiler, suff, llibs ? llibs : "");
init_lib();
ProcessArgs();
find_dependencies();
register struct file_list *a;
{
char *fn;
- register struct file_list *p, *prev = 0;
- if (! InsertFile(f_filename(a), DEFPATH, &fn)) {
+ if (!f_notfound(a) && ! InsertFile(f_filename(a), DEFPATH, &fn)) {
+ a->a_notfound = 1;
Gerror("Could not find %s", f_filename(a));
- f_walk(arglist, p) {
- if (p == a) {
- if (! prev) arglist = p->a_next;
- else prev->a_next = a->a_next;
- break;
- }
- prev = p;
- }
return 0;
}
FileName = fn;
if (dotspot && strcmp(dotspot, ".mod") == 0) {
register struct idf *id = f_idf(arg);
- if (id) {
+ if (! f_notfound(arg) && id) {
if (id->id_type == PROGRAM) {
*dotspot = 0;
print("%s ", fn);
if (dotspot && strcmp(dotspot, ".mod") == 0) {
register struct idf *id = f_idf(arg);
- if (id) {
+ if (! f_notfound(arg) && id) {
char *obj = object(arg);
register struct file_list *a;
f_walk(arglist, a) {
char *dotp = strrindex(f_filename(a), '.');
- if (dotp && strcmp(dotp, ".mod") == 0) {
+ if (dotp && strcmp(dotp, ".mod") == 0 && ! f_notfound(a)) {
*dotp = 0;
if (strcmp(f_filename(a), n) == 0) {
*dotp = '.';
if (module_in_arglist(f_filename(p)) || ! f_dir(p)) {
/* nothing */
}
- else if (! is_library_dir(f_dir(p))) {
+ else if (! is_library_dir(f_dir(p))) {
print(" \\\n\t%s/%s", f_dir(p), object(p));
}
}
print("\n\n");
print("o_files:\t$(OBS_%s)\n\n", id->id_text);
print("%s:\t$(OBS_%s) $(OBS2_%s)\n", basename(f_filename(a)), id->id_text, id->id_text);
- print("\t$(MOD) -.mod -o %s $(M2FLAGS) $(OBS_%s) $(OBS2_%s)\n", basename(f_filename(a)), id->id_text, id->id_text);
+ print("\t$(MOD) -.mod -o %s $(M2FLAGS) $(OBS_%s) $(OBS2_%s) $(LIBS)\n", basename(f_filename(a)), id->id_text, id->id_text);
}
programs()
if (dotspot && strcmp(dotspot, ".mod") == 0) {
register struct idf *id = f_idf(a);
- if (id && id->id_type == PROGRAM) {
+ if (! f_notfound(a) && id && id->id_type == PROGRAM) {
prog_dep(id, a);
/* *dotspot = 0; */
pr_prog_dep(id, a);
extern char *mflags;
extern char *suff;
extern char *compiler;
+ extern char *llibs;
switch(*text++) {
+ case 'L' :
+ AddLibDir(text);
+ break;
+
case 'I' :
AddInclDir(text);
break;
suff = text;
break;
+ case 'l':
+ { static unsigned int liblen = 0;
+ unsigned int len = strlen(text) + 4;
+
+ if (liblen) {
+ llibs = Realloc(llibs, liblen += len);
+ }
+ else {
+ llibs = Malloc(liblen = len);
+ *llibs = '\0';
+ }
+ strcat(llibs,"\\\n\t");
+ strcat(llibs, text);
+ }
+ break;
+
default:
Gerror("Unrecognized option: -%s", text-1);
break;
new = tmp;
}
}
+
+AddLibDir(text)
+ char *text;
+{
+ if (*text) {
+ set_libdir(ndirs);
+ AddInclDir(text);
+ }
+}