Using gnatdll (GNAT User’s Guide for Native Platforms)

#### 7.4.8.19 Using `gnatdll` ¶

`gnatdll` is a tool to automate the DLL build process once all the Ada and non-Ada sources that make up your DLL have been compiled. `gnatdll` is actually in charge of two distinct tasks: building both the static import library for the DLL and the actual DLL. You invoke the `gnatdll` command as

>     $ gnatdll [ switches ] list-of-files [ -largs opts ]

where `list-of-files` is a list of ALI and object files. The object file list must be the exact list of objects corresponding to the non-Ada sources whose services are to be included in the DLL. The ALI file list must be the exact list of ALI files for the corresponding Ada sources whose services are to be included in the DLL. If `list-of-files` is missing, only the static import library is generated.

You may specify any of the following switches to `gnatdll`:

`-a[`address']`

  Build a non-relocatable DLL at `address`. If you don’t specify `address`, `gnatdll` uses the default address of `0x11000000`. By default, when this switch is missing, `gnatdll` builds a relocatable DLL. We advise you to build relocatable DLL.

`-bargs `opts'`

  Binder switches. Pass `opts` to the binder.

`-d `dllfile'`

  `dllfile` is the name of the DLL. You must specify this switch for `gnatdll` to do anything. `gnatdll` names the generated import library algorithmically from `dllfile` as shown in the following example: if `dllfile` is `xyz.dll`, the import library name is `libxyz.dll.a`. `gnatdll` obtains the name of the definition file (if not specified by switch `-e`) algorithmically from `dllfile` as shown in the following example: if `dllfile` is `xyz.dll`, the definition file used is `xyz.def`.

`-e `deffile'`

  `deffile` is the name of the definition file.

`-g`

  Generate debugging information. This information is stored in the object file and copied from there to the final DLL file by the linker, where it can be read by the debugger. You must use the `-g` switch if you plan on using the debugger or the symbolic stack traceback.

`-h`

  Help mode. Displays `gnatdll` switch usage information.

`-I`dir'`

  Direct `gnatdll` to search the `dir` directory for source and object files needed to build the DLL. (Search Paths and the Run-Time Library (RTL)).

`-k`

  Removes the `@nn` suffix from the import library’s exported names, but keeps them for the link names. You must specify this switch if you want to use a `Stdcall` function in a DLL for which the `@nn` suffix has been removed. This is the case for most of the Windows NT DLL for example. This switch has no effect if you specify the `-n` switch.

`-l `file'`

  The list of ALI and object files used to build the DLL are listed in `file`, instead of being given in the command line. Each line in `file` contains the name of an ALI or object file.

`-m`

  Generate map file

`-n`

  No Import. Do not create the import library.

`-q`

  Quiet mode. Do not display unnecessary messages.

`-v`

  Verbose mode. Display extra information.

`-largs `opts'`

  Linker switches. Pass `opts` to the linker.

#### `gnatdll` Example ¶

As an example, the command to build a relocatable DLL from `api.adb` once `api.adb` has been compiled and `api.def` created is

>     $ gnatdll -d api.dll api.ali

The above command creates two files: `libapi.dll.a` (the import library) and `api.dll` (the actual DLL). If you want to create only the DLL, just type:

>     $ gnatdll -d api.dll -n api.ali

Alternatively, if you want to create just the import library, type:

>     $ gnatdll -d api.dll

#### `gnatdll` behind the Scenes ¶

This section details the steps involved in creating a DLL. `gnatdll` does these steps for you. Unless you are interested in understanding what goes on behind the scenes, you should skip this section.

We use the previous example of a DLL containing the Ada package `API`, to illustrate the steps necessary to build a DLL. The starting point is a set of objects that make up the DLL and the corresponding ALI files. In the case of this example, this means `api.o` and `api.ali`. To build a relocatable DLL, `gnatdll` does the following:

- builds the base file (`api.base`). A base file gives the information necessary to generate relocation information for the DLL.

      $ gnatbind -n api
      $ gnatlink api -o api.jnk -mdll -Wl,--base-file,api.base

  In addition to the base file, the `gnatlink` command generates an output file `api.jnk`, which can be discarded. The `-mdll` switch asks `gnatlink` to generate the routines `DllMain` and `DllMainCRTStartup` that are called by the Windows loader when the DLL is loaded into memory.

- uses `dlltool` (see Using dlltool) to build the export table (`api.exp`). The export table contains the relocation information in a form which can be used during the final link to ensure that the Windows loader is able to place the DLL anywhere in memory.

      $ dlltool --dllname api.dll --def api.def --base-file api.base \\
                --output-exp api.exp

- builds the base file using the new export table. Note that `gnatbind` must be called once again since the binder generated file has been deleted during the previous call to `gnatlink`.

      $ gnatbind -n api
      $ gnatlink api -o api.jnk api.exp -mdll
            -Wl,--base-file,api.base

- builds the new export table using the new base file and generates the DLL import library `libAPI.dll.a`.

      $ dlltool --dllname api.dll --def api.def --base-file api.base \\
                --output-exp api.exp --output-lib libAPI.a

- Finally, builds the relocatable DLL using the final export table.

      $ gnatbind -n api
      $ gnatlink api api.exp -o api.dll -mdll

#### Using `dlltool` ¶

`dlltool` is the low-level tool used by `gnatdll` to build DLLs and static import libraries. This section summarizes the most common `dlltool` switches. You run `dlltool` as follows:

>     $ dlltool [`switches`]

`dlltool` switches include:

`--base-file `basefile'`

  Read the base file `basefile` generated by the linker. You use this switch to create a relocatable DLL.

`--def `deffile'`

  Read the definition file.

`--dllname `name'`

  Gives the name of the DLL. You use this switch to embed the name of the DLL in the static import library generated by `dlltool` with switch `--output-lib`.

`-k`

  Kill `@nn` from exported names (Windows Calling Conventions for a discussion about `Stdcall`-style symbols).

`--help`

  Prints the `dlltool` switches with a concise description.

`--output-exp `exportfile'`

  Generate an export file `exportfile`. The export file contains the export table (list of symbols in the DLL) and is used to create the DLL.

`--output-lib `libfile'`

  Generate a static import library `libfile`.

`-v`

  Verbose mode.

`--as `assembler-name'`

  Use `assembler-name` as the assembler. The default is `as`.