I wrote a go package that is just a wrapper for a C program, which requires openssl to work.
My CGO setup is as follow:
// #cgo CFLAGS: -Imy/library/include -Imy/library/src -I/usr/local/opt/openssl/include
// #cgo LDFLAGS: -L/usr/include/openssl -Lmy/library/src -lcrypto
// #include <my_library.c>
// #include <stdlib.h>
import "C"
I can compile and run it both in my Mac and on a Docker container I created, but when I try to run (it is already compiled) on a different machine I get the error:
error while loading shared libraries: libcrypto.so.1.1: cannot open shared object file: No such file or directory
How can I make it work also on PCs without libssl-dev installed?
Related
package xxx
/*
#cgo pkg-config: vips
#include "vips/vips.h"
*/
import "C"
When I built my code,it returned "vips/vips.h: No such file or directory".
Centos.
I have installed vips and pkg-conf.But it seems not effect.
I'm trying to dynamically play audio in a Go application. Basically the only way I found was to use a Go binding to call a C library, more specifically portaudio.
I found this binding but I don't know how to use it. I downloaded these pre-compiled DLLs and replaced the lines
/*
#cgo pkg-config: portaudio-2.0
#include <portaudio.h>
extern PaStreamCallback* paStreamCallback;
*/
with
/*
#cgo LDFLAGS: -LC:\portaudio-binaries -lportaudio
#include "portaudio.h"
extern PaStreamCallback* paStreamCallback;
*/
but when I try to compile the Go project I still get
cc1.exe: sorry, unimplemented: 64-bit mode not compiled in
I also got this error when trying to import versions of portaudio I compiled using mingw. Its output had the format of a .la file alongside a .libs folder, which contained a .dll file plus others. But I'm not sure how I'm supposed to import this format of libraries.
On Windows 64 bit i have a simple go program with following cgo statement.
/*
#cgo LDFLAGS: -L./lib -ltuser.lib
#include <stdio.h>
#include <windows.h>
*/
import "C"
The tuser.lib is a lib file for the Windows DLL and is the folder same as the go file.
When I build the go code I see the error: cannot find -ltuser.lib.
Any suggestion as to what changes need to be made in order to make this work.
The following worked:
#cgo LDFLAGS: -L./ -ltuser.dll
So it seems that it should be a dll instead of a lib.
I am trying to include the libsodium into my Go project. For that, I've copied the repo inside my project
// #cgo CFLAGS: -I/mypath/libsodium/src/libsodium/include/sodium
// #include <stdlib.h>
// #include "crypto_sign_ed25519.h"
import "C"
When trying to build the project I get the following error:
/tmp/go-build/cgo-gcc-prolog:53: undefined reference to `crypto_sign_ed25519_pk_to_curve25519'
collect2: error: ld returned 1 exit status
The file can be found but the error is there.
I've also tried to reference the '.c' file as well as to copy the crypto_sign_ed25519.h into the src folder but it does not work.
My question is do I have to add LDFLAGS and therefore generate a .so file from the library or that is not needed and there is another possible way of doing it?
UPDATE: I've achieved to make it running by installing the library on my local ubuntu:
$ ./configure
$ make && make check
$ sudo make install
and adding
// #cgo LDFLAGS: -L/usr/local/lib -lsodium
But how can I do it without adding the local path?
You indeed need to link the library, the headers themselves are only the interface to the library and don't link the actual libsodium code to your binary.
Assuming libsodium ships a pkg-config file (it seems to be the case), you can use something like
// #cgo pkg-config: libsodium
// #include "crypto_sign_ed25519.h"
See https://golang.org/cmd/cgo/ for more information about pkg-config support.
To see what cflags/libs you'd be getting (so what cgo will use), run:
pkg-config --cflags --libs libsodium
After manually installing a library on Linux, you have to type ldconfig so that the linker becomes aware of it.
Also, in order to get libsodium prototypes, you should simply include <sodium.h> not <sodium/crypto_sign_ed25519.h> (not meant to be included directly), and call sodium_init() before any other function so that internal data structures are properly initialized.
See how this is done in existing bindings for Go: https://github.com/jamesruan/sodium/blob/master/core.go
You may want to use these bindings instead of reinventing your own. If they are missing some of the functions you need, their maintainers will probably be happy to accept your pull requests.
The two main Go bindings for libsodium that I am aware of are sodium and libsodium-go.
I'm trying to compile a go project in a raspberry pi.
The project has 5 files, two small .c files and its counterparts .h (one of these files is my code -- it calls the other, which is a base64 library) and a .go files which calls my .c code using cgo.
When I compile my C code only (with its calls and everything) with gcc alone at the raspberry pi it does well without any configuration.
When I compile the entire go project on my x86 Linux Ubuntu machine with go build, it also does pretty well.
But when I try to compile the go project with go build in the raspberry pi it doesn't get my C libraries:
fiatjaf#raspberrypi ~/g/s/b/f/project> go build -x
WORK=/tmp/go-build702187084
mkdir -p $WORK/bitbucket.org/fiatjaf/project/_obj/
cd /home/fiatjaf/go/src/bitbucket.org/fiatjaf/project
/usr/lib/go/pkg/tool/linux_arm/5c -FVw -I $WORK/bitbucket.org/fiatjaf/project/_obj/ -I /usr/lib/go/pkg/linux_arm -o $WORK/bitbucket.org/fiatjaf/project/_obj/base64.5 -DGOOS_linux -DGOARCH_arm ./base64.c
# bitbucket.org/fiatjaf/project
./base64.c:2 5c: No such file or directory: math.h
(If I put the <stdlib.h> before the <math.h> the problem occurs for it too, so the problem is not the absence of math.h, I think)
I tried to:
add // #cgo CFLAGS: -I/usr/include to the .go file
add // #cgo LDFLAGS: -I/usr/include (I can't discover what is the proper usage of these flags)
use go build -ldflags '-I/usr/include'
I don't understand why go is trying to compile base64.c with -I /usr/lib/go/pkg/linux_arm. Really don't. Someone help.
EDIT: Clarifying note about the structure of the project:
It has 5 files, 2 C (and its counterparts H):
base64.c
#include <math.h>
#include <stdint.h>
#include <stdlib.h>
... // definitions of functions used at project.c
project.c
#include <stdlib.h>
#include <string.h>
#include "base64.h"
... // functions used at project.go
and 1 Go:
...
// #include <stdlib.h>
// #include <string.h>
// #include "project.h"
// #cgo CFLAGS: -I/usr/include
// #cgo LDFLAGS: -lm
import "C"
...
Where, what and how should I change in this declarations for this thing to work? And why did it worked on my x86 linux?
cgo inline syntax
The correct syntax for cgo parameters in the go file is this:
// #cgo CFLAGS: -I/usr/include
without the whitespace between # and cgo. See cmd/cgo for details on the syntax.
-ldflags parameter
The go -ldflags parameter passes parameters to the go linkers (5l, 6l, 8l, ...).
Even if the parameter would be passed to the C linker, this wouldn't do you any good
as the linker does not handle includes, the compiler does.
I'm afraid that this parameter won't help you here. All relevant parameters should
be configured in the go source file using the #cgo tags.
misc. notes
If you're using math.h you most likely need to link libmath. You can do this
by writing this to your go source file:
// #cgo LDFLAGS: -lm
It seems my problem was something related to not having set the CGO_ENABLED flag.
I don't know for sure, but it seems, because I uninstalled my Go from the Raspbian repositories (which seems to come with CGO disabled by default) and installed Go from source (just like I had made in my x86 Linux) then it started to work.