Home > Blockchain >  How do I overcome gcc errors in SWIG-generated sources for libpg_query
How do I overcome gcc errors in SWIG-generated sources for libpg_query

Time:10-09

How do I overcome gcc compiler errors in SWIG-generated C source files for the libpg_query library? Here's what I mean.

libpg_query is a "C library for accessing the PostgreSQL parser outside of the server" maintained by the fine folks at pganalyze but importantly, not by me. It has bindings in Ruby, Go, and Python, but not in Java, so I would like to create them. I'm trying to do that using SWIG. The SWIG docs Introduction says, "SWIG normally requires no modifications to existing code and can often be used to build a usable interface in only a few minutes." Unfortunately, my hopes of that happening so far have been dashed. I followed their Java guides and, for good measure, the Python one as well but encountered the same gcc compiler errors with the generated C source files. Here are the detailed steps.

wget https://raw.githubusercontent.com/pganalyze/libpg_query/13-latest/pg_query.h
swig -java -module test pg_query.h
gcc -fPIC -c pg_query_wrap.c -I /usr/lib/jvm/jdk-11.0.7/include/ -I /usr/lib/jvm/jdk-11.0.7/include/linux/ &> errors.txt
cat errors.txt | grep "error:" | cut -d' ' -f3- | sort | uniq

In that compile step I get a ton of errors which basically boil down to:

expected expression before ‘)’ token
‘PgQueryDeparseResult’ undeclared (first use in this function)
‘PgQueryError’ undeclared (first use in this function)
‘PgQueryFingerprintResult’ undeclared (first use in this function)
‘PgQueryNormalizeResult’ undeclared (first use in this function)
‘PgQueryParseResult’ undeclared (first use in this function)
‘PgQueryPlpgsqlParseResult’ undeclared (first use in this function)
‘PgQueryProtobufParseResult’ undeclared (first use in this function)
‘PgQueryProtobuf’ undeclared (first use in this function)
‘PgQueryScanResult’ undeclared (first use in this function)
‘PgQuerySplitResult’ undeclared (first use in this function)
‘PgQuerySplitStmt’ undeclared (first use in this function)
request for member ‘context’ in something not a structure or union
request for member ‘cursorpos’ in something not a structure or union
request for member ‘data’ in something not a structure or union
request for member ‘error’ in something not a structure or union
request for member ‘filename’ in something not a structure or union
request for member ‘fingerprint’ in something not a structure or union
request for member ‘fingerprint_str’ in something not a structure or union
request for member ‘funcname’ in something not a structure or union
request for member ‘len’ in something not a structure or union
request for member ‘lineno’ in something not a structure or union
request for member ‘message’ in something not a structure or union
request for member ‘normalized_query’ in something not a structure or union
request for member ‘n_stmts’ in something not a structure or union
request for member ‘parse_tree’ in something not a structure or union
request for member ‘pbuf’ in something not a structure or union
request for member ‘plpgsql_funcs’ in something not a structure or union
request for member ‘query’ in something not a structure or union
request for member ‘stderr_buffer’ in something not a structure or union
request for member ‘stmt_len’ in something not a structure or union
request for member ‘stmt_location’ in something not a structure or union
request for member ‘stmts’ in something not a structure or union
‘uint64_t’ undeclared (first use in this function); did you mean ‘u_int64_t’?
unknown type name ‘PgQueryDeparseResult’
unknown type name ‘PgQueryError’
unknown type name ‘PgQueryFingerprintResult’
unknown type name ‘PgQueryNormalizeResult’
unknown type name ‘PgQueryParseResult’
unknown type name ‘PgQueryPlpgsqlParseResult’
unknown type name ‘PgQueryProtobuf’
unknown type name ‘PgQueryProtobufParseResult’
unknown type name ‘PgQueryScanResult’
unknown type name ‘PgQuerySplitResult’
unknown type name ‘PgQuerySplitStmt’
unknown type name ‘uint64_t’; did you mean ‘u_int64_t’?

As you can see, there are errors about undeclared types, about not using structures or unions, and about unknown types. I've found other similar StackOverflow questions regarding SWIG where the answers were to fix the C header file being wrapped, but I can't do that because I didn't write pg_query.h. Is there something I can do with way I'm invoking SWIG and/or the gcc compiler in order to make this work? Thanks!

EDIT 1

For whatever reason, using the simplest of all possible interface files worked, even though the SWIG documentation says that an interface file is not strictly necessary:

%module test
%{
#include "pg_query.h"
%}
%include "pg_query.h"

Perhaps another way to answer this question would be to say why this is needed.

CodePudding user response:

Generally, the following interface file is needed:

// test.i
%module test

// This code is directly injected into the wrapper, and probably
// what was missing running SWIG directly on the header itself.
%{
#include "pg_query.h"
%}

// Process top-level code in this header file and wrap functions and globals found.
// It does not recurse into other includes like stdint.h.
%include "pg_query.h"

Then, swig -java test.i.

Even if it compiles and links, you'll want to test every function. SWIG is very forgiving in its wrappers and treats anything it doesn't understand as opaque pointers.

  • Related