![]() |
![]() |
![]() |
![]() |
4
Projects, libraries, and processes
This chapter describes AVS/Express projects, libraries, and processes. For Developer Edition users only, there is also a discussion of the Save Compiled Project mechanism by which application runtimes can be generated.
- Introduction, Section 4.1
- Install area project, Section 4.2
- Creating and using your own projects, Section 4.3
- Understanding libraries, Section 4.4
- Understanding processes, Section 4.5
- Defining an object's process, Section 4.6
- Compiling a process, Section 4.7
- Understanding the compile process, Section 4.8
- Project architecture, Section 4.9
- Save Compiled Project, Section 4.10
An AVS/Express project defines your development and execution environment. Each time you work with AVS/Express, you are working on a project.
A project includes three major components:
When you first use AVS/Express, you access the install area's project, with its full complement of template objects from AVS/Express' kits. You do not modify the install project as you work (it is read-only), but rather create your own project.
Since you cannot modify the install project, you will need to create your own project(s) in which to work. New projects may be created from any existing project in which you are currently working (not just the install project) and can be one of two types:
- Distinct (the default) - A distinct copy of the current (parent) project that defines itself as being like the parent project at the time of creation. Distinct projects inherit from any projects from which the parent project inherits, but not from the parent project after the time of initial creation.
- Derived - A derived copy of the current (parent) project, and therefore inheriting from the parent project. Derived projects are therefore like the parent project in its current state, but with changes in the new project overriding files inherited from the parent.
The ability to create derived projects allows you to build a project hierarchy that consists of a chain of projects in which one project is a derivative of some other project, which in turn is a derivative of another project.
For more details about creating projects, see Section 4.3, Creating and using your own projects [page 4-6].
You can compile a process from within AVS/Express and from the command line. AVS/Express uses information that you provide-source filenames, library dependencies, and process name, for example-to construct a make file and, if possible, use it to build a new executable.
During the compile process, AVS/Express can also generate template source files in cases where an object's source file does not exist.
AVS/Express provides you with a mechanism to compile a selected set of objects into a separate project area. This mechanism allows you to build runtime versions of your AVS/Express applications that are smaller, start up faster, depend upon fewer files, and are therefore ideal for distribution.
In most cases, you do not need to know the underlying architecture of a project to use AVS/Express, nor to create your own project. AVS/Express sets up and manages projects for you.
The architecture is accessible to Developer Edition users, however. Once you understand the architecture, you can, for instance, create a project that completely replaces the install area project, or that includes a small subset of the install area project's libraries, or that has a completely different appearance in the Network Editor.
For a description of a project's underlying architecture, see Section 4.9, Project architecture [page 4-41].
The AVS/Express install area defines the install area project. This project includes:
- The libraries of template objects that define AVS/Express' various kits.
- The object files that define methods for those objects.
- Examples of AVS/Express applications.
- The express executable. express includes AVS/Express itself and the functions called by AVS/Express' kits.
- A single external process, called user. Initially, the only objects that use this process are those in Templates.USER (which appears in the Network Editor also under Libraries.User_Libraries.User_Modules). All of the other objects use the express process.
- A bootstrap executable, called base.
The install area is read-only - you cannot make changes to it. You must create a new project or projects in which to store your work. Projects created from the install area project (or any other read-only project) are derived from it - new projects define themselves as being like the install project, but with any additions and changes to you make to libraries, objects, and so on explicitly described.
The install project is made up of the contents of several subdirectories of the install directory. Here is a summary of the most significant of these directories:
The v directory includes the following V files (among others):
In order to add your own objects to AVS/Express, you will need to create your own projects using the Project'Save As pull-down command from the Network Editor. This section discusses describes the characteristics of distinct and derived projects and for what each type is appropriate, and then tells you how to create and use either type.
The type of project that you create when you do a Project'Save depends on whether the existing project is read-only, and whether the AVS/Express session was started with the -derived command line option.
If the current (parent) project is not read-only and the -derived option was not specified at AVS/Express startup, the new project created is a distinct copy of the parent project (that is, it defines itself as being like the parent project at the time of creation). Distinct projects inherit from any projects from which the parent project inherits, but not from the parent project after the time of initial creation. The new project will therefore reflect any changes you subsequently make to it and any projects from which it inherits, but will not reflect any changes made to the parent project.
If the current working project is read-only, and/or the -derived option was specified at AVS/Express startup, the new project created is a derived copy of that project. As with any derived object, the new project inherits the characteristics of its parent and any subsequent changes to the parent project not overridden by changes you make in the new project are reflected in the new project.
Note: You should avoid deleting a library/object in a base project from which other projects have been derived since this will lead to the derivation being lost.
The ability to create derived projects allows you to build a project hierarchy that consists of chains of derived projects in which one project is a derivative of some other project (typically a group project), which in turn is a derivative of yet another project (typically the install project). Working in a chained project hierarchy, developers can share objects and work on specific objects that are unique to their own development tasks. Files stored in a local project override those files stored in the parent project, which override those in their parent project, and so on.
To make a project read-only, you can either protect the project by removing write permission to the project directory, or create a file named .proj_lock (projlock on PC/NT platforms) in the project directory (.proj_lock/projlock need not have any contents or special permission).
1. Select the Project'Save As pull-down command from AVS/Express. A Save Project dialog box appears.
2. In the Selection field, specify the name of a new project directory. You can use the list boxes to navigate to the directory where you want the new project directory to appear.
When you select the OK button, AVS/Express creates a project directory. The directory contains the following files:
- avsenv - Defines the XP_PATH environment variable that specifies the list of project directories to search for files, and therefore the project hierarchy. For a project derived from the install area, this includes the path of the new project directory and the AVS/Express install area.
- bin (a directory) - Starts out empty. Executables you create are stored here under machine-specific subdirectories.
- include (a directory)- Contains the xp_defs.mk file which specifies options needed to compile your project and may also contain user include files and machine specific subdirectories (allowing you to override defaults for make, compile, and so on in AVS/Express.
- lib (a directory)- Starts out empty. Object files generated from source in this directory are placed here in machine-specific subdirectories.
- v (a directory) - Contains your project's versions of proc.v and templ.v. These files are defined to be derived from the install area files. Thus changes made to the install area's templ.v or proc.v are propagated to this local project. The v directory may also contain any other V files you want to add to AVS/Express.
Once you have created a project, there are several ways to get AVS/Express to use this project when you restart the express process:
- Use the command line option: "-project <your_project_dir>".
- Start the express process with your project directory as the current directory.
- Copy the avsenv file from your project directory to your home directory.
You should save a project whenever you have changed the object description of any objects through the Network Editor or the VCP and you want to make these changes permanent. This process updates the description of any objects that are defined in the templ.v file. This includes any objects that are interactively created or edited through the Network Editor.
To save a project, select the Project'Save pull-down command.
This command is available only when you are working on your own project; that is, when the project directory is not read-only (like the install area project).
If you have defined your objects using an flibrary object using the libfile property, you should make changes to these objects by directly editing the V file specified in the libfile property. Changes to these objects are not saved through the Project'Save pull-down command.
AVS/Express updates your project directory. Typically this entails modifying your project's templ.v file (located in the v directory) so that it describes the changes you have made. The previous version of templ.v is placed in templ.bak.
A library contains a list of AVS/Express templates. Templates are inactive objects that you can copy to create other objects. Libraries can contain macros, modules, parameters and other libraries. Their primary goal is to arrange the collection of available AVS/Express objects into sets that share common behaviors and purposes.
All AVS/Express objects are stored inside the Template object hierarchy. The Templates object itself is a library that contains other libraries. The nature of the Templates hierarchy is not appropriate for direct display in the Network Editor. The names of the libraries in the Templates hierarchy are usually short acronyms since these names are visible in the V language definition of the object. In addition, the libraries in Templates are stored in an order that defines their inter-dependencies and cannot be rearranged to suit a viewing preference.
Instead, the Network Editor displays another object defined as a child of Root called Libraries which contains a set of links into the Templates hierarchy. This structure allows the libraries in Templates to be given more readable names, and for their order to be rearranged. This structure is shown in the following diagram:
![]()
The last page in the standard Libraries object is a link to the Templates object itself. Use this page to create any new libraries and to access any libraries that do not have links from the Libraries hierarchy.
The Templates object is defined in the V file templ.v and the Libraries object is defined in the V file lib_xp.v. You can make changes to the Templates hierarchy directly using the Network Editor and save these changes by saving the project, but you must edit the lib_xp.v file manually in order to make changes to the Libraries hierarchy.
There are two methods by which you can make changes to the Libraries hierarchy. The method that you should use depends on whether you wish to inherit from the Libraries hierarchy of an existing project (most useful when you just want to add new libraries) or whether you wish to create a Libraries hierarchy that does not inherit from any other project (useful when you want to create a totally independent library structure).
In either case, the lib_xp.v file should only contain two kinds of AVS/Express objects:
You can use libraries to create new categories of objects that are shown in the Network Editor that are not defined in the Templates hierarchy. The NElink object is used to display a library in the Templates hierarchy at a specific location in the Libraries hierarchy. For example, the first few lines of the standard lib_xp.v file define the appearance of the Main page in the Libraries hierarchy:
library Libraries {
flibrary Main <NEdisplayMode="opened",needs_use_lic="GD DV",
NEhorizontal=1> {
NElink Readers<NEdisplayMode="opened"> = Templates.MODS.Readers;
NElink Filters<NEdisplayMode="opened"> = Templates.MODS.Filters;
NElink Mappers<NEdisplayMode="opened"> = Templates.MODS.Mappers;
NElink Imaging<NEdisplayMode="opened"> = Templates.IP.Macros;
NElink Viewers<NEdisplayMode="opened"> = Templates.VIEW.Viewers;
NElink Writers<NEdisplayMode="opened"> = Templates.MODS.Writers;
NElink Geometries<NEdisplayMode="opened"> = Templates.GEOMS;
NElink Colormaps<NEdisplayMode="opened"> = Templates.DATAS;
NElink Array_Modules<NEdisplayMode="opened"> =Templates.MODS_ARR;
NElink Field_Mappers<NEdisplayMode="opened"> = Templates.FLD_MAP;
};
.....
Before making changes to the lib_xp.v file, it is useful to understand the definition of the Network Editor properties (see Section 3.7, Network Editor properties [page 3-36] in the User's Guide).
If you want to use a Libraries hierarchy that inherits from that of an existing project, you should create a new project and then create an lib_xv.v file that takes the form shown below in the project's v subdirectory:
"old_proj_dir/v/lib_xp.v" Libraries {
flibrary OURS{
NElink OURS<NEdisplayMode="open"> => Templates.OURS;
};
};
To create a independent Libraries hierarchy that does not inherit (and will not therefore reflect changes made to the library structure of) the AVS/Express install or any other project, you should create a new project and then copy v/lib_xp.v from the install area into the v subdirectory of the new project and make appropriate modifications to that file.
It is important to have a way to uniquely identify every template object in the system. In some cases, it makes sense to simply define global names that are unique in the system. There is only one object in the system, for example, called UIbutton. In the V language, you can create an instance of the template UIbutton with the V statement:
In other cases, it makes sense to use the name of the library so that the name of the object need only be unique for that library. This mechanism partitions the name space into easily managed sets. The clamp object, for example, must be created by specifying the library name MODS along with the object name:
A global library does not require that its name be used to access its subobjects. The UI library is global, the MODS library is not. You can tell which libraries are global by using the $list command on the Templates object. Global libraries are defined either using the base type library or save their type with the string +global.
When you copy a template object to form either another template or an instance, usually the system makes a derived copy of the object. A derived copy retains a handle to the object that it was copied from. When you save the copy, only the changes that were made to the copy that differentiate it from the original object are saved. For example, if we define the following V construct
when saved, the object copied_obj saves itself in the same way you entered it. In this way, if we later make a change to base_obj's b subobject, this change is inherited by copied_obj.
Sometimes, having libraries make derived copies is not desirable. When you define a library of objects, you do not want instances or templates to be derived from that library. You can do this by setting the user_library property to zero on a library. For example, with the above example defined as
library MYLIB<user_library=0> {
group base_obj {
int a, b;
};
base_obj copied_obj {
a = 3;
int c;
};
};
when we save copied_obj, it is saved as
This property is particularly useful when you are rearranging objects that are already defined in a library without the user_library=0 property. In this way, V files that are saved only reference the original objects, not the rearranged versions.
Note: Do not set the user_library property to 0 on libraries that define C++ modules (using the cxxmethod). Instances of C++ objects must have a reference back to the template from which they were defined.
There are two base types from which you can build a library in AVS/Express: library and flibrary. The library base type is global by default and used only for simple libraries. The flibrary base type is more general since it can be made global or not, and can optionally store the definition of the objects it contains in a separate V file.
The first major decision that you must make when defining a new library is whether you want to define and maintain your objects using the V language or using the Network Editor. If you are defining modules (i.e., objects that interface to code) and you are defining more than just one or two, it is recommended that you invest the time to learn the V language to specify them. If you are defining macros, the Network Editor is a better mechanism for visually understanding and editing these objects.
Since the Network Editor saves its objects using fairly readable V, it is not too difficult to switch back and forth between the two ways of editing. If you define objects in V, load these descriptions into the Network Editor and save the resulting description, you will lose your specific formatting and all but specially defined comments.
To define a library that you edit using the Network Editor:
2. If you want your library to be global, select the library object; if you want your library not to be global, select the flibrary object.
5. A new library will be inserted at the end of the Templates library list (scroll all the way over to the right).
6. You can now change the name of this library. Make sure that the name you choose does not conflict with the name of any existing libraries.
To create a library that maintains objects directly using the V language, follow the instructions above except you must select an flibrary object in step 2 (a library object is not valid). Once you have defined a new flibrary object, bring up the Properties editor and set the libfile property to a string that contains the name of a V file. You can specify the libfile property with the absolute pathname of a V file or a relative pathname. If you use a relative pathname, the V file must be located in the path relative to the v subdirectory of your local project directory (or any project directory defined in your XP_PATH).
The objects defined in the specified V file are loaded as subobjects of the flibrary. If you defined a V file as
your library would contain the two objects my_module1 and my_module2.
The V file specified by the libfile property is loaded the first time that the subobjects of this library are accessed. This might be when the Network Editor is first asked to display these objects or when someone loads a V file that references one of your objects. If the library is global, the libfile is loaded right when the process starts.
When you save a project that has flibraries with libfiles, it saves the definition of the flibrary but does not save the definitions of the objects defined in the flibrary. The templ.v file you get when you save a project containing a simple flibrary with a libfile is
You can therefore define a project that has a combination of both libraries defined and edited through the Network Editor and libraries defined using the libfile property in the same project.
If you specify the value of the libfile property without a .v suffix, for example
the system automatically maintains a binary V equivalent of your text V file. This can improve the start-up time of an application significantly if your text V file is large. It also gives you a way to provide a user with the functionality of a particular library of objects without providing them with a readable description of the V code that defines these objects.
The first time a subobject of your library is accessed, AVS/Express looks in the v subdirectory of your XP_PATH for a libfile with a .vo suffix (a binary V file) and a libfile with the .v suffix (the text V file). There are several different cases that are handled:
- If AVS/Express does not find the binary .vo file, it tries to load the .v equivalent and generates a binary V file in the local project's v subdirectory with the .vo suffix.
- If AVS/Express does find a .vo file and there is no .v file with a more recent modification time, it loads the .vo file.
- If AVS/Express does find a .vo file but there is a .v file with a more recent modification time, it loads the .v file and generates a new .vo file in the local project's v subdirectory.
Note that if AVS/Express finds a .vo file and there is no .v file in the path, this is not considered an error. It is assumed that the .vo file is up-to-date.
There are a few caveats to using this functionality:
- If you have nested flibraries with libfiles, you must use binary V libfiles only at the inner level. To disable this feature, ensure that you specify a .v suffix explicitly in the libfile property for your outer flibrary.
- If your V file includes any other files or uses #defines that are defined in a separate V file, the .vo file can be out of date when AVS/Express does not detect this condition. You must either avoid using the binary V libfile mechanism or manually remove the .vo files when the includes or #defines change.
- To prevent AVS/Express from loading any .vo files, you can set the environment variable: OM_NO_BIN_LIBS.
- If AVS/Express encounters errors while reading a .v file, it does not generate the .vo file.
To access some of the more sophisticated features of libraries, you need to be able to merge additional base types into the library specification which you cannot do with the Network Editor. This is easy to do using the VCP. The objects you define can be accessed in the Network Editor and will be saved when you save your project.
In the VCP, traverse to the Templates object and simply enter the following statement to create an flibrary called MYLIB with the libfile property set to my_lib.v:
To define a global flibrary using the VCP, you enter
To define an flibrary whose objects are sorted alphabetically, you can use
For V files that contain large numbers of complex objects that are likely not to be used in any particular session, you can define a library to be buffered. When the system loads a buffered library, it delays the parsing of the V definition of the objects in the library until an attempt is made to copy one of these objects (either for another template or for an instance) or until these objects are selected in the Network Editor. When objects are in a buffered state, they are displayed in the Network Editor with parentheses around the name.
You can define a buffered library using the VCP with
OM(Root) -> Templates {
OM(Root) -> flibrary+buffered MYLIB;You can use the buffered base type with the libfile property.
Any number of processes can attach to a single AVS/Express session. Each AVS/Express object lives in a single process but all processes see the same object hierarchy and can operate on each object regardless of which process it lives in.
A single process, called the main process, manages the synchronization of the other processes. It must start up before any other process attaches to AVS/Express and must exit after all of the other processes have detached from AVS/Express. The main process serves as a hub for the exchange of addresses of other processes.When one process attempts to access an object in another process, it forms a direct socket connection to that other process.
A process can either exist on the same machine or can run on a remote host. Any data format conversions required are performed automatically by the system but only when the two hosts have different data formats.
Some processes are started by the main process automatically when you create an object that lives in that process. Other processes are started externally and attach to an existing session.
![]()
All processes in AVS/Express can initiate an operation but all operations are synchronized through the scheduler which is located in the main process. Synchronization is performed through the push_ctx and pop_ctx operations. The scheduler only allows a single push_ctx operation to be active in the system at any given time. If the scheduler already has an outstanding push_ctx, it queues any push_ctx operations it receives until the outstanding push_ctx is completed with a pop_ctx. The process initiating the queued push_ctx waits in the push_ctx call until it completes.
Each AVS/Express process has the following components:
All of these components are constructed automatically when your process is compiled from AVS/Express. In this case, you can modify these pieces individually by setting properties on the template objects in your process. You can also build a process manually without using the compile mechanism. In this case, you must provide your own version of each of these components.
When AVS/Express compiles a particular process, it generates code for two functions, PREinit and BASEinit, which are called by AVS/Express' initialization routine. These routines perform any process specific initialization required by the objects in this process (such as initializing the widget toolkit for the UI objects), set the name of this process, and build a table that maps method names to the method pointers using the OMadd_named_func routine.
The function PREinit is called before the object definitions in the Templates hierarchy are defined. The function BASEinit is called after the Templates objects have been defined but before any template objects have been instanced.
You can add your own code to the PREinit and BASEinit functions by setting the properties pre_init_code (for PREinit) and init_code (for BASEinit). Each of these properties specify C code that is directly added to PREinit or BASEinit functions. The string values should define complete C statements. These functions are generated in the order in which objects appear in the Templates library. Thus a library is defined after all libraries that it depends upon are defined.
Although PREinit and BASEinit are defined with C-scoped names, AVS/Express may compile them with a C++ compiler. You must, therefore, make sure that any functions that you call in the init_code and pre_init_code properties are declared before they are used. You can either specify a header file that declares these functions with the c_hdr_files or cxx_hdr_files properties or you can use the hdr_code property to declare the functions. The hdr_code property specifies a C statement that is inserted into the value of the current out_hdr_file property (which by default is processname.h).
For example, to call your function MYLIB_init in the BASEinit function when the library MYLIB is included in this process, your V code looks like:
Each process has a name. This name should correspond to the name of the object defined in the ProcTemplates database defined in the V file proc.v. It allows AVS/Express to determine which processes are running so that it can create the right objects in the right process.
The process name for a process that AVS/Express generates is set automatically by code inserted into the PREinit function using a call like
You only need to worry about setting the process name with code that you write if you generate your own PREinit and BASEinit functions for a process which will define local objects. In this case, you need to make sure that you set the process name to be the same name as the value of the process property set for the objects you intend to define locally.
When a process starts up it calls the initialization call. If you define certain environment variables before the initialization call is made, this process attaches to an existing main process. If you have not defined these environment variables, this process itself becomes the main process and then defines the environment variables. These environment variables are:
There are several ways that you can set these environment variables:
- Use the command-line option -server <filename> for the main process (which writes the environment variable definitions to a file) and the -client <filename> option on the client process (which loads these definitions).
- Use the command "$server_info > <filename>" to dump these variable definitions to a file.
- From anywhere within the main process, you can use the function getenv to retrieve the values for each of these variables and then manually set them in the environment of the client process.
The call you should use to initialize AVS/Express for UNIX platforms is
The command-line arguments that AVS/Express parses are parsed by these routines. You can disable them by passing in empty command line strings. If you have command-line arguments that your program recognizes, you should remove them from the arguments you pass to OMmain_init since the routine displays error messages about arguments that it does not recognize.
You must make this call before you attempt to access any AVS/Express objects. Once this call returns, you can create and destroy AVS/Express objects.
The return value to this routine is a flag that indicates whether or not the -vcp or -novcp options were specified in the command-line arguments. It should be passed to the OMmain_loop routine to enable the functionality of these command-line arguments.
The call to process events using AVS/Express is
This routine takes one argument which can have one of three values:
Enables the VCP for the main process and disable it for other processes
Never enables the VCP for this process
Always enables the VCP for this process
AVS/Express supplies a default C main in the library -lmnc and a default C++ main in the library -lmncxx. These libraries are by default included on the link line of any process that is constructed through an AVS/Express compilation.
If you want to define your own main for a particular process, set the property no_main=1 on an object in your process. This causes AVS/Express to omit the library containing a definition of main from the link of this process. Now you must include a definition of the main that you supply with the process. You can do that with the c_src_files, cxx_src_files, or link_files properties.
On UNIX systems, AVS/Express links your process with the C++ compiler if there are any objects that need C++, otherwise it will link with the C compiler. You must supply the correct type of main for your process. If you are in doubt, it is safe to use a C++ source file for supplying a main since that will require that C++ be used for the link.
On UNIX systems, you can configure your main process to use the standard Xt event dispatch facilities (for example, XtAppMainLoop, XtAppNextEvent, or XtAppProcessEvent) instead of the routine OMmain_loop. This makes it easer to integrate AVS/Express objects into existing Motif/Xt based applications. (See your platform documentation for information on the XT event dispatch facilities.)
In order to take advantage of this facility, you must place a call to the function EVXinit_display_xt() for each Display used in your program. This function is declared as follows:
To obtain a definition of this function, include the header file avs/event_x.h in your program as follows:
You should place this call sometime after you have opened the display but before you enter the event dispatch loop of your program; that is, before you call XtAppMainLoop, XtAppNextEvent or XtAppProcessEvent.
Next, define your own main loop, bypassing the AVS/Express main loop. When you do this, you cannot use the V Command Processor (VCP) from within this process. However, you can start up a VCP in another process that manipulates objects in the current process, as follows:
The VCP in the shell started by the base command will manipulate objects in your express process.
If you intend to use objects from the UI kit in your application, you must ensure that your code and the UI kit code share only a single XtAppContext. Currently, the only way to do this is to obtain the Widget pointer from the handle.widget subobject of a UI object used in your application. From this Widget pointer, you can use the XtWidgetToApplicationContext and XtDisplay functions to access the XtAppContext and the Display:
The following set of instructions explains how to create a dummy shell object outside of the express project mechanism, obtain a Widget pointer from that object, and perform an EVXinit_display_xt call.
1. Save the source code at the end of this section (labeled "Sample source code") into a file called xtmain.cxx in your project directory.
3. Select the Workspace_1 object (or any library that defines objects for the express process) for dummy.v.
The resulting express process uses the xtmain.cxx file as its main program.
---- xtmain.cxx:
#include <stdlib.h>
#include <avs/om.h>
#include <avs/event_x.h>
#include <X11/Intrinsic.h>
void
main (int argc, char **argv)
{
int vcp;
OMobj_id shell_id, widget_id, macro;
Widget widget;
vcp = OMmain_init(argc, argv);
OMpush_ctx(OMroot_obj,0,0,0);
macro = OMcreate_obj_from_path("macro", "my_macro", OMinst_obj);
shell_id = OMcreate_obj_from_path("UIshell", "xt_shell", macro);
OMset_name_int_val(shell_id, OMstr_to_name("visible"), 0);
OMpop_ctx(OMroot_obj);
widget_id = OMfind_str_subobj(shell_id,"handle.widget",OM_OBJ_RD);
if (OMget_ptr_val(widget_id, (void **)&widget, 0) != 1)
widget = NULL;
if (widget == NULL) {
fprintf(stderr,"can't get widget\n");
exit(-1);
}
EVXinit_display_xt(XtDisplay(widget));
XtAppMainLoop(XtWidgetToApplicationContext(widget));
OMexit(0);
}
You can define functions that AVS/Express will call in response to system events such as:
You can have a particular process exit using the C API routine
This process exits using the exit system call with the status code provided as the first argument in the process that issues this call.
To cause a particular process to exit, you can use the routine
This process forces the process specified by the proc_id argument to exit with the status specified by the status argument. It is most useful for an external process to cause the main process itself to exit. The main process always has a process id of 0.
Each template object in AVS/Express belongs to a single process. The process for an object is set using the process property which specifies the string name of an object defined in the root level ProcTemplates object. The process property is inherited as you move down the object hierarchy. If the process property is set on a library, all modules in that library are placed in the process specified (provided that they do not override this value by directly setting the process property on themselves). If no process property is set on any parent of a particular object, it is placed in the default process which is the first process in the ProcTemplates list (by default, this is express).
The first of the following rules that finds a process is used to select the process for an object:
1. If the process property is directly set on an object or the template an object was created from, the object is placed in that process.
3. If the process is set on an ancestor of a template object from which this object was created, the object is placed in that process.
These rules are illustrated in the following diagrams. The circles depict objects in the Templates hierarchy. When the process property is set on an object, the subobjects inherit the process of the parent. If no process is set on its parent, a subclass is given the process of its superclass.
![]()
When the library that contains C and D is given an explicit process setting, C no longer inherits the process from its superclass B. Instead, it now gets the process from its parent.
![]()
Once you change the process on an object, you have to recompile the processes affected by this change. The process that used to contain the object has a stale copy of the code for that object. More importantly, the new process needs to get a definition of the new object that was added to it.
You can compile a process from within AVS/Express. AVS/Express uses information that you provide-things like source filenames, library dependencies, and process name-to construct a make file and, if possible, execute it.
AVS/Express creates the make file by navigating all branches of the object hierarchy under Templates (except where it finds the compile_subs=0 property), looking for objects that are part of the process being compiled.
AVS/Express can also generate template source files in cases where the source file for an object does not exist.
The libmods.a library archive supplied now contains the image file reader and writer libraries that are normally dynamically loaded. This only applies to platforms on which shared libraries are provided.
This means that if you want to statically link your application (using the NO_DLLIBS environment variable for instance) your application will no longer be dependent on AVS/Express external libraries.
For applications that are dynamically linked (and reference the libmods.s, libmods.o, or libmods.o shared library) the image reader and writer libraries will be dynamically loaded. Dynamic linking is recommended.
AVS/Express uses shared libraries on all platforms except AIX, Digital UNIX, Windows NT, and Windows 95. Using shared libraries offers several benefits including smaller executable size and drastically reduced link times when relinking your processes.
If you want to avoid using shared libraries at compile and/or link time, you can do so by setting the NO_DLLIBS environment variable for the make process.
If NO_DLLIBS is set to a non-zero value ("t" or "1" are the recommended values to use), the AVS/Express shared libraries are not generated when compiling or included on the link line when linking - your process is linked with static libraries instead.
- In your project's templ.v file in the build_cmd property
- In the environment of the shell under which AVS/Express is running
Note: Setting NO_DLLIBS does not create a completely statically linked executable. It just prevents linking with the AVS/Express shared libraries. System libraries, X libraries, and so on are still linked dynamically when available.
1. Creates a make file for the process and places it in your project directory. The make file is called process_name.mk. If one already exists, AVS/Express removes it and creates a new one.
2. Generates files called process_name.c, xprocessname.cxx and process_name.h in your project directory.
3. Generates template source files in cases where a method's source file does not exist and the method specifies the src_file property.
6. If successful, places the process' executable in a machine specific subdirectory of your project's bin directory.
While AVS/Express is creating the make file, it sends informational and error messages, if any, to the start-up window (where the V Command Processor appears).
When AVS/Express runs make on the make file, it pops up a window in which any compile-time messages appear.
You cannot rebuild the express executable from within AVS/Express because a process cannot be recompiled while it is executing. To rebuild express, perform the following steps:
1. Prepare a make file for the express process using the Project'Compile pull-down command. In this case, AVS/Express creates the make file but does not submit it.
6. Once you have compiled the express process, make sure to run the process that you have just compiled, not the process in the AVS/Express install directory.
You can compile all process in your project (except base) as defined in proc.v (the ProcTemplates object) at once. Outside of AVS/Express, enter the following command
You can build a specific process from outside of AVS/Express using the command:
Your XP_PATH environment variable must be set properly, such as through the avsenv file.
You can create a new process, in addition to the three built-in ones (express, user, and base).
To create a process while running AVS/Express, use the VCP to traverse to the ProcTemplates object and define your new process like:
When you do a save project, your new proc.v file should look like:
Substitute your process' name for myproc. During the compile process, filenames are generated with your process name as the identifier. You should make sure that your process name is fewer than seven characters to avoid problems on machines that have limitations on filenames greater than eight characters.
Here are some common error messages that may appear in the start-up window when you compile a process:
The process is currently executing. AVS/Express creates the make file, but does not run make on it. Expect this message when you build the express process from within AVS/Express, or when you rebuild an external process, such as user, while the process is running (i.e., you have instanced an object that runs in the process).
Here are some common error messages that appear in the pop-up window while the make file is being processed. The actual messages depend on the operating system:
This message, from the linker, indicates that a required function is missing. If the undefined function belongs to an object you added, it could indicate that you omitted a c_src_files (or similar) property. If the undefined function belongs to an object in one of AVS/Express' kits, your objects may have a dependency that you did not account for with a libdeps property.
You are compiling a function that receives pointers to a C structure you have defined and a bitmask structure generated by AVS/Express. The generated file includes the header file where your C structure is defined, so you do not have to include it again in the function's source file.
Within AVS/Express, you can edit one or more source files. This feature works only with source files specified with the src_file property, and not with source files specified with the c_src_files property. Do the following:
AVS/Express starts your editor (as specified in the EDITOR environment variable) for the selected object's source file and for all source files below the object in the object hierarchy. This is equivalent to a command line that starts the editor on a list of source files.
This section provides information about how the compile process works in AVS/Express. This information is more detailed than is required for average uses of the compile mechanism but may be helpful for implementing and debugging problems with more complicated projects.
The compile process is divided into two main stages: the generate code stage and the build stage. During the generate code stage, AVS/Express generates the code and the makefile to build this process. During the build stage, AVS/Express simply runs the make program on the generated makefile.
The generate code stage makes two passes through the Templates hierarchy to:
The first pass uses the rules described in Section 4.6, Defining an object's process [page 4-29] to determine which objects belong in which process. When AVS/Express marks an object that is needed by this process, it makes sure that the library that contains this object is needed as well. For example, if the UIbutton is needed, the UI library is marked as needed. Note that the other UI objects (e.g., UIshell) are not marked as needed unless they too are needed individually.
When using the Project->Save Compiled Project option, this pass is modified so that only the objects that you have selected are marked as needed for this process. This gives you a process that only contains a subset of the objects defined for this process in templ.v without having to explicitly modify templ.v.
Two properties, libdeps and need_objs, affect the way in which objects are marked as needed.
The libdeps property takes a list of names of AVS/Express template objects. The objects whose names are specified are marked as needed by any process that needs this object. The subobjects of the object are not marked as needed. This is used to guarantee that link_files specified by one library are picked up whenever another library is needed by a process. This is only necessary when this dependency is not expressed by the AVS/Express objects directly.
For example, if you define a library that calls the FLD library but does not contain any FLD objects, you may see the FLD routines undefined when you link. To fix this problem, set the libdeps property to indicate this dependency:
The need_objs property indicates that the objects specified and their subobjects should be marked as needed by any process that needs this object. This is used by a module that dynamically creates objects to ensure that these objects are placed in any compiled project that contains the module.
For example, if you write a module that dynamically creates a UIbutton object and include this object in a compiled project, you may see that the UIbutton object was not included in your project. To fix this problem, you must specify that the UIbutton object is needed with the need_objs property:
AVS/Express generates four different sections of code during the generate code phase:
- initialization code which is executed when the process is started
- generated source definitions
- generated header definitions
- the process makefile
Code that is executed when the process is started is placed into the function BASEinit that is put into the file processname with a .cxx suffix if the file has C++ definitions and a .c suffix if the file only has C definitions.
By default, all source definitions are also put into this file and all header definitions are put into the file processname.h. These defaults are modified by the out_src_file and out_hdr_file properties which set the current file for generated source and header definitions respectively.
The makefile is put into the file processname.mk.
The second pass through the Templates hierarchy generates code for any objects that are marked as needed in the first pass. Code is generated for:
The code generated for a method is
- a declaration of the method in processname.h
- a call to the function OMadd_named_func added to the initialization code that builds a database mapping string names to function pointers
The build_dir property specifies the build directory for this object and its subobjects. If this property is specified with a relative pathname, it is taken to be relative to the project directory. If no build_dir has been specified on an object or its ancestor, the project directory itself is used as the build directory.
All build files processed for this object and its subobjects are taken to be relative to the current build_directory including values taken from the cxx_src_files, c_src_files, cxx_hdr_files, c_hdr_files, src_file, link_files and src_file properties.
These two properties specify one or more header files that contain definitions needed to compile this object or subobjects of this object. A #include of these files is added to the file containing generated header definitions for this object. This is the value of the out_hdr_file property if it has been set, otherwise processname.h.
If the system is able to find an absolute path to each header file (looking for them relative to the current build directory), it adds the header file to a list that is used to generate makefile dependencies for object files in this process. If the header files cannot be found, they are included with a pathname as specified from the property definition. This is not treated as an error but the system does not generate proper dependencies for this case.
These two properties specify one or more header files required for processes that need this object. Rules to construct object files from the source files are added to the process' makefile and these object files are added to the link line for this process. If a process needs an object that has the cxx_src_files property, it causes AVS/Express to use the C++ linker to link that process. These files are specified relative to the current build directory.
The src_file property implements the same logic on its argument as the cxx_src_files property (although it uses the suffix to determine which language this source file is defined in).
In addition, the base types omethod and cxxmethod look into the current value of the src_file property and see if a definition of the function they reference is defined in this file. If not, they generate a prototype of that function and append it to the end of the file specified by src_file. If no version of src_file exists in the project path, one is created in the local directory.
This functionality of generating prototypes can be turned off by setting the use_src_file property to 0 on the object containing the src_file property.
Although AVS/Express sets up and manages projects for you, the architecture is accessible to you. Once you understand the architecture, you can, for instance, create a project that completely replaces the install area project, or that includes a small subset of the install area project's libraries, or that has a completely different appearance in the Network Editor.
The project directory contains, at the minimum, a v directory.
It may also contain other files and directories, like avsenv, make files, project-level source and header files, data directories, source-code directories, and object-file directories.
XP_PATH is an environment variable that specifies a list of project directories, specified as absolute pathnames. Your project's directory (if any) should be specified first, followed by the install area project's directory.
When you start AVS/Express, AVS/Express looks for a definition of XP_PATH. It looks in the places described below, in the order listed:
If XP_PATH is undefined, AVS/Express sets it to the directory two levels above the executable's directory. So if the executable is in /home/express/bin/hp, AVS/Express sets XP_PATH to /home/express.
In V code, $XP_PATH<0> refers to the rightmost pathname in the XP_PATH environment variable. $XP_PATH<1> refers to the pathname to the left of it, and so forth.
For example, given the following
$XP_PATH<0> refers to /home/express, and $XP_PATH<1> refers to /home/users/me/proj1.
avsenv is a file containing environment-variable definitions. You can place any environment variable you want in avsenv. These take effect for AVS/Express only.
AVS/Express generates avsenv for you when you create or save a project. It creates the file in your project directory. Here is what it typically looks like:
# WARNING: this file is program generated. Remove this line to protect
XP_PATH=/home/users/me/proj1 /home/express
The first line tells you, and AVS/Express, that the file was generated by AVS/Express.
You can modify avsenv, for example, by adding other AVS/Express environment variables. If you do, remove the first line; AVS/Express will not regenerate the file the next time you save a project.
At start-up, AVS/Express looks for a file called avsenv. It looks in the following places, in the order listed:
- The directory specified by the -project command-line option, if any.
- The current directory.
- Your home directory (on UNIX systems only).
- The directory two above the executable's directory. So if the executable is in
/home/express/bin/hp, AVS/Express looks in /home/express.templ.v is a V file located in the v directory. templ.v defines the contents of the Templates library, which defines all of the templates that you can use to create new objects.
Here is a sample templ.v file, as it appears in your project directory:
"$XP_PATH<0>/v/templ.v" Templates {
flibrary MYLIB {
module my_module {
int p1;
omethod+notify+read update = "my_module_update";
};
};
};
creates your project's Templates library. Its type is actually a filename. $XP_PATH<0> refers to the rightmost path in XP_PATH, which typically is the install directory. $XP_PATH<0>/v/templ.v refers to the install area project's templ.v file. In this way, Templates for your project starts off with all of the objects in the install area project.
The lines that follow the first one define additions and modifications for your project. In this example, the project contains an additional library and a simple module defined in that library.
proc.v is a V file located in the v directory. proc.v creates an object called ProcTemplates, which lists a project's processes.
Here is a portion of it as it appears in the install area project directory:
This says that the project consists of three processes, known in AVS/Express as express, user, and base. The executable will be given the same name as the name of the process object.
Here is a version of proc.v as it might appear in your project directory:
The line creates your project's ProcTemplates object. Its type is actually a filename. $XP_PATH<0> refers to the rightmost path in XP_PATH, which typically is the install directory, so $XP_PATH<0>/v/proc.v refers to the install area project's proc.v file. In this way, ProcTemplates for your project starts off with all of the processes of the install area project.
You can manually insert other lines to create additional processes. For example:
libs.v is a V file located in the v directory. It includes files that define the libraries as they appear in the Network Editor.
The file that describes the AVS/Express Network Editor layout is lib_xp.v. It is simply a set of NElink objects and libraries of NElink objects, one for each major library collection.
The default AVS/Express environment provides access to a large number of objects in the application development process. AVS/Express provides a feature which allows you to generate a project that contains only a subset of the objects used in the base project. There are two main advantages to using this feature:
- This process eliminates code associated with objects that are not used in the compiled project.
- A compiled project uses a single binary V configuration file to store all of the V state associated with the compiled project. This reduces application start-up time and reduces the number of files required to support the project.
You should consider using this mechanism in the following circumstances:
- when deploying an application built entirely from AVS/Express components
- when deploying an application that is built from code that dynamically creates AVS/Express components
Access to the Save Compiled Project feature is provided through the "Project->Save Compiled Project..." menu entry in the Network Editor:
![]()
For all uses of the compiled project capability, a separate project directory is created that contains local versions of the AVS/Express-generated make and configuration files. This project directory contains a local version of each AVS/Express executable needed by the objects contained in the compiled project.
To use this dialog, you first must specify the directory where the compiled project should be created. This directory need not exist itself (but the parent directory should exist). This value is either entered using the typein or using the file-browser made visible by selecting the Browse button. If the directory specified does exist and already contains a project, the new project replaces the previous project.
You must specify which objects are to be contained in the compiled project. There are two options for this selection:
The first option ensures that all of the currently selected objects are required to be included in the compiled project. The second option automatically chooses the current application as the only object required to be included in the compiled project.
Any objects that are needed by the implementation of the selected objects are automatically included. Thus if you choose a macro object, all objects used by the macro are automatically included in the compiled project. If you choose a library object, all objects in that library are included.
This flag controls whether or not the objects selected for the compiled project operation are automatically instanced by AVS/Express when the main process (express) is started up. You should turn this flag on when you are using AVS/Express to generate a compiled project from a single object that contains the entire definition of the object. You should turn this flag off when your program dynamically creates the AVS/Express objects itself. Make sure that this flag is turned off when the objects you have selected are libraries since it does not make sense to instance a library of objects.
You should turn this flag on if you want the Network Editor to be a part of your project. The Network Editor is instanced when the main process (express) of your project is executed just as in a normal AVS/Express session. As usual, the default creation of the Network Editor can be disabled with the -none command line option.
Since the project you have created contains only a compiled of the system objects, the organization of the Libraries object in the Network Editor also must display a subset of the objects in the system. The current version of AVS/Express does not perform a subset operation on the existing Libraries organization for you. Instead, it creates a default v/libs.v file that displays the contents of the "Templates" object only. This display lists all of the libraries that are included in AVS/Express but in a very raw form. In order to get a better libraries organization, you must create your own customized v/libs.v file.
The save compiled project operation generates a single binary V file that contains the definition of all objects needed to implement the selected set of objects. This flag controls whether this V definition is stored in a separate V file that is loaded when the main process is started or whether the binary definition file is directly linked into the executable of the main process. By linking the V definition file into the executable, you can produce a single stand-alone executable file to deploy an application. Note, however, that any runtime files needed by any objects used by this compiled project will still be required. There are several runtime files, for example, that are required to use the Network Editor in an application.
Linking the V file into the executable takes longer than just storing it in a separate file. In addition, you must always relink the executable if the project is changed. With a separate V definition file, you can make some changes to the project that only require updating the V file and not relinking/rebuilding the project.
The save compiled project operation occurs in two different phases:
- The source for the project is generated. This includes the generation of the binary V definition file, the make files, and source files that AVS/Express requires to build the project.
- The system compiles the project. This amounts to simply running the make program using the generated makefiles.
The compiled project operation provides control over which of these two phases occurs:
- You can "compile" the project without regenerating the source. This would be useful if some C/C++/Fortran code associated with the project was modified but no objects associated with the project were modified. Ensure that the "Compile Project" option is turned on and the "Generate Source" option is turned off to get this behavior.
- You can "generate source" for the project only. This mode is useful if either you are not yet ready to perform the compilation stage or if you are replacing the compilation phase performed by the system.
In most cases, you want to generate source for the project and compile the result. Both options should be turned on.
The compiled project is chained off of the project directories of the active project at the time you compiled your project. You can determine which directories a particular project was created from by looking at the avsenv file in the compiled project directory.
The compiled project uses libraries and object files from these other project directories when its executable is being linked. These other projects must themselves be compiled if they define any new code used by the compiled project.
![]()
This directory contains the object files compiled for this project in a machine specific subdirectory. No files in this subdirectory tree are necessary to run an application built with this project.
This file contains the V definitions for the compiled project if the "Build V into executable" option is turned off. This file is necessary to run any application built from this project. It must be located in the v subdirectory of the XP_PATH when you run your compiled project.
This file is generated if the Network Editor is included in this compiled project. The version of this file that is generated is a simple prototype that you can replace by a custom version if you require one.
All process executables necessary to run this project are placed in the machine specific subdirectory of the bin directory. You can obtain the value of the $MACHINE variable for a particular platform by running the xp_mach shell script. On Windows systems, this value is always just pc.
These files are generated for each process used by this compiled project. They are needed only to compile the project, not to run an application built with the project.
This file is used to store the value of the XP_PATH variable used to construct this project. It is necessary to compile the project and may be necessary to run the project if any components used by this compiled project rely on any files stored relative to XP_PATH.
This file is generated if the flag "Build V into executable" is turned on. This source file contains a hexadecimal description of the binary V description for the objects used by this compiled project. It is needed to compile this project but is not needed to run the compiled project.
The following scenarios illustrate uses of save compiled project:
You have produced an application that is entirely represented using an AVS/Express network and want to produce a version of this application that both runs more efficiently and is easier to hand over to another user. This application is running as the current application. You perform this operation as follows:
3. Select "Save current application" (since the current application is the only object we need in our compiled project).
4. Turn off "Include network editor in project" since the user of this application will not be editing it.
You have constructed an application that dynamically creates and modifies AVS/Express networks. You want to deploy a more efficient version of this application to a set of users. This application dynamically creates objects from the Data Visualization and the Graphics Display kits. To create this compiled project you:
![]() |
![]() |
![]() |
![]() |
![]() |
Copyright © 2001 Advanced Visual Systems
Inc.
All rights reserved.