source: trunk/geant4/config/liblist.c@ 685

Last change on this file since 685 was 593, checked in by garnier, 18 years ago

r627@mac-90108: laurentgarnier | 2007-11-09 07:57:42 +0100
modif dans les includes directives

File size: 14.3 KB
Line 
1/* $Id: liblist.c,v 1.19 2007/07/18 14:21:15 gcosmo Exp $ */
2
3/*
4Given a "libname.map" file on standard input and a list or directory
5of .d dependency files liblist produces:
6 a) without -l option, a library list ordered according to the libname.map,
7 giving a warning if conflicting dependencies are found in the .d files.
8 b) with -l option, another libname.map, ordered according firstly to the
9 original libname.map file, then reordered according to the dependencies
10 found in the .d files. This option is used for compiling the file
11 libname.map from all the dependencies.
12 c) with -m <lpath> option, the whole existing libraries list ordered
13 according to the libname.map, where libraries are placed in <lpath>.
14The .d files are specified in the argument(s).
15The libname.map is on standard input.
16
17Usage:
18 liblist *.d < libname.map
19 liblist -d <ddir> < libname.map
20 liblist -l *.d < libname.map
21 liblist -ld <ddir> < libname.map
22 liblist -l -d <ddir> < libname.map
23 liblist -m <lpath> < libname.map
24where:
25 <ddir> is a directory name of a directory which is recursively
26 searched for dependency files
27 <lpath> is the path where libraries are located
28
29Frank Behner, John Allison 13th February 1999.
30*/
31
32#include <stdio.h>
33#include <string.h>
34#include <unistd.h>
35#include <dirent.h>
36#include <sys/stat.h>
37#include <unistd.h>
38#include <errno.h>
39#include <stdlib.h>
40
41#define BUFSIZE 1000000
42#define TRIGSIZE 1000
43#define NLIBMAX 200
44
45extern char *optarg;
46extern int optind, opterr, optopt;
47
48char** parsedir(char *directory,int *argc)
49{
50 DIR *actualdir;
51 FILE *actualfile;
52 struct dirent *entry;
53 char *buffer=0;
54 struct stat status;
55 char **targv=0,**ptr,**phelp;
56 int len,targc,s;
57
58 /*Open the actual directory*/
59 actualdir=opendir(directory);
60
61 if(!actualdir) return targv;
62
63 /*Loop over all entries */
64 for(entry=readdir(actualdir);entry!=NULL;entry=readdir(actualdir))
65 {
66 /* Throw away . and .. */
67 if(strcmp(entry->d_name,".")==0 ||
68 strcmp(entry->d_name,"..")==0) continue;
69 /* Obtain the status information of that entry */
70 if(buffer) free(buffer);
71 buffer=(char*) malloc((strlen(directory)+
72 strlen(entry->d_name)+2)*sizeof(char));
73 strcpy(buffer,directory);
74 strcat(buffer,"/");
75 strcat(buffer,entry->d_name);
76 s=stat(buffer,&status);
77 if(s==0)
78 {
79 if(S_ISDIR(status.st_mode))
80 {
81 /* a directory, so we are going recursive*/
82 targc=0;
83 ptr=parsedir(buffer,&targc);
84 if(targc)
85 {
86 phelp=targv;
87 targv=(char**) malloc((*argc+targc)*sizeof(char*));
88 memcpy(targv,phelp,*argc*sizeof(char*));
89 memcpy(&targv[*argc],ptr,targc*sizeof(char*));
90 *argc+=targc;
91 free(phelp);
92 free(ptr);
93 }
94 }
95 else if(S_ISREG(status.st_mode))
96 {
97 /* a regular file is it .d? */
98 len=strlen(entry->d_name);
99 if(entry->d_name[len-2]=='.' && entry->d_name[len-1]=='d')
100 {
101 phelp=targv;
102 targv=(char**) malloc((*argc+1)*sizeof(char*));
103 memcpy(targv,phelp,*argc*sizeof(char*));
104 targv[*argc]=strdup(buffer);
105 (*argc)++;
106 free(phelp);
107 }
108 }
109 }
110 else
111 {
112 fprintf
113 (stderr,
114 " No status - perhaps file %s does not exist.\n",
115 directory);
116 exit(1);
117 }
118 }
119
120 if(buffer) free(buffer);
121 closedir(actualdir);
122
123 return targv;
124}
125
126
127int main (int argc, char** argv) {
128
129 char static buffer[BUFSIZE],*bufferPtr,workbuf[256];
130 char *ptr,*p,**pp,**pp1,**pp2,*directory=0,*libpath=0;
131 char **rargv;
132 char libname[128];
133 int i,optl=0,optm=0,swapping,c,rargc;
134 FILE *fp;
135
136#if defined ( _WIN32 ) || defined ( __CYGWIN__ ) || defined ( __CYGWIN32__ )
137 char *ntg4tmp=0,*ntg4tmp1=0;
138 int nti;
139#endif
140
141 struct libmap_
142 {
143 char *lib; /* Library name, e.g., G4run. */
144 char *trigger; /* Source directory, e.g., source/run/. */
145 int used; /* True if used by these dependency files. */
146 char **uses; /* List of library names which this library uses. */
147 struct libmap_ *next;
148 };
149
150 struct libmap_ *libmap=0,*libmapPtr=0,*libmapPtr1=0,*libmapPtr2=0,
151 *prevPtr1,*prevPtr2,*tmpp,*userLibmapPtr;
152
153 while((c=getopt(argc,argv,"ld: m:"))!=EOF)
154 {
155 switch(c)
156 {
157 case 'l':
158 optl=1;
159 break;
160 case 'd':
161 directory=strdup(optarg);
162 break;
163 case 'm':
164 optm=1;
165 libpath=strdup(optarg);
166 break;
167 }
168 }
169
170 /*Adjust parameters after parsing options */
171
172 if(optind<argc)
173 {
174 rargv=&argv[optind];
175 rargc=argc-optind;
176 }
177 else
178 {
179 rargv=0;
180 rargc=0;
181 }
182
183 if(directory)
184 {
185 if(rargc==0)
186 {
187 rargv=parsedir(directory,&rargc);
188 }
189 else
190 {
191 fprintf
192 (stderr,
193 " ERROR: If you specify a directory don't also specify files\n");
194 exit(1);
195 }
196 }
197
198 if(optl)fprintf(stderr," Reading library name map file...\n");
199 while (!feof(stdin))
200 {
201 /* Get library name... */
202 gets(buffer);
203 if(feof(stdin)) break;
204 ptr=strtok(buffer,":\n");
205
206 /* Check for duplicate names... */
207 for(libmapPtr1=libmap;libmapPtr1;libmapPtr1=libmapPtr1->next)
208 {
209 if(strcmp(libmapPtr1->lib,ptr)==0)
210 {
211 fprintf(stderr," ERROR: Duplicate library name: %s\n",ptr);
212 fprintf(stderr,
213 " Perhaps a duplicate subdirectory with"
214 " a GNUmakefile with the same library name.\n"
215 );
216 exit(1);
217 }
218 }
219
220 if(libmap)
221 {
222 libmapPtr->next=(struct libmap_*) malloc(sizeof(struct libmap_));
223 libmapPtr=libmapPtr->next;
224 }
225 else /* First time through anchor libmapPtr to libmap. */
226 {
227 libmap=(struct libmap_*) malloc(sizeof(struct libmap_));
228 libmapPtr=libmap;
229 }
230 libmapPtr->next=0;
231 libmapPtr->lib=strdup(ptr);
232 libmapPtr->used=0;
233 libmapPtr->uses=(char**)calloc(NLIBMAX,sizeof(char*));
234
235 /* If option -l not specified, fill uses list... */
236 if(!optl && !optm)
237 {
238 pp=libmapPtr->uses;
239 if(ptr)
240 {
241 ptr=strtok(NULL," \n");
242 while (ptr)
243 {
244 *pp=strdup(ptr);
245 pp++;
246 ptr=strtok(NULL," \n");
247 }
248 }
249 }
250
251 if(!optm)
252 {
253 /* Get directory name... */
254 gets(buffer);
255 ptr=strtok(buffer,"/");
256 if(!ptr)
257 {
258 fprintf(stderr," ERROR: \"/\" before \"source\" expected.\n");
259 exit(1);
260 }
261 while(ptr&&strcmp (ptr,"source"))ptr=strtok(NULL,"/");
262 ptr=strtok(NULL,"/");
263 if(!ptr)
264 {
265 fprintf(stderr," ERROR: \"source\" expected.\n");
266 exit(1);
267 }
268 libmapPtr->trigger=(char*)malloc(TRIGSIZE);
269 strcpy(libmapPtr->trigger,ptr);
270 ptr=strtok(NULL,"/");
271 while(ptr&&strcmp(ptr,"GNUmakefile"))
272 {
273 strcat(libmapPtr->trigger,"/");
274 strcat(libmapPtr->trigger,ptr);
275 ptr=strtok(NULL,"/");
276 }
277 if(!ptr)
278 {
279 fprintf
280 (stderr,
281 " ERROR: \"source/<unique-sub-path>/GNUmakefile\" expected.\n");
282 exit(1);
283 }
284 }
285 }
286
287 if(optl)fprintf(stderr," Reading dependency files...\n");
288
289#if defined ( _WIN32 ) || defined ( __CYGWIN__ ) || defined ( __CYGWIN32__ )
290 ntg4tmp=getenv("G4TMP");
291 if ( ! ntg4tmp )
292 {
293 fprintf(stderr," ERROR: Cannot find environment variable G4TMP\n");
294 exit(1);
295 }
296 ntg4tmp1=strdup(ntg4tmp);
297#endif
298
299 for(i=0;i<rargc;i++)
300 {
301 fp=fopen(rargv[i],"r");
302 fgets(buffer,BUFSIZE,fp);
303
304#if defined ( _WIN32 ) || defined ( __CYGWIN__ ) || defined ( __CYGWIN32__ )
305 ptr=strchr(ntg4tmp1,':');
306
307 while ( ptr=strchr(buffer,'\\') ) *ptr='/';
308
309 while (ntg4tmp1!=NULL && (ptr=strstr(buffer,ntg4tmp1))!=NULL )
310 {
311 for(nti=0;nti<strlen(ntg4tmp1);nti++) ptr[nti]=' ';
312 }
313#endif
314
315 /* Clip target out of dependency file... */
316 ptr=strtok(buffer,":");
317
318 /* Look for a "user" library... */
319 for(libmapPtr=libmap;libmapPtr;libmapPtr=libmapPtr->next)
320 {
321 strcpy(workbuf,libmapPtr->lib);
322 /* Add trailing "/" to distinguish track/ and tracking/, etc. */
323 strcat(workbuf,"/");
324 if(strstr(ptr,workbuf)) break;
325 }
326 if(libmapPtr)
327 {
328 userLibmapPtr=libmapPtr;
329 }
330 else
331 {
332 userLibmapPtr=0;
333 }
334
335 if(!optm)
336 {
337 /* Look for a "used" library and add it to the "user" uses list... */
338 bufferPtr=strtok(NULL,"\n"); /* Start *after* ":". */
339 if (!bufferPtr)
340 {
341 fprintf(stderr," WARNING: It seems there is nothing after \':\' in dependency file %s.\n", rargv[i]);
342 }
343 else {
344 do
345 {
346 for(libmapPtr=libmap;libmapPtr;libmapPtr=libmapPtr->next)
347 {
348 /* Look for trigger string. */
349 strcpy(workbuf,libmapPtr->trigger);
350 strcat(workbuf,"/include");
351 ptr=strstr(bufferPtr,workbuf);
352 if(ptr && (userLibmapPtr != libmapPtr))
353 {
354 libmapPtr->used=1;
355 if(userLibmapPtr)
356 {
357 for(pp=userLibmapPtr->uses;*pp;pp++)
358 {
359 if(strcmp(*pp,libmapPtr->lib)==0)break;
360 }
361 if(!*pp)*pp=libmapPtr->lib;
362 }
363 }
364 /* Also look for library name in case header files are
365 placed in temporary directories under a subdirectory
366 with the same name as the library name. This can
367 happen with Objectivity which makes header files
368 from .ddl files and places them in a temporary
369 directory. */
370 strcpy(workbuf,libmapPtr->lib);
371 strcat(workbuf,"/");
372 ptr=strstr(bufferPtr,workbuf);
373 if(ptr && (userLibmapPtr != libmapPtr))
374 {
375 libmapPtr->used=1;
376 if(userLibmapPtr)
377 {
378 for(pp=userLibmapPtr->uses;*pp;pp++)
379 {
380 if(strcmp(*pp,libmapPtr->lib)==0)break;
381 }
382 if(!*pp)*pp=libmapPtr->lib;
383 }
384 }
385 }
386 fgets(buffer,BUFSIZE,fp);
387 bufferPtr=buffer;
388
389#if defined ( _WIN32 ) || defined ( __CYGWIN__ ) || defined ( __CYGWIN32__ )
390 while ( ptr=strchr(buffer,'\\') ) *ptr='/';
391
392 while (ntg4tmp1 && (ptr=strstr(buffer,ntg4tmp1)) )
393 {
394 for(nti=0;nti<strlen(ntg4tmp1);nti++) ptr[nti]=' ';
395 }
396#endif
397
398 } while(!feof(fp));
399 fclose(fp);
400 }
401 }
402 }
403
404#if defined ( _WIN32 ) || defined ( __CYGWIN__ ) || defined ( __CYGWIN32__ )
405 free(ntg4tmp1);
406#endif
407
408 if(optl) /* This option is used for compiling the file libname.map
409 from all the dependencies. */
410 {
411 fprintf(stderr," Checking for circular dependencies...\n");
412 for(libmapPtr=libmap;libmapPtr;libmapPtr=libmapPtr->next)
413 {
414 for(pp=libmapPtr->uses;*pp;pp++)
415 {
416 for(libmapPtr1=libmap;libmapPtr1!=libmapPtr;
417 libmapPtr1=libmapPtr1->next)
418 {
419 if(strcmp(libmapPtr1->lib,*pp)==0)
420 {
421 for(pp1=libmapPtr1->uses;*pp1;pp1++)
422 {
423 if(strcmp(*pp1,libmapPtr->lib)==0)break;
424 }
425 if(*pp1)
426 {
427 fprintf
428 (stderr,
429 " WARNING: %s and %s use each other.\n",
430 libmapPtr->lib,
431 libmapPtr1->lib);
432 }
433 }
434 else
435 {
436 /* Not right yet...
437 for(pp1=libmapPtr1->uses;*pp1;pp1++)
438 {
439 for(libmapPtr0=libmap;libmapPtr0!=libmapPtr1;
440 libmapPtr0=libmapPtr0->next)
441 {
442 if(libmapPtr0==*pp)
443 {
444 fprintf
445 (stderr,
446 " WARNING: triangular dependecy:\n"
447 " %s uses %s uses %s uses %s.\n",
448 libmapPtr->lib,
449 libmapPtr1->lib,
450 libmapPtr0->lib,
451 libmapPtr->lib);
452 }
453 }
454 }
455 */
456 }
457 }
458 }
459 }
460
461 fprintf(stderr," Reordering according to dependencies...\n");
462 do
463 {
464 swapping=0;
465 prevPtr2=0;
466 for(libmapPtr=libmap;libmapPtr;libmapPtr=libmapPtr->next)
467 {
468 for(pp=libmapPtr->uses;*pp;pp++)
469 {
470 prevPtr1=0;
471 for(libmapPtr1=libmap;libmapPtr1!=libmapPtr;
472 libmapPtr1=libmapPtr1->next)
473 {
474 if(strcmp(libmapPtr1->lib,*pp)==0)
475 {
476 /* Check that 1st doesn't use 2nd... */
477 for(pp1=libmapPtr1->uses;*pp1;pp1++)
478 {
479 if(strcmp(*pp1,libmapPtr->lib)==0)break;
480 }
481 if(!*pp1) /* If not... */
482 {
483 swapping=1;
484 /* Make previous of 1st now point to 2nd... */
485 if(prevPtr1)
486 {
487 prevPtr1->next=libmapPtr;
488 }
489 else
490 {
491 libmap=libmapPtr;
492 }
493 /* Make 2nd now point to what 1st did, unless
494 it's adjacent, in which case make it point
495 to 1st itself... */
496 tmpp=libmapPtr->next;
497 if(libmapPtr1->next==libmapPtr)
498 {
499 libmapPtr->next=libmapPtr1;
500 }
501 else
502 {
503 libmapPtr->next=libmapPtr1->next;
504 }
505 /* Make previous of 2nd point to 1st, unless
506 it's adjacent, in which case leave it... */
507 if(libmapPtr1->next!=libmapPtr)
508 {
509 prevPtr2->next=libmapPtr1;
510 }
511 /* Make 1st now point to what 2nd did... */
512 libmapPtr1->next=tmpp;
513 break;
514 }
515 }
516 prevPtr1=libmapPtr1;
517 }
518 if(swapping)break;
519 }
520 prevPtr2=libmapPtr;
521 if(swapping)break;
522 }
523 }while(swapping);
524
525 fprintf(stderr," Writing new library map file...\n");
526 for(libmapPtr=libmap;libmapPtr;libmapPtr=libmapPtr->next)
527 {
528 printf("%s:",libmapPtr->lib);
529 for(pp=libmapPtr->uses;*pp;pp++)
530 {
531 printf(" %s",*pp);
532 }
533 printf("\n");
534 printf("source/%s/GNUmakefile\n",libmapPtr->trigger);
535 }
536 }
537 else if (optm)
538 {
539 /* Write out full library list... */
540 for(libmapPtr=libmap;libmapPtr;libmapPtr=libmapPtr->next)
541 {
542 /* Check existance of libraries and print out only installed ones */
543 sprintf(libname, "%s/lib%s.a", libpath, libmapPtr->lib);
544 if (access(libname,R_OK))
545 {
546 sprintf(libname, "%s/lib%s.so", libpath, libmapPtr->lib);
547 if (!access(libname,R_OK))
548 {
549 printf("-l%s ",libmapPtr->lib);
550 }
551 else /* case MacOS .dylib */
552 {
553 sprintf(libname, "%s/lib%s.dylib", libpath, libmapPtr->lib);
554 if (!access(libname,R_OK))
555 {
556 printf("-l%s ",libmapPtr->lib);
557 }
558 }
559 }
560 else
561 {
562 printf("-l%s ",libmapPtr->lib);
563 }
564 libmapPtr=libmapPtr->next;
565 }
566 }
567 else
568 {
569 /* Add dependent libraries... */
570 for(libmapPtr=libmap;libmapPtr;libmapPtr=libmapPtr->next)
571 {
572 if(libmapPtr->used)
573 {
574 for(pp=libmapPtr->uses;*pp;pp++)
575 {
576 for(libmapPtr1=libmap;libmapPtr1;libmapPtr1=libmapPtr1->next)
577 {
578 if(strcmp(libmapPtr1->lib,*pp)==0)
579 {
580 libmapPtr1->used=1;
581 }
582 }
583 }
584 }
585 }
586
587 /* Write out library list... */
588 for(libmapPtr=libmap;libmapPtr;libmapPtr=libmapPtr->next)
589 {
590 if(libmapPtr->used)
591 {
592 printf("-l%s ",libmapPtr->lib);
593 }
594 }
595 }
596
597 exit(0);
598
599}
Note: See TracBrowser for help on using the repository browser.