Project and build files
A PowerBuilder application is more than its objects. Beside the libraries sit the files that say what the application is made of and what goes into a build: which targets a workspace or a Solution opens, which libraries each target searches and in what order, which resources the executable carries. They are short text files nobody reads until a build goes wrong, and a change to one of them changes the application as surely as a change to a script, without touching a single object. pb-diff reads each of them into the parts a build depends on, so a comparison of two releases shows those changes by name, beside the objects.
| File | What it is for | What pb-diff compares |
|---|---|---|
Workspace .pbw |
The targets the PowerBuilder IDE opens together, and the one it builds by default | Each target, and each setting |
Target .pbt |
One application: its application object, its library search path and the projects that build it | The library list library by library, each project, each setting |
Solution
.pbsln |
PowerBuilder 2025: the projects a Solution holds - its workspace | Each project |
Project
.pbproj |
PowerBuilder 2025: one application - its target | The library list library by library, each deploy configuration, each setting |
Resource file
.pbr |
The pictures, icons and DataWindow objects a build copies into the executable or a PBD | Each resource, grouped by kind |
PowerGen project
.gen |
E. Crane Computing's PowerGen: the applications it builds, each with its executable, its library list and how each library is built | Each application, its settings and its library list (best-effort) |
All of them are taken from a folder with the objects beside them: add
an application's folder to a File
Selection, or name two release folders to pb-diff.exe,
and they are listed in the summary with the libraries and exports. Each
can also be compared on its own, from New Comparison, the command line
or a source-control client, and merged.
Here are two releases of Order Desk's application folder side by side. The library is compared object by object, and beside its objects are the workspace, the target, the resource file and the tools target release 1.5 added:
A merge keeps the file as its tools write it. An object export is saved in UTF-16LE, the form the Library painter imports. These files are not imported: PowerBuilder and the build tools read them where they lie, and write them in ANSI. A merged build file is therefore saved in the encoding it was read in, with its own line endings, and a merge that decided nothing gives back the file byte for byte.
Workspaces (.pbw)
What it is for. A workspace is what the PowerBuilder
IDE opens with its Open Workspace command: the list of targets shown in
the System Tree, which of them is built by default, and how the IDE
exports objects for source control. PowerBuilder writes it as text in
what its first line calls Save Format:
Save Format v3.0(19990112)
@begin Targets
0 "src\\order_desk.pbt";
1 "tools\\order_tools.pbt";
@end;
DefaultTarget "src\\order_desk.pbt";
What a change does. A target added
or removed is an application the team now builds, or no
longer builds, from that workspace. A changed default
target changes what Deploy and Run act on, and a changed
export encoding (DefaultExportEncode)
changes how every object is written to source control from then on,
which shows as every object changing at the next commit.
What pb-diff shows. Each target is a node under
Targets, named by its path, and each setting is a node
named for what it holds, such as
Default target (DefaultTarget). The number in front of a
target is only its place in the System Tree, and PowerBuilder rewrites
it: a target is identified by its path, so one whose number changed is
the same target, modified, not one deleted and one added.
pb-diff-cli compare application/release-1.4/order_desk.pbw application/release-1.5/order_desk.pbw --format json
(result)
Targets (.pbt)
What it is for. A target is one application in a
workspace: the application object and the library it is in
(appname, applib), the library
list (LibList), and the project objects that build
it. The library list is the library search path: when an object is
referenced, PowerBuilder looks for it in these libraries in this order
and takes the first it finds.
What a change does. The target decides which code the application is made of:
- A library added to the list brings its objects into the application, and one removed takes them out; a reference to one of them no longer compiles.
- A library moved in the list can change which object the application uses, without a single object changing: when two libraries hold an object of the same name, the one earlier in the list wins. This is the change hardest to see any other way.
- A changed application object or application library starts a different application.
- A project added or removed changes what Deploy builds.
What pb-diff shows. Each setting is a node, named
for what it holds. The Library list is one setting with
each library beneath it, so a library added or removed is named. A
library moved is the list modified with no library added or removed
beneath it, and the line shows the order that changed. Each project is a
node named by the project and its library, such as
p_order_desk (orders.pbl).
In Order Desk, release 1.5 adds invoicing.pbl to the
search path:
pb-diff-cli compare application/release-1.4/src/order_desk.pbt application/release-1.5/src/order_desk.pbt --format json
(result)
Merging a workspace or a target. Each target, project and setting is a unit a merge takes or leaves, so two developers who each added a target to a workspace merge cleanly. The library list is taken or left whole, because its order is its meaning: two developers who each changed it meet in a conflict, and the person merging decides the order.
A workspace or a target is compared as a file. Opening one does not
compare the libraries it names: add those libraries, or the folder that
holds them, to compare the objects. Named after @ on a
command line, a workspace or a target is refused, because it is not a
list of arguments.
PowerBuilder 2025 Solutions and projects (.pbsln, .pbproj)
What they are for. A PowerBuilder 2025 Solution is
the new form of a workspace: Convert Workspace to
Solution turns the .pbw into a .pbsln
and each .pbt into a .pbproj. They hold what
the workspace and the targets held, written as XML:
- the solution lists its projects and names the default one;
- a project names its type and application, its
deploy configurations - the project objects that build
the executable, and the folder they build into - and its library
list, one
<Library>element per library in search-path order, with the application library (AppEntry).
What a change does. The same as for a workspace and
a target: a project added or removed is an application built or no
longer built; a library added, removed or moved changes
which code the application is made of and which object it finds first; a
deploy configuration added or removed changes what a build produces.
Appeon's guidance for moving PBL folders is to update the paths in both
the .pbproj and the .pbsln, which is the kind
of change worth reviewing before a commit.
What pb-diff shows. Each project of a solution is a
node under Projects, named by its path; the Projects
node itself shows the default project. A project's settings are nodes,
each deploy configuration is a node named with its project object, and
the Library list is one node with the application
library and each library beneath it. The list is compared line by line:
every element with all its attributes, and every comment, so only an
element's spacing is not a change. A library moved is the list modified
with every library beneath it unchanged: in Order Desk, Solution release
1.6 searches the shared PFC library before invoicing.pbl,
and builds through a new deploy configuration:
pb-diff-cli compare solution/release-1.5/order_desk.pbproj solution/release-1.6/order_desk.pbproj --format json
(result)
Merging. Projects, settings and deploy configurations are units a merge takes or leaves, and the library list is taken or left whole, as for a target. A merged solution or project stays UTF-8, with its byte-order mark or without one exactly as it was, and every line the merge did not decide is copied, so the result opens and builds in PowerBuilder 2025. Being a PowerBuilder 2025 file, it is certified with the Solution's sources (see PowerBuilder 2025 Solutions).
Resource files (.pbr)
What it is for. When PowerBuilder builds an
executable or a dynamic library (PBD or DLL), it copies in the pictures
and icons the objects name in their properties. It cannot see the ones a
script assigns at run time,
p_logo.PictureName = "logo.bmp", nor a DataWindow object
assigned only through a string, dw_1.DataObject = ls_name.
A resource file lists them: one per line, a file name with the path the
script uses, or a DataWindow object written as its library followed by
the object in parentheses, orders.pbl(d_order_lines). The
Project painter attaches one to the executable and one to each dynamic
library, and PowerGen names one for each library it builds.
What a change does. The PBR decides what the delivered application carries:
- A resource removed from the PBR is no longer in the executable. Unless the file is also installed beside it, the picture is blank at run time, or the DataWindow object is not found when a script assigns it.
- A resource added goes into the executable or the PBD, and makes it larger.
- A name whose case changed is a different resource
to PowerBuilder. It finds a resource by comparing the name the script
uses with the name the PBR lists, as strings, so
Customer.bmpin the PBR andcustomer.bmpin a script is a picture that does not display, although Windows would open the file either way. The path must match the same way:.\res\logo.bmpandlogo.bmpare two different resources.
What pb-diff shows. Each line is a resource node,
grouped as DataWindow objects,
Pictures, Icons,
Pointers and Other resources. A
DataWindow object is named by the object and then its library,
d_order_lines (orders.pbl). The order of the lines means
nothing to PowerBuilder, so a reordered PBR compares identical, and
blank lines and the blanks around a name are ignored. A name whose case
changed is paired with its other spelling and reported modified, with
the letters that changed marked.
In Order Desk, release 1.5 dropped the print preview window and its
picture, added an Export invoices picture for the new menu item, and
retyped customer.bmp with a capital C. The tree shows one
picture deleted, one new and one modified:
pb-diff-cli compare application/release-1.4/src/order_desk.pbr application/release-1.5/src/order_desk.pbr --format json
(result)
Merging. Each resource is a unit a merge takes or leaves: restore a deleted resource in a two-way merge, or let a three-way merge carry the resources each developer added into the Base.
PowerGen projects (.gen)
PowerGen, by E. Crane Computing, is a tool many PowerBuilder teams build their applications with. It is not part of PowerBuilder, and pb-diff reads its files best-effort: they are compared and merged, and they are not part of what pb-diff certifies. pb-diff never runs PowerGen.
What it is for. A PowerGen project lists the
applications PowerGen builds, in the order it builds them. For each one
it holds the application library, the executable to write and how, the
icon and the resource file, where the PBDs or DLLs go, and the
library list: one $Library line per
library, saying whether the library is regenerated, whether its objects
go into the executable, a PBD or a DLL, and which resource file it is
built with. The format is documented in PowerGen's own help, under
Understanding Project files:
$PowerGenVersion=17
$ApplicationName="order_desk",0,0,0,0,0,1707259592,1,0,1
$EXEPath=".\order_desk.exe","",1,1,"","",""
$Library=".\orders.pbl","",0,0,0,""
$Library=".\invoicing.pbl","",0,2,0,""
What a change does. The PowerGen project decides what the build delivers: a library moved from the executable into a PBD is a new file to install, a library added or removed changes the code of the application, a library moved in the list changes which object the application finds first, and the runtime named in the header is the PowerBuilder runtime every user needs.
What pb-diff shows. Each application is a node, with
each setting beneath it, named as PowerGen's help names it, such as
Executable ($EXEPath), and its Library
list. Each library beneath the list is named by its path and,
from the two fields the help documents, where its objects go and its
resource file: .\invoicing.pbl (PBD). A library whose build
options changed is that library modified, and a library moved is the
list modified with no library added or removed. Other fields, which
later versions of the format add, are compared as written and not
named.
A PowerGen project must open with its $PowerGenVersion=
line. A file called .gen that does not is not one, and a
PowerGen project saved under another name - a target's
.pbt, say - is not read as PowerGen: see When a file is not what
its name says.
In Order Desk, release 1.5 builds with the PowerBuilder 2025 runtime
and adds invoicing.pbl, built into a PBD:
pb-diff-cli compare application/release-1.4/src/order_desk.gen application/release-1.5/src/order_desk.gen --format json
(result)
Merging. Applications and settings are units a merge takes or leaves, so an application one side added arrives whole, and the library list of an application is taken or left whole, as for a target. A merged project is written in the encoding PowerGen wrote it in.
When a file is not what its name says
pb-diff reads a file as the format its extension names, and never guesses another one from its content. A file whose content is not that format is reported, not quietly read as something else:
- A
.pblor.pbdthat is not a PowerBuilder library - one another tool wrote, a PowerBASIC library for instance - is refused. Opened, dropped or named in New Comparison, it opens nothing and the status bar names it. In a folder or a File Selection it is left out of the comparison, and the summary's notes list it. - A build file or an object export whose content is not its
format - a
.pbtholding a PowerGen project, a.genthat is not one, a.pbprojthat is an MSBuild project - is compared as text. The File Compare shows a warning saying which format it is not and why, and a folder compare lists it in its notes beside its row. A resource file has nothing in it to check, and is refused only when its content is binary.
Each format is checked on what it must open with: a workspace or a
target on its Save Format line, a PowerGen project on its
$PowerGenVersion= line, a Solution on its root
<Solution>, a project on its root
<Project> holding
<Type Name="pb"/>, and an export on its
$PBExportHeader$ line. A file whose name says nothing at
all, such as the temporary files Git hands a diff tool, is the one case
where pb-diff reads the content to tell what it is.