Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/unity3d/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Cgo 如何说服Go找到C库_Cgo_Go Imagick - Fatal编程技术网

Cgo 如何说服Go找到C库

Cgo 如何说服Go找到C库,cgo,go-imagick,Cgo,Go Imagick,有谁能告诉我,在构建使用已安装到非标准位置的ImageMagick库的go程序时,我做错了什么 我想我看到的是程序构建了,但是没有在某个地方设置一个标志,告诉程序查找动态库的非标准位置,因此程序无法找到库 复制的步骤包括: 将ImageMagick配置为安装到非标准目录并生成它: # ./configure --prefix="/temp/imagemagick-temp" --without-magick-plus-plus --without-perl --disable-openmp --

有谁能告诉我,在构建使用已安装到非标准位置的ImageMagick库的go程序时,我做错了什么

我想我看到的是程序构建了,但是没有在某个地方设置一个标志,告诉程序查找动态库的非标准位置,因此程序无法找到库

复制的步骤包括:

将ImageMagick配置为安装到非标准目录并生成它:

# ./configure --prefix="/temp/imagemagick-temp" --without-magick-plus-plus --without-perl --disable-openmp --with-gvc=no
# make install
将pkgconfig目录添加到PKG_CONFIG_路径,以便PKG CONFIG可以找到它

# export PKG_CONFIG_PATH=/temp/imagemagick-temp/lib/pkgconfig
检查pkg config是否满意并可以找到它:

# pkg-config --cflags --libs MagickWand MagickCore
-DMAGICKCORE_HDRI_ENABLE=0 -DMAGICKCORE_QUANTUM_DEPTH=16 -I/temp/imagemagick-temp/include/ImageMagick-6  -L/temp/imagemagick-temp/lib -lMagickWand-6.Q16 -lMagickCore-6.Q16
构建程序并捕获所有输出:

# go build -v -x debug.go > debug_build.txt 2>&1
尝试运行它:

# ./debug
./debug: error while loading shared libraries: libMagickWand-6.Q16.so.2: cannot open shared object file: No such file or directory
我还通过strace运行了这个程序来捕获所有系统调用,下面是捕获。这表明程序找不到库文件的正确位置

当程序位于自定义位置时,我需要做什么才能使程序能够找到库

如果我手动设置CGO_CFLAGS和CGO_LDFLAGS,然后使用“no_pkgconfig”选项集进行构建,则会得到相同的结果

# export CGO_CFLAGS="-DMAGICKCORE_HDRI_ENABLE=0 -DMAGICKCORE_QUANTUM_DEPTH=16 -I/temp/imagemagick-temp/include/ImageMagick-6"
# export CGO_LDFLAGS="-L/temp/imagemagick-temp/lib -lMagickWand-6.Q16 -lMagickCore-6.Q16"
# go build -tags no_pkgconfig debug.go
# ./debug
./debug: error while loading shared libraries: libMagickWand-6.Q16.so.2: cannot open shared object file: No such file or directory
如果有关系,我在Centos6.4上使用“go版本go1.6.2 linux/amd64”

debug.go源文件

package main

/*
#cgo !no_pkgconfig pkg-config: MagickWand MagickCore
#include <wand/MagickWand.h>
*/
import "C"
import "fmt"

type KernelInfoType int

const (
    KERNEL_UNDEFINED     KernelInfoType = C.UndefinedKernel
)

func main() {
    fmt.Println("Hello world")
}
这是strace捕获的输出,显示程序没有在正确的位置查看

execve("./debug", ["./debug"], [/* 28 vars */]) = 0
brk(0)                                  = 0xc44000
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7facec440000
access("/etc/ld.so.preload", R_OK)      = -1 ENOENT (No such file or directory)
open("/etc/ld.so.cache", O_RDONLY)      = 3
fstat(3, {st_mode=S_IFREG|0644, st_size=30417, ...}) = 0
mmap(NULL, 30417, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7facec438000
close(3)                                = 0
open("/lib64/tls/x86_64/libMagickWand-6.Q16.so.2", O_RDONLY) = -1 ENOENT (No such file or directory)
stat("/lib64/tls/x86_64", 0x7fff50c5d9e0) = -1 ENOENT (No such file or directory)
open("/lib64/tls/libMagickWand-6.Q16.so.2", O_RDONLY) = -1 ENOENT (No such file or directory)
stat("/lib64/tls", {st_mode=S_IFDIR|0555, st_size=4096, ...}) = 0
open("/lib64/x86_64/libMagickWand-6.Q16.so.2", O_RDONLY) = -1 ENOENT (No such file or directory)
stat("/lib64/x86_64", 0x7fff50c5d9e0)   = -1 ENOENT (No such file or directory)
open("/lib64/libMagickWand-6.Q16.so.2", O_RDONLY) = -1 ENOENT (No such file or directory)
stat("/lib64", {st_mode=S_IFDIR|0555, st_size=12288, ...}) = 0
open("/usr/lib64/tls/x86_64/libMagickWand-6.Q16.so.2", O_RDONLY) = -1 ENOENT (No such file or directory)
stat("/usr/lib64/tls/x86_64", 0x7fff50c5d9e0) = -1 ENOENT (No such file or directory)
open("/usr/lib64/tls/libMagickWand-6.Q16.so.2", O_RDONLY) = -1 ENOENT (No such file or directory)
stat("/usr/lib64/tls", {st_mode=S_IFDIR|0555, st_size=4096, ...}) = 0
open("/usr/lib64/x86_64/libMagickWand-6.Q16.so.2", O_RDONLY) = -1 ENOENT (No such file or directory)
stat("/usr/lib64/x86_64", 0x7fff50c5d9e0) = -1 ENOENT (No such file or directory)
open("/usr/lib64/libMagickWand-6.Q16.so.2", O_RDONLY) = -1 ENOENT (No such file or directory)
stat("/usr/lib64", {st_mode=S_IFDIR|0555, st_size=20480, ...}) = 0
writev(2, [{"./debug", 7}, {": ", 2}, {"error while loading shared libra"..., 36}, {": ", 2}, {"libMagickWand-6.Q16.so.2", 24}, {": ", 2}, {"cannot open shared object file", 30}, {": ", 2}, {"No such file or directory", 25}, {"\n", 1}], 10./debug: error while loading shared libraries: libMagickWand-6.Q16.so.2: cannot open shared object file: No such file or directory
) = 131
exit_group(127)                         = ?
+++ exited with 127 +++

默认情况下,iMagick库被设置为依赖于pkg config,以便与package Manager中的标准ImageMagick安装兼容。它允许您使用build标记告诉它不要使用pkg config,而是依赖您自己提供的env来定位include和lib

这实际上是在项目中定义的:

构建标签

如果要在生成时手动指定CGO_CFLAGS/CGO_LDFLAGS, 例如,对于静态构建或不使用pkg config,可以使用 “no_pkgconfig”生成标记:

go build -tags no_pkgconfig gopkg.in/gographics/imagick.v2/imagick
在我自己使用iMagick的项目中,我使用了带有自定义ImageMagick位置的自定义构建标记

更新 由于您已经更新了您的问题,现在很明显,您的问题不是真正的Go问题,而是需要在运行时动态加载库的二进制文件的标准linux问题(您可以查看有关共享库如何工作的详细信息)

执行以下操作,它将修复您的运行时问题:

$ export LD_LIBRARY_PATH=/temp/imagemagick-temp/lib:$LD_LIBRARY_PATH
LD_LIBRARY_PATH
包含程序启动时链接器应搜索的路径列表。在构建程序时,您实际上已经成功地提供了正确的信息,您可以通过执行以下操作进行确认:

$ ldd ./debug

在前面提到的内容中,您还可以了解如何在构建二进制文件时提供rpath。这是一个烘焙到二进制文件中的路径,用于告诉链接器在该位置搜索依赖项。这将允许您避免将LD_LIBRARY_路径设置为该特定二进制文件的自定义ImageMagick位置。

您的意思是要说服Go去查找库吗?你说的“查找库”是什么意思?“Go肯定有一个find的实现,除非它消失了?”hauron我已经澄清了这个问题。该程序将使用一个C库,该库将被动态加载……这是一个库链接错误。是的,这就是我通过将变量CGO_LDFLAGS设置为“-L/usr/sbin/lib-lMagickWand-6.Q16-lMagickCore-6.Q16”所做的-我的理解是-L指示生成的程序在该目录中查找库。但它似乎没有任何效果。@Danack,那么你肯定用了build标签了?您是否使用-v和-x进行生成以查看生成正在执行的操作?我已使用完整生成输出和独立go文件更新了问题。@Danack,更新了我的答案以解决您的运行时问题。
$ ldd ./debug