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