makeAPIheader.pl

# NAME

makeAPIheader.pl - Create a header for marking API symbols import/export

# SYNOPSIS

makeAPIheader.pl [-h] [-o path/fileAPI.h] stem

# DESCRIPTION

Creates a C/C++ header file containing macro definitions for `STEM_API` and `epicsStdCall` which on Windows will expand to the appropriate `__declspec` and `__stdcall` keywords respectively, and on GCC to a `visibility` attribute and nothing.

# OPTIONS

makeAPIheader.pl understands the following options:

-h

  Help, display this document as text.

-o path/fileAPI.h

  Pathname to the output file to be created. Must end with `API.h`.

If no output filename is set, the name will be generated by appending `API.h` to the stem argument.

The stem used must be a legal C identifier, starting with a letter or underscore followed by any combination of digits, letters and underscores.

# PURPOSE

The generated header and the macros in it replace the `epicsShare` macros that were defined in the `shareLib.h` header, avoiding the need for shared library implementation code to define the `epicsExportSharedSymbols` macro in between the import and export headers. The order of including header files no longer matters when using this approach.

For libraries that contain EPICS record, device, driver or link support and use the epicsExport.h macros to publish the associated support entry table for the IOC to locate, switching from shareLib.h to a generated API header file is not recommended. The old approach is simpler in these cases.

# USING WITH EPICS

In a Makefile that is building a DLL or shared library, set the variable `API_HEADER` to the name of the API header file to be generated. This name must start with a legal C identifier and end with `API.h`. The C identifier part preceeding the `API.h` is referred to here as the stem for this header file, and should be a short name in lower case or camelCase. For example the stem used in the example here is `libCom`:

        # Generate our library API header file
        API_HEADER += libComAPI.h

The Makefile also needs to find the API stem given the name of the library. These may be different, as shown in our example since the libCom API actually gets used by a library whose formal name is just "Com". This relationship is indicated by setting the `library_API` variable to the API stem, like this:

        # Library to build:
        LIBRARY = Com
        # API stem for the Com library
        Com_API = libCom

Then in each header file that declares a function, global variable or C++ class or method to be exported by the library, include the generated header file and then decorate those declarations with the all-uppercase keyword `STEM_API` as in these examples:

        LIBCOM_API void epicsExit(int status);
        LIBCOM_API int asCheckClientIP;
        class LIBCOM_API epicsTime { ... }
        LIBCOM_API virtual ~fdManager ();

The generated header file also defines a second macro `epicsStdCall` which on Windows expands to `__stdcall` to indicate the calling convention for this routine. When used, this macro should be placed between the return type and the routine name, like this:

        LIBCOM_API int epicsStdCall iocshCmd(const char *cmd);

It is possible to build more than one shared library in the same Makefile, although each C or C++ source file can only be included in one library. Just repeat the above instructions, using different stems for each library.

# COPYRIGHT AND LICENSE

Copyright (C) 2020 UChicago Argonne LLC, as Operator of Argonne National Laboratory.

This software is distributed under the terms of the EPICS Open License.