pgcentralfoundation / pgrx

Build Postgres Extensions with Rust!
Other
3.72k stars 251 forks source link

libintl.h file not found #470

Open kev009 opened 2 years ago

kev009 commented 2 years ago

OS is FreeBSD. pgx is 0.4.0-beta-0. It seems to get pretty close to the end but then is missing a C header which would be in /usr/local.

cargo pgx init --pg13 pg_config with pg_config showing the correct INCLUDEDIR = /usr/local/include

kev-ws-aurora% cargo pgx run pg13
building extension with features ``
"cargo" "build" "--message-format=json-render-diagnostics"
   Compiling pgx-pg-sys v0.4.0-beta.0
error: failed to run custom build command for `pgx-pg-sys v0.4.0-beta.0`

Caused by:
  process didn't exit successfully: `/usr/home/kev009/pgxtest/target/debug/build/pgx-pg-sys-661c1c5f07b27fdc/build-script-build` (exit status: 101)
  --- stdout
  cargo:rerun-if-env-changed=PGX_PG_SYS_GENERATE_BINDINGS_FOR_RELEASE
  cargo:rerun-if-changed=/home/kev009/.pgx/config.toml
  cargo:rerun-if-changed=include/pg10.h
  cargo:rerun-if-changed=include/pg11.h
  cargo:rerun-if-changed=include/pg12.h
  cargo:rerun-if-changed=include/pg13.h
  cargo:rerun-if-changed=include/pg14.h
  cargo:rerun-if-changed=cshim/pgx-cshim.c
  cargo:rerun-if-changed=cshim/Makefile

  --- stderr
  manifest_dir=/home/kev009/.cargo/registry/src/github.com-1ecc6299db9ec823/pgx-pg-sys-0.4.0-beta.0
  shim_src=/home/kev009/.cargo/registry/src/github.com-1ecc6299db9ec823/pgx-pg-sys-0.4.0-beta.0/cshim
  shim_dst=/usr/home/kev009/pgxtest/target/debug/build/pgx-pg-sys-86f7123a0f3e30bb/out/cshim
  Generating bindings for pg13
  /usr/local/include/postgresql/server/c.h:75:10: fatal error: 'libintl.h' file not found
  /usr/local/include/postgresql/server/c.h:75:10: fatal error: 'libintl.h' file not found, err: true
  thread 'main' panicked at 'Unable to generate bindings for pg13: ()', /home/kev009/.cargo/registry/src/github.com-1ecc6299db9ec823/pgx-pg-sys-0.4.0-beta.0/build.rs:512:13
  note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
Hoverbear commented 2 years ago

Thanks for reporting this! Hmm... I don't currently have a freeBSD machine to reproduce this on.

JonyEpsilon commented 2 years ago

This is a bit of a drive-by, as I know almost nothing about rust, cargo, or pgx! But maybe it'll be helpful anyway ...

I came across this error trying to build the databases/postgres-promscale extension on FreeBSD (https://cgit.freebsd.org/ports/tree/databases/postgresql-promscale). I've proposed a patch to "fix" it on this bug https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=267550 . That's a patch to the promscale extension port, as it vendors in its own version of pgx. But I think the problem is a pgx problem rather than a promscale-specific problem.

My best guess is that there's an assumption baked in to the pgx-pg-sys buildgen code that 'libintl.h' will be located in /usr/include. On FreeBSD it's by default in /usr/local/include because it ships as part of a package (devel/gettext-runtime) rather than as part of the base system. The location of this local include directory is included in an environment variable set by the ports make system, CPPFLAGS (you can see the full cargo command being executed by the ports make system, for the vendored pgx in the promscale extension, in this comment https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=267550#c4 ).

So, maybe it's possible that this flag isn't being read by the buildgen code, and so the include directory is not being flagged to clang? I did notice this commit https://github.com/tcdi/pgx/commit/6aaad9803759e021a919fcc9242f9f5c932569ae while poking around the source, which adds some extra clang flags on MacOS. Maybe something in a similar spirit is needed to support FreeBSD?

Anyway, I may be off-base here - so take this with a pinch of salt - but maybe something in there helps.

workingjubilee commented 1 year ago

@JonyEpsilon That is not the right solution, and also it is not quite a PGX bug.

libintl.h is not an actual dependency of PGX at all. It is only bound against because rust-bindgen, by default, eagerly binds against transitive header dependencies, because it does not have the sense of whether a symbol actually requires a certain header in order to resolve its definition (not necessarily to compile it, which of course might require everything and then the kitchen sink). We do require postgres.h, but that includes c.h, which, if the build was instructed to ENABLE_NLS, includes libintl.h. But we don't need any of the definitions from that! PGX extensions should not need to use gettext: there are in-Rust for-Rust solutions for that facility.

I have opened https://github.com/tcdi/pgx/pull/940 to attempt to resolve this by directing bindgen to omit c.h and its definitions from the bindings, as I believe this should solve the problem for all OS. But if this does not solve the problem on BSDs, you may want to instead try to explicitly add .blocklist_file("libintl.h"). Again, we do not use it and should not need it as part of the build.

JonyEpsilon commented 1 year ago

Ahh, interesting. Thanks for taking the time to write the explanation :-)

If I remove the additional clang_arg and try adding either .blocklist_file("libintl.h") or .blocklist_file("c.h") I find that neither of them lead to a successful build on FreeBSD. The error is as before:

/usr/local/include/postgresql/server/c.h:75:10: fatal error: 'libintl.h' file not found

(It should noted that this against the 0.7.0 release, which is what targeted by the FreeBSD port, not against HEAD.)

I would speculate that something is trying to resolve the path to the file before the blocking is happening, but at this point I'm just making stuff up, as I've no idea how bindgen works!

sumerman commented 1 year ago

I'm getting this same message when trying to run cargo pgrx init against PostgreSQL 15 from brew.

thomcc commented 1 year ago

You probably have to run brew info gettext (and maybe some other packages, we should document this better/find PG's docs on it -- as of pg16 you'll need brew install icu4c too...)

Also note that we don't use the PostgreSQL you install globally except for a couple commands like package/install, so having installed it via brew doesn't really exempt you from these issues.

(Also, if you don't have it set up, make sure you have XCode and the CommandLineTools package installed, and make sure you've opened XCode at least once since installing)

samay-sharma commented 1 year ago

I was running into the same issue on a Mac while trying to run cargo pgrx install --release for https://github.com/tembo-io/pgmq even though I had libint.h present.

locate libintl
/Applications/Docker.app/Contents/Resources/lib/libintl.8.dylib
/opt/homebrew/Cellar/gettext/0.21.1/include/libintl.h
/opt/homebrew/Cellar/gettext/0.21.1/lib/libintl.8.dylib
/opt/homebrew/Cellar/gettext/0.21.1/lib/libintl.a
/opt/homebrew/Cellar/gettext/0.21.1/lib/libintl.dylib
/opt/homebrew/include/libintl.h
/opt/homebrew/lib/libintl.8.dylib
/opt/homebrew/lib/libintl.a
/opt/homebrew/lib/libintl.dylib

I was able to fix it by running export BINDGEN_EXTRA_CLANG_ARGS='-I"/opt/homebrew/include"' as indicated here: https://github.com/rust-lang/rust-bindgen

thomcc commented 1 year ago

It looks like this happens if you do cargo pgrx init --pgwhatever=$(which pg_config), e.g. use the system postgres. It can be fixed by handling it around https://github.com/pgcentralfoundation/pgrx/blob/c7b6fbab43c108902052b32e0fded82b0da77752/pgrx-pg-sys/build.rs#L877 or so, I think. It needs to be changed to look at the includes in --cppflags and such.