mirror of
https://github.com/postgres/postgres.git
synced 2026-01-27 21:43:08 +03:00
tests: Add a test C++ extension module
While we already test that our headers are valid C++ using headerscheck, it turns out that the macros we define might still expand to invalid C++ code. This adds a minimal test extension that is compiled using C++ to test that it's actually possible to build and run extensions written in C++. Future commits will improve C++ compatibility of some of our macros and add usage of them to this extension make sure that they don't regress in the future. The test module is for the moment disabled when using MSVC. In particular, the use of designated initializers in PG_MODULE_MAGIC would require C++20, for which we are currently not set up. (GCC and Clang support it as extensions.) It is planned to fix this. Author: Jelte Fennema-Nio <postgres@jeltef.nl> Discussion: https://www.postgresql.org/message-id/flat/CAGECzQR21OnnKiZO_1rLWO0-16kg1JBxnVq-wymYW0-_1cUNtg@mail.gmail.com
This commit is contained in:
8
configure
vendored
8
configure
vendored
@@ -760,6 +760,7 @@ CLANG
|
|||||||
LLVM_CONFIG
|
LLVM_CONFIG
|
||||||
AWK
|
AWK
|
||||||
with_llvm
|
with_llvm
|
||||||
|
have_cxx
|
||||||
ac_ct_CXX
|
ac_ct_CXX
|
||||||
CXXFLAGS
|
CXXFLAGS
|
||||||
CXX
|
CXX
|
||||||
@@ -4769,6 +4770,13 @@ ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $
|
|||||||
ac_compiler_gnu=$ac_cv_c_compiler_gnu
|
ac_compiler_gnu=$ac_cv_c_compiler_gnu
|
||||||
|
|
||||||
|
|
||||||
|
if test -n "$ac_ct_CXX"; then
|
||||||
|
have_cxx=yes
|
||||||
|
else
|
||||||
|
have_cxx=no
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
# Check if it's Intel's compiler, which (usually) pretends to be gcc,
|
# Check if it's Intel's compiler, which (usually) pretends to be gcc,
|
||||||
# but has idiosyncrasies of its own. We assume icc will define
|
# but has idiosyncrasies of its own. We assume icc will define
|
||||||
# __INTEL_COMPILER regardless of CFLAGS.
|
# __INTEL_COMPILER regardless of CFLAGS.
|
||||||
|
|||||||
@@ -387,6 +387,13 @@ fi
|
|||||||
|
|
||||||
AC_PROG_CXX([$pgac_cxx_list])
|
AC_PROG_CXX([$pgac_cxx_list])
|
||||||
|
|
||||||
|
if test -n "$ac_ct_CXX"; then
|
||||||
|
have_cxx=yes
|
||||||
|
else
|
||||||
|
have_cxx=no
|
||||||
|
fi
|
||||||
|
AC_SUBST(have_cxx)
|
||||||
|
|
||||||
# Check if it's Intel's compiler, which (usually) pretends to be gcc,
|
# Check if it's Intel's compiler, which (usually) pretends to be gcc,
|
||||||
# but has idiosyncrasies of its own. We assume icc will define
|
# but has idiosyncrasies of its own. We assume icc will define
|
||||||
# __INTEL_COMPILER regardless of CFLAGS.
|
# __INTEL_COMPILER regardless of CFLAGS.
|
||||||
|
|||||||
@@ -280,6 +280,8 @@ PERMIT_DECLARATION_AFTER_STATEMENT = @PERMIT_DECLARATION_AFTER_STATEMENT@
|
|||||||
PERMIT_MISSING_VARIABLE_DECLARATIONS = @PERMIT_MISSING_VARIABLE_DECLARATIONS@
|
PERMIT_MISSING_VARIABLE_DECLARATIONS = @PERMIT_MISSING_VARIABLE_DECLARATIONS@
|
||||||
CXXFLAGS = @CXXFLAGS@
|
CXXFLAGS = @CXXFLAGS@
|
||||||
|
|
||||||
|
have_cxx = @have_cxx@
|
||||||
|
|
||||||
LLVM_CPPFLAGS = @LLVM_CPPFLAGS@
|
LLVM_CPPFLAGS = @LLVM_CPPFLAGS@
|
||||||
LLVM_CFLAGS = @LLVM_CFLAGS@
|
LLVM_CFLAGS = @LLVM_CFLAGS@
|
||||||
LLVM_CXXFLAGS = @LLVM_CXXFLAGS@
|
LLVM_CXXFLAGS = @LLVM_CXXFLAGS@
|
||||||
|
|||||||
@@ -118,6 +118,8 @@ pgxs_kv = {
|
|||||||
'FLEXFLAGS': ' '.join(flex_flags),
|
'FLEXFLAGS': ' '.join(flex_flags),
|
||||||
|
|
||||||
'LIBS': var_libs,
|
'LIBS': var_libs,
|
||||||
|
|
||||||
|
'have_cxx': have_cxx ? 'yes' : 'no',
|
||||||
}
|
}
|
||||||
|
|
||||||
if llvm.found()
|
if llvm.found()
|
||||||
|
|||||||
@@ -75,5 +75,11 @@ else
|
|||||||
ALWAYS_SUBDIRS += ldap_password_func
|
ALWAYS_SUBDIRS += ldap_password_func
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
ifeq ($(have_cxx),yes)
|
||||||
|
SUBDIRS += test_cplusplusext
|
||||||
|
else
|
||||||
|
ALWAYS_SUBDIRS += test_cplusplusext
|
||||||
|
endif
|
||||||
|
|
||||||
$(recurse)
|
$(recurse)
|
||||||
$(recurse_always)
|
$(recurse_always)
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ subdir('test_bitmapset')
|
|||||||
subdir('test_bloomfilter')
|
subdir('test_bloomfilter')
|
||||||
subdir('test_cloexec')
|
subdir('test_cloexec')
|
||||||
subdir('test_copy_callbacks')
|
subdir('test_copy_callbacks')
|
||||||
|
subdir('test_cplusplusext')
|
||||||
subdir('test_custom_rmgrs')
|
subdir('test_custom_rmgrs')
|
||||||
subdir('test_custom_stats')
|
subdir('test_custom_stats')
|
||||||
subdir('test_ddl_deparse')
|
subdir('test_ddl_deparse')
|
||||||
|
|||||||
3
src/test/modules/test_cplusplusext/.gitignore
vendored
Normal file
3
src/test/modules/test_cplusplusext/.gitignore
vendored
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
/log/
|
||||||
|
/results/
|
||||||
|
/tmp_check/
|
||||||
26
src/test/modules/test_cplusplusext/Makefile
Normal file
26
src/test/modules/test_cplusplusext/Makefile
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
# src/test/modules/test_cplusplusext/Makefile
|
||||||
|
|
||||||
|
MODULE_big = test_cplusplusext
|
||||||
|
OBJS = \
|
||||||
|
$(WIN32RES) \
|
||||||
|
test_cplusplusext.o
|
||||||
|
PGFILEDESC = "test_cplusplusext - test C++ compatibility of PostgreSQL headers"
|
||||||
|
|
||||||
|
EXTENSION = test_cplusplusext
|
||||||
|
DATA = test_cplusplusext--1.0.sql
|
||||||
|
|
||||||
|
REGRESS = test_cplusplusext
|
||||||
|
|
||||||
|
# Use C++ compiler for linking because this module includes C++ files
|
||||||
|
override COMPILER = $(CXX) $(CXXFLAGS)
|
||||||
|
|
||||||
|
ifdef USE_PGXS
|
||||||
|
PG_CONFIG = pg_config
|
||||||
|
PGXS := $(shell $(PG_CONFIG) --pgxs)
|
||||||
|
include $(PGXS)
|
||||||
|
else
|
||||||
|
subdir = src/test/modules/test_cplusplusext
|
||||||
|
top_builddir = ../../../..
|
||||||
|
include $(top_builddir)/src/Makefile.global
|
||||||
|
include $(top_srcdir)/contrib/contrib-global.mk
|
||||||
|
endif
|
||||||
10
src/test/modules/test_cplusplusext/README
Normal file
10
src/test/modules/test_cplusplusext/README
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
test_cplusplusext - Test C++ Extension Compatibility
|
||||||
|
====================================================
|
||||||
|
|
||||||
|
This test module verifies that PostgreSQL headers and macros work
|
||||||
|
correctly when compiled with a C++ compiler.
|
||||||
|
|
||||||
|
While PostgreSQL already tests that headers are syntactically valid
|
||||||
|
C++ using headerscheck, the macros defined in those headers might
|
||||||
|
still expand to invalid C++ code. This module catches such issues by
|
||||||
|
actually compiling and running an extension that's written in C++.
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
CREATE EXTENSION test_cplusplusext;
|
||||||
|
SELECT test_cplusplus_add(1, 2);
|
||||||
|
test_cplusplus_add
|
||||||
|
--------------------
|
||||||
|
3
|
||||||
|
(1 row)
|
||||||
|
|
||||||
42
src/test/modules/test_cplusplusext/meson.build
Normal file
42
src/test/modules/test_cplusplusext/meson.build
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
# Copyright (c) 2025-2026, PostgreSQL Global Development Group
|
||||||
|
|
||||||
|
if not have_cxx
|
||||||
|
subdir_done()
|
||||||
|
endif
|
||||||
|
|
||||||
|
# Currently not supported, to be fixed.
|
||||||
|
if cc.get_id() == 'msvc'
|
||||||
|
subdir_done()
|
||||||
|
endif
|
||||||
|
|
||||||
|
test_cplusplusext_sources = files(
|
||||||
|
'test_cplusplusext.cpp',
|
||||||
|
)
|
||||||
|
|
||||||
|
if host_system == 'windows'
|
||||||
|
test_cplusplusext_sources += rc_lib_gen.process(win32ver_rc, extra_args: [
|
||||||
|
'--NAME', 'test_cplusplusext',
|
||||||
|
'--FILEDESC', 'test_cplusplusext - test C++ compatibility of PostgreSQL headers',])
|
||||||
|
endif
|
||||||
|
|
||||||
|
test_cplusplusext = shared_module('test_cplusplusext',
|
||||||
|
test_cplusplusext_sources,
|
||||||
|
kwargs: pg_test_mod_args,
|
||||||
|
)
|
||||||
|
test_install_libs += test_cplusplusext
|
||||||
|
|
||||||
|
test_install_data += files(
|
||||||
|
'test_cplusplusext.control',
|
||||||
|
'test_cplusplusext--1.0.sql',
|
||||||
|
)
|
||||||
|
|
||||||
|
tests += {
|
||||||
|
'name': 'test_cplusplusext',
|
||||||
|
'sd': meson.current_source_dir(),
|
||||||
|
'bd': meson.current_build_dir(),
|
||||||
|
'regress': {
|
||||||
|
'sql': [
|
||||||
|
'test_cplusplusext',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
}
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
CREATE EXTENSION test_cplusplusext;
|
||||||
|
|
||||||
|
SELECT test_cplusplus_add(1, 2);
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
/* src/test/modules/test_cplusplusext/test_cplusplusext--1.0.sql */
|
||||||
|
|
||||||
|
-- complain if script is sourced in psql, rather than via CREATE EXTENSION
|
||||||
|
\echo Use "CREATE EXTENSION test_cplusplusext" to load this file. \quit
|
||||||
|
|
||||||
|
CREATE FUNCTION test_cplusplus_add(int4, int4) RETURNS int4
|
||||||
|
AS 'MODULE_PATHNAME'
|
||||||
|
LANGUAGE C STRICT;
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
comment = 'Test module for C++ extension compatibility'
|
||||||
|
default_version = '1.0'
|
||||||
|
module_pathname = '$libdir/test_cplusplusext'
|
||||||
|
relocatable = true
|
||||||
37
src/test/modules/test_cplusplusext/test_cplusplusext.cpp
Normal file
37
src/test/modules/test_cplusplusext/test_cplusplusext.cpp
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
/*--------------------------------------------------------------------------
|
||||||
|
*
|
||||||
|
* test_cplusplusext.cpp
|
||||||
|
* Test that PostgreSQL headers compile with a C++ compiler.
|
||||||
|
*
|
||||||
|
* This file is compiled with a C++ compiler to verify that PostgreSQL
|
||||||
|
* headers remain compatible with C++ extensions.
|
||||||
|
*
|
||||||
|
* Copyright (c) 2025-2026, PostgreSQL Global Development Group
|
||||||
|
*
|
||||||
|
* IDENTIFICATION
|
||||||
|
* src/test/modules/test_cplusplusext/test_cplusplusext.cpp
|
||||||
|
*
|
||||||
|
* -------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
extern "C" {
|
||||||
|
#include "postgres.h"
|
||||||
|
#include "fmgr.h"
|
||||||
|
|
||||||
|
PG_MODULE_MAGIC;
|
||||||
|
|
||||||
|
PG_FUNCTION_INFO_V1(test_cplusplus_add);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Simple function that returns the sum of two integers. This verifies that
|
||||||
|
* C++ extension modules can be loaded and called correctly at runtime.
|
||||||
|
*/
|
||||||
|
extern "C" Datum
|
||||||
|
test_cplusplus_add(PG_FUNCTION_ARGS)
|
||||||
|
{
|
||||||
|
int32 a = PG_GETARG_INT32(0);
|
||||||
|
int32 b = PG_GETARG_INT32(1);
|
||||||
|
|
||||||
|
PG_RETURN_INT32(a + b);
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user