Projects
An optional project folder: one project.toml names the program, its type, its main module, its output folder and the password of its packed assets. pcpp init makes one, pcpp build builds it, pcpp pack packs its assets, and the editor knows it.
Opt-in
A single .pcpp file needs no project. A project is a folder with project.toml at its root; a build whose main module has no project.toml in its folder or any folder above it is a plain build, exactly as before.
- The project is the nearest
project.tomlfound walking up from the main module's folder. - Only project.toml's main module is a project build. Any other
.pcppin the project folder builds as a plain file. - An invalid project.toml above the file being built stops that build with its PJ reports, whichever file it is: nothing is skipped silently.
- project.toml's
typemust be the main module's kind; a mismatch is CMP0009 (project.toml says the project is a dll, but its main module <path> is not).
Making a project
pcpp init MyProject exe
This makes the folder MyProject in the current folder:
| Path | What it is |
|---|---|
project.toml | the project file, with a fresh random pack password |
src\MyProject.pcpp | the main module, a starter of the type asked for (exe, dll or lib) with a blank header to fill in |
assets\ | the files pcpp pack puts in the .dat (empty) |
pack.cmd | runs pcpp pack on this folder (pcpp.exe must be on PATH) |
- The password is 64 random printable characters (
!to~) from the OS's secure random source; you may replace it. - A folder that already exists is PJ0014 and nothing is written; a name that is not an identifier, a reserved word or a Windows device name is PJ0005.
project.toml
format = 1
[project]
name = "MyProject"
type = "exe"
main = "src/MyProject.pcpp"
output = "output"
[pack]
password = "..."
| Key | Required | Value |
|---|---|---|
format | yes | 1 |
project.name | yes | an identifier: a letter or _, then letters, digits and _ |
project.type | yes | exe, dll or lib |
project.main | yes | the main module, a .pcpp file relative to the project folder |
project.output | no (output) | the output folder, relative to the project folder; not the folder itself, not inside src or assets |
pack.password | no (none) | printable ASCII; empty or absent packs an unencrypted .dat |
Every problem in the file is reported, not only the first:
| Code | Problem |
|---|---|
| PJ0001 | the file cannot be read or is not TOML |
| PJ0002, PJ0003 | a required key is missing, a key holds the wrong kind of value |
| PJ0004 (warning) | an unknown key or table (ignored, so a misspelled optional key is never silently defaulted) |
| PJ0005, PJ0006 | the name or the type is not valid |
| PJ0007, PJ0008 | the main module path is not valid, or the file does not exist |
| PJ0009 | the output folder is not valid |
| PJ0010 | the password holds a character that is not printable ASCII |
| PJ0011 | a format this compiler does not read |
| PJ0012, PJ0013 | project.toml cannot be saved, or the search for it fails |
| PJ0014, PJ0015, PJ0016 | pcpp init: the folder exists, cannot be created, no password can be made |
Building
pcpp build MyProject -r
pcpp build MyProject -r -t x86_64-linux-gnu
pcpp build [<folder>] builds the project whose project.toml is in that folder (the current folder by default, never searched above it) with the same options as a file build. The exe lands in the project's output\bin; -o and @outputpath still win over project.toml's output.
$R:at the start of a directive path is the project root, in every file of a project build:@addmodulepath "$R:units";. In a build with no project it is PR0065. It is a build-time prefix only:SysUtils.ResolvePathgives""for it at run time.- A project build of its own output folder removes the files an earlier build of it put there and this build no longer produces (a
.pdbafter a switch from debug, the old exe after a rename). It keeps one record per target,pcpp-project\<triple>.txt, so a Linux build never removes the Windows exe beside it. A plain build, or a build into another folder, removes nothing.
Packing assets
pcpp pack MyProject
pcpp pack [<folder>] zips the project's assets\, entries named relative to it and deflated, into <output>\bin\<name>.dat with project.toml's password. A build never writes the .dat; pack.cmd runs the same command.
- A
.datis a plain zip with a.datname, so the zip routines that read any zip open it:CreateZipFileIO("$P:MyProject.dat", "sprites/ship.png", ProjectPassword()). - pcpp builds its packer into
<output>\pack\on the first pack; zig's cache makes later packs quick.pcpp --cleanremovespack\in a project's own output folder only. - An empty
assets\packs an empty archive; a project with noassets\folder is an error, exit 1.
ProjectPassword()
ProjectPassword() returns project.toml's pack password at run time, in a project build only (the main module and the units it imports); "" when there is none. Outside a project build it is SM0433.
- The build writes the password into the program scrambled, never as plain text: no whole, UTF-16 or 6-byte run of it is in the exe or the generated C++.
- A
.datpacked before a password change opens no entry until it is packed again.
How strong it is, honestly: the .dat uses ZipCrypto, the zip format's legacy encryption. Its key state is 96 bits, so about 15 random characters already fill it (64 add no strength), and it is weak against someone who knows part of an entry's content. It keeps assets out of casual reach; it is not strong encryption.
In the editor
A folder in the explorer whose project.toml is valid is shown as a project: a badge with its type, its output folder dimmed and collapsed. Inside it, Build and Run build the project whatever file is active, Debug debugs its main module, and Build > Pack (Ctrl+Alt+B) packs its assets. File > New Project... makes a new one. See The editor.