d6d3811864ea4c0f8926c127b7a2fb67fde2412c
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-2015, 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 }
95 Pkg.makePrologue += "\ninclude makefile\n";
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');
112 var xdcTargetType = java.lang.System.getenv("XDCTARGET");
113 var toolsBaseDir = java.lang.System.getenv("XDCCGROOT");
115 makefile.writeLine("\n# Output for prebuilt generated libraries");
116 makefile.writeLine("export LIBDIR ?= ./lib");
117 /* use sectti.exe from path */
118 makefile.writeLine("export SECTTI ?= sectti");
120 /* Create INCDIR from XDCPATH */
122 /* copy the environment array from the current environment */
123 var env = java.lang.System.getenv();
124 var getxdcpath=String(java.lang.System.getenv("XDCPATH"));
125 getxdcpath= getxdcpath.replace(/\\/g,"/");
126 var keys = env.keySet().toArray();
127 var key;
128 var stat={};
129 var env_j=[];
130 var listxdcpath = new Array();
131 for (var i = 0; i < keys.length; i++) {
132 key = String(keys[i]);
133 if((key.match("INSTALL_PATH")) || (key.match("INSTALLDIR")))
134 {
135 var keyPath=String(env.get(key));
136 keyPath=keyPath.replace(/\\/g,"/");
137 var file = xdc.module('xdc.services.io.File');
138 keyPath=file.getDOSPath(keyPath);
139 if(getxdcpath.toString().match(keyPath))
140 {
141 listxdcpath.push({keyname: key,keypath: keyPath});
142 while(getxdcpath.toString().match(keyPath))
143 {
144 getxdcpath=getxdcpath.toString().replace(keyPath,"$("+key+")");
145 }
146 }
147 }
149 }
150 var pkgroot="..";
151 for (var i = Pkg.name.split('.').length; i > 1; i--) {
152 pkgroot+="/..";
153 }
155 makefile.writeLine("\n# ROOT Directory");
156 makefile.writeLine("export ROOTDIR := "+pkgroot);
158 makefile.writeLine("\n# INCLUDE Directory");
159 makefile.writeLine("export INCDIR := "+getxdcpath+";$(ROOTDIR)");
161 makefile.writeLine("\n# Common Macros used in make");
162 makefile.writeLine("\nifndef RM");
163 makefile.writeLine("export RM = rm -f");
164 makefile.writeLine("endif");
166 makefile.writeLine("\nifndef CP");
167 makefile.writeLine("export CP = cp -p");
168 makefile.writeLine("endif");
170 makefile.writeLine("\nexport MKDIR = mkdir -p");
172 makefile.writeLine("\nifndef RMDIR");
173 makefile.writeLine("export RMDIR = rm -rf");
174 makefile.writeLine("endif");
176 makefile.writeLine("\nifndef SED");
177 makefile.writeLine("export SED = sed");
178 makefile.writeLine("endif");
180 makefile.writeLine("\nifndef MAKE");
181 makefile.writeLine("export MAKE = make");
182 makefile.writeLine("endif");
184 makefile.writeLine("\n# PHONY Targets");
185 makefile.writeLine(".PHONY: all clean cleanall ");
187 makefile.writeLine("\n# FORCE Targets");
188 makefile.writeLine("FORCE: ");
190 makefile.writeLine("\n# all rule");
191 makefile.writeLine("all: .executables");
192 makefile.writeLine(".executables: .libraries");
193 makefile.writeLine(".libraries:");
195 makefile.writeLine("\n# Clean Rule");
196 makefile.writeLine("clean:: clean_package");
197 makefile.writeLine("# Clean Top Level Object Directory ");
198 makefile.writeLine("clean_package:")
199 for each (var libdir in devices)
200 {
201 makefile.writeLine("\t$(RMDIR) $(LIBDIR)/"+libdir.toString()+"/*/");
202 }
203 makefile.writeLine("\t$(RMDIR) package/cfg");
204 }
205 else
206 {
207 try{
208 makefile = fileModule.open("makefile", "a");
209 } catch (ex)
210 {
211 print("makefile cannot be written to. Please check Writing Permissions.");
212 java.lang.System.exit(1);
213 }
215 }
217 return makefile;
218 }
220 function createLibMake(device, makelibname,targetname, objectPath)
221 {
222 var tooldir;
223 var stringname=String(targetname).replace("(xdc.bld.ITarget.Module)","");
224 if(stringname.match("ARM11"))
225 {
226 tooldir="TI_ARM11_GEN_INSTALL_PATH";
227 }
228 else
229 {
230 tooldir="C6X_GEN_INSTALL_PATH";
231 }
232 switch(stringname)
233 {
234 case String(C66LE):
235 targetname=C66LE;
236 break;
237 case String(C66BE):
238 targetname=C66BE;
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)");
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");
304 return libmakefile;
306 }
308 function makeAddObjects(srcString, makefilename, srcfiles, flags,fileExt, targetName)
309 {
310 var sourcestring = (srcString + fileExt).toString().toUpperCase();
311 var compileflagstring = sourcestring + "FLAGS";
312 var objectliststring = sourcestring + "OBJS";
313 /* List all the source files */
314 makefilename.writeLine("\n#List the "+srcString+" Files");
315 makefilename.writeLine(sourcestring + "= \\");
316 for(var i=0;i<srcfiles.length-1;i++)
317 {
318 makefilename.writeLine(" "+srcfiles[i]+"\\");
319 }
320 makefilename.writeLine(" "+srcfiles[i]+"\n");
322 /* Flags for the source files */
323 makefilename.writeLine("# FLAGS for the "+srcString+" Files");
324 var compileflags="";
325 if(fileExt == "asm" && flags.aopts != undefined)
326 {
327 compileflags+=" "+flags.aopts;
328 }
329 else if((fileExt == "c" || fileExt == "sa")&& flags.copts != undefined)
330 {
331 compileflags+=" "+flags.copts;
332 }
334 if(flags.incs != undefined)
335 {
336 compileflags+=" "+flags.incs;
337 }
340 makefilename.writeLine(compileflagstring+" = "+compileflags +" \n");
341 makefilename.writeLine("# Make Rule for the "+srcString+" Files");
343 makefilename.writeLine(objectliststring +" = $(patsubst %."+fileExt+", $(OBJDIR)/%.$(OBJEXT), $(" + sourcestring + "))");
344 makefilename.writeLine("\n$("+objectliststring+"): $(OBJDIR)/%.$(OBJEXT): %."+fileExt);
345 if(fileExt == "c")
346 {
347 makefilename.writeLine("\t-@echo cl"+targetName.suffix +" $< ...");
348 }
349 else
350 {
351 makefilename.writeLine("\t-@echo asm"+targetName.suffix +" $< ...");
352 }
353 makefilename.writeLine("\tif [ ! -d $(@D) ]; then $(MKDIR) $(@D) ; fi;");
355 if(fileExt == "c")
356 {
357 makefilename.writeLine("\t$(RM) $@.dep");
358 makefilename.writeLine("\t$(CC) $("+compileflagstring+") $(INTERNALDEFS) $(INCS) -fc $< ");
359 makefilename.writeLine("\t-@$(CP) $@.dep $@.pp; \\");
360 makefilename.writeLine(" $(SED) -e 's/#.*//' -e 's/^[^:]*: *//' -e 's/ *\\\\$$//' \\");
361 makefilename.writeLine(" -e '/^$$/ d' -e 's/$$/ :/' < $@.pp >> $@.dep; \\");
362 makefilename.writeLine(" $(RM) $@.pp ");
363 }
364 else if(fileExt == "asm")
365 {
366 makefilename.writeLine("\t$(AC) $("+compileflagstring+") $(INTERNALDEFS) $(INCS) -fa $< ");
367 }
368 else if(fileExt == "sa")
369 {
370 makefilename.writeLine("\t$(AC) $("+compileflagstring+") $(INTERNALDEFS) $(INCS) $< ");
371 }
372 makefilename.writeLine("\n#Create Empty rule for dependency");
373 makefilename.writeLine("$("+objectliststring+"):"+makefilename.$private.fd);
374 makefilename.writeLine(makefilename.$private.fd+":");
375 makefilename.writeLine("\n#Include Depedency for "+srcString+" Files");
376 makefilename.writeLine("ifneq (clean,$(MAKECMDGOALS))");
377 makefilename.writeLine(" -include $("+objectliststring+":%.$(OBJEXT)=%.$(OBJEXT).dep)");
378 makefilename.writeLine("endif");
380 }
382 /**************************************************************************
383 * FUNCTION NAME : buildLibrary
384 **************************************************************************
385 * DESCRIPTION :
386 * Utility function which will build a specific library
387 **************************************************************************/
388 var makefilelocal;
389 function buildLibrary (device, libOptions, libName, target, libFiles)
390 {
391 var lldFullLibraryPath = "./lib/" + device.toString() + "/" + libName;
392 var lldFullBuildPath = "./build/" + device.toString() + "/" + libName;
393 var lldFullLibraryPathMake = "$(LIBDIR)/" + device.toString() + "/" + libName;
395 /* Create Main make file in the root of package folder */
396 makefilelocal = createMake(makefilelocal);
398 /* Write the rule to make library in main makefile */
399 lib = lldFullBuildPath+".a"+target.suffix;
400 libMake = lldFullLibraryPathMake+".a"+target.suffix;
401 var objectPath= "./package/"+lldFullBuildPath;
402 makefilelocal.writeLine("\n\n# Make rule to create "+libMake+" library");
403 makefilelocal.writeLine(".libraries: "+ libMake);
404 makefilelocal.writeLine(libMake+": FORCE\n\t$(MAKE) -f "+lib+".mk $@");
406 /* Create Library make file in the lib folder */
407 var makefilelib= createLibMake(device, lib+".mk",target,objectPath);
409 /* Rule to clean library in main makefile */
410 makefilelocal.writeLine("# Rule to clean "+libMake+" library");
411 makefilelocal.writeLine("clean ::\n\t$(RM) "+ libMake);
412 librule="\n\n"+libMake+" :";
414 /* Add files to be compiled */
415 /* Separate out the C and assembly files */
416 var cfiles= new Array();
417 var afiles= new Array();
418 var safiles= new Array();
419 for each(var srcFile in libFiles)
420 {
421 var srcFile=String(srcFile);
422 var dot = srcFile.lastIndexOf(".");
423 var extension = srcFile.substr(dot,srcFile.length);
424 if(extension == ".c")
425 {
426 cfiles.push(srcFile);
427 }
428 else if(extension == ".sa")
429 {
430 safiles.push(srcFile);
431 }
432 else if(extension == ".asm")
433 {
434 afiles.push(srcFile);
435 }
436 else
437 {
438 print("ERROR: Unsupported file extension");
439 java.lang.System.exit(1);
440 }
441 }
442 if(cfiles.length > 0)
443 {
444 makeAddObjects("COMMONSRC",makefilelib,cfiles,libOptions,"c",target);
445 librule += " $(COMMONSRCCOBJS)";
446 }
447 if(afiles.length > 0)
448 {
449 makeAddObjects("COMMONSRC",makefilelib,afiles,libOptions,"asm",target);
450 librule += " $(COMMONSRCASMOBJS)";
451 }
452 if(safiles.length > 0)
453 {
454 makeAddObjects("COMMONSRC",makefilelib,safiles,libOptions,"sa",target);
455 librule += " $(COMMONSRCSAOBJS)";
456 }
458 makefilelib.writeLine(librule);
459 makefilelib.writeLine("\t@echo archiving $? into $@ ...");
460 makefilelib.writeLine("\tif [ ! -d $(LIBDIR)/" + device.toString() + " ]; then $(MKDIR) $(LIBDIR)/" + device.toString() + " ; fi;");
461 makefilelib.writeLine("\t$(ARIN) $@ $?");
462 makefilelib.close();
465 /* Create the Epilogue; which executes after all the builds are completed.
466 * This is used to generate the benchmark information for the built library.
467 * Also add the benchmarking information file to the package. */
469 /* Put the temp file in object directory since javascript doesn't have a built in tmpname,
470 * and don't want --jobs=# with # > 1 to result in collisions */
471 var libFullName = lldFullLibraryPath + ".a" + target.suffix;
472 var tempFile = libFullName + ".xml";
473 Pkg.makeEpilogue += ".libraries: " + libFullName + "_size.txt\n";
474 Pkg.makeEpilogue += libFullName + "_size.txt: " + libFullName + "\n";
475 Pkg.makeEpilogue += "\n\t $(C6X_GEN_INSTALL_PATH)/bin/ofd6x -x " + libFullName + " > " + tempFile;
476 Pkg.makeEpilogue += "\n\t $(SECTTI) " + tempFile + " > " + libFullName + "_size.txt";
477 Pkg.makeEpilogue += "\n\t $(RM) " + tempFile + "\n\n";
478 Pkg.otherFiles[Pkg.otherFiles.length++] = lldFullLibraryPath + ".a" + target.suffix + "_size.txt";
479 Pkg.otherFiles[Pkg.otherFiles.length++] = lldFullLibraryPath + ".a" + target.suffix + ".mk";
481 /* We need to clean after ourselves; extend the 'clean' target to take care of this. */
482 Pkg.makeEpilogue += "clean::\n\t";
483 Pkg.makeEpilogue += "$(RM) " + lldFullLibraryPath + ".a" + target.suffix + "_size.txt\n\n";
485 return lib;
486 }
488 /**************************************************************************
489 * FUNCTION NAME : createMiniPkg
490 **************************************************************************
491 * DESCRIPTION :
492 * The function is responsible for creating the mini tar package
493 * The MINI package has the following files:-
494 * - Driver Source Files.
495 * - Header files (exported and internal driver files)
496 * - Simple Makefiles.
497 **************************************************************************/
498 function createMiniPkg(pkgName)
499 {
500 /* Get the package Name. */
501 var packageRepository = xdc.getPackageRepository(Pkg.name);
502 var packageBase = xdc.getPackageBase(Pkg.name);
503 var packageName = packageBase.substring(packageRepository.length + 1);
505 /* Convert the Package name by replacing back slashes with forward slashes. This is required because
506 * otherwise with long names the tar is unable to change directory. */
507 var newPkgName = new java.lang.String(packageRepository);
508 var newPkgRep = newPkgName.replace('\\', '/');
510 /* Step1: Create the MINI Package and add the simple Big and Little Endian Makefiles to the package */
511 Pkg.makeEpilogue += "release: mini_pkg\n";
512 Pkg.makeEpilogue += "mini_pkg:\n";
513 Pkg.makeEpilogue += "\t tar -C " + '"' + newPkgRep + '"' + " -cf packages/" + pkgName + "_mini.tar " +
514 packageName + "simpleC66LE.mak " +
515 packageName + "simpleC66BE.mak\n";
517 /* Step2: Add the exported header files to the package */
518 var includeFiles = listAllFiles (".h", ".", false);
519 for (var k = 0 ; k < includeFiles.length; k++)
520 Pkg.makeEpilogue += "\t tar -C " + '"' + newPkgRep + '"' + " -rf packages/" + pkgName + "_mini.tar " +
521 packageName + includeFiles[k] + "\n";
523 /* Step3: Add the driver source files to the package; the filter should have generated a source listing */
524 Pkg.makeEpilogue += "\t tar -C " + '"' + newPkgRep + '"' + " -T src.lst -rf packages/" + pkgName + "_mini.tar " + "\n";
526 /* Ensure that we clean up the mini package */
527 Pkg.makeEpilogue += "clean::\n";
528 Pkg.makeEpilogue += "\t $(RM) packages/" + pkgName + "_mini.tar\n";
529 }