According to the docs for CGO:
When building, the CGO_CFLAGS, CGO_CPPFLAGS, CGO_CXXFLAGS and CGO_LDFLAGS environment variables are added to the flags derived from these directives. Package-specific flags should be set using the directives, not the environment variables, so that builds work in unmodified environments.
Using this knowledge, I have had success building a third-party package that wraps a C library so long as it provides it as a system package. The example I linked to:
package sdl
// #cgo LDFLAGS: -lSDL2
// #include <SDL2/SDL.h>
import "C"
Even though it specifies a system package for SDL2, and I have SDL2 installed in some non-system directory, I am able to still build this package using some of the environment variables I mentioned, such as in the following:
export SDL_PATH=/home/mark/where/I/installed/sdl
CGO_CFLAGS="-I$SDL_PATH/include" CGO_LDFLAGS="-L$SDL_PATH/lib" go build hello.go
LD_LIBRARY_PATH="$SDL_PATH/lib" ./hello
Of course, this is Linux, but you can probably use the same ideas in Windows.
Answer from Mark Hildreth on Stack Overflowcmd/cgo: #include relative to current directory broken since Go 1.8
cgo compile c files housed in different directory than go files
include - How to point to C header files in GO? - Stack Overflow
New to cgo - unable to include header
According to the docs for CGO:
When building, the CGO_CFLAGS, CGO_CPPFLAGS, CGO_CXXFLAGS and CGO_LDFLAGS environment variables are added to the flags derived from these directives. Package-specific flags should be set using the directives, not the environment variables, so that builds work in unmodified environments.
Using this knowledge, I have had success building a third-party package that wraps a C library so long as it provides it as a system package. The example I linked to:
package sdl
// #cgo LDFLAGS: -lSDL2
// #include <SDL2/SDL.h>
import "C"
Even though it specifies a system package for SDL2, and I have SDL2 installed in some non-system directory, I am able to still build this package using some of the environment variables I mentioned, such as in the following:
export SDL_PATH=/home/mark/where/I/installed/sdl
CGO_CFLAGS="-I$SDL_PATH/include" CGO_LDFLAGS="-L$SDL_PATH/lib" go build hello.go
LD_LIBRARY_PATH="$SDL_PATH/lib" ./hello
Of course, this is Linux, but you can probably use the same ideas in Windows.
You could try using environment variables, the Gentoo Linux Wiki page on Safe C Flags has an example in the following format
CXXFLAGS="${CFLAGS}"
So you may be able to do something like
// #cgo windows CFLAGS: -I "${EXTLIBS}"/include/
but my syntax may be off, and that may be Makefile specific.
You could also try setting a CPATH environment variable which:
specifies a list of directories to be searched as if specified with -I, but after any paths given with -I options on the command line. This environment variable is used regardless of which language is being preprocessed.
The equivalent for -L is, I think, LIBRARY_PATH (Described at the CPATH link).
According to http://golang.org/cmd/cgo/ one sort of recommended way to get around this in a platform independant way is to use pkg-config.
// #cgo pkg-config: mylib otherlib
It's available for windows (http://ftp.gnome.org/pub/gnome/binaries/win32/dependencies/) and there's some more information on installing it at this question (How to install pkg config in windows?)
Other than that, put all the dependencies into a sub-directory of the go-code, use relative paths in your CFLAGS and LDFLAGS, and share the entire bundle with other developers.
Hello folks.
I am working on writing an Interpreter which is written in C and I want build a go api for my interpreter.
My current directory structure is something like this
... cpank/*.c cpank/stdlib/*.c cpank/ext/*.c cpank/ext/*.h cpank/include/*.h goapi/api.go ...
cpank/*.c contains the core files, stdlib contains source for standard library, ext curently contains 2 files xxhash.c and xxhash.h but can and will contain more files later.
I have tried putting the go file in main cpank directory but it fails. If I directly include the c files, cgo throws duplicate errors. Only thing that works is copying all c files from cpank, stdlib, ext and the include directory into the goapi directory.
Is there any way to tell cgo to compile this this and that files like we use with normal c projects.
How do I make this work?
Any help or suggestions will be appreciated.
I would like to include C source files together with my bindings for raylib https://github.com/gen2brain/raylib-go. It is not a library that you can just apt-get/dnf/brew so I think it would be nice if I bundle C source together with Go files.
I know for some examples, like gousb or glwf3 that bundle C source files, and include .c files together with .h but I am not sure where to start. So in raylib C version, there are 5-6 .c files, they are built to .o and then linked to one static library. How will that work in cgo, if I just include .c files how are they linked?
Use CGO CFLAGS directive to reference additional include path.
//#cgo CFLAGS: -I $GOPATH/src/github.com/yada/yada/
...
//#include "yoda.go.h"
import "C"
CORRECTION:
The go tool does not expand $GOPATH variable during build. Instead, the full path should be used there. Corrected code:
//#cgo CFLAGS: -I /full/path/to/src/github.com/yada/yada/
//#include "yoda.go.h"
Probably not a good idea to try and reference it directly, since it's not an exported entity, and is subject to change or removal.
If you really need that header, you'll have to reference it directly in your local filesystem. (of course you're free to copy into your project too)