Using the Weak Packaging Directive
Go Up to Compiling Packages
Weak units (weakly packaged units) are units defined in a package (i.e., a package project). However, the linking is different for dynamically linked packages.
Normally, a unit lives in the package itself. The BPI file (package import library) when linked to causes a reference to the package.
In contrast, a weakly packaged unit lives in the BPI itself. This means that even for a dynamically linked package, a weakly packaged unit is directly linked to the package consumer module. Importantly, updating the BPL file separately from recompiling the software using the BPL means that the weakly packaged unit supposedly contained in the BPL is not updated in the software using it, because it's actually in the import library (BPI) and so is linked into the package consumer.
If you use only a weak unit from a package, your application will not depend on that package (i.e., you will not have a dependency on the BPL file). Because instead of an import object, the BPI contains the unit’s object file (as if it were a static package), and the object file is linked in, as a result, there is no dependency on the package itself. In other words, weakly linked units create a mix of dynamic and static, where the weak units are static.
Bellow you have some examples that describes this behavior for Delphi and C++Builder
Delphi
The $WEAKPACKAGEUNIT
directive affects the way a .dcu
file is stored in a package's .dcp
and .bpl
files.
If {$WEAKPACKAGEUNIT ON}
appears in a unit file, the compiler omits the unit from BPLs when possible and creates a non-packaged local copy of the unit when another application or package requires it. A unit compiled with this directive is said to be weakly packaged.
For example, suppose you created a package called pack1 that contains only one unit, unit1. Suppose unit1 does not use any additional units, but it makes calls to rare.dll. If you put the {$WEAKPACKAGEUNIT ON}
directive in unit1.pas (Delphi) or unit1.cpp (C++) when you compile your package, unit1 will not be included in pack1.bpl; you will not have to distribute copies of rare.dll with pack1. However, unit1 will still be included in pack1.dcp. If unit1 is referenced by another package or application that uses pack1, it will be copied from pack1.dcp and compiled directly into the project.
Now suppose you add a second unit, unit2, to pack1. Suppose that unit2 uses unit1. This time, even if you compile pack1 with {$WEAKPACKAGEUNIT ON}
in unit1.pas, the compiler will include unit1 in pack1.bpl. But other packages or applications tha.
{$WEAKPACKAGEUNIT ON}
directive must not have global variables, initialization sections, or finalization sections.The {$WEAKPACKAGEUNIT ON}
directive is an advanced feature intended for developers who distribute their packages to other programmers. It can help you to avoid distribution of infrequently used DLLs, and to eliminate conflicts among packages that may depend on the same external library.
For example, the PenWin unit references PenWin.dll. Most projects don't use PenWin, and most computers don't have PenWin.dll installed on them. For this reason, the PenWin unit is weakly packaged in vcl. When you compile a project that uses PenWin and the vcl package, PenWin is copied from vcl70.dcp and bound directly into your project; the resulting executable is statically linked to PenWin.dll.
If PenWin were not weakly packaged, two problems would arise. First, vcl itself would be statically linked to PenWin.dll, and so you could not load it on any computer that didn't have PenWin.dll installed. Second, if you tried to create a package that contained PenWin, a compiler error would result because the PenWin unit would be contained in both vcl and your package. Thus, without weak packaging, PenWin could not be included in standard distributions of vcl.
C++Builder
The #pragma package(smart_init, weak)
directive affects the way an .obj file is stored in a package's .bpi and .bpl files. (For information about files generated by the compiler and linker, see Packages and Standard DLLs.) If #pragma package(smart_init, weak)
appears in a unit file, the linker omits the unit from bpls when possible, and creates a non-packaged local copy of the unit when it is required by another application or package. A unit compiled with this directive is said to be weakly packaged.
For example, suppose you've created a package called PACK that contains only one unit, UNIT1. Suppose UNIT1 does not use any additional units, but it makes calls to RARE.dll. If you put #pragma package(smart_init, weak)
in UNIT1.cpp when you build your package, UNIT1 will not be included in PACK.bpl; you will not have to distribute copies of RARE.dll with PACK. However, UNIT1 will still be included in PACK.bpi. If UNIT1 is referenced by another package or application that uses PACK, it will be copied from PACK.bpi and linked directly into the project.
Now suppose you add a second unit, UNIT2, to PACK. Suppose that UNIT2 uses UNIT1. This time, even if you compile PACK with #pragma package(smart_init, weak)
in UNIT1.cpp, the linker will include UNIT1 in PACK.bpl. But other packages or applications that reference UNIT1 will use the (non-packaged) copy taken from PACK.bpi.
#pragma package(smart_init, weak)
directive must not have global variables.#pragma package(smart_init, weak)
is an advanced feature intended for developers who distribute their bpls to other C++Builder programmers. It can help you to avoid distribution of infrequently used DLLs, and to eliminate conflicts among packages that may depend on the same external library.
For example, the PenWin unit references PenWin.dll. Most projects do not use PenWin, and most computers do not have PenWin.dll installed on them. For this reason, the PenWin unit is weakly packaged in vcl. When you link a project that uses PenWin and the vcl package, PenWin is copied from vcl60.bpi and bound directly into your project; the resulting executable is statically linked to PenWin.dll.
If PenWin were not weakly packaged, two problems would arise. First, vcl itself would be statically linked to PenWin.dll, and so you could not load it on any computer that did not have PenWin.dll installed. Second, if you tried to create a package that contained PenWin, a build error would result because the PenWin unit would be contained in both vcl and your package. Thus, without weak packaging, PenWin could not be included in standard distributions of vcl.
For more information, see the C++ documentation on #pragma package(smart_init, weak) Delphi documentation on weak packaging and the weak packaging directive.
See Also
- Working with Packages and Components - Overview
- Compiling Packages
- Package-specific Compiler Directives
- Weak packaging Delphi compiler directive