Initial commit.
[keystone-rtos/fault_mgmt.git] / build / buildlib.xs
1 /******************************************************************************
2  * FILE PURPOSE: Build Library Utilities
3  ******************************************************************************
4  * FILE NAME: buildlib.xs
5  *
6  * DESCRIPTION: 
7  *  This file contains common routines that are used by the Fault Management 
8  *  component.
9  *
10  * Copyright (C) 2012-2014, Texas Instruments, Inc.
11  *****************************************************************************/
13 /**************************************************************************
14  * FUNCTION NAME : listAllFiles
15  **************************************************************************
16  * DESCRIPTION   :
17  *  Utility function which lists all files with a specific extension 
18  *  present in a directory and any directory inside it.
19  **************************************************************************/
20 function listAllFiles(ext, dir, recurse)
21 {     
22     var srcFile = [];
23     var d;
25     /* If recurse parameter is not specified we default to recursive search. */
26     if (recurse == null)
27         recurse = true;
29     if (dir == undefined) 
30           d = ".";
31     else 
32       d = dir;
34     /* Get access to the current directory. */
35     var file = new java.io.File(d);
37     /* Check if the file exists and it is a directory. */
38     if (file.exists() && file.isDirectory()) 
39     {
40         /* Get a list of all files in the specific directory. */
41         var fileList = file.listFiles();
42         for (var i = 0; i < fileList.length; i++) 
43         {
44             /* Dont add the generated directory 'package' and any of its files 
45              * to the list here. */
46             if (fileList[i].getName().matches("package") == false)
47             {
48                 /* Check if the detected file is a directory */
49                 if (fileList[i].isDirectory())
50                 {
51                     /* We will recurse into the subdirectory only if required to do so. */
52                     if (recurse == true)
53                     {
54                         /* Generate the directory Name in which we will recurse. */ 
55                         var directoryName = d + "/" + fileList[i].getName();
57                         /* Get a list of all files in this directory */
58                         var fileListing = listAllFiles (ext, directoryName, recurse);
59                         if (fileListing != null)
60                         {
61                             /* Return a list of all file names in the directory. */
62                             for (var j = 0 ; j < fileListing.length; j++) 
63                                 srcFile[srcFile.length++] = fileListing[j];
64                         }
65                     }
66                 }
67                 else
68                 {
69                     /* This was a file. Check if the file name matches the extension */
70                     if (fileList[i].getName().endsWith(ext) == true)
71                         srcFile[srcFile.length++] = d + "/" + fileList[i].getName();
72                 }
73             }
74         }
76         return srcFile;
77     }
78     return null;
79 }
81 function createMake(makefile)
82 {
83     /* Create the main make file */
84     var fileModule = xdc.module('xdc.services.io.File');
85     if(makefile==undefined)
86     {
87       try{
88           makefile = fileModule.open("makefile", "w");
89          } catch (ex)
90          {
91            print("makefile cannot be written to. Please check Writing Permissions.");
92            java.lang.System.exit(1);
93          }   
94     
95       Pkg.makePrologue += "\ninclude makefile\n"; 
96          
97       Pkg.makeEpilogue += "\nclean::\n\t-$(RM)  makefile\n";
98       makefile.writeLine("#*******************************************************************************");
99       makefile.writeLine("#* FILE PURPOSE: Top level makefile for Creating Component Libraries");
100       makefile.writeLine("#*******************************************************************************");
101       makefile.writeLine("#* FILE NAME: makefile");
102       makefile.writeLine("#*");
103       makefile.writeLine("#* DESCRIPTION: Defines Compiler tools paths, libraries , Build Options ");
104       makefile.writeLine("#*");
105       makefile.writeLine("#*");
106       makefile.writeLine("#*******************************************************************************");
107       makefile.writeLine("#*");
108       makefile.writeLine("# (Mandatory) Specify where various tools are installed.");
110       var file = xdc.module('xdc.services.io.File');
111     
112       var xdcTargetType = java.lang.System.getenv("XDCTARGET");
113       var toolsBaseDir = java.lang.System.getenv("XDCCGROOT");   
114       
115       makefile.writeLine("\n# Output for prebuilt generated libraries");
116       makefile.writeLine("export LIBDIR ?= ./lib");
118       /* Create INCDIR from XDCPATH */
119     
120       /* copy the environment array from the current environment */
121       var env   = java.lang.System.getenv();
122       var getxdcpath=String(java.lang.System.getenv("XDCPATH"));
123       getxdcpath= getxdcpath.replace(/\\/g,"/");
124       var keys  = env.keySet().toArray();
125       var key;
126       var stat={};
127       var env_j=[];
128       var listxdcpath = new Array();
129       for (var i = 0; i < keys.length; i++) {
130            key = String(keys[i]);
131            if((key.match("INSTALL_PATH")) || (key.match("INSTALLDIR")))
132            {
133              var keyPath=String(env.get(key));
134              keyPath=keyPath.replace(/\\/g,"/");
135              var file = xdc.module('xdc.services.io.File');
136              keyPath=file.getDOSPath(keyPath);
137              if(getxdcpath.toString().match(keyPath))
138              {
139                  listxdcpath.push({keyname: key,keypath: keyPath});
140                  while(getxdcpath.toString().match(keyPath))
141                  {
142                    getxdcpath=getxdcpath.toString().replace(keyPath,"$("+key+")");
143                  }
144              }
145            }
146     
147      }
148        var pkgroot="..";
149        for (var i = Pkg.name.split('.').length; i > 1; i--) {
150               pkgroot+="/..";
151           }
152         
153       makefile.writeLine("\n# ROOT Directory");        
154       makefile.writeLine("export ROOTDIR := "+pkgroot);
155     
156       makefile.writeLine("\n# INCLUDE Directory");
157       makefile.writeLine("export INCDIR := "+getxdcpath+";$(ROOTDIR)");       
158     
159       makefile.writeLine("\n# Common Macros used in make");  
160       makefile.writeLine("\nifndef RM");     
161       makefile.writeLine("export RM = rm -f");
162       makefile.writeLine("endif");        
163     
164       makefile.writeLine("\nifndef CP");     
165       makefile.writeLine("export CP = cp -p");    
166       makefile.writeLine("endif");    
167         
168       makefile.writeLine("\nexport MKDIR = mkdir -p");
169     
170       makefile.writeLine("\nifndef RMDIR");         
171       makefile.writeLine("export RMDIR = rm -rf");
172       makefile.writeLine("endif");        
173     
174       makefile.writeLine("\nifndef SED"); 
175       makefile.writeLine("export SED = sed");    
176       makefile.writeLine("endif");    
177     
178       makefile.writeLine("\nifndef MAKE"); 
179       makefile.writeLine("export MAKE = make");    
180       makefile.writeLine("endif");        
182       makefile.writeLine("\n# PHONY Targets");                
183       makefile.writeLine(".PHONY: all clean cleanall ");    
184       
185       makefile.writeLine("\n# FORCE Targets");                
186       makefile.writeLine("FORCE: ");          
187       
188       makefile.writeLine("\n# all rule");                
189       makefile.writeLine("all: .executables");           
190       makefile.writeLine(".executables: .libraries");
191       makefile.writeLine(".libraries:");
192       
193       makefile.writeLine("\n# Clean Rule");          
194       makefile.writeLine("clean:: clean_package");          
195       makefile.writeLine("# Clean Top Level Object Directory ");  
196       makefile.writeLine("clean_package:")
197       for each (var libdir in devices)
198       {         
199         makefile.writeLine("\t$(RMDIR) $(LIBDIR)/"+libdir.toString()+"/*/");  
200       }    
201       makefile.writeLine("\t$(RMDIR) package/cfg");            
202    }
203    else
204    {
205      try{
206           makefile = fileModule.open("makefile", "a");
207          } catch (ex)
208          {
209            print("makefile cannot be written to. Please check Writing Permissions.");
210            java.lang.System.exit(1);
211          }  
212     
213     }
215  return makefile;
218 function createLibMake(device, makelibname,targetname, objectPath)
220    var tooldir;
221    var stringname=String(targetname).replace("(xdc.bld.ITarget.Module)","");
222    if(stringname.match("ARM11"))
223    {
224      tooldir="TI_ARM11_GEN_INSTALL_PATH"; 
225    }
226    else
227    {
228      tooldir="C6X_GEN_INSTALL_PATH";
229    }
230    switch(stringname)
231    {
232     case String(C66LE):
233       targetname=C66LE;
234       break;
235     case String(C66BE):
236       targetname=C66BE;
237       break;
239    }
240     var fileModule = xdc.module('xdc.services.io.File');
241     try{
242      var dstFile = new java.io.File(makelibname);
243      dstFile.getParentFile().mkdirs();    
244      libmakefile = fileModule.open(makelibname, "w");
245      /* Add to Archive list */
246     } catch (ex)
247     {
248      print(makelibname+" cannot be written to. Please check Writing Permissions.");
249      java.lang.System.exit(1);
250     }   
251     libmakefile.writeLine("#*******************************************************************************");
252     libmakefile.writeLine("#* FILE PURPOSE: Lower level makefile for Creating Component Libraries");
253     libmakefile.writeLine("#*******************************************************************************");
254     libmakefile.writeLine("#* FILE NAME: "+makelibname);
255     libmakefile.writeLine("#*");
256     libmakefile.writeLine("#* DESCRIPTION: Defines Source Files, Compilers flags and build rules");
257     libmakefile.writeLine("#*");
258     libmakefile.writeLine("#*");
259     libmakefile.writeLine("#*******************************************************************************");
260     libmakefile.writeLine("#");
261     libmakefile.writeLine("");
262     libmakefile.writeLine("#");
263     libmakefile.writeLine("# Macro definitions referenced below");
264     libmakefile.writeLine("#");
265     libmakefile.writeLine("empty =");
266     libmakefile.writeLine("space =$(empty) $(empty)");
267           
268     if(stringname.match("ti.targets"))
269     {
271        var rtslibtemp = targetname.lnkOpts.suffix.toString().split("/");
272        var rtslib;
273        for(n=0;n<rtslibtemp.length;n++)
274        {
275           if(rtslibtemp[n].match(".lib"))
276           { 
277              rtslib=rtslibtemp[n];
278           }
279        }
281       libmakefile.writeLine("CC = $("+tooldir+")/bin/"+targetname.cc.cmd +" "+targetname.ccOpts.prefix+" "+targetname.cc.opts);
282       libmakefile.writeLine("AC = $("+tooldir+")/bin/"+targetname.asm.cmd +" "+targetname.asmOpts.prefix+" "+targetname.asm.opts);    
283       libmakefile.writeLine("ARIN = $("+tooldir+")/bin/"+targetname.ar.cmd +" "+targetname.ar.opts);    
284       libmakefile.writeLine("LD = $("+tooldir+")/bin/"+targetname.lnk.cmd +" "+targetname.lnk.opts);   
285       libmakefile.writeLine("RTSLIB = -l $("+tooldir+")/lib/"+rtslib);        
286     }
287     else
288     {
289       print("Error: Non-TI targets are not currently supported ");
290       java.lang.System.exit(1);
292     }
293         
294     libmakefile.writeLine("INCS = -I. -I$(strip $(subst ;, -I,$(subst $(space),\\$(space),$(INCDIR))))");
295     libmakefile.writeLine("OBJEXT = o"+targetname.suffix); 
296     libmakefile.writeLine("AOBJEXT = s"+targetname.suffix);     
297     /* libmakefile.writeLine("INTERNALDEFS = -D"+stringname.replace(/\./g,"_")+" -Dxdc_target_types__=ti/targets/std.h -DMAKEFILE_BUILD -eo.$(OBJEXT) -ea.$(AOBJEXT) -fr=$(@D) -fs=$(@D) -ppa -ppd=$@.dep");*/
298     libmakefile.writeLine("INTERNALDEFS = -D"+stringname.replace(/\./g,"_")+"  -DMAKEFILE_BUILD -eo.$(OBJEXT) -ea.$(AOBJEXT) -fr=$(@D) -fs=$(@D) -ppa -ppd=$@.dep");
299     libmakefile.writeLine("INTERNALLINKDEFS = -o $@ -m $@.map");
300     libmakefile.writeLine("OBJDIR = $(LIBDIR)/" + device.toString() + "/obj");
301    
302     return libmakefile;
306 function makeAddObjects(srcString, makefilename, srcfiles, flags,fileExt, targetName)
308   var  sourcestring = (srcString + fileExt).toString().toUpperCase();
309   var  compileflagstring = sourcestring + "FLAGS";
310   var  objectliststring = sourcestring + "OBJS";
311   /* List all the source files */
312   makefilename.writeLine("\n#List the "+srcString+" Files");  
313   makefilename.writeLine(sourcestring + "= \\");
314   for(var i=0;i<srcfiles.length-1;i++)
315   {
316     makefilename.writeLine("    "+srcfiles[i]+"\\");
317   }
318     makefilename.writeLine("    "+srcfiles[i]+"\n");
319     
320  /* Flags for the source files */
321  makefilename.writeLine("# FLAGS for the "+srcString+" Files"); 
322  var compileflags="";
323  if(fileExt == "asm" && flags.aopts != undefined)
324  {
325    compileflags+=" "+flags.aopts;
326  }
327  else if((fileExt == "c" || fileExt == "sa")&& flags.copts != undefined)
328  {
329    compileflags+=" "+flags.copts;
330  } 
332  if(flags.incs != undefined)
333  {
334    compileflags+=" "+flags.incs;
335  }
338  makefilename.writeLine(compileflagstring+" = "+compileflags +" \n");     
339  makefilename.writeLine("# Make Rule for the "+srcString+" Files");  
340  
341  makefilename.writeLine(objectliststring +" = $(patsubst %."+fileExt+", $(OBJDIR)/%.$(OBJEXT), $(" + sourcestring + "))"); 
342  makefilename.writeLine("\n$("+objectliststring+"): $(OBJDIR)/%.$(OBJEXT): %."+fileExt);   
343  if(fileExt == "c")
344  { 
345    makefilename.writeLine("\t-@echo cl"+targetName.suffix +" $< ...");     
346  }
347  else
348  {
349    makefilename.writeLine("\t-@echo asm"+targetName.suffix +" $< ...");      
350  }
351  makefilename.writeLine("\tif [ ! -d $(@D) ]; then $(MKDIR) $(@D) ; fi;");           
352  
353  if(fileExt == "c")
354  {
355    makefilename.writeLine("\t$(RM) $@.dep");
356    makefilename.writeLine("\t$(CC) $("+compileflagstring+") $(INTERNALDEFS) $(INCS) -fc $< ");
357    makefilename.writeLine("\t-@$(CP) $@.dep $@.pp; \\");
358    makefilename.writeLine("         $(SED) -e 's/#.*//' -e 's/^[^:]*: *//' -e 's/ *\\\\$$//' \\");
359    makefilename.writeLine("             -e '/^$$/ d' -e 's/$$/ :/' < $@.pp >> $@.dep; \\");
360    makefilename.writeLine("         $(RM) $@.pp ");
361  }
362  else if(fileExt == "asm")
363  {
364    makefilename.writeLine("\t$(AC) $("+compileflagstring+") $(INTERNALDEFS) $(INCS) -fa $< ");
365  }
366  else if(fileExt == "sa")
367  {
368    makefilename.writeLine("\t$(AC) $("+compileflagstring+") $(INTERNALDEFS) $(INCS) $< ");
369  }
370    makefilename.writeLine("\n#Create Empty rule for dependency");
371    makefilename.writeLine("$("+objectliststring+"):"+makefilename.$private.fd);
372    makefilename.writeLine(makefilename.$private.fd+":");
373    makefilename.writeLine("\n#Include Depedency for "+srcString+" Files");
374    makefilename.writeLine("ifneq (clean,$(MAKECMDGOALS))");
375    makefilename.writeLine(" -include $("+objectliststring+":%.$(OBJEXT)=%.$(OBJEXT).dep)");
376    makefilename.writeLine("endif");
377  
380 /**************************************************************************
381  * FUNCTION NAME : buildLibrary
382  **************************************************************************
383  * DESCRIPTION   :
384  *  Utility function which will build a specific library
385  **************************************************************************/
386 var makefilelocal;
387 function buildLibrary (device, libOptions, libName, target, libFiles) 
389     var lldFullLibraryPath = "./lib/" + device.toString() + "/" + libName;
390     var lldFullBuildPath = "./build/" + device.toString() + "/" + libName;
391     var lldFullLibraryPathMake = "$(LIBDIR)/" + device.toString() + "/" + libName;
393     /* Create Main make file in the root of package folder */
394     makefilelocal = createMake(makefilelocal);
396     /* Write the rule to make library in main makefile */
397     lib = lldFullBuildPath+".a"+target.suffix;
398     libMake = lldFullLibraryPathMake+".a"+target.suffix;
399     var objectPath= "./package/"+lldFullBuildPath;
400     makefilelocal.writeLine("\n\n# Make rule to create "+libMake+" library");
401     makefilelocal.writeLine(".libraries: "+ libMake);
402     makefilelocal.writeLine(libMake+": FORCE\n\t$(MAKE) -f "+lib+".mk $@");                                 
404     /* Create Library make file in the lib folder */
405     var makefilelib= createLibMake(device, lib+".mk",target,objectPath);  
407     /* Rule to clean library in main makefile */
408     makefilelocal.writeLine("# Rule to clean "+libMake+" library");                                              
409     makefilelocal.writeLine("clean ::\n\t$(RM) "+ libMake);                                          
410     librule="\n\n"+libMake+" :";
412     /* Add files to be compiled */
413     /* Separate out the C and assembly files */
414     var cfiles= new Array();
415     var afiles= new Array();
416     var safiles= new Array();
417     for each(var srcFile in libFiles)
418     {
419         var srcFile=String(srcFile);
420         var dot = srcFile.lastIndexOf(".");
421         var extension = srcFile.substr(dot,srcFile.length);      
422         if(extension == ".c")
423         {
424           cfiles.push(srcFile);
425         }
426         else if(extension == ".sa")
427         {
428           safiles.push(srcFile);
429         }
430         else if(extension == ".asm")
431         {
432            afiles.push(srcFile);
433         }
434         else
435         {
436            print("ERROR: Unsupported file extension");
437            java.lang.System.exit(1);
438         }
439      }
440     if(cfiles.length > 0)
441     {                                                
442       makeAddObjects("COMMONSRC",makefilelib,cfiles,libOptions,"c",target);
443       librule += " $(COMMONSRCCOBJS)";                   
444     }
445     if(afiles.length > 0)
446     {                                                
447       makeAddObjects("COMMONSRC",makefilelib,afiles,libOptions,"asm",target);
448       librule += " $(COMMONSRCASMOBJS)";                   
449     }
450     if(safiles.length > 0)
451     {                                                
452       makeAddObjects("COMMONSRC",makefilelib,safiles,libOptions,"sa",target);
453       librule += " $(COMMONSRCSAOBJS)";                   
454     }
456     makefilelib.writeLine(librule);
457     makefilelib.writeLine("\t@echo archiving $? into $@ ...");
458     makefilelib.writeLine("\tif [ ! -d $(LIBDIR)/" + device.toString() + " ]; then $(MKDIR) $(LIBDIR)/" + device.toString() + " ; fi;"); 
459                 makefilelib.writeLine("\t$(ARIN) $@ $?");
460                 makefilelib.close();   
462     
463     /* Create the Epilogue; which executes after all the builds are completed. 
464      * This is used to generate the benchmark information for the built library. 
465      * Also add the benchmarking information file to the package. */
466      /*
467     Pkg.makeEpilogue += ".libraries: benchmarking_"  + device + "_" + target.suffix + "\n";
468     Pkg.makeEpilogue += "benchmarking_" + device + "_" + target.suffix + ":";
469     Pkg.makeEpilogue += "\n\t ofd6x -x " + lldFullLibraryPath + ".a" + target.suffix + " > tmp.xml";
470     Pkg.makeEpilogue += "\n\t sectti tmp.xml > " + lldFullLibraryPath + ".a" + target.suffix +  "_size.txt";
471     Pkg.makeEpilogue += "\n\t $(RM) tmp.xml\n\n";
472     Pkg.otherFiles[Pkg.otherFiles.length++] = lldFullLibraryPath + ".a" + target.suffix + "_size.txt";
473     */
474     Pkg.otherFiles[Pkg.otherFiles.length++] = lldFullBuildPath + ".a" + target.suffix + ".mk";
475     Pkg.otherFiles[Pkg.otherFiles.length++] = lldFullLibraryPath + ".a" + target.suffix;
477     /* We need to clean after ourselves; extend the 'clean' target to take care of this. */
478     Pkg.makeEpilogue += "clean::\n";
479     Pkg.makeEpilogue += "\t$(RM) " + lldFullBuildPath + ".a" + target.suffix + "_size.txt\n";
480     Pkg.makeEpilogue += "\t$(RMDIR) " + "$(LIBDIR)/" + device.toString() + " \n\n";
482     return lib;
485 /**************************************************************************
486  * FUNCTION NAME : createMiniPkg
487  **************************************************************************
488  * DESCRIPTION   :
489  *  The function is responsible for creating the mini tar package
490  *  The MINI package has the following files:- 
491  *      - Driver Source Files. 
492  *      - Header files (exported and internal driver files) 
493  *      - Simple Makefiles. 
494  **************************************************************************/
495 function createMiniPkg(pkgName)
497     /* Get the package Name. */
498     var packageRepository = xdc.getPackageRepository(Pkg.name);
499     var packageBase       = xdc.getPackageBase(Pkg.name);
500     var packageName       = packageBase.substring(packageRepository.length + 1);
502     /* Convert the Package name by replacing back slashes with forward slashes. This is required because
503      * otherwise with long names the tar is unable to change directory. */
504     var newPkgName = new java.lang.String(packageRepository);
505     var newPkgRep  = newPkgName.replace('\\', '/');
507     /* Step1: Create the MINI Package and add the simple Big and Little Endian Makefiles to the package */
508     Pkg.makeEpilogue += "release: mini_pkg\n";
509     Pkg.makeEpilogue += "mini_pkg:\n";
510     Pkg.makeEpilogue += "\t tar -C " + '"' + newPkgRep + '"' + " -cf packages/" + pkgName + "_mini.tar " +
511                         packageName + "simpleC66LE.mak " +
512                         packageName + "simpleC66BE.mak\n";
514     /* Step2: Add the exported header files to the package */
515     var includeFiles = listAllFiles (".h", ".", false);
516     for (var k = 0 ; k < includeFiles.length; k++)
517         Pkg.makeEpilogue += "\t tar -C " + '"' + newPkgRep + '"' + " -rf packages/" + pkgName + "_mini.tar " + 
518                         packageName + includeFiles[k] + "\n";
520     /* Step3: Add the driver source files to the package; the filter should have generated a source listing */
521     Pkg.makeEpilogue += "\t tar -C " + '"' + newPkgRep + '"' + " -T src.lst -rf packages/" + pkgName + "_mini.tar " + "\n";
523     /* Ensure that we clean up the mini package */
524     Pkg.makeEpilogue += "clean::\n";
525     Pkg.makeEpilogue += "\t $(RM) packages/" + pkgName + "_mini.tar\n";