Update generator script

Rename xxxSTD_API to epicsStdCall, don't redefine.
Ensure name stem is a legal C identifier.
Update the Pod text
This commit is contained in:
Andrew Johnson
2020-03-10 23:41:15 -05:00
parent eb817ba056
commit 017d561b8d

View File

@@ -10,17 +10,18 @@ use Pod::Usage;
=head1 NAME
makeAPIheader.pl - Create a header for marking API import/export
makeAPIheader.pl - Create a header for marking API symbols import/export
=head1 SYNOPSIS
B<makeAPIheader.pl> [B<-h>] [B<-o> fileAPI.h] stem
B<makeAPIheader.pl> [B<-h>] [B<-o> path/fileB<API.h>] stem
=head1 DESCRIPTION
Creates a C/C++ header file containing macro definitions for C<STEM_API> and
C<STEMSTD_API> which on Windows will expand to the appropriate C<__declspec>
and C<__stdcall> keywords and under GCC to a C<visibility> attribute.
C<epicsStdCall> which on Windows will expand to the appropriate C<__declspec>
and C<__stdcall> keywords respectively, and on GCC to a C<visibility>
attribute and nothing.
=head1 OPTIONS
@@ -32,58 +33,81 @@ B<makeAPIheader.pl> understands the following options:
Help, display this document as text.
=item B<-o> fileAPI.h
=item B<-o> path/fileB<API.h>
Name of the output file to be created. Must end C<API.h>.
Pathname to the output file to be created. Must end with C<API.h>.
=back
If no output filename is set, the filename will be generated by appending
C<API.h> to the B<stem> argument.
If no output filename is set, the name will be generated by appending
C<API.h> to the I<stem> argument.
=head1 USAGE FOR EPICS
The I<stem> used must be a legal C identifier, starting with a letter or
underscore followed by any combination of digits, letters and underscores.
In the Makefile that is building a DLL or shared library, set the variable
C<API_HEADER> to the name of the name of the header file to be generated,
which must end with C<API.h>. The part before that is referred to as the
I<stem> for this library. For example the stem here is C<libCom>:
=head1 PURPOSE
The generated header and the macros in it replace the C<epicsShare> macros
that were defined in the C<shareLib.h> header, avoiding the need for shared
library implementation code to define the C<epicsExportSharedSymbols> macro in
between the import and export headers. The order of including header files no
longer matters when using this approach.
=head1 USING WITH EPICS
In a Makefile that is building a DLL or shared library, set the variable
C<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 C<API.h>. The C identifier
part preceeding the C<API.h> is referred to here as the I<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 C<libCom>:
# Generate our library API header file
API_HEADER = libComAPI.h
API_HEADER += libComAPI.h
Lower down in the RULES section of the same Makefile (below the line that
includes the C<$(TOP)/configure/RULES> file), add a line like this:
says C<include $(TOP)/configure/RULES>), add another line like this:
# Set the API Building flag while we are building the code
$(LIBNAME) $(SHRLIBNAME): USR_CPPFLAGS += -DLIBCOM_API_BUILDING
$(LIBNAME) $(SHRLIBNAME): USR_CPPFLAGS += -DBUILDING_libCom_API
Replace the string C<LIBCOM> above with the upper-case version of the stem
that you used in your header filename.
For your library replace the string C<libCom> in the last word above with
the stem from your header filename.
Then in each header and source file that declares or defines a routine to be
exported by the library, decorate the routine declaration or definition with
the keyword C<STEM_API> like this:
Then in each header file that declares a function, global variable or C++
class or method to be exported by the library, decorate those declarations
with the all-uppercase keyword C<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 header also defines a second macro C<STEMSTD_API> which is for Windows
builds to indicate that the calling convention for this routine must be
C<__stdcall>. If needed, this macro should be placed between the return type
and the routine name, like this:
The generated header file also defines a second macro C<epicsStdCall> which on
Windows expands to C<__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 LIBCOMSTD_API iocshCmd(const char *cmd);
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.
=cut
our ($opt_o, $opt_h);
sub HELP_MESSAGE {
pod2usage(-exitval => 2, -verbose => $opt_h);
pod2usage(-exitval => 2, -verbose => $opt_h ? 2 : 0);
}
HELP_MESSAGE() if !getopts('ho:') || $opt_h || @ARGV != 1;
my $stem = shift @ARGV;
die "makeAPIheader.pl: API stem '$stem' is not a legal C identifier\n"
unless $stem =~ m/^ [A-Za-z_][0-9A-Za-z_]* $/x;
my $outfile = defined($opt_o) ? $opt_o : "${stem}API.h";
die "makeAPIheader.pl: Output filename must end with 'API.h'\n"
@@ -102,7 +126,10 @@ print $o <<"__EOF__";
#define $guard
#if defined(_WIN32) || defined(__CYGWIN__)
# define ${STEM}STD_API __stdcall
# if !defined(epicsStdCall)
# define epicsStdCall __stdcall
# endif
# if defined(BUILDING_${stem}_API) && defined(EPICS_BUILD_DLL)
/* Building library as dll */
@@ -120,8 +147,8 @@ print $o <<"__EOF__";
# define ${STEM}_API
#endif
#if !defined(${STEM}STD_API)
# define ${STEM}STD_API
#if !defined(epicsStdCall)
# define epicsStdCall
#endif
#endif /* $guard */