]> Gitweb @ Texas Instruments - Open Source Git Repositories - git.TI.com/gitweb - ipc/ipcdev.git/blob - src/ti/sdo/ipc/build/test.bld
Rename: Renamed packages to src to allow application of ipc-j tree commits.
[ipc/ipcdev.git] / src / ti / sdo / ipc / build / test.bld
1 /*
2  * Copyright (c) 2012-2013, Texas Instruments Incorporated
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  *
9  * *  Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  *
12  * *  Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  *
16  * *  Neither the name of Texas Instruments Incorporated nor the names of
17  *    its contributors may be used to endorse or promote products derived
18  *    from this software without specific prior written permission.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
22  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
24  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
25  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
26  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
27  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
28  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
29  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
30  * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31  */
32 /*
33  *  ======== test.bld ========
34  */
36 /*
37  *  "testing.doc" in ti.sysbios.build.doc details specifying, building, and
38  *  running tests. Below are details on the properties supported by tests
39  *  in a package's testArray.
40  *
41  *  ======== testArray ========
42  *  The testArray is used by buildTests in test.bld to generate the makefile
43  *  goals for the tests in this package. The test objects in this array can
44  *  have the following properties:
45  *    name: The name of the test.
46  *    sources: An array of the names of the source files, without the '.c's
47  *    config: The name of the config file, without the '.cfg'
48  *    buildTargets: The names of the targets supported by the test. If this
49  *             property is undefined, the test will be built for all targets,
50  *             so this array is really intended for restricting the test to
51  *             the specified targets.
52  *    noBuildTargets: The names of targets *not* supported by the test.
53  *              The test will be built for all other targets listed in
54  *              Build.targets array. Cannot use buildTargets and noBuildTargets
55  *              for the same test.
56  *    buildPlatforms: The names of the platforms supported by the test. If this
57  *             property is undefined, the test will support all of the
58  *             platforms in the target.platforms[] array in config.bld, so this
59  *             array is really intended for restricting the test to specific
60  *             platforms. When actually building the tests with sm-make, the
61  *             platform to build for is specified using XDCARGS. Only specify
62  *             the platform suffix, not the entire name.
63  *
64  *  Only the test name is required. If none of the other properties are
65  *  specified, they will be inferred from the test name by adding the
66  *  appropriate file extension.
67  *
68  *  The buildTargets and buildPlatforms are really there so that tests whose
69  *  output changes depending on the target or platform can be separated.
70  *
71  */
73 /*
74  *  ======== buildTests ========
75  *  This function generates the makefile goals for all of the
76  *  tests in the testArray parameter. Each test package, in its
77  *  package.bld, should define a testArray, import this file, and
78  *  call buildTests. The second argument is the XDCARGS environment
79  *  variable. In package.bld, just pass 'arguments' as the second
80  *  parameter.
81  */
82 function buildTests(testArray, xdcArgs)
83 {
84     /* The XDCARGS specify which profiles and platforms to build for. */
85     var profiles = getProfiles(xdcArgs);
86     if (profiles.length == 0) {
87         if (Pkg.attrs.profile != null && Pkg.attrs.profile !== undefined) {
88             profiles[0] = Pkg.attrs.profile;
89         }
90         else {
91             profiles[0] = "release";
92         }
93     }
94     var platform = getPlatform(xdcArgs);
96     /*
97      *  'PackageContents.uses' allows us to provide legacy include path
98      *  for the compiler.  This adds '-I<elem>/ti/bios/include' for
99      *  each <elem> in XDCPATH.  This is more portable than using
100      *  copts and $(PKGROOT) which only works if test cases are in same
101      *  repository as BIOS itself (as is the case for avala tree, but not
102      *  for TII/Wipro testing and also for ndk and cudatest trees).
103      */
104     var PackageContents = xdc.useModule('xdc.bld.PackageContents');
105     PackageContents.uses = ["ti/bios/include"];
107     /*  ==== LOOP OVER TESTS ==== */
108     for (var i = 0; i < testArray.length; i++) {
109         var test = testArray[i];
111         /* Infer any missing properties from the name */
112         fillIn(test);
114         /* ==== LOOP OVER TARGETS ==== */
115         for (var j = 0; j < Build.targets.length; j++) {
116             var targ = Build.targets[j];
118             /* If the test doesn't support this target, skip this target. */
119             if (!testSupportsTarget(test, targ)) {
120                 continue;
121             }
123             /*
124              *  ==== platform=default ====
125              *  If we're using the default platform, don't create a platform
126              *  subdirectory for the test.
127              */
128             if (platform.useDefaultPlatform) {
129                 platform.name = targ.platform;
130                 if (!testSupportsPlatform(test, platform.name)) {
131                     platform.name = platformSuffix(targ.platform);
132                     if (!testSupportsPlatform(test, platform.name)) {
133                         continue;
134                     }
135                 }
137                 /* For each profile... */
138                 for (var m = 0; m < profiles.length; m++) {
139                     var profile = profiles[m];
141                     var testName = profile + '/' + test.name;
143                     addTestGoals(test, profile, targ, targ.platform, testName);
144                 }
145             }
146             /*
147              *  ==== platform=<platform> =====
148              *  If a platform was specified explicitly, place it in a platform
149              *  subdirectory, regardless of whether or not it's the default.
150              */
151             else if (platform.useThisPlatform) {
152                 if (!testSupportsPlatform(test, platform.name)) {
153                     continue;
154                 }
156                 /*
157                  * We have the platform suffix but need the full platform. Look
158                  * through the targ.platforms array to see find the full
159                  * platform name. It's possible that this target doesn't support
160                  * this platform, in which case, continue.
161                  */
162                 var fullPlatformName = "";
164                 for (var m = 0; m < targ.platforms.length; m++) {
165                     if (targ.platforms[m].indexOf(platform.name) != -1) {
166                         fullPlatformName = targ.platforms[m];
167                         break;
168                     }
169                 }
170                 /*
171                  * If the platform wasn't found then it's not supported
172                  * by this target.
173                  */
174                 if (fullPlatformName == "") {
175                     continue;
176                 }
178                 /* For each profile... */
179                 for (var m = 0; m < profiles.length; m++) {
180                     var profile = profiles[m];
182                     /* Replace any ':' in platform name with '_' */
183                     platform.name = platform.name.replace(/\:/g, '_');
185                     var testName = platform.name + '/' + profile + '/' +
186                                    test.name;
188                     addTestGoals(test, profile, targ, fullPlatformName,
189                                  testName);
190                 }
191             }
192             /*
193              *  ==== platform=all =====
194              *  If we are building for all platforms, place them ALL in
195              *  platform subdirectories, even the default platform.
196              */
197             else if (platform.useAllPlatforms) {
198                 /* For all of this target's platforms.. */
199                 for (var k = 0; k < targ.platforms.length; k++) {
200                     platform.name = targ.platforms[k];
201                     if (!testSupportsPlatform(test, platform.name)) {
202                         platform.name = platformSuffix(targ.platforms[k]);
203                         if (!testSupportsPlatform(test, platform.name)) {
204                             continue;
205                         }
206                     }
208                     /* For each profile... */
209                     for (var m = 0; m < profiles.length; m++) {
210                         var profile = profiles[m];
212                         /* Replace any '.' in platform name with '_' */
213                         platform.name = platform.name.replace(/\./g, '_');
214                         /* Replace any ':' in platform name with '_' */
215                         platform.name = platform.name.replace(/\:/g, '_');
217                         var testName = platform.name + '/' + profile + '/' +
218                                        test.name;
220                         addTestGoals(test, profile, targ, targ.platforms[k],
221                                      testName);
222                     }
223                 }
224             }
225             else {
226                 print("\nERROR: Test.bld has incorrectly read in the " +
227                       "platform from XDCARGS.\n");
228                 return(-1);
229             }
230         }
231     }
235 /*
236  *  ======== getProfiles ========
237  *  Determines which profiles to build for.
238  *
239  *  Any argument in XDCARGS which does not contain platform= is treated
240  *  as a profile here. This way multiple build profiles can be specified
241  *  just by separating them with a space.
242  */
243 function getProfiles(xdcArgs)
245     /*
246      * cmdlProf[1] gets matched to "whole_program,debug" if
247      * ["abc", "profile=whole_program,debug"] is passed in as xdcArgs
248      */
249     var cmdlProf = (" " + xdcArgs.join(" ") + " ").match(/ profile=([^ ]+) /);
252     if (cmdlProf == null) {
253         /* No profile=XYZ found */
254         return [];
255     }
257     /* Split "whole_program,debug" into ["whole_program", "debug"] */
258     var profiles = cmdlProf[1].split(',');
260     return profiles;
263 /*
264  *  ======== getPlatform ========
265  *  Reads the XDCARGS to determine what platforms to build for. This function
266  *  returns an object containing all of the info about what platforms to build
267  *  for.
268  */
269 function getPlatform(xdcArgs)
271     var platform = new Object();
272     platform.name = "";
273     platform.useDefaultPlatform = true;
274     platform.useAllPlatforms = false;
275     platform.useThisPlatform = false;
277     /*
278      * Look through all of the XDCARGS to see if a platform has been
279      * specified.
280      */
281     for (var i = 0; i < xdcArgs.length; i++) {
282         var index = xdcArgs[i].indexOf("platform=");
283         if (index != -1) {
284             platform.name = xdcArgs[i].substring(index + 9, xdcArgs[i].length);
285             if (platform.name == "default") {
286                 return (platform)
287             }
288             else if (platform.name == "all") {
289                 platform.useDefaultPlatform = false;
290                 platform.useAllPlatforms = true;
291                 return (platform);
292             }
293             else {
294                 platform.useDefaultPlatform = false;
295                 platform.useThisPlatform = true;
296                 return (platform);
297             }
298         }
299     }
301     /* If nothing was specified in XDCARGS, use the default platform. */
302     return (platform);
305 /*
306  *  ======== testSupportsTarget ========
307  *  Returns true if the given test supports the given target.
308  *  If there are no filter arrays, that's taken to mean that
309  *  the test should be built for all targets.
310  *  Only one filter array is allowed.
311  */
312 function testSupportsTarget(test, target)
314     var count = 0;
315     var noFlag = false;
316     var fieldName;
317     var list;
319     for (var f in test) {
320         switch (f) {
321             case 'noBuildTargets':
322             case 'noNameList': {
323                 noFlag = true;
324             }
325             case 'buildTargets':
326             case 'nameList': {
327                 fieldName = 'name';
328                 list = test[f];
329                 count++;
330                 break;
331             }
333             case 'noIsaList': {
334                 noFlag = true;
335             }
336             case 'isaList': {
337                 fieldName = 'isa';
338                 list = test[f];
339                 count++;
340                 break;
341             }
343             case 'noSuffixList': {
344                 noFlag = true;
345             }
346             case 'suffixList': {
347                 fieldName = 'suffix';
348                 list = test[f];
349                 count++;
350                 break;
351             }
352         }
353     }
355     /* if no filters specified, then test supports all targets */
356     if (count == 0) {
357         return (true);
358     }
360     /* make sure only one filter list was specified */
361     if (count != 1) {
362         throw Error("cannot specify more than one filter list, "
363             + "test.name = " + test.name);
364     }
366     /*
367      * add ',' at front and and tail of list and field strings to allow
368      * use of simple match API.  For example, the string is updated to:
369      * ',v5T,v7R,' to allow match of ',v5t,'.
370      */
371     if (String(','+list.toString()+',').match(','+target[fieldName]+',')) {
372         return (!noFlag);
373     }
374     else {
375         return (noFlag);
376     }
378     /* should not get here */
379     throw Error("internal error in testSupportsTarget()");
382 /*
383  *  ======== testSupportsPlatform ========
384  *  This function is to support the buildPlatforms array.
385  */
386 function testSupportsPlatform(test, platform)
388     if ((test.buildPlatforms == null) || (test.buildPlatforms.length == 0)) {
389         return (true);
390     }
392     for (var i = 0; i < test.buildPlatforms.length; i++) {
393         if (test.buildPlatforms[i] == platform) {
394             return(true);
395         }
396     }
398     return (false);
401 /*
402  *  ======== platformSuffix ========
403  *  Parses a full platform name ("ti.platforms.ezdsp2812") to return only the
404  *  the platform suffix ("ezdsp2812"). It does this by returning everything
405  *  after the last period '.' in the platform name.
406  */
407 function platformSuffix(platform)
409     var begin = platform.lastIndexOf('.') + 1;
411     return (platform.substring(begin, platform.length));
415 /*
416  *  ======== addTestGoal ========
417  *  This function calls pkg.addExecutable to create the .test and
418  *  .regress.test goals for the given test, profile, and target.
419  */
420 function addTestGoals(test, profile, target, platform, testName)
422     /* FIRST, specify the basic executable without reference output. */
424     /* Specify the .test goal */
425     var testAttrs = {
426                         execArgs: test.timeout,
427                         args: ""
428                     };
429     /* get the options defined in the test argument */
430     var defs = (test.defs == undefined) ? "" : test.defs;
431     var copts = (test.copts == undefined) ? "" : test.copts;
432     var aopts = (test.aopts == undefined) ? "" : test.aopts;
433     var lopts = (test.lopts == undefined) ? "" : test.lopts;
435     /*
436      *  profileCopts are needed for cudatest.  Since avala builds non tiTargets,
437      *  comment this out for now, and resolve later.
438      */
439     var profileCopts = undefined;
440             //tiTargets[target.name].profiles[profile].compileOpts.copts;
441     var profileAopts = undefined;
442             //tiTargets[target.name].profiles[profile].compileOpts.aopts;
443     var profileLopts = undefined;
444             //tiTargets[target.name].profiles[profile].linkOpts;
445     var profileDefs = undefined;
446             //tiTargets[target.name].profiles[profile].compileOpts.defs;
448     /* verify they are defined */
449     profileCopts = (profileCopts == undefined) ? "" : profileCopts;
450     profileAopts = (profileAopts == undefined) ? "" : profileAopts;
451     profileLopts = (profileLopts == undefined) ? "" : profileLopts;
452     profileDefs = (profileDefs == undefined) ? "" : profileDefs;
454     /* get config arguments, if any */
455     var cfgArgs = (test.cfgArgs == undefined || test.cfgArgs == "") ?
456             "" : test.cfgArgs;
458     /* Specify the executable's properties */
459     var execAttrs = {
460                         defs:  defs + profileDefs,
461                         copts: copts + profileCopts,
462                         aopts: aopts + profileAopts,
463                         lopts: lopts + profileLopts,
464                         cfgScript: test.config + ".cfg",
465                         cfgArgs: test.cfgArgs,
466                         profile: profile,
467                         test: testAttrs,
468                     };
470     var prog = Pkg.addExecutable(testName, target, platform, execAttrs);
472     /* Add the source files */
473     prog.addObjects(test.sources);
475     /*
476      * SECOND, add additional test goals as necessary for regression and for
477      * different sets of arguments.
478      */
480     /* Specify the .regress.test goal */
481     var rTestAttrs = {
482                          groupName: "regress",
483                          refOutput: "golden/" + test.refOutput + ".k",
484                          execArgs: test.timeout,
485                          args: ""
486                      };
488     /* If there are no arguments, then just add the regression goal. */
489     if (test.argsToMain.length == 0) {
490         prog.addTest(rTestAttrs);
491     }
492     /*
493      * If there are arguments, then for each set of arguments, add one test
494      * goal with reference output (the regression test) and one without.
495      */
496     else {
497         for (var i = 0; i < test.argsToMain.length; i++) {
498             testAttrs.args = test.argsToMain[i].args;
499             prog.addTest(testAttrs);
501             rTestAttrs.refOutput = "golden/" + test.argsToMain[i].refOutput + ".k";
502             rTestAttrs.args = test.argsToMain[i].args;
503             prog.addTest(rTestAttrs);
504         }
505     }
509 /*
510  *  ======== fillIn ========
511  *  Fills in any missing test properties (except for targets array)
512  *  using the test name.
513  */
514 function fillIn(test)
516     if ((test.name == undefined) || (test.name == "")) {
517         throw "Each test must have a test.name";
518     }
519     if ((test.sources == undefined) || (test.sources == null)) {
520         test.sources = [test.name];
521     }
522     if ((test.config == undefined) || (test.config == "")) {
523         test.config = test.name;
524     }
525     if ((test.refOutput == undefined) || (test.refOutput == "")) {
526         test.refOutput = test.name;
527     }
529     /*
530      * Test timeout needs to be converted from int to String.
531      * Default is 60 seconds.
532      */
533     if ((test.timeout == undefined)) {
534         test.timeout = "-t 60";
535     }
536     else {
537         test.timeout = "-t " + test.timeout;
538     }
540     /* argsToMain is an array. */
541     if ((test.argsToMain == undefined) || (test.argsToMain == null)) {
542         test.argsToMain = new Array();
543     }
545     /* Fill in any missing reference outputs for the different arguments. */
546     for (var i = 0; i < test.argsToMain.length; i++) {
547         if ((test.argsToMain[i].refOutput == undefined) ||
548             (test.argsToMain[i].refOutput == null)) {
549             test.argsToMain[i].refOutput = test.refOutput;
550         }
551     }