Visual Basic

The Linker

As I've already said, C2.EXE compiles each component to an object file. When all the components are compiled, they are linked using LINK.EXE. Table 7-3 lists the command line arguments you might find in a typical run when creating an EXE containing a single form, class module, and standard module. The only compile option switched on for this run was Create Symbolic Debug Info. This information was captured using the OUTARGS.EXE program.

Again, LINK.EXE is taken from the Visual C++ 6.0 compiler. At the time of writing, its version number was 6.00.8168.0-exactly the same version as that supplied with C2.DLL. See the Visual C++ documentation or MSDN for more information regarding these linker switches.

The linker is also used to create a p-code application, by the way. The difference in the invocation is that VBAEXE6.LIB is not linked in and that only one object file is used as input-ProjectName.OBJ.

Table 7-3 Command-Line Switches for the Linker

Switch Explanation
C:\TEMP\Form1.OBJ Form OBJ file
C:\TEMP\Module1.OBJ Module OBJ file
C:\TEMP\Class1.OBJ Class OBJ file
C:\TEMP\Project1.OBJ Project OBJ file
C:\PROGRAM FILES\VISUAL STUDIO\VB\VBAEXE6.LIB Library of Visual Basic OBJs
/ENTRY:__vbaS Sets the starting address for an executable file or DLL. The entry point should be a function that is defined with the stdcall calling convention. The parameters and the return value must be defined as documented in the Win32 API for WinMain (for an . EXE) or DllEntryPoint (for a DLL). This entry point is in your <project name>.OBJ file-here it will be in PROJECT1.OBJ. Note that neither Sub Main nor Form_Load is mentioned.
/OUT:C:\TEMP\Project1.exe The output file-the EXE!
/BASE:0x400000 Sets a base address for the program, overriding the default location for an executable file (at 0x400000) or a DLL (at 0x10000000). The operating system first attempts to load a program at its specified or default base address. If sufficient space is not available there, the system relocates the program. To prevent relocation, use the /FIXED option. The BASE generated by Visual Basic 6 for an ActiveX DLL is 0x11000000-something that's different from the default at last.
/SUBSYSTEM:WINDOWS,4.0 Tells the operating system how to run the .EXE file. (Options include CONSOLE | WINDOWS | NATIVE | POSIX.)
/VERSION:1.0 Tells the linker to put a version number in the header of the executable file or DLL. (This option has nothing to do with a VERSIONINFO resource.) The major and minor arguments are decimal numbers in the range 0 through 65535. The default is version 0.0. Visual Basic uses the Major and Minor settings on the Make tab of the Project Properties dialog box for these values. This switch is used to document the image version as shown by DUMPBIN.EXE (another Microsoft Visual C++ tool).
/DEBUG Creates debugging information for the executable file or DLL. The linker puts the debugging information into a program database (PDB). It updates the program database during subsequent builds of the program.
/DEBUGTYPE:{CV|COFF|BOTH} Generates debugging information in one of three ways: Microsoft format, COFF format, or both. CV is CodeView; COFF is Common Object File Format.
/INCREMENTAL:NO Specifies whether incremental linking is required.
/OPT:REF Excludes unreferenced packaged functions from the executable file. Packaged functions are created using the Gy flag at compile time (see Table 7-1). Packaged functions have several uses (not mentioned here) and are created automatically, sometimes by the compiler. For example, C++ member functions are automatically packaged.
/MERGE:from=to Combines the first section (from) with the second section (to), naming the resulting section "to". If the second section does not exist, LINK renames the section "from" as "to". The /MERGE option is most useful for creating VxDs and for overriding the compiler-generated section names.
/IGNORE:4078 Ignores certain warnings (defined in LINK.ERR). 4078 means that LINK found two or more sections that have the same name but different attributes.

Why these switches?

I have no idea why some of these switches are used explicitly (on the compiler also), particularly since some are set to the default anyway. Perhaps some of the reasons for using these switches will be documented at later.