Re: Mostly Harmless: c++configure - patch 3 of 4

Поиск
Список
Период
Сортировка
От Kurt Harriman
Тема Re: Mostly Harmless: c++configure - patch 3 of 4
Дата
Msg-id 4938F1F6.8040005@acm.org
обсуждение исходный текст
Ответ на Mostly Harmless: Welcoming our C++ friends  (Kurt Harriman <harriman@acm.org>)
Ответы Re: Mostly Harmless: c++configure - patch 3 of 4  (Peter Eisentraut <peter_e@gmx.net>)
Список pgsql-hackers
(Re-sending just the third of four patches: c++configure)

These patches are based on CVS head in which the latest commit was
  user:        petere
  date:        Thu Dec 04 17:51:28 2008 +0000
  summary:     Default values for function arguments

3. c++configure

     This patch adds C++ support to the PostgreSQL build system.

     After you have applied the patch, cd to the top of the source
     tree (to the directory containing the file 'configure.in') and
     execute these two commands to regenerate the 'configure' script
     and some related files:
         autoconf
         autoheader

     Much as it already does for the C compiler, the 'configure' script
     will try to find the C++ compiler and set up appropriate command
     line options.  If 'configure' finds a C++ compiler, it will set up
     src/Makefile.global to define the following makefile variables:

         CXX = command for invoking C++ compiler
         CXXCPP = command for invoking C++ preprocessor
         CXXFLAGS = C++ compiler options
         GXX = 'yes' if the C++ compiler is gcc/g++

     Implicit rules are defined so that gmake will automatically invoke
     the C++ compiler using the above variables given a source file name
     suffixed with '.cpp' or '.cc'.  So, to add a file named marvin.cpp
     to the build, just add 'marvin.o' to the OBJS list in the Makefile.

     To C++-compile a file with '.c' suffix, the Makefile should list
     the .o file in both OBJS and CXXOBJS.

     The pg_config utility can be used to display the CXX and CXXFLAGS.

     Most C++ code typically uses some C++ features whose implementation
     makes use of the compiler's runtime library: exceptions, static
     constructors, new/delete, STL containers, stream I/O, etc.  Specify
     the following 'configure' option to link the C++ runtime library
     into the postgres backend:

         --enable-cplusplus

     If --enable-cplusplus is specified, the makefile variable
     'enable_cplusplus' will be set to 'yes', and pg_config.h will
     #define ENABLE_CPLUSPLUS.

     To ensure that the C++ runtime library is properly initialized,
     on some platforms it is necessary for the main() function to be
     compiled as C++.  Therefore, if --enable-cplusplus is configured,
     src/backend/main/main.c will be compiled as C++.  This is
     handled by the following lines in src/backend/main/Makefile:

         ifeq ($(enable_cplusplus),yes)
         CXXOBJS = main.o
         endif

     Fortunately, main.c can be compiled as either C or C++ with no
     difficulty after applying the c++reserved and c++bookends
     patches.  To make main.c bilingual, all that was needed was
     a pair of bookends around its #includes.

     Limitations:

     - I haven't added support for profiling and code coverage for
       C++.  Automatic dependency generation is supported, however.

     - This ought to work on platforms which use GCC, and maybe some
       others.  The only one I have tested is x86_32 Linux with GCC
       4.1.2.  Hopefully some interested hackers will try it on
       platforms to which they have access, and post the results.

diff -r 257c0be599ab config/c-compiler.m4
--- a/config/c-compiler.m4
+++ b/config/c-compiler.m4
@@ -103,6 +103,7 @@
 # command-line option. If it does, add the string to CFLAGS.
 AC_DEFUN([PGAC_PROG_CC_CFLAGS_OPT],
 [AC_MSG_CHECKING([if $CC supports $1])
+AC_LANG_ASSERT([C])
 pgac_save_CFLAGS=$CFLAGS
 CFLAGS="$pgac_save_CFLAGS $1"
 _AC_COMPILE_IFELSE([AC_LANG_PROGRAM()],
@@ -110,6 +111,23 @@
                    [CFLAGS="$pgac_save_CFLAGS"
                     AC_MSG_RESULT(no)])
 ])# PGAC_PROG_CC_CFLAGS_OPT
+
+
+
+# PGAC_PROG_CXX_CXXFLAGS_OPT
+# -----------------------
+# Given a string, check if the C++ compiler supports the string as a
+# command-line option. If it does, add the string to CXXFLAGS.
+AC_DEFUN([PGAC_PROG_CXX_CXXFLAGS_OPT],
+[AC_MSG_CHECKING([if $CXX supports $1])
+AC_LANG_ASSERT([C++])
+pgac_save_CXXFLAGS=$CXXFLAGS
+CXXFLAGS="$pgac_save_CXXFLAGS $1"
+_AC_COMPILE_IFELSE([AC_LANG_PROGRAM()],
+                   AC_MSG_RESULT(yes),
+                   [CXXFLAGS="$pgac_save_CXXFLAGS"
+                    AC_MSG_RESULT(no)])
+])# PGAC_PROG_CXX_CXXFLAGS_OPT



diff -r 257c0be599ab configure.in
--- a/configure.in
+++ b/configure.in
@@ -195,6 +195,14 @@
 PGAC_ARG_BOOL(enable, debug, no,
               [build with debugging symbols (-g)])
 AC_SUBST(enable_debug)
+
+#
+# --enable-cplusplus links the postgres backend with the C++ runtime library
+#
+PGAC_ARG_BOOL(enable, cplusplus, no, [build with C++ runtime library],
+              [AC_DEFINE([ENABLE_CPLUSPLUS], 1,
+                         [Define to 1 for mixed C/C++ build. (--enable-cplusplus)])])
+AC_SUBST(enable_cplusplus)

 #
 # --enable-profiling enables gcc profiling
@@ -365,9 +373,9 @@
 PGAC_ARG_REQ(with, CC, [CMD], [set compiler (deprecated)], [CC=$with_CC])

 case $template in
-  aix) pgac_cc_list="gcc xlc";;
- irix) pgac_cc_list="cc";; # no gcc
-    *) pgac_cc_list="gcc cc";;
+  aix) pgac_cc_list="gcc xlc";  pgac_cxx_list="g++ xlC";;
+ irix) pgac_cc_list="cc";       pgac_cxx_list="CC";;            # no gcc
+    *) pgac_cc_list="gcc cc";   pgac_cxx_list="g++ CC";;
 esac

 AC_PROG_CC([$pgac_cc_list])
@@ -387,7 +395,15 @@

 AC_SUBST(SUN_STUDIO_CC)

+#
+# C++ compiler
+#
+AC_PROG_CXX([$pgac_cxx_list])
+AC_PROG_CXXCPP
+AC_SUBST(GXX)
+
 unset CFLAGS
+unset CXXFLAGS

 #
 # Read the template
@@ -421,9 +437,8 @@
 # ICC pretends to be GCC but it's lying; it doesn't support these options.

 if test "$GCC" = yes -a "$ICC" = no; then
-  CFLAGS="$CFLAGS -Wall -Wmissing-prototypes -Wpointer-arith"
+  CFLAGS="$CFLAGS -Wall -Wpointer-arith"
   # These work in some but not all gcc versions
-  PGAC_PROG_CC_CFLAGS_OPT([-Wdeclaration-after-statement])
   PGAC_PROG_CC_CFLAGS_OPT([-Wendif-labels])
   # Disable strict-aliasing rules; needed for gcc 3.3+
   PGAC_PROG_CC_CFLAGS_OPT([-fno-strict-aliasing])
@@ -470,12 +485,53 @@
   CPPFLAGS="$CPPFLAGS -I$srcdir/src/include/port/win32 -DEXEC_BACKEND"
 fi

+#
+# Initialize C++ flags from CFLAGS unless overridden in environment or template
+#
+if test "$ac_env_CXXFLAGS_set" = set; then
+  CXXFLAGS=$ac_env_CXXFLAGS_value
+elif test "${CXXFLAGS+set}" = set; then
+  : # (keep what template set)
+else
+  CXXFLAGS="$CFLAGS"
+fi
+
+# Some CXXFLAGS are only valid for C++, not for C.  Add them here.
+if test "$GXX" = yes -a "$ICC" = no; then
+  AC_LANG_PUSH([C++])
+  CXXFLAGS="$CXXFLAGS -Wabi"
+  PGAC_PROG_CXX_CXXFLAGS_OPT([-fno-enforce-eh-specs])
+  PGAC_PROG_CXX_CXXFLAGS_OPT([-fno-threadsafe-statics])
+  AC_LANG_POP([C++])
+fi
+
+# Some CFLAGS are only valid for C, not for C++.  Add them here.
+if test "$GCC" = yes -a "$ICC" = no; then
+  CFLAGS="$CFLAGS -Wmissing-prototypes"
+  # These work in some but not all gcc versions
+  PGAC_PROG_CC_CFLAGS_OPT([-Wdeclaration-after-statement])
+fi
+
+
+#
 # Check if the compiler still works with the template settings
+#
 AC_MSG_CHECKING([whether the C compiler still works])
 AC_TRY_LINK([], [return 0;],
   [AC_MSG_RESULT(yes)],
   [AC_MSG_RESULT(no)
    AC_MSG_ERROR([cannot proceed])])
+
+if test "$enable_cplusplus" = yes; then
+  AC_LANG_PUSH([C++])
+  AC_MSG_CHECKING([whether the C++ compiler still works])
+  AC_TRY_LINK([class X {public: bool b; X(bool bb){this->b = bb;}};],
+    [X* x = new X(true);],
+    [AC_MSG_RESULT(yes)],
+    [AC_MSG_RESULT(no)
+     AC_MSG_ERROR([cannot proceed])])
+  AC_LANG_POP([C++])
+fi

 # Defend against gcc -ffast-math
 if test "$GCC" = yes; then
@@ -1765,6 +1821,7 @@
 # Begin output steps

 AC_MSG_NOTICE([using CFLAGS=$CFLAGS])
+AC_MSG_NOTICE([using CXXFLAGS=$CXXFLAGS])
 AC_MSG_NOTICE([using CPPFLAGS=$CPPFLAGS])
 AC_MSG_NOTICE([using LDFLAGS=$LDFLAGS])

diff -r 257c0be599ab doc/src/sgml/installation.sgml
--- a/doc/src/sgml/installation.sgml
+++ b/doc/src/sgml/installation.sgml
@@ -1261,6 +1261,17 @@
          can be profiled.  On backend exit, a subdirectory will be created
          that contains the <filename>gmon.out</> file for use in profiling.
          This option is for use only with GCC and when doing development work.
+        </para>
+       </listitem>
+      </varlistentry>
+
+      <varlistentry>
+       <term><option>--enable-cplusplus</option></term>
+       <listitem>
+        <para>
+         Compiles the <filename>postgres</> server with C++ runtime
+         library support.  Specify this option only if you intend to use or
+         develop server extensions or modifications in the C++ language.
         </para>
        </listitem>
       </varlistentry>
diff -r 257c0be599ab doc/src/sgml/ref/pg_config-ref.sgml
--- a/doc/src/sgml/ref/pg_config-ref.sgml
+++ b/doc/src/sgml/ref/pg_config-ref.sgml
@@ -223,6 +223,27 @@
     </varlistentry>

     <varlistentry>
+     <term><option>--cxx</option></>
+     <listitem>
+      <para>
+       Print the value of the <varname>CXX</varname> variable showing the C++
+       compiler that was used for building C++ modules (if any) in the
+       <productname>PostgreSQL</> backend.
+      </para>
+     </listitem>
+    </varlistentry>
+
+    <varlistentry>
+     <term><option>--cxxflags</option></>
+     <listitem>
+      <para>
+       Print the value of the <varname>CXXFLAGS</varname> variable that was used for building
+       <productname>PostgreSQL</>.  This shows C++ compiler switches.
+      </para>
+     </listitem>
+    </varlistentry>
+
+    <varlistentry>
      <term><option>--ldflags</option></>
      <listitem>
       <para>
diff -r 257c0be599ab src/Makefile.global.in
--- a/src/Makefile.global.in
+++ b/src/Makefile.global.in
@@ -164,6 +164,7 @@
 enable_debug    = @enable_debug@
 enable_dtrace    = @enable_dtrace@
 enable_coverage    = @enable_coverage@
+enable_cplusplus    = @enable_cplusplus@
 enable_thread_safety    = @enable_thread_safety@

 python_includespec    = @python_includespec@
@@ -214,6 +215,21 @@
 GCC = @GCC@
 SUN_STUDIO_CC = @SUN_STUDIO_CC@
 CFLAGS = @CFLAGS@
+
+CXX = @CXX@
+CXXCPP = @CXXCPP@
+CXXFLAGS = @CXXFLAGS@
+GXX = @GXX@
+
+# gmake predefines these and uses them in its predefined implicit rules.
+# We include them here just in case someone uses a version of gmake which
+# doesn't have them built in.  These are as defined by gmake 3.81.
+COMPILE.c   ?= $(CC) $(CFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -c
+LINK.c      ?= $(CC) $(CFLAGS) $(CPPFLAGS) $(LDFLAGS) $(TARGET_ARCH)
+COMPILE.cc  ?= $(CXX) $(CXXFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -c
+LINK.cc     ?= $(CXX) $(CXXFLAGS) $(CPPFLAGS) $(LDFLAGS) $(TARGET_ARCH)
+COMPILE.cpp ?= $(COMPILE.cc)
+LINK.cpp    ?= $(LINK.cc)

 # Kind-of compilers

@@ -545,18 +561,25 @@

 ifeq ($(autodepend), yes)

-ifndef COMPILE.c
-COMPILE.c = $(CC) $(CFLAGS) $(CPPFLAGS) -c
-endif
-
 DEPDIR = .deps
+DEPMKDIR = @if test ! -d $(DEPDIR); then mkdir -p $(DEPDIR); fi

 ifeq ($(GCC), yes)

 # GCC allows us to create object and dependency file in one invocation.
+DEPFLAGS = -MMD -MP -MF $(DEPDIR)/$(*F).Po
+
 %.o : %.c
-    @if test ! -d $(DEPDIR); then mkdir -p $(DEPDIR); fi
-    $(COMPILE.c) -o $@ $< -MMD -MP -MF $(DEPDIR)/$(*F).Po
+    $(DEPMKDIR)
+    $(COMPILE.c) $(DEPFLAGS) -o $@ $<
+
+%.o : %.cc
+    $(DEPMKDIR)
+    $(COMPILE.cc) $(DEPFLAGS) -o $@ $<
+
+%.o: %.cpp
+    $(DEPMKDIR)
+    $(COMPILE.cpp) $(DEPFLAGS) -o $@ $<

 endif # GCC

diff -r 257c0be599ab src/backend/Makefile
--- a/src/backend/Makefile
+++ b/src/backend/Makefile
@@ -43,7 +43,12 @@
 ifneq ($(PORTNAME), aix)

 postgres: $(OBJS)
+ifeq ($(enable_cplusplus), yes)
+    # Link with C++ runtime support
+    $(CXX) $(CXXFLAGS) $(LDFLAGS) $(export_dynamic) $(call expand_subsys,$^) $(LIBS) -o $@
+else
     $(CC) $(CFLAGS) $(LDFLAGS) $(export_dynamic) $(call expand_subsys,$^) $(LIBS) -o $@
+endif

 endif
 endif
@@ -111,7 +116,12 @@
 # The postgres.o target is needed by the rule in Makefile.global that
 # creates the exports file when MAKE_EXPORTS = true.
 postgres.o: $(OBJS)
+ifeq ($(enable_cplusplus), yes)
+    # Link with C++ runtime support
+    $(CXX) $(LDREL) $(LDFLAGS) $(call expand_subsys,$^) $(LIBS) -o $@
+else
     $(CC) $(LDREL) $(LDFLAGS) $(call expand_subsys,$^) $(LIBS) -o $@
+endif


 # The following targets are specified in make commands that appear in
@@ -268,4 +278,9 @@
 # are up to date.  It saves the time of doing all the submakes.
 .PHONY: quick
 quick: $(OBJS)
+ifeq ($(enable_cplusplus), yes)
+    # Link with C++ runtime support
+    $(CXX) $(CXXFLAGS) $(LDFLAGS) $(export_dynamic) $(call expand_subsys,$^) $(LIBS) -o postgres
+else
     $(CC) $(CFLAGS) $(LDFLAGS) $(export_dynamic) $(call expand_subsys,$^) $(LIBS) -o postgres
+endif
diff -r 257c0be599ab src/backend/common.mk
--- a/src/backend/common.mk
+++ b/src/backend/common.mk
@@ -6,7 +6,7 @@

 # When including this file, set OBJS to the object files created in
 # this directory and SUBDIRS to subdirectories containing more things
-# to build.
+# to build.  Set CXXOBJS to the subset of OBJS which are to be C++ compiled.

 ifdef PARTIAL_LINKING
 # old style: linking using SUBSYS.o
@@ -36,6 +36,11 @@
 # Parallel make trickery
 $(SUBDIROBJS): $(SUBDIRS:%=%-recursive) ;

+# For .o files listed in CXXOBJS, use C++ compiler to make .o from .c
+$(CXXOBJS) : %.o: %.c
+    $(DEPMKDIR)
+    $(COMPILE.cc) $(DEPFLAGS) -o $@ $<
+
 .PHONY: $(SUBDIRS:%=%-recursive)
 $(SUBDIRS:%=%-recursive):
     $(MAKE) -C $(subst -recursive,,$@) all
diff -r 257c0be599ab src/backend/main/Makefile
--- a/src/backend/main/Makefile
+++ b/src/backend/main/Makefile
@@ -14,4 +14,11 @@

 OBJS = main.o

+# If "configure --enable-cplusplus" was specified, make list of modules
+# which are to be compiled as C++.  The main() function should be compiled as
+# C++ to ensure proper initialization of the mixed C/C++ runtime environment.
+ifeq ($(enable_cplusplus),yes)
+CXXOBJS = main.o
+endif
+
 include $(top_srcdir)/src/backend/common.mk
diff -r 257c0be599ab src/backend/main/main.c
--- a/src/backend/main/main.c
+++ b/src/backend/main/main.c
@@ -34,6 +34,14 @@
 #include <sys/param.h>
 #endif

+#if defined(ENABLE_CPLUSPLUS) && !defined(__cplusplus)
+#error --enable-cplusplus configure option specified; this file should be compiled as C++
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
 #include "bootstrap/bootstrap.h"
 #include "postmaster/postmaster.h"
 #include "tcop/tcopprot.h"
@@ -42,6 +50,10 @@
 #include "utils/ps_status.h"
 #ifdef WIN32
 #include "libpq/pqsignal.h"
+#endif
+
+#ifdef __cplusplus
+}   /* extern "C" */
 #endif


diff -r 257c0be599ab src/bin/pg_config/Makefile
--- a/src/bin/pg_config/Makefile
+++ b/src/bin/pg_config/Makefile
@@ -24,6 +24,8 @@
 override CPPFLAGS += -DVAL_CPPFLAGS="\"$(STD_CPPFLAGS)\""
 override CPPFLAGS += -DVAL_CFLAGS="\"$(CFLAGS)\""
 override CPPFLAGS += -DVAL_CFLAGS_SL="\"$(CFLAGS_SL)\""
+override CPPFLAGS += -DVAL_CXX="\"$(CXX)\""
+override CPPFLAGS += -DVAL_CXXFLAGS="\"$(CXXFLAGS)\""
 override CPPFLAGS += -DVAL_LDFLAGS="\"$(STD_LDFLAGS)\""
 override CPPFLAGS += -DVAL_LDFLAGS_SL="\"$(LDFLAGS_SL)\""
 override CPPFLAGS += -DVAL_LIBS="\"$(LIBS)\""
diff -r 257c0be599ab src/bin/pg_config/pg_config.c
--- a/src/bin/pg_config/pg_config.c
+++ b/src/bin/pg_config/pg_config.c
@@ -311,6 +311,38 @@
 }

 static void
+show_cxx(bool all)
+{
+#ifdef VAL_CXX
+    if (all)
+        printf("CXX = ");
+    printf("%s\n", VAL_CXX);
+#else
+    if (!all)
+    {
+        fprintf(stderr, _("not recorded\n"));
+        exit(1);
+    }
+#endif
+}
+
+static void
+show_cxxflags(bool all)
+{
+#ifdef VAL_CXXFLAGS
+    if (all)
+        printf("CXXFLAGS = ");
+    printf("%s\n", VAL_CXXFLAGS);
+#else
+    if (!all)
+    {
+        fprintf(stderr, _("not recorded\n"));
+        exit(1);
+    }
+#endif
+}
+
+static void
 show_ldflags(bool all)
 {
 #ifdef VAL_LDFLAGS
@@ -397,6 +429,8 @@
     {"--cppflags", show_cppflags},
     {"--cflags", show_cflags},
     {"--cflags_sl", show_cflags_sl},
+    {"--cxx", show_cxx},
+    {"--cxxflags", show_cxxflags},
     {"--ldflags", show_ldflags},
     {"--ldflags_sl", show_ldflags_sl},
     {"--libs", show_libs},
@@ -432,6 +466,8 @@
     printf(_("  --cppflags            show CPPFLAGS value used when PostgreSQL was built\n"));
     printf(_("  --cflags              show CFLAGS value used when PostgreSQL was built\n"));
     printf(_("  --cflags_sl           show CFLAGS_SL value used when PostgreSQL was built\n"));
+    printf(_("  --cxx                 show CXX value used when PostgreSQL was built\n"));
+    printf(_("  --cxxflags            show CXXFLAGS value used when PostgreSQL was built\n"));
     printf(_("  --ldflags             show LDFLAGS value used when PostgreSQL was built\n"));
     printf(_("  --ldflags_sl          show LDFLAGS_SL value used when PostgreSQL was built\n"));
     printf(_("  --libs                show LIBS value used when PostgreSQL was built\n"));
diff -r 257c0be599ab src/include/pg_config.h.in
--- a/src/include/pg_config.h.in
+++ b/src/include/pg_config.h.in
@@ -44,6 +44,9 @@

 /* Define to the default TCP port number as a string constant. */
 #undef DEF_PGPORT_STR
+
+/* Define to 1 for mixed C/C++ build. (--enable-cplusplus) */
+#undef ENABLE_CPLUSPLUS

 /* Define to 1 to enable DTrace support. (--enable-dtrace) */
 #undef ENABLE_DTRACE

В списке pgsql-hackers по дате отправления:

Предыдущее
От: Kurt Harriman
Дата:
Сообщение: Re: Mostly Harmless: c++bookends - patch 2 of 4
Следующее
От: Kurt Harriman
Дата:
Сообщение: Re: Mostly Harmless: c++exception - patch 4 of 4