From RTSC-Pedia

Jump to: navigation, search
revision tip
—— LANDSCAPE orientation
[printable version]  offline version generated on 04-Aug-2010 21:08 UTC  

RTSC Packaging Primer/Lesson 6

Package Release — manufacturing charlie.sqrtlib archives

Having finally built charlie.sqrtlib, we'll return again to the process of creating deliverable archives during the release phase of package production. Using charlie.sqrtlib as illustrative of a "typical" RTSC package that houses target content, we'll now explore some more advanced capabilities of the xdc.bld meta-modules which ultimately give the package producer greater control at the tail-end of RTSC build flow.

This lesson will also expose even more of XDCscript as a general-purpose programming language, useful for scripting a wide-range of hosted tasks often required when producing a RTSC package.

Contents

Releasing multiple archives

The basic xdc.bld mechanisms first introduced in Lesson 4 for defining the contents of the (default) package archive file can in fact scale to handle scenarios when a single package yields multiple archives. As an example, let's assume the supplier of charlie.sqrtlib wants to manufacture three distinctly named package archives:

  • charlie_sqrtlib.zip, which delivers (binary) libraries compiled for all RTSC targets;
  • charlie_sqrtlib-DSP.zip, which delivers (binary) libraries compiled only for one target; and
  • charlie_sqrtlib-SRC.zip, which delivers a buildable (source) form of the original package.

Another variation on this theme occurs when suppliers wish to deliver a special "evaluation-only" release of their content that may lack certain features otherwise available in the default "production-quality" offering.

To illustrate the technique, we'll now complete the package.bld script for charlie.sqrtlib begun in the last lesson—filling in the details of what to release as well as what to build.

charlie/sqrtlib/package.bld
 
 
 
 
 
1
 
 
 
 
 
 
2
 
 
3
 
 
 
4
 
 
5
var Build = xdc.useModule('xdc.bld.BuildEnvironment');
var Pkg = xdc.useModule('xdc.bld.PackageContents');
 
/* ---- what to build ---- */
 
for each (var targ in Build.targets) {
    Pkg.addLibrary("lib/isqrt_loop", targ).addObjects(["isqrt_loop.c"]);
    Pkg.addLibrary("lib/isqrt_unroll", targ).addObjects(["isqrt_unroll.c"]);
}
 
/* ---- what to release ---- */
 
Pkg.attrs.archiver = "zip";
Pkg.otherFiles = ["isqrt.h"];
 
var relDSP = Pkg.addRelease("charlie_sqrtlib-DSP");
relDSP.otherFiles = ["lib/isqrt_loop.a64P", "lib/isqrt_unroll.a64P"];
relDSP.attrs.label = "DSP";
 
var relSRC = Pkg.addRelease("charlie_sqrtlib-SRC");
relSRC.attrs.exportAll = true;
relSRC.attrs.label = "SRC";
relSRC.attrs.relScript = "./copyright.rel";

With multiple releases defined here, the pair of assignments at line 2 in fact prescribe characteristics common to all archives produced by this package—not just the package's "default" archive (automatically added under the name "charlie_sqrtlib" and labeled as "default"). In this example, all package releases would use .zip files; and all package releases would include the isqrt.h header.

Explicit calls to the addRelease meta-function at lines 3 and 4 then return new XDCscript objects with an analogous set of assignable properties, selectively updated to override or else extend default values taken from the PackageContents module itself. Looking closer at the DSP-only release defined after line 3, the assignment here to otherFiles effectively adds these two libraries to the array of files already common to all releases—just isqrt.h in our case; the assignment of "DSP" to attrs.label, by contrast, replaces its original "default" value.

You might note that adding the same pair of function libraries (compiled for "all" targets) to the default package release happens implicitly here—a convenient side-effect of the fact that we've already named these libraries as generated artifacts via the addLibrary calls after line 1. Suffice it to say that the RTSC package build flow already comprehends many different categories of generated files; and the default package release will automatically contain an appropriate subset of these if the supplier takes no further action.

In the case of the source-code release defined after line 4, setting attrs.exportAll effectively adds all of the files not generated during package build to this particular archive—including the package.bld file itself. As a further consequence of the addLibrary calls after line 1, this set includes the C source files directly used when generating the lib/isqrt_loop and lib/isqrt_unroll libraries.

In cases where a package producer must deliver libraries built outside of the RTSC build flow—but nevertheless still rooted in the current package directory—simply follow the protocol first illustrated in Lesson 4 and add their paths to the otherFiles array. Along these lines, we should mention that the PackageContents meta-module has a makePrologue and makeEpilogue property through which producers can furnish customized gmake command sequences that will bracket the generated package.mak file. Strange as it might seem, the xdc command (alias gmake) could in fact fire off a legacy build flow for some legacy content; and by applying the techniques illustrated between lines 2 and 5 of the earlier package.bld script, the containing package could even release a buildable form of itself.

Filtering released content

Besides prescribing the file-level contents of individual archives manufactured during package release, more advanced mechanisms exist that allow you to filter individual files as well—programmatically transforming a copy of the file itself just before adding it to one of the released package archives. As a motivating (and not uncommon) example, let's assume the supplier of charlie.sqrtlib wants to add a special comment of the form /* Copyright Charlie & Co. */ at the top of each .c file included in this package's source-code release.

The assignment to attrs.relScript at line 5 of the package.bld script presented above already sets the stage, naming yet another XDCscript source file which then organizes and performs the filtering per se. As evidenced from the form of its name, the ./copyright.rel file presumably exists within the charlie/sqrtlib package directory.

In practice, a file like copyright.rel might reside within a separate package—say, charlie.common—used to house artifacts shared across Charlie & Co. Our package.bld script would then reference this file as "charlie/common/copyright.rel" using a stable canonical name ultimately resolved by searching the current package path—no differently from the #include directive used in Lesson 3.

charlie/sqrtlib/copyright.rel
1
 
2
 
3
 
4
 
 
 
 
 
5
 
6
 
 
 
 
7
 
 
8
 
 
 
 
 
 
var Manifest = xdc.useModule('xdc.bld.Manifest');
 
for each (var fname in Manifest.files) {
    if (!fname.match(/[\/]package[\/]/) && fname.match(/[\.]c$/)) {
        var filter = new Manifest.Filter();
        filter.operation = addComment;
        Manifest.filterMap[fname] = filter;
    }
}
 
var COPYRIGHT_COMMENT = "/* Copyright Charlie & Co. */\n\n";
 
function addComment( filter, src, dst, base )
{
    print("copyrighting " + base + " ...");
 
    var infile = new java.io.BufferedReader(new java.io.FileReader(src));
    var outfile = new java.io.BufferedWriter(new java.io.FileWriter(dst));
 
    outfile.write(COPYRIGHT_COMMENT);
 
    var line;
    while ((line = infile.readLine()) != null) {
        outfile.write(line);
    }
 
    infile.close();
    outfile.close();
}

Similar to how package.bld manipulates PackageContents, this script works with parameters of the special Manifest meta-module imported at line 1—likewise found in the xdc.bld package bundled with XDCtools. The main portion of this script iterates over each file name contained in the Manifest.files array, beginning at line 2. Using a built-in XDCscript method for matching character strings against regular expressions (courtesy of the underlying JavaScript engine), files not found within the special package/ sub-directory and whose names end with .c become entries in the Manifest.filterMap at line 4.

Our copyright.rel script bypasses generated C files like package/package_charlie_sqrtlib.c, discussed briefly back in Lesson 5.

Each entry in Manifest.filterMap—an XDCscript hash-table keyed by the names of individual files—itself represents another XDCscript object of type Manifest.Filter, newly-created back at line 3. The value then assigned to this object's operation property further identifies an XDCscript function called addComment, also defined inside of copyright.rel beginning at line 5.

Other properties of Manifest.Filter objects not only enable you to pass additional arguments to the operation function, but also give you the flexibility to actually choose a different name for the corresponding file. Taking matters one step further, your release script can directly manipulate the Manifest.files arrays—not only removing unwanted files but even adding (newly-generated!) files at this time. Collectively, these capabilities allow package producers to accommodate a wide range of physical designs when manufacturing package archives—even legacy designs that don't necessarily align with RTSC conventions.

Turning now to the body of addComment—which may even surprise some readers already familiar with JavaScript—this function basically writes the COPYRIGHT_COMMENT string to the output file (named dst) [7] followed then with each successive line read from the input file (named src) [8]. Note that while dst will generally reference a temporary directory used in manufacturing package archives, the base argument to addComment printed at the outset [6] mirrors the original file name contained in the Manifest.files arrays searched back at line 2; for completeness, the filter argument to addComment tracks the Manifest.Filter instance object originally created back at line 3.

Contrary to what the textbooks may tell you, JavaScript can script Java—or at least the Rhino/JavaScript engine underlying XDCscript can, using a technology known as LiveConnect. In a nutshell, this technology grants scripts access to any of the public fields or functions available through any Java class—no differently from how we've already accessed client-visible properties of native XDCscript objects. This bridge to the world of Java consequently puts a large, robust, and widely-deployed base of general-purpose capabilities—file management, network services, graphics toolkits, and so forth—at the immediate disposal of XDCscript content developers.

Using the xdc command

Invoking the xdc release command—first illustrated back in Lesson 4—would here manufacture all three of the package archives prescribed in the package.bld script for charlie.sqrtlib. Alternatively, you can manufacture just one of these package archives by invoking (say) xdc release,charlie_sqrtlib-SRC from within the package directory.

 
1
 
2
 
%> xdc release,charlie_sqrtlib-SRC
all files complete.
making release file charlie_sqrtlib-SRC.zip (because of ...) ...
copyrighting charlie/sqrtlib/isqrt_loop.c ...
copyrighting charlie/sqrtlib/isqrt_unroll.c ...

The output at line 1 reflects the fact that we've already built this package; otherwise, you'd see output commensurate with invoking xdc all immediately before running this command. As you'd expect from any flow based on gmake, the generated package.mak file for this package enforces this dependency and re-builds when necessary.

The output at line 2 tracks the print statement at line 6 of copyright.rel—not only confirming that we've extracted the correct files from the Manifest.files array beginning at line 2 of the same file, but also reinforcing the fact that copyright.rel executes near the end of the RTSC build flow.

To increase your understanding here, try dropping a print statement inside of the package.bld script after line 1 which then displays the current value of the targ.isa property—the "instruction-set architecture" for this particular target. Upon re-entering the same xdc release,charlie_sqrtlib-SRC command, you'd now see additional output with values like "64P" or "x86" at the very beginning of the process—when package.bld itself executes prior to generating the package.mak file which then manages the rest of the flow.

See also

TODO:  write it

[printable version]  offline version generated on 04-Aug-2010 21:08 UTC  
Copyright © 2008 The Eclipse Foundation. All Rights Reserved
Views
Personal tools
package reference