Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Override an external package's cgo compiler and linker flags?

Tags:

go

cgo

Let's say I want to use some awesome go package. I can include it by:

import "github.com/really-awesome/project/foobar"

And inside that project's foobar.go file, it defines some cgo instructions like:

#cgo windows CFLAGS: -I C:/some-path/Include
#cgo windows LDFLAGS: -L C:/some-path/Lib -lfoobar

But if I have that foobar C dependency installed somewhere else, I would really need those lines to say:

#cgo windows CFLAGS: -I C:/different-path/Include
#cgo windows LDFLAGS: -L C:/different-path/Lib -lfoobar

Is there a way to override or trump where cgo is looking for these dependencies? Right now my fix is to manually edit those two lines after running go get ./... which will fetch the github.comreally-awesome/project/foobar code.

NOTE: I'm using the MinGw compiler, though I doubt that matters.

update:

I have tried adding flags to go build to no avail:

go build -x -gcflags="-I C:/different/include -L C:/different-path/lib -lfoobar"
go build -x -ccflags="-I C:/different/include" -ldflags="-L C:/different-path/lib -lfoobar"

With the -x argument I see the printout of flags and they don't include the ones I am setting on the command line. Perhaps the #cgo CFLAGS/LDFLAGS statements at the top of the external go package squash what I am telling it to use...

like image 262
jCuga Avatar asked Feb 25 '15 02:02

jCuga


People also ask

How does CGO combine go and C files?

Given a Go source file written with some special features, cgo outputs Go and C files that can be combined into a single Go package. To lead with an example, here’s a Go package that provides two functions - Random and Seed - that wrap C’s random and srandom functions. Let’s look at what’s happening here, starting with the import statement.

What are the compiler options for CGO tool?

go tool cgo [cgo options] [-- compiler options] gofiles... Cgo transforms the specified input Go source files into several output Go and C source files. The compiler options are passed through uninterpreted when invoking the C compiler to compile the C parts of the package. The following options are available when running cgo directly:

What is the use of CGO header in C?

Any lines starting with #cgo followed by a space character are removed; these become directives for cgo. The remaining lines are used as a header when compiling the C parts of the package. In this case those lines are just a single #include statement, but they can be almost any C code.

Where do I find compiler flags in GCC?

Documentation for compiler flags is available in the GCC manual. Those flags (which start with -Wl) are passed to the linker and are described in the documentation for ld . -D_GLIBCXX_ASSERTIONS enables additional C++ standard library hardening.


2 Answers

You can do this by setting the CGO_CPPFLAGS and CGO_LDFLAGS environment variables.

For example, on my MacBook, Homebrew is installed in ~/.homebrew (instead of /usr/local), so when I try to go get packages with native bindings they can't find the headers and libs.

To fix that I added these two lines to my ~/.zshenv file:

export CGO_CPPFLAGS="-I $BREW_HOME/include"
export CGO_LDFLAGS="-L $BREW_HOME/lib"
like image 82
David E Avatar answered Oct 23 '22 02:10

David E


This is kind of the role filled by #cgo pkgconfig: foobar. If the library had been written that way, it would pick up the correct paths from foobar's pkgconfig definition.

I realise its not a direct answer to the question, and that pkgconfig isn't exactly a native windows tool... I'd be interested to hear if any other solutions exist.

like image 26
sqweek Avatar answered Oct 23 '22 02:10

sqweek