Background
When a source file ( .prg or .arc) is compiled, then an intermediate file ( .obj or .res ) is created that is finally linked to an executable ( .exe ) or library ( .dll ). The Xbase++ compilers xpp.exe and arc.exe create the intermediates next to their source files. This behavior is often not desired because it quickly clutters the directory with the source files. Furthermore, an object file and consequently also the target ultimately depend on whether a debug or release target is to be created and on the compiler settings specified for the target.OBJ_DIR
In the Xbase++ project file ( .xpj ), a directory in which the intermediate files are created can be specified with the define OBJ_DIR. This way, the directory with the source files remains clear. However, the OBJ_DIR directory is the same for both debug and release builds. If you switch between a Debug and a Release build, it is therefore essential to delete and rebuild all intermediates to avoid mixing of debug and release objects. This is crucial because both versions may contain different code, for example, code sections included/excluded using
Code:
#ifdef DEBUG
INTERMEDIATE_DEBUG and INTERMEDIATE_RELEASE
To avoid mixing of debug and release objects, the definitions INTERMEDIATE_DEBUG and INTERMEDIATE_RELEASE were introduced in the Xbase++ project file. By convention, the values of these defines should be ".debug" and ".release" and both definitions must be present to take effect.
Code:
[PROJECT]
...
[PROJECT.XPJ]
mdidemo.exe
[mdidemo.exe]
...
INTERMEDIATE_DEBUG = .debug
INTERMEDIATE_RELEASE = .release
...
Example for the INTERMEDIATE_DEBUG directory of the MDIDMO application:
Benefits
Easily switch between Debug and Release builds
If you want to switch between a Debug and Release build, it is no longer necessary to delete the intermediates. If the project is rebuilt after such a switch, only those sources are compiled whose intermediates are outdated. Also, because the target binary is stored in the target-specific subdirectory, linking the EXE or DLL is no longer necessary after such a switch when the source files are up-to-date. Instead, the ProjectBuilder simply copies the target binary from its intermediate directory into the target directory.Target-specific defines are safe
// $TW: Is this a good example? I thought we don't want to promote this scenario!Since it is possible to use the same source file in several targets which may use different define values for COMPILE_FLAGS, for example, each target build possibly produces a different intermediate ( .obj ) file. Consider the following example in which target-specific source code is compiled into the target using preprocessor defines.
Code:
[PROJECT]
...
[PROJECT.XPJ]
app-customer-a.exe
app-customer-b.exe
[app-customer-a.exe]
...
INTERMEDIATE_DEBUG = .debug
INTERMEDIATE_RELEASE = .release
COMPILE_FLAGS = /q /dMODULE_CALENDER /dMODULE_MAIL
...
// The menu will have an entry for calender and mailing
main-menu.prg
[app-customer-b.exe]
...
INTERMEDIATE_DEBUG = .debug
INTERMEDIATE_RELEASE = .release
COMPILE_FLAGS = /q /dMODULE_CKALENDER
...
// The menu will have an entry for calender only.
main-menu.prg
Summary
The intermediates of a target depend on whether they were created with or without debug information. However, they also depend on which definitions were passed to the compiler. Other than OBJ_DIR, using the defines INTERMEDIATE_DEBUG and INTERMEDIATE_RELEASE in the project file guarantees that the correct intermediates are linked to the target.References
- Xbase++ documentation: The definitions in a project file