build support for Keystone1
[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 : 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 }
82 function createMake(makefile)
83 {
84     /* Create the main make file */
85     var fileModule = xdc.module('xdc.services.io.File');
86     if(makefile==undefined)
87     {
88       try{
89           makefile = fileModule.open("makefile", "w");
90          } catch (ex)
91          {
92            print("makefile cannot be written to. Please check Writing Permissions.");
93            java.lang.System.exit(1);
94          }   
95     
96       Pkg.makePrologue += "\ninclude makefile\n"; 
97          
98       Pkg.makeEpilogue += "\nclean::\n\t-$(RM)  makefile\n";
99       makefile.writeLine("#*******************************************************************************");
100       makefile.writeLine("#* FILE PURPOSE: Top level makefile for Creating Component Libraries");
101       makefile.writeLine("#*******************************************************************************");
102       makefile.writeLine("#* FILE NAME: makefile");
103       makefile.writeLine("#*");
104       makefile.writeLine("#* DESCRIPTION: Defines Compiler tools paths, libraries , Build Options ");
105       makefile.writeLine("#*");
106       makefile.writeLine("#*");
107       makefile.writeLine("#*******************************************************************************");
108       makefile.writeLine("#*");
109       makefile.writeLine("# (Mandatory) Specify where various tools are installed.");
111       var file = xdc.module('xdc.services.io.File');
112     
113       var xdcTargetType = java.lang.System.getenv("XDCTARGET");
114       var toolsBaseDir = java.lang.System.getenv("XDCCGROOT");   
115       
116       makefile.writeLine("\n# Output for prebuilt generated libraries");
117       makefile.writeLine("export LIBDIR ?= ./lib");
118       /* use sectti.exe from path */
119       makefile.writeLine("export SECTTI ?= sectti");
121       /* Create INCDIR from XDCPATH */
122     
123       /* copy the environment array from the current environment */
124       var env   = java.lang.System.getenv();
125       var getxdcpath=String(java.lang.System.getenv("XDCPATH"));
126       getxdcpath= getxdcpath.replace(/\\/g,"/");
127       var keys  = env.keySet().toArray();
128       var key;
129       var stat={};
130       var env_j=[];
131       var listxdcpath = new Array();
132       for (var i = 0; i < keys.length; i++) {
133            key = String(keys[i]);
134            if((key.match("INSTALL_PATH")) || (key.match("INSTALLDIR")))
135            {
136              var keyPath=String(env.get(key));
137              keyPath=keyPath.replace(/\\/g,"/");
138              var file = xdc.module('xdc.services.io.File');
139              keyPath=file.getDOSPath(keyPath);
140              if(getxdcpath.toString().match(keyPath))
141              {
142                  listxdcpath.push({keyname: key,keypath: keyPath});
143                  while(getxdcpath.toString().match(keyPath))
144                  {
145                    getxdcpath=getxdcpath.toString().replace(keyPath,"$("+key+")");
146                  }
147              }
148            }
149     
150      }
151        var pkgroot="..";
152        for (var i = Pkg.name.split('.').length; i > 1; i--) {
153               pkgroot+="/..";
154           }
155         
156       makefile.writeLine("\n# ROOT Directory");        
157       makefile.writeLine("export ROOTDIR := "+pkgroot);
158     
159       makefile.writeLine("\n# INCLUDE Directory");
160       makefile.writeLine("export INCDIR := "+getxdcpath+";$(ROOTDIR);$(C6X_GEN_INSTALL_PATH)/include");       
161     
162       makefile.writeLine("\n# Common Macros used in make");  
163       makefile.writeLine("\nifndef RM");     
164       makefile.writeLine("export RM = rm -f");
165       makefile.writeLine("endif");        
166     
167       makefile.writeLine("\nifndef CP");     
168       makefile.writeLine("export CP = cp -p");    
169       makefile.writeLine("endif");    
170         
171       makefile.writeLine("\nexport MKDIR = mkdir -p");
172     
173       makefile.writeLine("\nifndef RMDIR");         
174       makefile.writeLine("export RMDIR = rm -rf");
175       makefile.writeLine("endif");        
176     
177       makefile.writeLine("\nifndef SED"); 
178       makefile.writeLine("export SED = sed");    
179       makefile.writeLine("endif");    
180     
181       makefile.writeLine("\nifndef MAKE"); 
182       makefile.writeLine("export MAKE = make");    
183       makefile.writeLine("endif");        
185       makefile.writeLine("\n# PHONY Targets");                
186       makefile.writeLine(".PHONY: all clean cleanall ");    
187       
188       makefile.writeLine("\n# FORCE Targets");                
189       makefile.writeLine("FORCE: ");          
190       
191       makefile.writeLine("\n# all rule");                
192       makefile.writeLine("all: .executables");           
193       makefile.writeLine(".executables: .libraries");
194       makefile.writeLine(".libraries:");
195       
196       makefile.writeLine("\n# Clean Rule");          
197       makefile.writeLine("clean:: clean_package");                  
198       makefile.writeLine("# Clean Top Level Object Directory ");          
199       makefile.writeLine("clean_package :\n\t$(RMDIR) $(LIBDIR)/*/");      
200       makefile.writeLine("\t$(RMDIR) package/cfg");            
201    }
202    else
203    {
204      try{
205           makefile = fileModule.open("makefile", "a");
206          } catch (ex)
207          {
208            print("makefile cannot be written to. Please check Writing Permissions.");
209            java.lang.System.exit(1);
210          }  
211     
212     }
214  return makefile;
217 function createLibMake(device, makelibname,targetname, objectPath)
219    var tooldir;
220    var stringname=String(targetname).replace("(xdc.bld.ITarget.Module)","");
221    if(stringname.match("ARM11"))
222    {
223      tooldir="TI_ARM11_GEN_INSTALL_PATH"; 
224    }
225    else
226    {
227      tooldir="C6X_GEN_INSTALL_PATH";
228    }
229    switch(stringname)
230    {
231     case String(C66LE):
232       targetname=C66LE;
233       break;
234     case String(C66BE):
235       targetname=C66BE;
236       break;
237     case String(C67LE):
238       targetname=C67LE;
239       break;
241    }
242     var fileModule = xdc.module('xdc.services.io.File');
243     try{
244      var dstFile = new java.io.File(makelibname);
245      dstFile.getParentFile().mkdirs();    
246      libmakefile = fileModule.open(makelibname, "w");
247      /* Add to Archive list */
248     } catch (ex)
249     {
250      print(makelibname+" cannot be written to. Please check Writing Permissions.");
251      java.lang.System.exit(1);
252     }   
253     libmakefile.writeLine("#*******************************************************************************");
254     libmakefile.writeLine("#* FILE PURPOSE: Lower level makefile for Creating Component Libraries");
255     libmakefile.writeLine("#*******************************************************************************");
256     libmakefile.writeLine("#* FILE NAME: "+makelibname);
257     libmakefile.writeLine("#*");
258     libmakefile.writeLine("#* DESCRIPTION: Defines Source Files, Compilers flags and build rules");
259     libmakefile.writeLine("#*");
260     libmakefile.writeLine("#*");
261     libmakefile.writeLine("#*******************************************************************************");
262     libmakefile.writeLine("#");
263     libmakefile.writeLine("");
264     libmakefile.writeLine("#");
265     libmakefile.writeLine("# Macro definitions referenced below");
266     libmakefile.writeLine("#");
267     libmakefile.writeLine("empty =");
268     libmakefile.writeLine("space =$(empty) $(empty)");
269   
270     if(stringname.match("ti.targets"))
271     {
273        var rtslibtemp = targetname.lnkOpts.suffix.toString().split("/");
274        var rtslib;
275        for(n=0;n<rtslibtemp.length;n++)
276        {
277           if(rtslibtemp[n].match(".lib"))
278           { 
279              rtslib=rtslibtemp[n];
280           }
281        }
283       libmakefile.writeLine("CC = $("+tooldir+")/bin/"+targetname.cc.cmd +" "+targetname.ccOpts.prefix+" "+targetname.cc.opts);
284       libmakefile.writeLine("AC = $("+tooldir+")/bin/"+targetname.asm.cmd +" "+targetname.asmOpts.prefix+" "+targetname.asm.opts);    
285       libmakefile.writeLine("ARIN = $("+tooldir+")/bin/"+targetname.ar.cmd +" "+targetname.ar.opts);    
286       libmakefile.writeLine("LD = $("+tooldir+")/bin/"+targetname.lnk.cmd +" "+targetname.lnk.opts);   
287       libmakefile.writeLine("RTSLIB = -l $("+tooldir+")/lib/"+rtslib);        
288     }
289     else
290     {
291       print("Error: Non-TI targets are not currently supported ");
292       java.lang.System.exit(1);
294     }
296     libmakefile.writeLine("INCS = -I. -I$(strip $(subst ;, -I,$(subst $(space),\\$(space),$(INCDIR))))");
297     libmakefile.writeLine("OBJEXT = o"+targetname.suffix); 
298     libmakefile.writeLine("AOBJEXT = s"+targetname.suffix);     
299     /* 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");*/
300     libmakefile.writeLine("INTERNALDEFS = -D"+stringname.replace(/\./g,"_")+"  -DMAKEFILE_BUILD -eo.$(OBJEXT) -ea.$(AOBJEXT) -fr=$(@D) -fs=$(@D) -ppa -ppd=$@.dep");
301     libmakefile.writeLine("INTERNALLINKDEFS = -o $@ -m $@.map");
302     libmakefile.writeLine("OBJDIR = $(LIBDIR)/" + device.toString() + "/obj");
303     libmakefile.writeLine("DEVOBJDIR = $(LIBDIR)/" + device.toString() + "/obj");
304    
305  return libmakefile;
309 function makeAddObjects(srcString, makefilename, srcfiles, flags,fileExt, targetName, objDir)
311   var  sourcestring = (srcString + fileExt).toString().toUpperCase();
312   var  compileflagstring = sourcestring + "FLAGS";
313   var  objectliststring = sourcestring + "OBJS";
314   /* List all the source files */
315   makefilename.writeLine("\n#List the "+srcString+" Files");  
316   makefilename.writeLine(sourcestring + "= \\");
317   for(var i=0;i<srcfiles.length-1;i++)
318   {
319     makefilename.writeLine("    "+srcfiles[i]+"\\");
320   }
321     makefilename.writeLine("    "+srcfiles[i]+"\n");
322     
323  /* Flags for the source files */
324  makefilename.writeLine("# FLAGS for the "+srcString+" Files"); 
325  var compileflags="";
326  if(fileExt == "asm" && flags.aopts != undefined)
327  {
328    compileflags+=" "+flags.aopts;
329  }
330  else if((fileExt == "c" || fileExt == "sa")&& flags.copts != undefined)
331  {
332    compileflags+=" "+flags.copts;
333  } 
335  if(flags.incs != undefined)
336  {
337    compileflags+=" "+flags.incs;
338  }
341  makefilename.writeLine(compileflagstring+" = "+compileflags +" \n");     
342  makefilename.writeLine("# Make Rule for the "+srcString+" Files");  
343  
344  makefilename.writeLine(objectliststring +" = $(patsubst %."+fileExt+", "+objDir+"/%.$(OBJEXT), $(" + sourcestring + "))"); 
345  makefilename.writeLine("\n$("+objectliststring+"): "+objDir+"/%.$(OBJEXT): %."+fileExt);   
346  if(fileExt == "c")
347  { 
348    makefilename.writeLine("\t-@echo cl"+targetName.suffix +" $< ...");     
349  }
350  else
351  {
352    makefilename.writeLine("\t-@echo asm"+targetName.suffix +" $< ...");      
353  }
354  makefilename.writeLine("\tif [ ! -d $(@D) ]; then $(MKDIR) $(@D) ; fi;");           
355  
356  if(fileExt == "c")
357  {
358    makefilename.writeLine("\t$(RM) $@.dep");
359    makefilename.writeLine("\t$(CC) $("+compileflagstring+") $(INTERNALDEFS) $(INCS) -fc $< ");
360    makefilename.writeLine("\t-@$(CP) $@.dep $@.pp; \\");
361    makefilename.writeLine("         $(SED) -e 's/#.*//' -e 's/^[^:]*: *//' -e 's/ *\\\\$$//' \\");
362    makefilename.writeLine("             -e '/^$$/ d' -e 's/$$/ :/' < $@.pp >> $@.dep; \\");
363    makefilename.writeLine("         $(RM) $@.pp ");
364  }
365  else if(fileExt == "asm")
366  {
367    makefilename.writeLine("\t$(AC) $("+compileflagstring+") $(INTERNALDEFS) $(INCS) -fa $< ");
368  }
369  else if(fileExt == "sa")
370  {
371    makefilename.writeLine("\t$(AC) $("+compileflagstring+") $(INTERNALDEFS) $(INCS) $< ");
372  }
373    makefilename.writeLine("\n#Create Empty rule for dependency");
374    makefilename.writeLine("$("+objectliststring+"):"+makefilename.$private.fd);
375    makefilename.writeLine(makefilename.$private.fd+":");
376    makefilename.writeLine("\n#Include Depedency for "+srcString+" Files");
377    makefilename.writeLine("ifneq (clean,$(MAKECMDGOALS))");
378    makefilename.writeLine(" -include $("+objectliststring+":%.$(OBJEXT)=%.$(OBJEXT).dep)");
379    makefilename.writeLine("endif");
380  
383 /**************************************************************************
384  * FUNCTION NAME : buildLibrary
385  **************************************************************************
386  * DESCRIPTION   :
387  *  Utility function which will build a specific library
388  **************************************************************************/
389 var makefilelocal;
390 function buildLibrary (socName, isSoc, libOptions, libName, target, libFiles) 
392     var targetDir;
393     var objExtDir;
394     
395     if (target.name == "A15F")
396     {
397         targetDir = "armv7";
398     }
399     else if (target.name == "A9F")
400     {
401         targetDir = "armv7";
402     }
403     else if (target.name == "A8F")
404     {
405         targetDir = "armv7";
406     }
407     else if (target.name == "M4")
408     {
409         targetDir = "m4";
410     }
411     else
412     {
413         targetDir = "c66";
414     }
415     
416     /* Derive the operating system and soc names */
417     if (isSoc == "true") {
418         var libNameExp = libName+"."+socName;
419         targetDir = socName+"/"+targetDir;
420         objExtDir = "soc";
421     }
422     else  {
423         var libNameExp = libName;
424         objExtDir = "all";
425     }
427     var lldFullLibraryPath = "./lib/" + targetDir +"/" + libNameExp;
428     var lldFullBuildPath = "./build/" + targetDir +"/" + libNameExp;
429     var lldFullLibraryPathMake = "$(LIBDIR)/" + targetDir +"/" + libNameExp;
431     /* Create Main make file in the root of package folder */
432     makefilelocal = createMake(makefilelocal);
434     /* Write the rule to make library in main makefile */
435     lib = lldFullBuildPath+".a"+target.suffix;
436     libMake = lldFullLibraryPathMake+".a"+target.suffix;
437     var objectPath= "./package/"+lldFullBuildPath;
438     makefilelocal.writeLine("\n\n# Make rule to create "+libMake+" library");
439     makefilelocal.writeLine(".libraries: "+ libMake);
440     makefilelocal.writeLine(libMake+": FORCE\n\t$(MAKE) -f "+lib+".mk $@");                                 
442     /* Create Library make file in the lib folder */
443     var makefilelib= createLibMake(socName, lib+".mk",target,objectPath);  
445     /* Rule to clean library in main makefile */
446     makefilelocal.writeLine("# Rule to clean "+libMake+" library");                                              
447     makefilelocal.writeLine("clean ::\n\t$(RM) "+ libMake);                                          
448     librule="\n\n"+libMake+" :";
450     /* Add files to be compiled */
451     /* Separate out the C and assembly files */
452     var cfiles= new Array();
453     var afiles= new Array();
454     var safiles= new Array();
455     for each(var srcFile in libFiles)
456     {
457         var srcFile=String(srcFile);
458         var dot = srcFile.lastIndexOf(".");
459         var extension = srcFile.substr(dot,srcFile.length);      
460         if(extension == ".c")
461         {
462           cfiles.push(srcFile);
463         }
464         else if(extension == ".sa")
465         {
466           safiles.push(srcFile);
467         }
468         else if(extension == ".asm")
469         {
470            afiles.push(srcFile);
471         }
472         else
473         {
474            print("ERROR: Unsupported file extension");
475            java.lang.System.exit(1);
476         }
477      }
478     if(cfiles.length > 0)
479     {                                                
480       makeAddObjects("COMMONSRC",makefilelib,cfiles,libOptions,"c",target, "$(OBJDIR)");
481       librule += " $(COMMONSRCCOBJS)";                   
482     }
483     if(afiles.length > 0)
484     {                                                
485       makeAddObjects("COMMONSRC",makefilelib,afiles,libOptions,"asm",target, "$(OBJDIR)");
486       librule += " $(COMMONSRCASMOBJS)";                   
487     }
488     if(safiles.length > 0)
489     {                                                
490       makeAddObjects("COMMONSRC",makefilelib,safiles,libOptions,"sa",target, "$(OBJDIR)");
491       librule += " $(COMMONSRCSAOBJS)";                   
492     }
494     makefilelib.writeLine(librule);
495     makefilelib.writeLine("\t@echo archiving $? into $@ ...");
496     makefilelib.writeLine("\tif [ ! -d $(LIBDIR)/"+targetDir+" ]; then $(MKDIR) $(LIBDIR)/"+targetDir+" ; fi;"); 
497     makefilelib.writeLine("\t$(ARIN) $@ $?");
498     makefilelib.close();   
500     /* Create the Epilogue; which executes after all the builds are completed. 
501      * This is used to generate the benchmark information for the built library. 
502      * Also add the benchmarking information file to the package. */
504     /* Put the temp file in object directory since javascript doesn't have a built in tmpname, 
505      * and don't want --jobs=# with # > 1 to result in collisions */
506     var libFullName = lldFullLibraryPath + ".a" + target.suffix;
507     var tempFile = libFullName + ".xml";
508     Pkg.makeEpilogue += ".libraries: " + libFullName +  "_size.txt\n";
509     Pkg.makeEpilogue += libFullName +  "_size.txt: " + libFullName + "\n";
510     if ( java.lang.String(target.name).contains('66') )
511     {    
512         Pkg.makeEpilogue += "\n\t $(C6X_GEN_INSTALL_PATH)/bin/ofd6x -x " + libFullName + " > " + tempFile;
513         Pkg.makeEpilogue += "\n\t $(SECTTI) " + tempFile + " > " + libFullName +  "_size.txt";
514         Pkg.makeEpilogue += "\n\t $(RM) " + tempFile + "\n\n";
515     }   
516     else if (target.name == "M4")
517     {
518         Pkg.makeEpilogue += "\n\t $(TOOLCHAIN_PATH_M4)/bin/armofd -x " + libFullName + " > " + tempFile;
519         Pkg.makeEpilogue += "\n\t $(SECTTI) " + tempFile + " > " + libFullName +  "_size.txt";
520         Pkg.makeEpilogue += "\n\t $(RM) " + tempFile + "\n\n";
521     }
522     else
523     {
524         Pkg.makeEpilogue += "\n\t $(TOOLCHAIN_PATH_A15)/bin/$(CROSS_TOOL_PRFX)size " + libFullName + " > " + libFullName + "_size.txt";
525     }                
526     Pkg.otherFiles[Pkg.otherFiles.length++] = lldFullLibraryPath + ".a" + target.suffix + "_size.txt";
527     Pkg.otherFiles[Pkg.otherFiles.length++] = lldFullBuildPath + ".a" + target.suffix + ".mk";
528     Pkg.otherFiles[Pkg.otherFiles.length++] = lldFullLibraryPath + ".a" + target.suffix;
530     /* We need to clean after ourselves; extend the 'clean' target to take care of this. */
531     Pkg.makeEpilogue += "\nclean::\n";
532     Pkg.makeEpilogue += "\t$(RM) " + lldFullBuildPath + ".a" + target.suffix + "_size.txt\n";    
533     Pkg.makeEpilogue += "\t$(RMDIR) " + "$(LIBDIR)/" + targetDir + "/ \n\n";
535     return lib;