"Undefined symbols for architecture x86_64:" for library using cgo on macOS Sierra

I am trying to make use of a library, https://github.com/go-steem/rpc, that makes use of some C code, which references a library.

The C library can be found here, https://github.com/bitcoin-core/secp256k1

I followed the steps to get that installed

$ ./autogen.sh
$ ./configure
$ make
$ ./tests
$ sudo make install  # optional

And have this output;

$ sudo make install
Password:
  CC       src/libsecp256k1_la-secp256k1.lo
  CCLD     libsecp256k1.la
  CC       src/tests-tests.o
  CCLD     tests
  CC       src/exhaustive_tests-tests_exhaustive.o
  CCLD     exhaustive_tests
 build-aux/install-sh -c -d '/usr/local/lib'
 /bin/sh ./libtool   --mode=install /usr/bin/install -c   libsecp256k1.la '/usr/local/lib'
libtool: install: /usr/bin/install -c .libs/libsecp256k1.0.dylib /usr/local/lib/libsecp256k1.0.dylib
libtool: install: (cd /usr/local/lib && { ln -s -f libsecp256k1.0.dylib libsecp256k1.dylib || { rm -f libsecp256k1.dylib && ln -s libsecp256k1.0.dylib libsecp256k1.dylib; }; })
libtool: install: /usr/bin/install -c .libs/libsecp256k1.lai /usr/local/lib/libsecp256k1.la
libtool: install: /usr/bin/install -c .libs/libsecp256k1.a /usr/local/lib/libsecp256k1.a
libtool: install: chmod 644 /usr/local/lib/libsecp256k1.a
libtool: install: /usr/bin/ranlib /usr/local/lib/libsecp256k1.a
 build-aux/install-sh -c -d '/usr/local/include'
 /usr/bin/install -c -m 644 include/secp256k1.h '/usr/local/include'
 build-aux/install-sh -c -d '/usr/local/lib/pkgconfig'
 /usr/bin/install -c -m 644 libsecp256k1.pc '/usr/local/lib/pkgconfig'

I try to run the upvote example from that Go library, go-steem/rpc/examples/upvote/ and get the following output;

$ go run main.go 
# github.com/go-steem/rpc/transactions
../../transactions/signing.c:5:10: fatal error: 'secp256k1.h' file not found

Already it feels as though the wheels are falling off…

Please bear with me as I do not develop in C, so I get a bit hack-y.

After much reading, and googling I decide to copy the files from the ‘include’ directory where I compiled libsecp256k1 into the same directory as the error is originating from.

You can see the files are not there;

$ ls -la ../../transactions/
total 48
drwxr-xr-x   8 shaunmorrow  staff   272 May  8 18:09 .
drwxr-xr-x  15 shaunmorrow  staff   510 May  8 18:09 ..
-rw-r--r--   1 shaunmorrow  staff   256 Apr 27 17:53 chains.go
-rw-r--r--   1 shaunmorrow  staff  3731 May  8 18:09 signed_transaction.go
-rw-r--r--   1 shaunmorrow  staff  1849 May  8 18:09 signed_transaction_test.go
-rw-r--r--   1 shaunmorrow  staff  3075 Apr 27 17:53 signing.c
-rw-r--r--   1 shaunmorrow  staff   408 Apr 27 17:53 signing.h
-rw-r--r--   1 shaunmorrow  staff  1049 May  8 18:09 transactions.go

and after the copy;

$ ls -la ../../transactions/
total 128
drwxr-xr-x  11 shaunmorrow  staff    374 Jul 18 19:08 .
drwxr-xr-x  15 shaunmorrow  staff    510 May  8 18:09 ..
-rw-r--r--   1 shaunmorrow  staff    256 Apr 27 17:53 chains.go
-rw-r--r--   1 shaunmorrow  staff  27071 Jul 18 19:08 secp256k1.h
-rw-r--r--   1 shaunmorrow  staff   1014 Jul 18 19:08 secp256k1_ecdh.h
-rw-r--r--   1 shaunmorrow  staff   4700 Jul 18 19:08 secp256k1_recovery.h
-rw-r--r--   1 shaunmorrow  staff   3731 Jul 18 19:05 signed_transaction.go
-rw-r--r--   1 shaunmorrow  staff   1849 May  8 18:09 signed_transaction_test.go
-rw-r--r--   1 shaunmorrow  staff   3075 Apr 27 17:53 signing.c
-rw-r--r--   1 shaunmorrow  staff    408 Apr 27 17:53 signing.h
-rw-r--r--   1 shaunmorrow  staff   1049 May  8 18:09 transactions.go

Now I get a new error;

$ go run main.go 
# github.com/go-steem/rpc/transactions
ld: library not found for -lsecp256k1
clang: error: linker command failed with exit code 1 (use -v to see invocation)

This has me reading and googling some more,

Finally I get even more hack-y and change transactions.go;

// #cgo LDFLAGS: -lsecp256k1
// #include <stdlib.h>
// #include "signing.h"
import "C"

becomes

// #cgo LDFLAGS: -L/usr/local/lib
// #include <stdlib.h>
// #include "signing.h"
import "C"

which fails, output on that later

I also try;

// #cgo LDFLAGS: -L/usr/local/lib -I/usr/local/include
// #include <stdlib.h>
// #include "signing.h"
import "C"

and copy the .h files into the /usr/local/include directory.

None of this works and now I am stuck with an error like this

$ go run main.go 
# github.com/go-steem/rpc/transactions
ld: library not found for -lsecp256k1
clang: error: linker command failed with exit code 1 (use -v to see invocation)
ShaunsSePc-2:upvote shaunmorrow$ go run main.go 
# github.com/go-steem/rpc/transactions
Undefined symbols for architecture x86_64:
  "_secp256k1_context_create", referenced from:
      _sign_transaction in signing.o
      _verify_recoverable_signature in signing.o
  "_secp256k1_context_destroy", referenced from:
      _sign_transaction in signing.o
      _verify_recoverable_signature in signing.o
  "_secp256k1_ec_pubkey_serialize", referenced from:
      _verify_recoverable_signature in signing.o
  "_secp256k1_ecdsa_recover", referenced from:
      _verify_recoverable_signature in signing.o
  "_secp256k1_ecdsa_recoverable_signature_convert", referenced from:
      _verify_recoverable_signature in signing.o
  "_secp256k1_ecdsa_recoverable_signature_parse_compact", referenced from:
      _verify_recoverable_signature in signing.o
  "_secp256k1_ecdsa_recoverable_signature_serialize_compact", referenced from:
      _sign_transaction in signing.o
  "_secp256k1_ecdsa_sign_recoverable", referenced from:
      _sign_transaction in signing.o
  "_secp256k1_ecdsa_verify", referenced from:
      _verify_recoverable_signature in signing.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)

At this point I really have no idea how to continue.

As you can see I am not experienced in C at all and have no idea how to test if the library libsecp256k1 is even installed properly!

This is where I ended up, but it’s highly likely I took a wrong turn early in my journey, I would appreciate any help given as I have been struggling with this for a few nights already now :frowning:

Not sure whats needed so here some env variables

$ go env
GOARCH="amd64"
GOBIN=""
GOEXE=""
GOHOSTARCH="amd64"
GOHOSTOS="darwin"
GOOS="darwin"
GOPATH="/Users/shaunmorrow/Work/go/"
GORACE=""
GOROOT="/usr/local/go"
GOTOOLDIR="/usr/local/go/pkg/tool/darwin_amd64"
GCCGO="gccgo"
CC="clang"
GOGCCFLAGS="-fPIC -m64 -pthread -fno-caret-diagnostics -Qunused-arguments -fmessage-length=0 -fdebug-prefix-map=/var/folders/86/hlqptn5101z5bcydjz05qy8m0000gn/T/go-build689438019=/tmp/go-build -gno-record-gcc-switches -fno-common"
CXX="clang++"
CGO_ENABLED="1"
PKG_CONFIG="pkg-config"
CGO_CFLAGS="-g -O2"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-g -O2"
CGO_FFLAGS="-g -O2"
CGO_LDFLAGS="-g -O2"

Thanks!

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.