Creating an executable version of your application

The next few sections tell you more about the packaging process and provide information to help you make choices about the resulting application. They cover:

  • Compiler basics

  • What can go in the package

  • How to choose a packaging model

  • How to implement your packaging model

  • How to test the executable application you create

Compiler basics

When you plan an application, one of the fundamental topics to think about is the compiler format in which you want that application generated. PowerBuilder offers two alternatives: Pcode and machine code.

Pcode

Pcode (short for pseudocode) is an interpreted language that is supported on all PowerBuilder platforms. This is the same format that PowerBuilder uses in libraries (PBL files) to store individual objects in an executable state. Advantages of Pcode include its size, reliability, and portability.

Machine code

PowerBuilder generates and compiles code to create a machine code executable or dynamic library. The key advantage of machine code is speed of execution.

PowerBuilder DLLs cannot be called

PowerBuilder machine code DLLs cannot be called from other applications.

Deciding which one to use

Here are some guidelines to help you decide whether Pcode or machine code is right for your project:

  • Speed

    If your application does intensive script processing, you might want to consider using machine code. It will perform better than Pcode if your code makes heavy use of looping constructs, floating point or integer arithmetic, or function calls. If your application does not have these characteristics, machine code does not perform noticeably better than Pcode. If you think your application might benefit from the use of machine code, perform some benchmark testing to find out.

    Pcode is faster to generate than machine code. Even if you plan to distribute your application using machine code, you might want to use Pcode when you want to quickly create an executable version of an application for testing.

  • Size

    The files generated for Pcode are smaller than those generated for machine code. If your application is to be deployed on computers where file size is a major issue, or if you deploy it using a Web download or file transfer, then you might decide to give up the speed of machine code and choose Pcode instead.

Learning what can go in the package

No matter which compiler format you pick, an application that you create in PowerBuilder can consist of one or more of the following pieces:

  • An executable file

  • Dynamic libraries

  • Resources

To decide which of these pieces are required for your particular project, you need to know something about them.

About the executable file

If you are building a single- or two-tier application that you will distribute to users as an executable file, rather than as a Web application, you always create an executable (EXE) file. 

At minimum, the executable file contains code that enables your application to run as a native application on its target platform. That means, for example, that when users want to start your application, they can double-click the executable file's icon on their desktop.

What else can go in the executable file

Depending on the packaging model you choose for your application, the executable file also contains one or more of the following:

  • Compiled versions of objects from your application's libraries

    You can choose to put all of your objects in the executable file so that you have only one file to deliver, or you can choose to split your application into one executable file and one or more dynamic libraries. For more information, see About dynamic libraries.

  • An execution library list that the PowerBuilder execution system uses to find objects and resources in any dynamic libraries you have packaged for the application

  • Resources that your application uses (such as bitmaps)

Figure: Executable file contents

About dynamic libraries

As an alternative to putting your entire application in one large executable file, you can deliver some (or even all) of its objects in one or more dynamic libraries. The way PowerBuilder implements dynamic libraries depends on the compiler format you choose.

If you are generating

Your dynamic libraries will be

Machine code

DLL files (dynamic link libraries).

Machine-code dynamic libraries are given the extension .dll. These dynamic libraries are like any other standard shared libraries in your operating environment. The only caveat is that they are not intended to be called from external programs.

Pcode

PBD files (PowerBuilder dynamic libraries).

These dynamic libraries are similar to DLLs in that they are linked to your application at runtime. They are not interchangeable with DLLs, however, because they have a different internal format.

You cannot mix the two different kinds of dynamic libraries (DLLs and PBDs) in one application.


As with an executable file, only compiled versions of objects (and not their sources) go into dynamic libraries.

Figure: Compiled objects in dynamic libraries

What else can go in dynamic libraries

Unlike your executable file, dynamic libraries do not include any start-up code. They cannot be executed independently. Instead, they are accessed as an application executes when it cannot find the objects it requires in the executable file.

Dynamic libraries can include resources such as bitmaps. You might want to put any resources needed by a dynamic library's objects in its DLL or PBD file. This makes the dynamic library a self-contained unit that can easily be reused. If performance is your main concern, however, be aware that resources are loaded faster at runtime when they are in the executable file.

Figure: Resources in dynamic libraries

Why use them

The following table lists several reasons why you might want to use dynamic libraries.

Reason

Details

Modularity

They let you break up your application into smaller, more modular files that are easier to manage.

Maintainability

They enable you to deliver application components separately. To provide users with a bug fix, you can often give them the particular dynamic library that was affected.

Reusability

They make it possible for multiple applications to reuse the same components because dynamic libraries can be shared among applications as well as among users.

Flexibility

They enable you to provide your application with objects that it references only dynamically at runtime (such as a window object referenced only through a string variable).

You cannot put such objects in your executable file (unless they are DataWindow objects).

Efficiency

They can help a large application use memory efficiently because:

  • PowerBuilder does not load an entire dynamic library into memory at once. Instead, it loads individual objects from the dynamic library only when needed.

  • Your executable file can remain small, making it faster to load and less obtrusive.


Organizing them

Once you decide to use a dynamic library, you need to tell PowerBuilder which library (PBL file) to create it from. PowerBuilder then places compiled versions of all objects from that PBL file into the DLL or PBD file.

If your application uses only some of those objects, you might not want the dynamic library to include the superfluous ones, which only make the file larger. The solution is to:

  1. Create a new PBL file and copy only the objects you want into it.

  2. Use this new PBL file as the source of your dynamic library.

About resources

In addition to PowerBuilder objects such as windows and menus, applications also use various resources. Examples of resources include:

  • Bitmaps that you might display in Picture or PictureButton controls

  • Custom pointers that you might assign to windows

When you use resources, you need to deliver them as part of the application along with your PowerBuilder objects.

What kinds there are

A PowerBuilder application can employ several different kinds of resources. The following table lists resources according to the specific objects in which they might be needed.

These objects

Can use these kinds of resources

Window objects and user objects

Icons (ICO files)

Pictures (BMP, GIF, JPEG, PNG, RLE, and WMF files)

Pointers (CUR files)

DataWindow objects

Pictures (BMP, GIF, JPEG, PNG, RLE, and WMF files)

Menu objects (when in an MDI application)

Pictures (BMP, GIF, JPEG, PNG, RLE, and WMF files)


Delivering them

When deciding how to package the resources that need to accompany your application, you can choose from the following approaches:

  • Include them in the executable file.

    Whenever you create an executable file, PowerBuilder automatically examines the objects it places in that file to see if they explicitly reference any resources (icons, pictures, pointers). It then copies all such resources right into the executable file.

    PowerBuilder does not automatically copy in resources that are dynamically referenced (through string variables). To get such resources into the executable file, you must use a resource (PBR) file. This is simply a text file in which you list existing ICO, BMP, GIF, JPEG, PNG, RLE, WMF, and CUR files.

    Once you have a PBR file, you can tell PowerBuilder to read from it when creating the executable file to determine which additional resources to copy in. (This might even include resources used by the objects in your dynamic libraries, if you decide to put most or all resources in the executable file for performance reasons.)

  • Include them in dynamic libraries.

    You might often need to include resources directly in one or more dynamic libraries, but PowerBuilder does not automatically copy any resources into a dynamic library that you create even if they are explicitly referenced by objects in that file. You need to produce a PBR file that tells PowerBuilder which resources you want in this particular DLL or PBD file.

    Use a different PBR file for each dynamic library in which you want to include resources. (When appropriate, you can even use this approach to generate a dynamic library that contains only resources and no objects. Simply start with an empty PBL file as the source.)

  • Deliver them as separate files.

    This means that when you deploy the application, you give users various image files in addition to the application's executable file and any dynamic libraries. As long as you do not mind delivering a lot of files, this can be useful if you expect to revise some of them in the future.

    Keep in mind that this is not the fastest approach at runtime, because it requires more searching. Whenever your application needs a resource, it searches the executable file and then the dynamic libraries. If the resource is not found, the application searches for a separate file.

    Make sure that your application can find where these separate files are stored, otherwise it cannot display the corresponding resources.

You can use one of these approaches or any combination of them when packaging a particular application.

Using a PBR file to include a dynamically referenced DataWindow object

You might occasionally want to include a dynamically referenced DataWindow object (one that your application knows about only through a string variable) in the executable file you are creating. To do that, you must list its name in a PBR file along with the names of the resources you want PowerBuilder to copy into that executable file.

You do not need to do this when creating a dynamic library, because PowerBuilder automatically includes every DataWindow object from the source library (PBL file) in your new DLL or PBD file.

Creating a PowerBuilder resource file

A PBR file is an ASCII text file in which you list resource names (such as BMP, CUR, ICO, and so on) and DataWindow objects. To create a PBR file, use a text editor. List the name of each resource, one resource on each line, then save the list as a file with the extension PBR. Here is a sample PBR file:

ct_graph.ico
document.ico
codes.ico
button.bmp
next1.bmp
prior1.bmp

To create and use a PowerBuilder resource file:

  1. Using a text editor, create a text file that lists all resource files referenced dynamically in your application (see below for information about creating the file).

    When creating a resource file for a dynamic library, list all resources used by the dynamic library, not just those assigned dynamically in a script.

  2. Specify the resource files in the Project painter. The executable file can have a resource file attached to it, as can each of the dynamic libraries.

    When PowerBuilder builds the project, it includes all resources specified in the PBR file in the executable file or dynamic library. You no longer have to distribute your dynamically assigned resources separately; they are in the application.

Naming resources

If the resource file is in the current directory, you can simply list the file, such as:

FROWN.BMP

If the resource file is in a different directory, include the path to the file, such as:

C:\BITMAPS\FROWN.BMP

Paths in PBR files and scripts must match exactly

The file name specified in the PBR file must exactly match the way the resource is referenced in scripts.

If the reference in a script uses a path, you must specify the same path in the PBR file. If the resource file is not qualified with a path in the script, it must not be qualified in the PBR file.

For example, if the script reads:

p_logo.PictureName = "FROWN.BMP"

then the PBR file must read:

FROWN.BMP

If the PBR file says something like:

C:\MYAPP\FROWN.BMP

and the script does not specify the path, PowerBuilder cannot find the resource at runtime. That is because PowerBuilder does a simple string comparison at runtime. In the preceding example, when PowerBuilder executes the script, it looks for the object identified by the string FROWN.BMP in the executable file. It cannot find it, because the resource is identified in the executable file as C:\MYAPP\FROWN.BMP.

In this case, the picture does not display at runtime; the control is empty in the window.

Including DataWindows objects in a PBR file

To include a DataWindow object in the list, enter the name of the library (with extension PBL) followed by the DataWindow object name enclosed in parentheses. For example:

sales.pbl(d_emplist)

If the DataWindow library is not in the directory that is current when the executable is built, fully qualify the reference in the PBR file. For example:

c:\myapp\sales.pbl(d_emplist)

Choosing a packaging model

As indicated in the previous section, you have many options for packaging an executable version of an application. Here are several of the most common packaging models you might consider.

A standalone executable file

In this model, you include everything (all objects and resources) in the executable file, so that there is just one file to deliver.

Illustration

The following figure shows a sample of what this model can look like.

Figure: Standalone executable model

Use

This model is good for small, simple applications -- especially those that are likely not to need a lot of maintenance. For such projects, this model ensures the best performance and the easiest delivery.

An executable file and external resources

In this model, you include all objects and most resources in the executable file, but you deliver separate files for particular resources.

Illustration

The following figure shows a sample of what this model can look like.

Figure: Executable with external resources model

Use

This model is also for small, simple applications, but it differs from the preceding model in that it facilitates maintenance of resources that are subject to change. In other words, it lets you give users revised copies of specific resources without forcing you to deliver a revised copy of the executable file.

You can also use this model to deal with resources that must be shared by other applications or that are large and infrequently needed.

An executable file and dynamic libraries

In this model, you split up your application into an executable file and one or more dynamic library files (DLLs or PBDs). When doing so, you can organize your objects and resources in various ways. The following table shows some of these techniques.

To organize

You can

Objects

Place them all in dynamic libraries so that there are none in the executable file, which facilitates maintenance, or

Place a few of the most frequently accessed ones in the executable file to optimize access to them and place all the rest in dynamic libraries.

Resources

Place most or all of them in dynamic libraries along with the objects that use them, which facilitates reuse, or

Place most or all of them in the executable file to optimize access to them.


Illustration

The following figure shows a sample of what this model can look like.

Figure: Executable with dynamic libraries model

Use

This model is good for most substantial projects because it gives you flexibility in organizing and maintaining your applications. For instance, it enables you to make revisions to a particular part of an application in one dynamic library.

Note

Whenever you revise an application, Appeon recommends that you always perform a full rebuild and distribute the executable file and all the application's dynamic libraries. For example, changes to any of the following objects might affect other objects:

  • Property names and types

  • Function names

  • Function arguments and return values

  • The sequence of functions or properties in objects or groups

  • Anything that might affect inherited objects in other PBLs

An executable file, dynamic libraries, and external resources

This model is just like the preceding one except that you deliver separate files for particular resources (instead of including all of them in your executable file and dynamic libraries).

Illustration

The following figure shows a sample of what this model can look like.

Figure: Executable with dynamic libraries and external resources model

Use

This model is good for substantial applications, particularly those that call for flexibility in handling certain resources. Such flexibility may be needed if a resource:

  • Might have to be revised

  • Must be shared by other applications

  • Is large and infrequently used

Implementing your packaging model

When you have decided which is the appropriate packaging model for your application, you can use the packaging facilities in PowerBuilder to implement it. For the most part, this involves working in the Project painter. You can use the Project painter to build components, proxy libraries, and HTML files as well as executable applications.

Using the Project painter for executable applications

The Project painter for executable applications orchestrates all aspects of the packaging job by enabling you to:

  • Specify the executable file to create

  • Specify any dynamic libraries (DLL or PBD files) to create

  • Specify the resources you want included in the executable file or in each particular dynamic library (by using appropriate PBR files that indicate where to get those resources)

  • Choose machine code or Pcode as the compiler format to generate

    With machine code, you can also specify a variety of code generation options (such as optimization, trace information, and error context information).

  • Choose build options, including whether you want the Project painter to do a full or incremental rebuild of your application's objects when generating the executable application

  • Save all of these specifications as a project object that you can use whenever necessary to rebuild the whole package

For more information on using the Project painter, see the section called “Using the Project painter” in Users Guide.

Building individual dynamic libraries

When you make revisions to an existing application, your changes might not affect all its dynamic libraries. You can rebuild individual dynamic libraries from the pop-up menu in the System Tree or the Library painter.

If changes are isolated and do not affect inherited objects in other PBLs, you might be able to distribute individual PBDs to your users to provide an upgrade or bug fix. However, Appeon recommends that you always perform a full rebuild and distribute the executable file and all the application's dynamic libraries whenever you revise an application.

Testing the executable application

Once you create the executable version of your application, test how it runs before proceeding with delivery. You may have already executed the application many times within the PowerBuilder development environment, but it is still very important to run the executable version as an independent application -- just the way end users will.

To do this, you:

  1. Leave PowerBuilder and go to your operating system environment.

  2. Make sure that the PowerBuilder runtime libraries are accessible to the application.

    You can do this by verifying that the location of the PowerBuilder virtual machine and other runtime files is in your PATH environment variable, or you can create a registry entry for the application that specifies the path.

  3. Run the application's executable file as you run any native application.

Tracing the application's execution

To help you track down problems, PowerBuilder provides tracing and profiling facilities that you can use in the development environment and when running the executable version of an application. Even if your application's executable is problem free, you might consider using this facility to generate an audit trail of its operation. For more information on tracing execution, see the PowerBuilder Users Guide.