| /* --COPYRIGHT--,EPL |
| * Copyright (c) 2008-2019 Texas Instruments Incorporated |
| * All rights reserved. This program and the accompanying materials |
| * are made available under the terms of the Eclipse Public License v1.0 |
| * which accompanies this distribution, and is available at |
| * http://www.eclipse.org/legal/epl-v10.html |
| * |
| * Contributors: |
| * Texas Instruments - initial implementation |
| * |
| * --/COPYRIGHT--*/ |
| var bldPkg = xdc.om["xdc.bld"]; |
| |
| var _Clock = xdc.module("xdc.services.global.Clock"); |
| |
| /* |
| * ======== initializeModel ======== |
| */ |
| function initializeModel(args) |
| { |
| xdc.$$make_om('bld'); /* create and name this object model */ |
| |
| /* load build model's modules and interfaces */ |
| xdc.loadPackage('xdc.bld'); |
| |
| /* init global objects */ |
| xdc.global.Pkg = xdc.om['xdc.bld.PackageContents']; |
| xdc.global.Build = xdc.om['xdc.bld.BuildEnvironment']; |
| |
| /* bind the root object for this model in the generic "OM" */ |
| xdc.om.$$bind('$root', Pkg); |
| |
| /* scan the package's modules and interfaces */ |
| Build.$private.scanPkg(Pkg); |
| |
| /* run the config.bld script */ |
| var $save = xdc.global.arguments; |
| xdc.global.arguments = args; |
| Build.$private.sourceCfg(args[0]); |
| xdc.global.arguments = $save; |
| } |
| |
| /* |
| * ======== BuildEnvironment.onInit ======== |
| * Called when the singleton Build Module Value is first |
| * created. |
| * |
| * Context: |
| * this the Build Module Value |
| * Params: |
| * Returns: |
| * void |
| */ |
| function onInit() { |
| |
| /* |
| * ======== scanPkg ======== |
| * Read package.xdc and populate the pkg object with the |
| * information declared there: |
| * pkg.name string name of package |
| * pkg.modules array of modules in this package |
| * pkg.interfaces array of interface in this package |
| * |
| * Params: |
| * pkg xdc.bld.PackageContents module |
| * |
| * Returns |
| * void |
| * |
| * Throws |
| * exceptions thrown are for fatal errors |
| */ |
| function scanPkg(pkg) |
| { |
| var file = new java.io.File("package.xdc"); |
| if (file.exists()) { |
| var scan = new Packages.xdc.services.intern.cmd.Scan( |
| xdc.$$private.Env |
| ); |
| |
| pkg.name = "" + scan.read("package.xdc", false); |
| pkg.$seal("name"); |
| |
| pkg.version = "" + scan.getKey(); |
| pkg.$seal("version"); |
| |
| var a = scan.getModules(); |
| for (var i = 0; i < a.length; i++) { |
| pkg.modules[pkg.modules.length++] = "" + a[i]; |
| } |
| pkg.modules.$seal(); |
| |
| var a = scan.getInterfaces(); |
| for (var i = 0; i < a.length; i++) { |
| pkg.interfaces[pkg.interfaces.length++] = "" + a[i]; |
| } |
| pkg.interfaces.$seal(); |
| |
| var a = scan.getImports(); |
| for (var i = 0; i < a.length; i++) { |
| pkg.imports[pkg.imports.length++] = "" + a[i]; |
| } |
| pkg.imports.$seal(); |
| } |
| } |
| |
| /* |
| * ======== sourceCfg ======== |
| * Source global build configuration file and do light semantic |
| * processing prior to running package specific build script. |
| * This script typically loads packages of targets and configures |
| * the targets for the build environment. |
| * |
| * The sourced file may set useTargets and excludeTargets and |
| * configure various targets. sourceCfg checks that all targets |
| * included have their rootDir set and propagates the rootDir |
| * setting to any target that declares another as its base (see |
| * ITarget). |
| * |
| * Params: |
| * file string naming the file to load and execute. |
| * This file is searched for along the import path |
| * (which includes the package path) |
| * Returns |
| * void |
| * Throws |
| * exceptions thrown are for fatal errors |
| */ |
| function sourceCfg(cfgFile) |
| { |
| /* import the user's "global" configuration of the target tools */ |
| |
| /* we expand to an absolute file name to ensure that importFile() |
| * doesn't find the file in the current script directory (which in |
| * this case is the bld package directory); e.g., "./config.bld" |
| * should be found along the import path rather than in bld/. |
| */ |
| cfgFile = (new java.io.File(cfgFile)).getAbsolutePath() + ""; |
| xdc.$$trace("xdc.bld loading " + cfgFile, 1, ["xdccore"]); |
| utils.importFile(cfgFile); |
| |
| /* This case, where config.bld caused an error but there is no |
| * exception can't be reproduced. This is most likely a leftover from |
| * an older error handling architecture. |
| */ |
| if (utils.hasReportedError()) { |
| throw xdc.$$XDCException("xdc.bld.TARGET_CONFIG_ERROR", |
| "Error in configuration. Check '" + cfgFile + "'"); |
| } |
| |
| _Clock.print("bld: config.bld loaded."); |
| |
| /* initialize build model's native target (if necessary) */ |
| var nativeName; |
| if (this.bld.nativeTarget == null) { |
| if (this.bld.hostOSName == "Windows") { |
| nativeName = "microsoft.targets.Win64"; |
| } |
| else if (this.bld.hostOSName == "Linux") { |
| nativeName = "gnu.targets.Linux86_64"; |
| } |
| else if (this.bld.hostOSName == "MacOS") { |
| nativeName = "gnu.targets.Mac86_64"; |
| } |
| if (nativeName != null && (nativeName in xdc.om)) { |
| this.bld.nativeTarget = xdc.om[nativeName]; |
| } |
| } |
| |
| /* initialize build model's targets array (if necessary) */ |
| if (this.bld.targets.length == 0) { |
| var inc, xcl; |
| if ((inc = this.bld.useTargets) === undefined) { |
| if ((inc = environment["xdc.bld.targets"]) == null) { |
| inc = ""; |
| } |
| } |
| if (inc == "") { |
| inc = "native"; |
| } |
| if (inc != null) { |
| if (this.bld.excludeTargets != null) { |
| xcl = this.bld.excludeTargets; |
| } |
| _exportTargets(this.bld.targets, inc, xcl, true); |
| } |
| } |
| |
| _Clock.print("bld: exported targets."); |
| |
| /* initialize all targets */ |
| for (var i = 0; i < this.bld.targets.length; i++) { |
| var targ = this.bld.targets[i]; |
| if (targ == undefined) { |
| throw xdc.$$XDCException("xdc.bld.TARGET_CONFIG_ERROR", |
| "Undefined target found in Build.targets (at index = " |
| + i + "). " |
| + this.bld.printBuildTargets()); |
| } |
| |
| if (targ instanceof this.bld.$package.ITarget.Module) { |
| var index = this.targsTab[targ.suffix]; |
| /* check for duplicate suffixes in the target array */ |
| if (index != null) { |
| var otarg = this.bld.targets[index]; |
| var msg; |
| if (otarg.$name != targ.$name) { |
| msg = "The target '" + targ.$name |
| + "' has the same suffix as the target '" |
| + otarg.$name + "'"; |
| } |
| else { |
| msg = "The target '" + targ.$name |
| + "' appears more than once in the Build.targets array"; |
| } |
| throw xdc.$$XDCException("xdc.bld.DUPLICATE_TARGET_ERROR", |
| msg); |
| } |
| |
| this.targsTab[targ.suffix] = i; /* fill in targsTab hash */ |
| |
| /* white space support for Windows (CQ18010) */ |
| if (targ.rootDir != null && targ.rootDir.match(/\s+/) && |
| this.bld.hostOSName == "Windows") { |
| var file = xdc.module('xdc.services.io.File'); |
| targ.rootDir = file.getDOSPath(targ.rootDir); |
| } |
| |
| /* patch targets that fail to initialize t_Size */ |
| var t = targ.stdTypes["t_Size"]; |
| if (t == null || t.align == null || t.size == null) { |
| // print("patching target " + targ.name + "'s t_Size ..."); |
| targ.stdTypes.$unseal(); |
| targ.stdTypes["t_Size"] = targ.stdTypes["t_Int"]; |
| targ.stdTypes.$seal(); |
| } |
| |
| /* propagate rootDir to targets that don't have it defined */ |
| if (targ.rootDir == null && targ.base != null) { |
| targ.rootDir = targ.base.rootDir; |
| } |
| if (targ.rootDir == null) { |
| throw xdc.$$XDCException("xdc.bld.ROOTDIR_NOT_SET", |
| "'rootDir' has not been set for the target " |
| + targ.$name + "; define 'rootDir' in " |
| + java.lang.System.getenv("XDCBUILDCFG")); |
| } |
| |
| /* initialize target's and platforms array and default plat */ |
| if (targ.platforms == null) { |
| targ.platforms = []; |
| } |
| if (targ.platform == null) { |
| if (targ.platforms.length > 0) { |
| targ.platform = targ.platforms[0]; |
| } |
| } |
| if (targ.platforms.length == 0) { |
| if (targ.platform != null) { |
| targ.platforms.length = 1; |
| targ.platforms[0] = targ.platform; |
| } |
| } |
| } |
| } |
| _Clock.print("bld: initialized targets defaults."); |
| |
| /* seal target to prevent user from changing in package.bld */ |
| for (var i = 0; i < this.bld.targets.length; i++) { |
| var targ = this.bld.targets[i]; |
| targ.$seal(); /* must do this in a separate loop from above |
| * because seal follows references. A seal of |
| * targ will also seal targ.base; e.g., sealing |
| * C64 will seal the C62 before the C62 is |
| * initialized! |
| */ |
| } |
| |
| _Clock.print("bld: targets sealed."); |
| /* BUG?: should we fail if bld.targets is empty? */ |
| |
| /* seal (make readonly) the fields that should not be modified |
| * by package.bld scripts |
| */ |
| this.bld.targets.$seal(); |
| this.bld.$seal("useTargets"); |
| this.bld.$seal("platformTable"); |
| this.bld.$seal("excludeTargets"); |
| this.bld.$seal("nativeTarget"); |
| } |
| |
| /* initialize private state */ |
| var priv = this.$private; /* private Build Module state */ |
| |
| /* private methods/data that we don't want scripts to see */ |
| priv.scanPkg = scanPkg; |
| priv.sourceCfg = sourceCfg; |
| priv.bld = this; |
| priv.targsTab = {}; |
| } |
| |
| /* |
| * ======== BuildEnvironment.usePlatform ======== |
| */ |
| function usePlatform(platformName) |
| { |
| if (!(typeof platformName == "string")) { |
| throw xdc.$$XDCException("xdc.bld.PARAMETER_MISMATCH", |
| "Parameter must be a string: was passed " + platformName); |
| } |
| |
| var plat = this.platforms[platformName]; |
| |
| if (plat == null) { |
| var pa = platformName.split(':'); |
| |
| /* load platform package */ |
| var pkg = xdc.loadPackage(pa[0]); |
| |
| /* create platform instance */ |
| var args = this.platformTable[platformName]; |
| plat = pkg.Platform.create( |
| platformName.substring(pa[0].length + 1), |
| args == null ? {} : args); |
| |
| this.platforms[platformName] = plat; |
| } |
| |
| return (plat); |
| } |
| |
| /* |
| * ======== BuildEnvironment.printBuildTargets ======== |
| */ |
| function printBuildTargets() |
| { |
| if (this.targets.length == 0) { |
| return ("No target modules were loaded.\n"); |
| } |
| var str = "Valid Build Targets:\n"; |
| for (var i = 0; i < this.targets.length; i++) { |
| if (this.targets[i] != undefined) { |
| str = str + this.targets[i].$name + "\n"; |
| } |
| } |
| |
| return str; |
| } |
| |
| |
| /* |
| * ======== BuildEnvironment.isInTargetsArray ======== |
| */ |
| function isInTargetsArray(targ) |
| { |
| return (this.$private.targsTab[targ.suffix] == null ? false : true); |
| } |
| |
| /* |
| * ======== BuildEnvironment.getReleaseDescs ======== |
| */ |
| function getReleaseDescs(pname) |
| { |
| var result = []; |
| |
| /* locate the package.bld.xml file (which describes a package's releases */ |
| var xname = xdc.getPackageBase(pname) + "/package/package.bld.xml"; |
| var xfile = new java.io.File(xname); |
| if (!xfile.exists()) { |
| throw xdc.$$XDCException("xdc.bld.PACKAGE_NOT_BUILT", "The package '" |
| + pname + "' has not been built. Try re-building the package."); |
| } |
| |
| /* parse the XML file */ |
| var doc = Packages.xdc.services.global.XML.parse(xname); |
| if (doc == null) { |
| throw xdc.$$XDCException("xdc.bld.INVALID_PACKAGE", "The package '" |
| + pname + "' has an invalid package.bld.xml file (" + xname |
| + "). Try re-building the package."); |
| } |
| |
| /* extract from this file the release information */ |
| var rels = Packages.xdc.services.global.XML.getHMaps(doc, "releases", |
| ["name", "label", "pname"]); /* pname stands for "physical name" */ |
| |
| /* create the release description objects */ |
| for (var i = 0; i < rels.length; i++) { |
| var obj = rels[i]; |
| var desc = new xdc.om['xdc.bld.Release'].Desc({ |
| name: obj.get("name"), |
| aname: obj.get("pname"), |
| label: obj.get("label") |
| }); |
| result.push(desc); |
| } |
| |
| return (result); |
| } |
| |
| /* |
| * ======== _exportTargets ======== |
| * Given the names (or patterns) of modules that implement ITarget, add |
| * each to the array of targets in build. |
| */ |
| function _exportTargets(targArray, list, exclude, warnings) |
| { |
| var ta = list.split(/[,;:\s]+/); |
| var ma = xdc.om.$modules; |
| var targets = []; |
| var ep = exclude == null ? null : new RegExp(exclude); |
| |
| /* put all matching targets into local targets array */ |
| for (var j = 0; j < ta.length; j++) { |
| |
| /* check for "native" target */ |
| if (ta[j] == "native" && bldPkg.BuildEnvironment.nativeTarget != null) { |
| targArray[targArray.length++] = bldPkg.BuildEnvironment.nativeTarget; |
| continue; |
| } |
| |
| /* match name against target module names */ |
| var pattern = new RegExp(ta[j]); |
| var found = false; |
| var tmp; |
| for (var i = 0; i < ma.length; i++) { |
| var sname = ma[i].$name; |
| if ((tmp = sname.match(pattern)) != null && tmp[0] == sname) { |
| if (ep != null |
| && (tmp = sname.match(ep)) != null && tmp[0] == sname) { |
| continue; |
| } |
| if (ma[i] instanceof bldPkg.ITarget.Module) { |
| targArray[targArray.length++] = ma[i]; |
| found = true; |
| } |
| } |
| } |
| |
| /* try appending the TI package prefix to the target specification */ |
| if (found == false) { |
| for (var i = 0; i < ma.length; i++) { |
| var sname = ma[i].$name; |
| if (("ti.targets." + ta[j]) == sname |
| && ma[i] instanceof bldPkg.ITarget.Module) { |
| if (ep != null |
| && (tmp = sname.match(ep)) != null && tmp[0] == sname){ |
| continue; |
| } |
| targArray[targArray.length++] = ma[i]; |
| found = true; |
| break; |
| } |
| } |
| } |
| |
| /* if no match is found for a pattern, print a warning */ |
| if (found == false && warnings == true) { |
| print("Warning: Target specification '" + ta[j] + |
| "' does not match any loaded target module.\n" + |
| xdc.module('xdc.bld.BuildEnvironment').printBuildTargets()); |
| } |
| } |
| } |