英文:
Is it possible to use environment variables in a cgo CFLAGS comment?
问题
我正在尝试为Go语言编写一些C绑定,并在设置Windows的Cgo编译时遇到了一些棘手的问题。我有以下代码:
// #cgo windows CFLAGS: -I C:/dev/extlibs/include/
// #cgo windows LDFLAGS: -lMyLib -L C:/dev/extlibs/lib/
// #include <mylib/mylib.h>
import "C"
这样可以避免直接将DLL、库和头文件安装到C:\Windows目录中,但在其他开发人员使用不同的文件系统设置时(他们都需要将库放在C:/dev/extlibs/...中),这样做就没有太多的灵活性。
我能否在代码中引用环境变量?也许可以这样做:
// #cgo windows CFLAGS: -I $EXTLIBS$/include/
或者还有其他解决这个问题的方法吗?我在这个问题上花了一些时间搜索,但没有找到太多有用的信息和资源,所以任何信息和/或资源都将是真正的帮助!
英文:
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!
答案1
得分: 19
根据CGO的文档:
> 在构建时,CGO_CFLAGS、CGO_CPPFLAGS、CGO_CXXFLAGS和CGO_LDFLAGS环境变量会添加到从这些指令派生的标志中。应该使用指令设置特定于包的标志,而不是环境变量,以便在未修改的环境中进行构建。
利用这个知识,只要将第三方包提供为系统包,我就成功地构建了一个包装C库的第三方包。我提供的示例代码如下:
package sdl
// #cgo LDFLAGS: -lSDL2
// #include <SDL2/SDL.h>
import "C"
即使它为SDL2指定了一个系统包,而我在某个非系统目录中安装了SDL2,我仍然可以使用我提到的一些环境变量来构建这个包,例如:
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
当然,这是在Linux上,但你可能可以在Windows上使用相同的思路。
英文:
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.
答案2
得分: 9
你可以尝试使用环境变量,Gentoo Linux Wiki页面上的Safe C Flags有一个以下格式的示例:
CXXFLAGS="${CFLAGS}"
所以你可以尝试做一些类似的事情
// #cgo windows CFLAGS: -I "${EXTLIBS}"/include/
但是我的语法可能有问题,而且可能是特定于Makefile的。
你也可以尝试设置CPATH
环境变量,它:
>指定要搜索的目录列表,就像在命令行上使用-I指定的一样,但是在命令行上使用-I选项指定的路径之后。无论预处理哪种语言,都会使用此环境变量。
相当于-L
的等效方式是LIBRARY_PATH
(在CPATH
链接中描述)。
根据http://golang.org/cmd/cgo/,在一个平台无关的方式中,一种有点推荐的方法是使用pkg-config。
// #cgo pkg-config: mylib otherlib
它在Windows上可用(http://ftp.gnome.org/pub/gnome/binaries/win32/dependencies/),并且在这个问题(如何在Windows上安装pkg config?)中有一些更多关于安装它的信息。
除此之外,将所有依赖项放入go代码的子目录中,在CFLAGS
和LDFLAGS
中使用相对路径,并与其他开发人员共享整个包。
英文:
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.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论