The next few sections tell you more about the packaging process and provide information to help you make choices about the resulting application.
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 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.
Machine code is supported in the PowerBuilder workspace, but unsupported in the PowerBuilder solution.
PowerBuilder DLLs cannot be called
PowerBuilder machine code DLLs cannot be called from other applications.
Configuring PowerBuilder Runtime
Starting from version 2019 R3, a machine-code executable must add the location of PowerBuilder Runtime to the path environment variable or copy the runtime files to the same directory as the executable, before it can be run.
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.
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
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:
|
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:
-
Create a new PBL file and copy only the objects you want into it.
-
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
-
The UI theme files that you apply to your application
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 |
---|---|
Application |
"theme" folder* |
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) |
Note
"theme" folder is unsupported to be referenced by a resource (PBR) file. You can only manually copy it from the "%AppeonInstallPath%\PowerBuilder [version]\IDE" directory to the root of the application installation directory, when creating the application installation package.
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.
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:
-
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.
-
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)
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
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.
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:
-
Leave PowerBuilder and go to your operating system environment.
-
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.
-
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.
You can digitally sign the application's executable file and DLL file compiled in PowerBuilder. Signing a PowerBuilder EXE or DLL is no different from signing the other EXE/DLL. You can contact one of the digital certificate suppliers (such as DigiCert, GlobalSign, Entrust, VeriSign) and follow their instructions to sign the file. Or you may look into related discussions on the website first, for example, How can I digitally sign an executable?.