1

I am trying to build the steampipe-postgres-fdw project in a Mac M1 with the latest go version (1.21).

It currently uses go version 1.19.

The FDW is designed to work with Postgresql 14.

The project comes with a Makefile which generates the go files with the C import headers (relies on the pg_config in $PATH).

I changed the go directive in the go.mod file (go mod edit --go 1.21), but when I run make, I hit upon the error below:

Undefined symbols for architecture arm64:
  "_res_9_nclose", referenced from:
      _internal/syscall/unix.libresolv_res_9_nclose_trampoline.abi0 in steampipe_postgres_fdw.a(go.o)
  "_res_9_ninit", referenced from:
      _internal/syscall/unix.libresolv_res_9_ninit_trampoline.abi0 in steampipe_postgres_fdw.a(go.o)
  "_res_9_nsearch", referenced from:
      _internal/syscall/unix.libresolv_res_9_nsearch_trampoline.abi0 in steampipe_postgres_fdw.a(go.o)
ld: symbol(s) not found for architecture arm64
Binaek Sarkar
  • 617
  • 8
  • 21
  • [Googling](https://www.google.com/search?q=Undefined+symbols+for+architecture+arm64%3A+++%22_res_9_nclose%22) for the error message brings in [this](https://github.com/golang/go/issues/58159)–basically, it says linking should be done with specifying `-lresolv` (that is, you should link against the `libresolv` library. Exactly how to make the build process use `-lresolv` when linking is a separate question. – kostix Aug 11 '23 at 17:08
  • While we're at it, I should point out that changing Go version in a `go.mod` file has nothing to do with changing the version of Go used for compiling–it merely says hints toolchain about what's the lowest version of Go is supported by the module; the actual Go version used for building is that of the `go` command which is run (by you). You can run `go version` to see what version is it. – kostix Aug 11 '23 at 17:09
  • @kostix thank you for the direction. `libresolv` was a no-go, but it turns out that adding a ` -tags=netgo` to the `go build` command solves the issue. – Binaek Sarkar Aug 17 '23 at 11:01
  • «adding a `-tags=netgo` … solves the issue»–should work, yes, if you clearly understand possible repercussions: basically, your program will use a somewhat dumbed-down DNS resolver (provided by a Go's internal package) whose behavior might slightly deviate from "typically expected" behavior in some subtle cases–such as (not) caching the lookup results or caching with different TTL or not reloading the system-wide resolver configuration at runtime, when it changes, etc. I mean, you might want to read up on this and figure out whether that really works acceptably for your prospective use cases. – kostix Aug 17 '23 at 11:20
  • BTW, be sure to accept your own answer (maybe after some timeout imposed by SO). – kostix Aug 17 '23 at 11:23
  • « program will use a somewhat dumbed-down DNS resolver » - Thanks for the heads up. I don't suppose that's going to be a problem, since the project does not do any DNS resolution. It uses the `net` package heavily though. I will take a look if the `netgo` solution has any side-effects. – Binaek Sarkar Aug 18 '23 at 10:34

1 Answers1

0

Adding a -tags=netgo to go build resolved the issue.

The writeup here is a great reference on how dynamic linking works in go.

Caution: As @kostix mentions, this uses the go DNS resolver, "whose behavior might slightly deviate from "typically expected" behavior in some subtle cases"

Binaek Sarkar
  • 617
  • 8
  • 21