Chapter 32 Exercises: Deploying Your Application
Part A: Conceptual Understanding
A.1. Explain the difference between a debug build and a release build. List at least four specific differences and explain why each matters.
Guidance
1. Debug symbols (present in debug, stripped in release) — enable the debugger to map execution to source lines but increase file size. 2. Range checking (enabled in debug, disabled in release) — catches array bounds errors but adds overhead. 3. Optimization level (none in debug, -O2/-O3 in release) — optimized code runs faster but is harder to debug. 4. Executable size (15-25 MB debug vs 3-6 MB release) — users should not download unnecessarily large files. 5. Startup time (slower in debug due to debug initialization).A.2. What is the difference between static and dynamic linking? Give an example of each in the context of PennyWise.
Guidance
Static linking compiles library code directly into the executable — the Pascal runtime is statically linked by default, making the executable self-contained. Dynamic linking loads library code from separate files at runtime — SQLite3 is dynamically linked (sqlite3.dll on Windows), meaning the DLL must be present alongside the executable or in the system path. Static linking produces a single file but larger executables. Dynamic linking reduces executable size but creates deployment dependencies.A.3. Why should you test your release build on a clean system (one without development tools installed)?
Guidance
Your development machine has all tools, libraries, and runtime components installed. A clean system may be missing dynamically linked libraries (DLLs/.so files) that your application depends on. Testing on a clean system reveals missing dependencies before your users encounter them. Common issues: missing sqlite3.dll on Windows, missing GTK libraries on a minimal Linux installation, missing code signing on macOS.A.4. Explain the purpose of each file in a macOS .app bundle: Info.plist, MacOS/executable, Resources/icon.icns, Frameworks/.
Guidance
Info.plist: XML file with application metadata (name, version, identifier, icon file name, supported architectures). MacOS/executable: the actual compiled binary. Resources/icon.icns: the application icon in macOS icon format. Frameworks/: bundled dynamic libraries that the application depends on (optional — used when you cannot rely on the library being installed system-wide).
Part B: Exploration and Analysis
B.1. Build PennyWise in both debug and release modes. Compare the executable sizes. On Windows, run the release build from a command prompt to see if any error messages appear about missing DLLs. On Linux, run ldd ./PennyWise on the release build and list all dependencies.
B.2. If you have access to Inno Setup (free download for Windows), create an installer for a simple "Hello World" Lazarus application. Customize the installer wizard with your application name, version, and icon. Verify that the installer creates Start Menu and desktop shortcuts, and that the uninstaller works.
B.3. On your current platform, find where GetAppConfigDir(False) points. Write a small program that creates a config file there and reads it back. This verifies that your application can store persistent settings in the correct location.
Part C: Coding Challenges
C.1. Build Mode Automation (Easy)
Create a shell script (bash or batch) that builds your Lazarus project in both debug and release modes, reports the executable size for each, and copies the release build to a dist/ directory.
C.2. Self-Updating Version Info (Intermediate)
Create an About dialog that displays: application name, version (from a constant), build date (using {$I %DATE%}`), Free Pascal version (using `{$I %FPCVERSION%}), target platform (using {$I %FPCTARGETCPU%}` and `{$I %FPCTARGETOS%}), and a "Copy to Clipboard" button that copies all info as text.
C.3. Portable Mode Detection (Intermediate)
Modify PennyWise to support "portable mode": if a file named portable.flag exists in the application directory, store all configuration and data in the application directory instead of the system config directory. This lets users run PennyWise from a USB drive.
Hints
In FormCreate, checkFileExists(Application.Location + 'portable.flag'). If true, set the config and data paths to Application.Location. Otherwise, use GetAppConfigDir(False). Store the chosen path in a variable that all file operations reference.
C.4. Complete Inno Setup Script (Advanced) Write a complete Inno Setup script for PennyWise that: installs the executable and sqlite3.dll, creates Start Menu and desktop shortcuts, registers the .pw file extension so double-clicking a .pw file opens PennyWise, includes a license agreement page, checks for a minimum Windows version, and offers a custom install path.
C.5. Linux .deb Package (Advanced)
Create the complete directory structure and control files for a .deb package of PennyWise. Include a .desktop file for the application menu and an icon. Build the package with dpkg-deb --build. Test installation with sudo dpkg -i and verify the application appears in the Linux application menu.
Part M: Metacognitive Exercises
M.1. Before reading this chapter, what did you think "deploying an application" involved? How has your understanding changed?
M.2. Think about an application you use daily. How was it delivered to you? (App store, installer, download, pre-installed?) What happens when it updates? How does this compare to the deployment methods described in this chapter?
M.3. The chapter mentioned testing on a clean system. Do you have access to a virtual machine for testing? If not, what is your plan for verifying that your application works on a fresh installation?