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 3

Client Applications — consuming deployed package content

Having deployed both acme.utils and charlie.sqrtlib, we'll turn now to a small yet typical client application that consumes the target content of these packages—which, in the final analysis, boils down to a set of C header files and function libraries. Along the way, we'll introduce one of most important facets of RTSC from the content consumer's perspective—program configuration—which enables RTSC packages to become active participants within the familiar process of compiling/linking your program.

Much of the material presented here, though self-contained, receives more thorough treatment within the first two lessons of the RTSC Module Primer. While not a prerequisite to understanding RTSC packages, we'd still encourage you to learn about RTSC modules as well.

Contents

Reading the program

Our client application program—whose source resides in the charlie.sqrtlib.samples package—benchmarks an integer square-root function (isqrt) available through charlie.sqrtlib itself. To measure performance, our sample program leverages a RTSC module named Bench—found in the acme.utils package—which enables us to sandwich a single isqrt call between a pair of benchmark "begin/end" functions. Besides reporting the measurement in a message, our application outputs the value returned from the isqrt call using a familiar-looking printf function supported by another RTSC module named System—part of the xdc.runtime package contained within the XDCtools product itself.

Looking now at the code, our client application actually comprises a pair of source files. The first file (prog.c) should appear rather ordinary to anyone familiar with C—though our use of multi-segment paths within #include directives may seem unusual at first. By contrast, the second file (prog.cfg) truly represents something new and different here—a RTSC meta-program that configures the corresponding target-program.

If you're not sure what role prog.cfg plays in the overall flow—or for that matter, what language we're even using here—you will by the end of this lesson. If you've already tackled the RTSC Module Primer, however, we've clearly returned to familiar territory.

charlie/sqrtlib/samples/prog.c
1a
 
 
2a
 
 
 
 
 
 
 
 
3a
4a
 
 
 
 
 
#include <acme/utils/Bench.h>
#include <xdc/runtime/System.h>
 
#include <charlie/sqrtlib/isqrt.h>
 
int main()
{
    unsigned int x, y;
 
    x = 1000;
    System_printf("==> isqrt(%d)\n, x");
 
    Bench_begin("cycle count:");
    y = isqrt(x);
    Bench_end();
 
    System_printf("<== %d\n", y);
    return 0;
}
charlie/sqrtlib/samples/prog.cfg
1b
 
 
2b
 
3b
4b
var Bench = xdc.useModule('acme.utils.Bench');
var System = xdc.useModule('xdc.runtime.System');
 
var Settings = xdc.useModule('charlie.sqrtlib.Settings');
 
Bench.enable = true;
Settings.optimize = Settings.OPTIMIZE_FOR_TIME;

The target-program.  Starting with prog.c, this application follows the same pattern used in virtually every other piece of C code—first #include some headers [1a, 2a] and then call some functions defined therein [3a, 4a]. As for the multi-segment paths leading to Bench.h and isqrt.h, you should (obviously!) recognize these as the acme.utils and charlie.sqrtlib package directories—which (obviously!) must contain these header files.

Drilling a little deeper, you might have also sensed some subtle differences between the contents of charlie.sqrtlib compared with the other packages used here. In the case of acme.utils and xdc.runtime, both packages happen to contain full-fledged RTSC modules—cohesive collections of constants, types, and functions with a public specification and a private implementation (not unlike a class in C++ or Java). Though our focus here remains on RTSC packages, you should start to recognize and appreciate the programming style and discipline surrounding RTSC modules.

As it turns out, the charlie.sqrtlib package houses what we'll refer to as legacy content—C language headers and function libraries delivered in their original format rather than under the guise of a specified RTSC module. At the same time, just think of RTSC modules as a more disciplined development approach that ultimately yields the same sorts of artifacts—headers and libraries. Either way, RTSC packaging provide a standardized delivery vehicle and deployment mechanism that can streamline the integration of C-based target content originating from different suppliers.

The meta-program.  By design, RTSC target-programs—ordinary C programs with a main entry-point—metaphorically begin life as a corresponding meta-program that executes on your host computer before the final compiling/linking of your application. In our example at hand, the outcome of running the prog.cfg meta-program effectively configures the downstream prog.c target-program—identifying all RTSC modules used in the program [1b, 2b] as well as optionally assigning values to configuration parameters furnished by these modules [3b, 4b].

Here again, charlie.sqrtlib appears to break the pattern used with the other packages, in which xdc.useModule calls within the meta-program strictly mirror #include directives found in the target-program; observe the predictable correspondence between lines 1a and 1b above, an idiom applied with each RTSC module used in the application. But also recall that charlie.sqrtlib houses legacy content—C headers and libraries delivered outside the scope of any specified RTSC module; and yet, charlie.sqrtlib should merit the same level of participation in the RTSC configuration process as afforded module-rich packages such as acme.utils or xdc.runtime.

To achieve parity, charlie.sqrtlib just so happens to furnish a special meta-only module named Settings which effectively serves as a configuration agent for legacy C functions like isqrt contained within this package. Just like the acme.utils.Bench module, the charlie.sqrtlib.Settings meta-module defines configuration parameters that impact the ultimate behavior of the target-program depending upon their value at the end of the meta-program:

  • alternatively assigning the module configuration parameter Bench.enable the built-in value false at line 3b of prog.cfg would effectively turn the runtime calls to the Bench_begin and Begin_end functions beginning at line 3a of prog.c into NOPs; and

  • alternatively assigning the module configuration parameter Settings.optimize the enumerated value Settings.OPTIMIZE_FOR_SPACE at line 4b of prog.cfg would potentially bind the isqrt function call at line 4a of prog.c to a slower but more compact implementation.

As for the programming language used in prog.cfg, you'll (of course!) express RTSC meta-programs using the RTSC meta-language—which is XDCscript, a superset of industry-standard JavaScript that builds upon Mozilla's openly available Rhino implementation. We have in fact extended Rhino/JavaScript to better integrate with other elements in the overall RTSC development flow—for sure, you won't find xdc.useModule described in any JavaScript textbooks.

Recall that XDCscript is one of two special-purpose languages introduced by RTSC under the banner of eXpanDed  C—suggesting that C alone is not enough. As we start exploring RTSC packages from the supplier's perspective in the next lesson, we'll introduce the other special-purpose eXpanDed  C language—the higher-level XDCspec specification language which works hand-in-hand with XDCscript to enable package producers to satisfy the diverse needs of their consumers.

Configuring RTSC programs

RTSC configuration, as we've already hinted, occurs before the final compile/link of your application: executing the prog.cfg meta-program serves as a "pre-build" step that ultimately affects the compiling and linking of the prog.c target-program. To ease integration into existing program build flows—whether driven by command-line tools or a graphical IDE—we'll rely here on another tool known as configuro to orchestrate the RTSC configuration process:

image:ModPrimerFig1.png

Included as part of the XDCtools product you've already installed in Lesson 0, configuro generates two output files that in turn become inputs to the compiler and linker when building your target-program:

  • compiler.opt, which sets all -D and -I compiler flags needed to locate any C headers included by this program (such as acme/utils/Bench.h or charlie/sqrtlib/isqrt.h); and

  • linker.cmd, which lists the appropriate C libraries containing implementations of any functions used by this program (such as Bench_begin or isqrt).

Putting some of the pieces together, the #include search-path defined through the -I flags in compiler.opt exactly reflects the current package path on a per-repository basis—which explains how the compiler finds headers named <acme/utils/Bench.h> or <charlie/sqrtlib/isqrt.h>. Rather than collecting all .h files into a centralized include/ directory, C headers delivered within RTSC packages remain in place at the consumer's site to help ensure their integrity. We'd also claim that using package directory paths in #include directives makes code more maintainable, leaving little doubt as to the particular supplier of each file; and this approach further enables different suppliers of (uniquely-named) packages to coincidently choose the same name for a header—say, Types.h.

Besides the prog.cfg meta-program, input to configuro will typically designate a RTSC target as well as a RTSC platform—pre-defined XDCscript recipes that respectively guide the compiling and linking of prog.c in our example at hand:

  • a RTSC target knows how to compile C sources into an object-code library for a particular CPU instruction set and memory model using a specific vendor tool-chain; and

  • a RTSC platform knows how to link and execute a C program for a particular hardware board (real or simulated) featuring a specific complement of processors, memory, and peripherals.

While clearly impacting the contents of compiler.opt and linker.cmd, the wealth of information encapsulated within a RTSC target and RTSC platform is generally available throughout the XDCscript environment—during execution of the prog.cfg meta-program as well as from within special back-end meta-functions we'll encounter later on.

Putting a few more of the pieces together, the generated linker.cmd references function libraries using full directory paths such as «local»/myrepo/acme/utils/lib/acme.utils.a64P. As you'll learn in Lesson 7, RTSC packages play an integral role during program configuration in selecting the set of libraries used for the final link step. As the .a64P suffix may suggest, packages containing libraries compiled for different RTSC targets can query the current target's identify when making this selection. Special XDCscript meta-functions implemented by package suppliers can also reflect upon the current RTSC platform when identifying libraries; or else—in the case of charlie.sqrtlib with its Settings meta-module—use the current value of a client-visible configuration parameter to guide the choice.

Building and running the program

If you're "playing along" with us and actually want to build and run the program at this time, we'd recommend first copying the charlie.sqrtlib.samples package into «local»/myrepo using the repoman -c command. This way, you can freely tweak the application sources without tainting the original package contents which would still remain in «shared»/products/charlie_sqrtlib_2_71/packages.

 
1
 
 
 
2
%> xs xdc.tools.repoman -c -v -r «local»/myrepo -p «shared»/products/cha.../packages charlie.sqrtlib.samples
xdc.tools.repoman: deleting charlie.sqrtlib.samples from «local»/myrepo
xdc.tools.repoman: checking if charlie.sqrtlib.samples is a bundle 
xdc.tools.repoman:     charlie.sqrtlib.samples is not a bundle.
xdc.tools.repoman: deleting contents of directory myrepo/charlie/sqrtlib/demos/package
xdc.tools.repoman: copying charlie.sqrtlib.samples from «shared»/products/cha.../packages to «local»/myrepo

The output between lines 1 and 2 occurs whenever «local»/myrepo already contains a version of the charlie.sqrtlib.samples package. To reinforce the concept of RTSC packages as individual logical entities rather than a mass of physical files, repoman will also delete packages as a unit prior to replacing them with a fresh copy. But why not simply use the native delete and copy commands of your host computer to perform these operations.... For one, because RTSC packages often house complex directory structures of their own which cannot be compromised; but even more important, because RTSC package directories may also serve as stepping-stones to other RTSC packages—try deleting a version of charlie.sqrtlib without removing the contents of charlie.sqrtlib.samples as well.

In addition to prog.c and prog.cfg, the charlie.sqrtlib.samples package contains a standard GNU makefile that enables you to build and run our sample application. Before doing so, however, you'll need to edit a pair of lines at the top of the makefile to reflect the actual directories you've chosen for «xdcroot» and «c6xtools» back in Lesson 0.

charlie/sqrtlib/samples/makefile
 
 
 
XDCROOT = «xdcroot»
C6XTOOLS = «c6xtools»            
   ...

Windows-hosted developers should surround «xdcroot» or «c6xtools» with double-quotes "..." if these directory paths contain any spaces in their names.

Linux-hosted developers should also edit the definition of the RMCMD symbol per instructions found in the makefile.

Using a version of gmake bundled with XDCtools—and assuming you've added «xdcroot» to your PATH—invoking the command gmake all from the charlie/matlib/samples package directory (now) residing within the «local»/myrepo package repository should yield the following messages:

 
1
 
 
 
 
2
3
%> gmake all
«xdcroot»/xs xdc.tools.configuro -c «c6xtools» -t ti.targets.C64P -p ti.platforms.sim64Pxx -o cfgsite prog.cfg
making package.mak (because of package.bld) ...
generating interfaces for package cfgsite (because package/package.xdc.xml is older than package.xdc) ...
configuring prog.x64P from package/cfg/prog_x64P.cfg ...
cl64P package/cfg/prog_x64P.c ...
«c6xtools»/bin/cl6x -q -@cfgsite/compiler.opt -c prog.c
«c6xtools»/bin/lnk6x -q -z -c prog.obj cfgsite/linker.cmd -o prog.out -l «c6xtools»/lib/rts64plus.lib

Lines 1, 2, and 3 respectively follow the flow outlined in the earlier figure, but now with all the details of invoking these tools made explicit. Looking at little closer at the options passed to configuro at line 1, suffice it to say that ti.targets.C64P designates a meta-module—the RTSC target—which guides compilation of this program and that ti.platforms.sim64Pxx identifies a package—the RTSC platform—which directs program linking and loading.

To read more about the hundreds of RTSC packages and modules bundled with the XDCtools product—and hence already found along the current package path—just fire-up xdc.tools.cdoc.sg using the standard xs command to interactively browse client documentation originally sourced in XDCspec files contained in each package; you'll even see some documentation for third-party packages, such as acme.utils and charlie.sqrtlib.  (You can also visit rtsc.eclipse.org for a snapshot of the latest XDCtools package documentation.)

To execute the program, simply invoke the gmake test command:

 
 
 
 
%> gmake test
==> isqrt(1000)
cycle count: [63]    
<== 31

At this point, feel free to explore the effect upon program output when you vary the value passed to the isqrt(x) function call on line 4a of prog.c; or else, when you assign Settings.OPTIMIZE_FOR_SPACE on line 4b of prog.cfg. After you make any changes, (re-)invoking the gmake test command will first perform the requisite build-steps—but only what's needed, given the structure of our makefile—before executing the program. To rebuild the all of the pieces from scratch, first invoke gmake clean to remove all generated files.

See also

Consuming Configurable Content Introduction to the RTSC configuration process
Command - xdc.tools.configuro Target content configuration tool
The XDCscript Language XDCscript overview

[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