1 /* MetaMake - A Make extension
2 Copyright © 1995-2004, The AROS Development Team. All rights reserved.
4 This file is part of MetaMake.
6 MetaMake is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
11 MetaMake is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with GNU CC; see the file COPYING. If not, write to
18 the Free Software Foundation, 59 Temple Place - Suite 330,
19 Boston, MA 02111-1307, USA. */
39 static Project
* defaultprj
= NULL
;
42 readvars (Project
* prj
)
53 printf ("Read vars...\n");
55 setvar (&prj
->vars
, "TOP", prj
->top
);
56 setvar (&prj
->vars
, "CURDIR", "");
58 if (prj
->globalvarfile
)
63 char * name
, * value
, * ptr
;
65 fn
= xstrdup (substvars (&prj
->vars
, prj
->globalvarfile
));
68 if (!fh
&& prj
->genglobalvarfile
)
70 char * gen
= xstrdup (substvars (&prj
->vars
, prj
->genglobalvarfile
));
72 printf ("Generating %s...\n", fn
);
74 if (!execute (prj
, gen
, "-", "-", ""))
76 error ("Error while creating \"%s\" with \"%s\"", fn
, gen
);
87 error ("readvars():fopen(): Opening \"%s\" for reading", fn
);
93 while (fgets (line
, sizeof(line
), fh
))
95 if (*line
== '\n' || *line
== '#') continue;
96 line
[strlen(line
)-1] = 0;
99 while (isspace (*ptr
)) ptr
++;
101 while (*ptr
&& !isspace(*ptr
) && *ptr
!= ':' && *ptr
!= '=')
107 while (isspace(*ptr
) || *ptr
== ':' || *ptr
== '=')
112 while (*ptr
&& *ptr
!= '#')
118 printf ("%s=%s\n", name
, substvars (&prj
->vars
, value
));
121 setvar (&prj
->vars
, name
, substvars (&prj
->vars
, value
));
128 ForeachNodeSafe (&prj
->genmakefiledeps
, node
, next
)
131 AddTail (&deps
, node
);
134 ForeachNodeSafe (&deps
, node
, next
)
137 dep
= newdepnode (substvars (&prj
->vars
, node
->name
));
138 AddTail (&prj
->genmakefiledeps
, dep
);
145 printf ("project %s.genmfdeps=\n", prj
->node
.name
);
146 printlist (&prj
->genmakefiledeps
);
151 printf ("project %s.vars=", prj
->node
.name
);
152 printvarlist (&prj
->vars
);
157 initproject (char * name
)
159 Project
* prj
= new (Project
);
161 memset (prj
, 0, sizeof(Project
));
165 prj
->maketool
= xstrdup ("make \"TOP=$(TOP)\" \"CURDIR=$(CURDIR)\"");
166 prj
->defaultmakefilename
= xstrdup ("Makefile");
167 prj
->top
= getcwd (NULL
, 1024);
168 prj
->defaulttarget
= xstrdup ("all");
169 prj
->genmakefilescript
= NULL
;
170 prj
->globalvarfile
= NULL
;
171 prj
->genglobalvarfile
= NULL
;
175 prj
->maketool
= xstrdup (defaultprj
->maketool
);
176 prj
->defaultmakefilename
= xstrdup (defaultprj
->defaultmakefilename
);
177 prj
->top
= xstrdup (defaultprj
->top
);
178 prj
->defaulttarget
= xstrdup (defaultprj
->defaulttarget
);
179 SETSTR (prj
->genmakefilescript
, defaultprj
->genmakefilescript
);
180 SETSTR (prj
->globalvarfile
, defaultprj
->globalvarfile
);
181 SETSTR (prj
->genglobalvarfile
, defaultprj
->genglobalvarfile
);
184 prj
->node
.name
= xstrdup (name
);
188 NewList(&prj
->genmakefiledeps
);
189 NewList(&prj
->ignoredirs
);
191 NewList(&prj
->extramakefiles
);
197 freeproject (Project
* prj
)
201 cfree (prj
->node
.name
);
202 cfree (prj
->maketool
);
203 cfree (prj
->defaultmakefilename
);
205 cfree (prj
->defaulttarget
);
206 cfree (prj
->genmakefilescript
);
207 cfree (prj
->globalvarfile
);
208 cfree (prj
->genglobalvarfile
);
211 closecache (prj
->cache
);
213 freelist (&prj
->genmakefiledeps
);
214 freelist (&prj
->ignoredirs
);
215 freevarlist (&prj
->vars
);
216 freelist (&prj
->extramakefiles
);
222 callmake (Project
* prj
, const char * tname
, Makefile
* makefile
)
224 static char buffer
[4096];
225 const char * path
= buildpath (makefile
->dir
);
231 setvar (&prj
->vars
, "CURDIR", path
);
232 setvar (&prj
->vars
, "TARGET", tname
);
236 for (t
=0; t
<mflagc
; t
++)
238 strcat (buffer
, mflags
[t
]);
239 strcat (buffer
, " ");
242 if (strcmp (makefile
->node
.name
, "Makefile")!=0 && strcmp (makefile
->node
.name
, "makefile")!=0);
244 strcat (buffer
, "--file=");
245 strcat (buffer
, makefile
->node
.name
);
246 strcat (buffer
, " ");
249 strcat (buffer
, tname
);
251 printf ("Making %s in %s\n", tname
, path
);
253 if (!execute (prj
, prj
->maketool
, "-", "-", buffer
))
255 error ("Error while running make in %s", path
);
271 defaultprj
= project
= initproject ("default");
272 AddTail(&projects
, project
);
275 /* Try "$MMAKE_CONFIG" */
276 if ((optionfile
= getenv ("MMAKE_CONFIG")))
277 optfh
= fopen (optionfile
, "r");
279 /* Try "$HOME/.mmake.config" */
282 if ((home
= getenv("HOME")))
284 optionfile
= xmalloc (strlen(home
) + sizeof("/.mmake.config") + 1);
285 sprintf (optionfile
, "%s/.mmake.config", home
);
286 optfh
= fopen (optionfile
, "r");
291 /* Try with $CWD/.mmake.config" */
293 optfh
= fopen (".mmake.config", "r");
295 /* Try with "$CWD/mmake.config */
297 optfh
= fopen ("mmake.config", "r");
303 "Please set the HOME or MMAKE_CONFIG env var (with setenv or export)\n"
305 error ("Opening mmake.config for reading");
309 while (fgets (line
, sizeof(line
), optfh
))
311 if (*line
== '\n' || *line
== '#') continue;
312 line
[strlen(line
)-1] = 0;
319 while (*ptr
&& *ptr
!= ']')
325 printf ("name=%s\n", name
);
328 project
= initproject (name
);
330 AddTail(&projects
,project
);
334 char * cmd
, * args
, * ptr
;
337 while (isspace (*cmd
))
341 while (*args
&& !isspace(*args
))
343 *args
= tolower (*args
);
348 while (isspace (*args
))
353 while (*ptr
&& *ptr
!= '\n')
358 if (!strcmp (cmd
, "add"))
362 AddTail(&project
->extramakefiles
, n
);
364 else if (!strcmp (cmd
, "ignoredir"))
368 AddTail(&project
->ignoredirs
, n
);
370 else if (!strcmp (cmd
, "defaultmakefilename"))
372 SETSTR(project
->defaultmakefilename
,args
);
374 else if (!strcmp (cmd
, "top"))
376 SETSTR(project
->top
,args
);
378 else if (!strcmp (cmd
, "defaulttarget"))
380 SETSTR(project
->defaulttarget
,args
);
382 else if (!strcmp (cmd
, "genmakefilescript"))
384 SETSTR(project
->genmakefilescript
,args
);
386 else if (!strcmp (cmd
, "genmakefiledeps"))
390 char ** deps
= getargs (args
, &depc
, NULL
);
392 for (t
=0; t
<depc
; t
++)
394 dep
= addnodeonce (&project
->genmakefiledeps
, deps
[t
]);
397 else if (!strcmp (cmd
, "globalvarfile"))
399 SETSTR(project
->globalvarfile
,args
);
401 else if (!strcmp (cmd
, "genglobalvarfile"))
403 SETSTR(project
->genglobalvarfile
,args
);
405 else if (!strcmp (cmd
, "maketool"))
407 SETSTR(project
->maketool
,args
);
411 setvar(&project
->vars
, cmd
, args
);
418 /* Clean up memory from getargs */
419 getargs (NULL
, NULL
, NULL
);
423 printf ("known projects: ");
424 printlist (&projects
);
429 expungeprojects (void)
433 ForeachNodeSafe (&projects
, prj
, next
)
441 findproject (const char * pname
)
443 return FindNode (&projects
, pname
);
447 getfirstproject (void)
449 Project
* prj
= GetHead (&projects
);
451 if (prj
&& prj
== defaultprj
)
458 execute (Project
* prj
, const char * cmd
, const char * in
,
459 const char * out
, const char * args
)
465 strcpy (buffer
, cmd
);
466 strcat (buffer
, " ");
468 if (strcmp (in
, "-"))
470 strcat (buffer
, "<");
472 strcat (buffer
, " ");
475 if (strcmp (out
, "-"))
477 strcat (buffer
, ">");
478 strcat (buffer
, out
);
479 strcat (buffer
, " ");
482 strcat (buffer
, args
);
484 cmdstr
= substvars (&prj
->vars
, buffer
);
487 printf ("Executing %s...\n", cmdstr
);
489 rc
= system (cmdstr
);
493 printf ("%s failed: %d\n", cmdstr
, rc
);
500 maketarget (Project
* prj
, char * tname
)
502 Target
* target
, * subtarget
;
505 MakefileTarget
* mftarget
;
508 printf ("Building %s.%s\n", prj
->node
.name
, tname
);
517 prj
->cache
= activatecache (prj
);
520 tname
= prj
->defaulttarget
;
522 target
= FindNode (&prj
->cache
->targets
, tname
);
526 printf ("Nothing known about target %s in project %s\n", tname
, prj
->node
.name
);
532 ForeachNode (&target
->makefiles
, mfref
)
534 mftarget
= FindNode (&mfref
->makefile
->targets
, tname
);
536 ForeachNode (&mftarget
->deps
, node
)
537 addnodeonce (&deps
, node
->name
);
540 ForeachNode (&deps
, node
)
542 subtarget
= FindNode (&prj
->cache
->targets
, node
->name
);
546 printf ("Nothing known about target %s in project %s\n", node
->name
, prj
->node
.name
);
548 else if (!subtarget
->updated
)
550 maketarget (prj
, node
->name
);
556 ForeachNode (&target
->makefiles
, mfref
)
558 if (!mfref
->virtualtarget
)
560 callmake (prj
, tname
, mfref
->makefile
);