Octave: use pre-compiled headers to speed up test suite, if supported

This commit is contained in:
Karl Wette 2020-05-29 17:05:01 +10:00
commit d11e29615d
12 changed files with 225 additions and 133 deletions

2
.gitignore vendored
View file

@ -173,6 +173,8 @@ Examples/ocaml/**/swigp4.ml
# Octave
swigexample*.oct
Examples/test-suite/octave/*.oct
Examples/test-suite/octave/octheaders.hpp
Examples/test-suite/octave/octheaders.hpp.gch
# Perl5
Examples/test-suite/perl5/*.pm

View file

@ -58,6 +58,7 @@ INTERFACE =
INTERFACEDIR =
INTERFACEPATH = $(SRCDIR)$(INTERFACEDIR)$(INTERFACE)
SWIGOPT =
PCHSUPPORT = @PCHSUPPORT@
# SWIG_LIB_DIR and SWIGEXE must be explicitly set by Makefiles using this Makefile
SWIG_LIB_DIR = ./Lib
@ -438,14 +439,37 @@ OCTAVE_SO = @OCTAVE_SO@
OCTAVE_SCRIPT = $(SRCDIR)$(RUNME).m
# ----------------------------------------------------------------
# Pre-compile Octave headers, if supported
# ----------------------------------------------------------------
ifeq (yes,$(PCHSUPPORT))
octave_precompile_headers:
echo "precompiling $(OCTHEADERS)"
cp -f $(OCTHEADERSSRC) $(OCTHEADERS)
if $(CXX) -c $(CCSHARED) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) $(OCTAVE_CXX) $(OCTHEADERS); then \
: ; \
else \
rm -f $(OCTHEADERSGCH); \
exit 1; \
fi
else
octave_precompile_headers:
echo "precompiling Octave headers not supported"; exit 1
endif
# ----------------------------------------------------------------
# Build a C dynamically loadable module
# Note: Octave requires C++ compiler when compiling C wrappers
# ----------------------------------------------------------------
octave: $(SRCDIR_SRCS)
$(SWIG) -octave $(SWIGOPT) -o $(ICXXSRCS) $(INTERFACEPATH)
$(CXX) -g -c $(CCSHARED) $(CPPFLAGS) $(CXXFLAGS) $(ICXXSRCS) $(INCLUDES) $(OCTAVE_CXX)
$(SWIG) -octave $(SWIGOCTHDROPT) $(SWIGOPT) -o $(ICXXSRCS) $(INTERFACEPATH)
$(CXX) -g -c $(IOCTHEADERS) $(CCSHARED) $(CPPFLAGS) $(CXXFLAGS) $(ICXXSRCS) $(INCLUDES) $(OCTAVE_CXX)
$(CC) -g -c $(CCSHARED) $(CPPFLAGS) $(CFLAGS) $(SRCDIR_SRCS) $(SRCDIR_CSRCS) $(INCLUDES)
$(LDSHARED) $(CFLAGS) $(LDFLAGS) $(OBJS) $(IOBJS) $(OCTAVE_DLNK) $(LIBS) -o $(LIBPREFIX)$(TARGET)$(OCTAVE_SO)
@ -454,8 +478,8 @@ octave: $(SRCDIR_SRCS)
# -----------------------------------------------------------------
octave_cpp: $(SRCDIR_SRCS)
$(SWIG) -c++ -octave $(SWIGOPT) -o $(ICXXSRCS) $(INTERFACEPATH)
$(CXX) -g -c $(CCSHARED) $(CPPFLAGS) $(CXXFLAGS) $(ICXXSRCS) $(SRCDIR_SRCS) $(SRCDIR_CXXSRCS) $(INCLUDES) $(OCTAVE_CXX)
$(SWIG) -c++ -octave $(SWIGOCTHDROPT) $(SWIGOPT) -o $(ICXXSRCS) $(INTERFACEPATH)
$(CXX) -g -c $(IOCTHEADERS) $(CCSHARED) $(CPPFLAGS) $(CXXFLAGS) $(ICXXSRCS) $(SRCDIR_SRCS) $(SRCDIR_CXXSRCS) $(INCLUDES) $(OCTAVE_CXX)
$(CXXSHARED) -g $(CXXFLAGS) $(LDFLAGS) $(OBJS) $(IOBJS) $(OCTAVE_DLNK) $(LIBS) $(CPP_DLLIBS) -o $(LIBPREFIX)$(TARGET)$(OCTAVE_SO)
# -----------------------------------------------------------------
@ -481,6 +505,7 @@ octave_clean:
rm -f *_wrap* *~ .~* myoctave@EXEEXT@ *.pyc
rm -f core @EXTRA_CLEAN@
rm -f *.@OBJEXT@ *@SO@ *$(OCTAVE_SO)
rm -f $(OCTHEADERS) $(OCTHEADERSGCH)
##################################################################
##### GUILE ######

View file

@ -8,25 +8,25 @@ TARGET = swigexample
INTERFACE = example.i
check: build
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' octave_run
$(MAKE) -f $(TOP)/Makefile PCHSUPPORT=no SRCDIR='$(SRCDIR)' octave_run
build:
ifneq (,$(SRCS))
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' SRCS='$(SRCS)' \
$(MAKE) -f $(TOP)/Makefile PCHSUPPORT=no SRCDIR='$(SRCDIR)' SRCS='$(SRCS)' \
SWIG_LIB_DIR='$(SWIG_LIB_DIR)' SWIGEXE='$(SWIGEXE)' \
SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' octave
else
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' CXXSRCS='$(CXXSRCS)' \
$(MAKE) -f $(TOP)/Makefile PCHSUPPORT=no SRCDIR='$(SRCDIR)' CXXSRCS='$(CXXSRCS)' \
SWIG_LIB_DIR='$(SWIG_LIB_DIR)' SWIGEXE='$(SWIGEXE)' \
SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' octave_cpp
endif
ifneq (,$(TARGET2)$(SWIGOPT2))
ifneq (,$(SRCS))
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' SRCS='$(SRCS)' \
$(MAKE) -f $(TOP)/Makefile PCHSUPPORT=no SRCDIR='$(SRCDIR)' SRCS='$(SRCS)' \
SWIG_LIB_DIR='$(SWIG_LIB_DIR)' SWIGEXE='$(SWIGEXE)' \
SWIGOPT='$(SWIGOPT2)' TARGET='$(TARGET2)' INTERFACE='$(INTERFACE)' octave
else
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' CXXSRCS='$(CXXSRCS)' \
$(MAKE) -f $(TOP)/Makefile PCHSUPPORT=no SRCDIR='$(SRCDIR)' CXXSRCS='$(CXXSRCS)' \
SWIG_LIB_DIR='$(SWIG_LIB_DIR)' SWIGEXE='$(SWIGEXE)' \
SWIGOPT='$(SWIGOPT2)' TARGET='$(TARGET2)' INTERFACE='$(INTERFACE)' octave_cpp
endif
@ -34,4 +34,4 @@ endif
clean:
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' octave_clean
$(MAKE) -f $(TOP)/Makefile PCHSUPPORT=no SRCDIR='$(SRCDIR)' octave_clean

View file

@ -5,6 +5,7 @@
LANGUAGE = octave
OCTAVE = @OCTAVE@
SCRIPTSUFFIX = _runme.m
PCHSUPPORT = @PCHSUPPORT@
srcdir = @srcdir@
top_srcdir = @top_srcdir@
@ -61,6 +62,23 @@ CSRCS = octave_empty.c
+$(swig_and_compile_multi_cpp)
$(run_testcase)
# Pre-compile Octave headers, if supported
ifeq (yes,$(PCHSUPPORT))
export OCTHEADERSSRC = @top_srcdir@/Lib/octave/octheaders.hpp
export OCTHEADERS = @top_builddir@/Examples/test-suite/octave/octheaders.hpp
export OCTHEADERSGCH = $(OCTHEADERS).gch
export SWIGOCTHDROPT = -DSWIG_OCTAVE_EXTERNAL_OCTHEADERS
export IOCTHEADERS = -I@top_builddir@/Examples/test-suite/octave @PCHINCLUDEARG@ $(OCTHEADERS)@PCHINCLUDEEXT@
$(OCTHEADERSGCH): $(OCTHEADERSSRC)
$(MAKE) -f $(top_builddir)/$(EXAMPLES)/Makefile octave_precompile_headers
$(NOT_BROKEN_TEST_CASES) $(BROKEN_TEST_CASES): $(OCTHEADERSGCH)
endif
# Runs the testcase. A testcase is only run if
# a file is found which has _runme.m appended after the testcase name.
run_testcase = \

View file

@ -7,8 +7,6 @@
# define SWIG_DIRECTOR_CAST(ARG) dynamic_cast<Swig::Director *>(ARG)
#include <exception>
namespace Swig {
class Director {

View file

@ -0,0 +1,2 @@
# see top-level Makefile.in
octheaders.hpp

View file

@ -11,12 +11,6 @@
* be the case.
* ----------------------------------------------------------------------------- */
%{
#include <climits>
#include <iostream>
%}
#if !defined(SWIG_NO_EXPORT_ITERATOR_METHODS)
# if !defined(SWIG_EXPORT_ITERATOR_METHODS)
# define SWIG_EXPORT_ITERATOR_METHODS SWIG_EXPORT_ITERATOR_METHODS
@ -64,7 +58,6 @@ namespace swig {
%fragment("OctSequence_Base","header",fragment="<stddef.h>")
{
%#include <functional>
namespace std {
template <>

130
Lib/octave/octheaders.hpp Normal file
View file

@ -0,0 +1,130 @@
//
// This header includes all C++ headers required for generated Octave wrapper code.
// Using a single header file allows pre-compilation of Octave headers, as follows:
// * Check out this header file:
// swig -octave -co octheaders.hpp
// * Pre-compile header file into octheaders.hpp.gch:
// g++ -c ... octheaders.hpp
// * Use pre-compiled header file:
// g++ -c -include octheaders.hpp ...
//
#if !defined(_SWIG_OCTAVE_OCTHEADERS_HPP)
#define _SWIG_OCTAVE_OCTHEADERS_HPP
// Required C++ headers
#include <cstdlib>
#include <climits>
#include <iostream>
#include <exception>
#include <functional>
#include <complex>
#include <string>
#include <vector>
#include <map>
// Minimal headers to define Octave version
#include <octave/oct.h>
#include <octave/version.h>
// Macro for enabling features which require Octave version >= major.minor.patch
// - Use (OCTAVE_PATCH_VERSION + 0) to handle both '<digit>' (released) and '<digit>+' (in development) patch numbers
#define SWIG_OCTAVE_PREREQ(major, minor, patch) \
( (OCTAVE_MAJOR_VERSION<<16) + (OCTAVE_MINOR_VERSION<<8) + (OCTAVE_PATCH_VERSION + 0) >= ((major)<<16) + ((minor)<<8) + (patch) )
// Reconstruct Octave major, minor, and patch versions for releases prior to 3.8.1
#if !defined(OCTAVE_MAJOR_VERSION)
# if !defined(OCTAVE_API_VERSION_NUMBER)
// Hack to distinguish between Octave 3.8.0, which removed OCTAVE_API_VERSION_NUMBER but did not yet
// introduce OCTAVE_MAJOR_VERSION, and Octave <= 3.2, which did not define OCTAVE_API_VERSION_NUMBER
# include <octave/ov.h>
# if defined(octave_ov_h)
# define OCTAVE_MAJOR_VERSION 3
# define OCTAVE_MINOR_VERSION 8
# define OCTAVE_PATCH_VERSION 0
# else
// Hack to distinguish between Octave 3.2 and earlier versions, before OCTAVE_API_VERSION_NUMBER existed
# define ComplexLU __ignore
# include <octave/CmplxLU.h>
# undef ComplexLU
# if defined(octave_Complex_LU_h)
// We know only that this version is prior to Octave 3.2, i.e. OCTAVE_API_VERSION_NUMBER < 37
# define OCTAVE_MAJOR_VERSION 3
# define OCTAVE_MINOR_VERSION 1
# define OCTAVE_PATCH_VERSION 99
# else
// OCTAVE_API_VERSION_NUMBER == 37
# define OCTAVE_MAJOR_VERSION 3
# define OCTAVE_MINOR_VERSION 2
# define OCTAVE_PATCH_VERSION 0
# endif // defined(octave_Complex_LU_h)
# endif // defined(octave_ov_h)
// Correlation between Octave API and version numbers extracted from Octave's
// ChangeLogs; version is the *earliest* released Octave with that API number
# elif OCTAVE_API_VERSION_NUMBER >= 48
# define OCTAVE_MAJOR_VERSION 3
# define OCTAVE_MINOR_VERSION 6
# define OCTAVE_PATCH_VERSION 0
# elif OCTAVE_API_VERSION_NUMBER >= 45
# define OCTAVE_MAJOR_VERSION 3
# define OCTAVE_MINOR_VERSION 4
# define OCTAVE_PATCH_VERSION 1
# elif OCTAVE_API_VERSION_NUMBER >= 42
# define OCTAVE_MAJOR_VERSION 3
# define OCTAVE_MINOR_VERSION 3
# define OCTAVE_PATCH_VERSION 54
# elif OCTAVE_API_VERSION_NUMBER >= 41
# define OCTAVE_MAJOR_VERSION 3
# define OCTAVE_MINOR_VERSION 3
# define OCTAVE_PATCH_VERSION 53
# elif OCTAVE_API_VERSION_NUMBER >= 40
# define OCTAVE_MAJOR_VERSION 3
# define OCTAVE_MINOR_VERSION 3
# define OCTAVE_PATCH_VERSION 52
# elif OCTAVE_API_VERSION_NUMBER >= 39
# define OCTAVE_MAJOR_VERSION 3
# define OCTAVE_MINOR_VERSION 3
# define OCTAVE_PATCH_VERSION 51
# else // OCTAVE_API_VERSION_NUMBER == 38
# define OCTAVE_MAJOR_VERSION 3
# define OCTAVE_MINOR_VERSION 3
# define OCTAVE_PATCH_VERSION 50
# endif // !defined(OCTAVE_API_VERSION_NUMBER)
#endif // !defined(OCTAVE_MAJOR_VERSION)
// Required Octave headers
#include <octave/Cell.h>
#include <octave/dynamic-ld.h>
#include <octave/oct-env.h>
#include <octave/oct-map.h>
#include <octave/ov-scalar.h>
#include <octave/ov-fcn-handle.h>
#include <octave/parse.h>
#if SWIG_OCTAVE_PREREQ(4,2,0)
#include <octave/interpreter.h>
#else
#include <octave/toplev.h>
#endif
#include <octave/unwind-prot.h>
#if SWIG_OCTAVE_PREREQ(4,2,0)
#include <octave/call-stack.h>
#endif
#endif // !defined(_SWIG_OCTAVE_OCTHEADERS_HPP)

View file

@ -89,10 +89,6 @@ SWIGRUNTIME void SWIG_Octave_SetModule(void *clientdata, swig_module_info *point
// Runtime API implementation
#include <map>
#include <vector>
#include <string>
typedef octave_value_list(*octave_func) (const octave_value_list &, int);
class octave_swig_type;

View file

@ -1,111 +1,10 @@
#ifdef SWIG_OCTAVE_EXTERNAL_OCTHEADERS
%insert(runtime) %{
#include <cstdlib>
#include <iostream>
#include <octave/oct.h>
#include <octave/version.h>
// Macro for enabling features which require Octave version >= major.minor.patch
// - Use (OCTAVE_PATCH_VERSION + 0) to handle both '<digit>' (released) and '<digit>+' (in development) patch numbers
#define SWIG_OCTAVE_PREREQ(major, minor, patch) \
( (OCTAVE_MAJOR_VERSION<<16) + (OCTAVE_MINOR_VERSION<<8) + (OCTAVE_PATCH_VERSION + 0) >= ((major)<<16) + ((minor)<<8) + (patch) )
// Reconstruct Octave major, minor, and patch versions for releases prior to 3.8.1
#if !defined(OCTAVE_MAJOR_VERSION)
# if !defined(OCTAVE_API_VERSION_NUMBER)
// Hack to distinguish between Octave 3.8.0, which removed OCTAVE_API_VERSION_NUMBER but did not yet
// introduce OCTAVE_MAJOR_VERSION, and Octave <= 3.2, which did not define OCTAVE_API_VERSION_NUMBER
# include <octave/ov.h>
# if defined(octave_ov_h)
# define OCTAVE_MAJOR_VERSION 3
# define OCTAVE_MINOR_VERSION 8
# define OCTAVE_PATCH_VERSION 0
# else
// Hack to distinguish between Octave 3.2 and earlier versions, before OCTAVE_API_VERSION_NUMBER existed
# define ComplexLU __ignore
# include <octave/CmplxLU.h>
# undef ComplexLU
# if defined(octave_Complex_LU_h)
// We know only that this version is prior to Octave 3.2, i.e. OCTAVE_API_VERSION_NUMBER < 37
# define OCTAVE_MAJOR_VERSION 3
# define OCTAVE_MINOR_VERSION 1
# define OCTAVE_PATCH_VERSION 99
# else
// OCTAVE_API_VERSION_NUMBER == 37
# define OCTAVE_MAJOR_VERSION 3
# define OCTAVE_MINOR_VERSION 2
# define OCTAVE_PATCH_VERSION 0
# endif // defined(octave_Complex_LU_h)
# endif // defined(octave_ov_h)
// Correlation between Octave API and version numbers extracted from Octave's
// ChangeLogs; version is the *earliest* released Octave with that API number
# elif OCTAVE_API_VERSION_NUMBER >= 48
# define OCTAVE_MAJOR_VERSION 3
# define OCTAVE_MINOR_VERSION 6
# define OCTAVE_PATCH_VERSION 0
# elif OCTAVE_API_VERSION_NUMBER >= 45
# define OCTAVE_MAJOR_VERSION 3
# define OCTAVE_MINOR_VERSION 4
# define OCTAVE_PATCH_VERSION 1
# elif OCTAVE_API_VERSION_NUMBER >= 42
# define OCTAVE_MAJOR_VERSION 3
# define OCTAVE_MINOR_VERSION 3
# define OCTAVE_PATCH_VERSION 54
# elif OCTAVE_API_VERSION_NUMBER >= 41
# define OCTAVE_MAJOR_VERSION 3
# define OCTAVE_MINOR_VERSION 3
# define OCTAVE_PATCH_VERSION 53
# elif OCTAVE_API_VERSION_NUMBER >= 40
# define OCTAVE_MAJOR_VERSION 3
# define OCTAVE_MINOR_VERSION 3
# define OCTAVE_PATCH_VERSION 52
# elif OCTAVE_API_VERSION_NUMBER >= 39
# define OCTAVE_MAJOR_VERSION 3
# define OCTAVE_MINOR_VERSION 3
# define OCTAVE_PATCH_VERSION 51
# else // OCTAVE_API_VERSION_NUMBER == 38
# define OCTAVE_MAJOR_VERSION 3
# define OCTAVE_MINOR_VERSION 3
# define OCTAVE_PATCH_VERSION 50
# endif // !defined(OCTAVE_API_VERSION_NUMBER)
#endif // !defined(OCTAVE_MAJOR_VERSION)
#include <octave/Cell.h>
#include <octave/dynamic-ld.h>
#include <octave/oct-env.h>
#include <octave/oct-map.h>
#include <octave/ov-scalar.h>
#include <octave/ov-fcn-handle.h>
#include <octave/parse.h>
#if SWIG_OCTAVE_PREREQ(4,2,0)
#include <octave/interpreter.h>
#else
#include <octave/toplev.h>
#endif
#include <octave/unwind-prot.h>
#if SWIG_OCTAVE_PREREQ(4,2,0)
#include <octave/call-stack.h>
#endif
#include "octheaders.hpp"
%}
#else
%insert(runtime) "octheaders.hpp";
#endif
%insert(runtime) "swigrun.swg";
%insert(runtime) "swigerrors.swg";

View file

@ -4,10 +4,6 @@
%include <octcomplex.swg>
%{
#include <complex>
%}
namespace std {
%naturalvar complex;
template<typename T> class complex;

View file

@ -333,6 +333,39 @@ case $host in
*) ;;
esac
# Check for compiler pre-compiled header support
AC_MSG_CHECKING([if compiler supports pre-compiled headers])
PCHSUPPORT=no
if test "$CLANGXX" = "yes"; then
PCHINCLUDEARG="-include-pch"
PCHINCLUDEEXT=".gch"
else
PCHINCLUDEARG="-include"
PCHINCLUDEEXT=""
fi
AC_LANG_PUSH([C++])
echo '#include <cstdlib>' > conftest.hpp
echo '#include "conftest.hpp"' > conftest.cpp
$CXX -c conftest.hpp 2>/dev/null
if test $? -eq 0; then
if test -f conftest.hpp.gch; then
$CXX -H -c -I. ${PCHINCLUDEARG} ./conftest.hpp${PCHINCLUDEEXT} -o conftest.o conftest.cpp >conftest.out 2>&1
if test $? -eq 0; then
if test "$CLANGXX" = "yes"; then
PCHSUPPORT=yes
elif grep -q '^!.*conftest.hpp.gch$' conftest.out; then
PCHSUPPORT=yes
fi
fi
fi
fi
rm -f conftest.hpp conftest.cpp conftest.out
AC_LANG_POP([C++])
AC_MSG_RESULT([$PCHSUPPORT])
AC_SUBST(PCHSUPPORT)
AC_SUBST(PCHINCLUDEARG)
AC_SUBST(PCHINCLUDEEXT)
# Set info about shared libraries.
AC_SUBST(SO)
AC_SUBST(LDSHARED)