I'm attempting to write some C bindings for the Go language, and have run into a sort of sticky situation when setting up the Cgo compilation in Windows. I have code that looks like the following:
// #cgo windows CFLAGS: -I C:/dev/extlibs/include/
// #cgo windows LDFLAGS: -lMyLib -L C:/dev/extlibs/lib/
// #include <mylib/mylib.h>
import "C"
which is allows me to avoid installing Dlls, libs, and header files directly into my C:\Windows directory, but doesn't allow for much flexibility when other developers are working with a different file system setup (they all need the libs to be in C:/dev/extlibs/...).
Is there a way I could referent an environment variable from within the code? Perhaps something along the lines of:
// #cgo windows CFLAGS: -I $EXTLIBS$/include/
Or is there another way that people solve this issue that I have missed? I've spent some time googling around on this subject and haven't seen much that has been useful, so any information and/or resources could be a real help!
Environment variables can be used to pass configuration to an application when it is run. This is done by adding the definition of the environment variable to the deployment configuration for the application. To add a new environment variable use the oc set env command.
The cgo tool is enabled by default for native builds on systems where it is expected to work. It is disabled by default when cross-compiling. You can control this by setting the CGO_ENABLED environment variable when running the go tool: set it to 1 to enable the use of cgo, and to 0 to disable it.
CGO_LDFLAGS is meant for both internal linking and external linking mode, whereas -extldflags is meant only. for external linking. Ok , that seems like a logical distinction, though I haven't figured out how to pass in multiple options to -extldflags from the command line.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With