From eaee851a2d1bf4c768de753937cea91842867d2e Mon Sep 17 00:00:00 2001 From: Andrew Johnson Date: Tue, 3 Mar 2020 00:58:48 -0600 Subject: [PATCH] Add script to generate *API.h headers --- src/tools/Makefile | 2 + src/tools/makeAPIheader.pl | 141 +++++++++++++++++++++++++++++++++++++ 2 files changed, 143 insertions(+) create mode 100644 src/tools/makeAPIheader.pl diff --git a/src/tools/Makefile b/src/tools/Makefile index c58c923b9..792440591 100644 --- a/src/tools/Makefile +++ b/src/tools/Makefile @@ -29,6 +29,7 @@ PERL_SCRIPTS += epicsProve.pl PERL_SCRIPTS += expandVars.pl PERL_SCRIPTS += fullPathName.pl PERL_SCRIPTS += installEpics.pl +PERL_SCRIPTS += makeAPIheader.pl PERL_SCRIPTS += makeMakefile.pl PERL_SCRIPTS += makeTestfile.pl PERL_SCRIPTS += mkmf.pl @@ -47,6 +48,7 @@ HTMLS += EPICS/Getopts.html HTMLS += EPICS/Path.html HTMLS += EPICS/Readfile.html HTMLS += fullPathName.html +HTMLS += makeAPIheader.html HTMLS += munch.html HTMLS += podToHtml.html HTMLS += podRemove.html diff --git a/src/tools/makeAPIheader.pl b/src/tools/makeAPIheader.pl new file mode 100644 index 000000000..79965a615 --- /dev/null +++ b/src/tools/makeAPIheader.pl @@ -0,0 +1,141 @@ +#!/usr/bin/env perl + +use strict; +use warnings; + +use Getopt::Std; +$Getopt::Std::STANDARD_HELP_VERSION = 1; + +use Pod::Usage; + +=head1 NAME + +makeAPIheader.pl - Create a header for marking API import/export + +=head1 SYNOPSIS + +B [B<-h>] [B<-o> fileAPI.h] stem + +=head1 DESCRIPTION + +Creates a C/C++ header file containing macro definitions for C and +C which on Windows will expand to the appropriate C<__declspec> +and C<__stdcall> keywords and under GCC to a C attribute. + +=head1 OPTIONS + +B understands the following options: + +=over 4 + +=item B<-h> + +Help, display this document as text. + +=item B<-o> fileAPI.h + +Name of the output file to be created. Must end C. + +=back + +If no output filename is set, the filename will be generated by appending +C to the B argument. + +=head1 USAGE FOR EPICS + +In the Makefile that is building a DLL or shared library, set the variable +C to the name of the name of the header file to be generated, +which must end with C. The part before that is referred to as the +I for this library. For example the stem here is C: + + # Generate our library API header file + 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: + + # Set the API Building flag while we are building the code + $(LIBNAME) $(SHRLIBNAME): USR_CPPFLAGS += -DLIBCOM_API_BUILDING + +Replace the string C above with the upper-case version of the stem +that you used in 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 like this: + + LIBCOM_API void epicsExit(int status); + +The header also defines a second macro C 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: + + LIBCOM_API int LIBCOMSTD_API iocshCmd(const char *cmd); + +=cut + +our ($opt_o, $opt_h); + +sub HELP_MESSAGE { + pod2usage(-exitval => 2, -verbose => $opt_h); +} + +HELP_MESSAGE() if !getopts('ho:') || $opt_h || @ARGV != 1; + +my $stem = shift @ARGV; +my $outfile = defined($opt_o) ? $opt_o : "${stem}API.h"; + +die "makeAPIheader.pl: Output filename must end with 'API.h'\n" + unless $outfile =~ m/API\.h$/; + +my $STEM = uc $stem; +my $guard = "INC_${stem}API_H"; + +open my $o, '>', $outfile or + die "makeAPIheader.pl: Can't create $outfile: $!\n"; + +print $o <<"__EOF__"; +/* This is a generated file, do not edit! */ + +#ifndef $guard +#define $guard + +#if defined(_WIN32) || defined(__CYGWIN__) +# define ${STEM}STD_API __stdcall + +# if defined(BUILDING_${stem}_API) && defined(EPICS_BUILD_DLL) +/* Building library as dll */ +# define ${STEM}_API __declspec(dllexport) +# elif !defined(BUILDING_${stem}_API) && defined(EPICS_CALL_DLL) +/* Calling library in dll form */ +# define ${STEM}_API __declspec(dllimport) +# endif + +#elif __GNUC__ >= 4 +# define ${STEM}_API __attribute__ ((visibility("default"))) +#endif + +#if !defined(${STEM}_API) +# define ${STEM}_API +#endif + +#if !defined(${STEM}STD_API) +# define ${STEM}STD_API +#endif + +#endif /* $guard */ + +__EOF__ + +close $o; + + +=head1 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. + +=cut