Howdy folks,

While playing around with pg_duckdb[0], a Postgres extension written in 
C++ which uses PGXS, I came across a strange build error:

std=c++17  -Wno-sign-compare...
/bin/sh: line 1: -Wno-sign-compare: command not found

I was very confused by the error, but reading the command line, it made 
sense. After talking to Jelte off-list, he told me to try a Postgres 
installation that had been built with autotools. Today, I finally had 
a chance to try that tip, and building pg_duckdb succeeded.

I spent some time exploring the Meson build a bit, and I realized that 
C++ support in PGXS is tied to LLVM enablement. Checking the autotools 
build in the configure.ac script indicates that that is not the case for 
it.

On master, C++ support looks like:

llvmopt = get_option('llvm')
llvm = not_found_dep
if add_languages('cpp', required: llvmopt, native: false)
  llvm = dependency('llvm', version: '>=14', method: 'config-tool', required: 
llvmopt)
    if llvm.found()

      cdata.set('USE_LLVM', 1)

      cpp = meson.get_compiler('cpp')

By default, the `llvm` option is disabled, which Meson takes to mean, 
"do not check for C++ support". Thusly, add_languages() returns false. 
In addition, every check for adding to cxxflags, et. al. is gated on 
llvm.found(), which is always false for the `not_found_dep`. All this 
considered, the Makefile.global of a Postgres build roughly looked like:

CXX =
CXXFLAGS = 
...

This then accounts for the original pg_duckdb command line looking the 
way that it did.

Attached is a patch which decouples C++ support in PGXS from LLVM for 
a Meson-compiled Postgres.

[0]: https://github.com/duckdb/pg_duckdb

-- 
Tristan Partin
Neon (https://neon.tech)
From aba365ed36a82f41e8bd6a7f61b90c91f1556d08 Mon Sep 17 00:00:00 2001
From: Tristan Partin <tris...@partin.io>
Date: Wed, 16 Apr 2025 20:25:21 -0500
Subject: [PATCH] Decouple C++ support in Meson's PGXS from LLVM enablement

This is important for Postgres extensions that are written in C++, such
as pg_duckdb, which uses PGXS as the build system currently. In the
autotools build, C++ is not coupled to LLVM. If the autotools build is
configured without --with-llvm, the C++ compiler and the various flags
get persisted into the Makefile.global.

Signed-off-by: Tristan Partin <tris...@partin.io>
---
 meson.build               | 27 +++++++++++++++++----------
 src/include/meson.build   |  2 +-
 src/makefiles/meson.build |  9 ++++++---
 3 files changed, 24 insertions(+), 14 deletions(-)

diff --git a/meson.build b/meson.build
index a1516e54529..f63769f8b67 100644
--- a/meson.build
+++ b/meson.build
@@ -40,6 +40,10 @@ build_system = build_machine.system()
 host_cpu = host_machine.cpu_family()
 
 cc = meson.get_compiler('c')
+have_cpp = add_languages('cpp', required: false, native: false)
+if have_cpp
+  cpp = meson.get_compiler('cpp')
+endif
 
 not_found_dep = dependency('', required: false)
 thread_dep = dependency('threads')
@@ -798,15 +802,13 @@ endif
 
 llvmopt = get_option('llvm')
 llvm = not_found_dep
-if add_languages('cpp', required: llvmopt, native: false)
+if have_cpp and not llvmopt.disabled()
   llvm = dependency('llvm', version: '>=14', method: 'config-tool', required: llvmopt)
 
   if llvm.found()
 
     cdata.set('USE_LLVM', 1)
 
-    cpp = meson.get_compiler('cpp')
-
     llvm_binpath = llvm.get_variable(configtool: 'bindir')
 
     ccache = find_program('ccache', native: true, required: false)
@@ -815,8 +817,13 @@ if add_languages('cpp', required: llvmopt, native: false)
     # find via PATH, too.
     clang = find_program(llvm_binpath / 'clang', 'clang', required: true)
   endif
-elif llvmopt.auto()
-  message('llvm requires a C++ compiler')
+else
+  msg = 'llvm requires a C++ compiler'
+  if llvmopt.auto()
+    message(msg)
+  elif llvmopt.enabled()
+    error(msg)
+  endif
 endif
 
 
@@ -2053,7 +2060,7 @@ common_functional_flags = [
 ]
 
 cflags += cc.get_supported_arguments(common_functional_flags)
-if llvm.found()
+if have_cpp
   cxxflags += cpp.get_supported_arguments(common_functional_flags)
 endif
 
@@ -2077,7 +2084,7 @@ common_warning_flags = [
 ]
 
 cflags_warn += cc.get_supported_arguments(common_warning_flags)
-if llvm.found()
+if have_cpp
   cxxflags_warn += cpp.get_supported_arguments(common_warning_flags)
 endif
 
@@ -2131,7 +2138,7 @@ foreach w : negative_warning_flags
   if cc.has_argument('-W' + w)
     cflags_warn += '-Wno-' + w
   endif
-  if llvm.found() and cpp.has_argument('-W' + w)
+  if have_cpp and cpp.has_argument('-W' + w)
     cxxflags_warn += '-Wno-' + w
   endif
 endforeach
@@ -2192,7 +2199,7 @@ elif optimization == 's'
 endif
 
 cflags_builtin = cc.get_supported_arguments(common_builtin_flags)
-if llvm.found()
+if have_cpp
   cxxflags_builtin = cpp.get_supported_arguments(common_builtin_flags)
 endif
 
@@ -3920,7 +3927,7 @@ if meson.version().version_compare('>=0.57')
     section: 'Compiler Flags',
   )
 
-  if llvm.found()
+  if have_cpp
     summary(
       {
         'C++ compiler': '@0@ @1@'.format(cpp.get_id(), cpp.version()),
diff --git a/src/include/meson.build b/src/include/meson.build
index 2e4b7aa529e..c2aef484fcc 100644
--- a/src/include/meson.build
+++ b/src/include/meson.build
@@ -36,7 +36,7 @@ config_paths_data.set_quoted('MANDIR', dir_prefix / dir_man)
 var_cc = ' '.join(cc.cmd_array())
 var_cpp = ' '.join(cc.cmd_array() + ['-E'])
 var_cflags = ' '.join(cflags + cflags_builtin + cflags_warn + get_option('c_args'))
-if llvm.found()
+if have_cpp
   var_cxxflags = ' '.join(cxxflags + cxxflags_builtin + cxxflags_warn + get_option('cpp_args'))
 else
   var_cxxflags = ''
diff --git a/src/makefiles/meson.build b/src/makefiles/meson.build
index 55da678ec27..bee83a66e81 100644
--- a/src/makefiles/meson.build
+++ b/src/makefiles/meson.build
@@ -31,7 +31,6 @@ if not working_strip
   strip_shared_cmd = [':']
 endif
 
-
 pgxs_kv = {
   'PACKAGE_URL': pg_url,
   'PACKAGE_VERSION': pg_version,
@@ -121,16 +120,20 @@ pgxs_kv = {
   'LIBS': var_libs,
 }
 
+if have_cpp
+  pgxs_kv += {
+    'CXX': ' '.join(cpp.cmd_array()),
+  }
+endif
+
 if llvm.found()
   pgxs_kv += {
     'CLANG': clang.path(),
-    'CXX': ' '.join(cpp.cmd_array()),
     'LLVM_BINPATH': llvm_binpath,
   }
 else
   pgxs_kv += {
     'CLANG': '',
-    'CXX': '',
     'LLVM_BINPATH': '',
   }
 endif
-- 
Tristan Partin
https://tristan.partin.io

Reply via email to