首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何说服去寻找C库

如何说服去寻找C库
EN

Stack Overflow用户
提问于 2016-07-10 20:42:05
回答 1查看 5.6K关注 0票数 2

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

我认为我看到的是程序构建,但是告诉程序查看动态库的非标准位置的标志并没有设置在某个地方,所以程序无法定位库。

复制步骤如下:

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

代码语言:javascript
复制
# ./configure --prefix="/temp/imagemagick-temp" --without-magick-plus-plus --without-perl --disable-openmp --with-gvc=no
# make install

将pkgconfig目录添加到PKG_CONFIG_PATH中,以便pkg-config可以找到它。

代码语言:javascript
复制
# export PKG_CONFIG_PATH=/temp/imagemagick-temp/lib/pkgconfig

检查pkg-config是否高兴并可以找到它:

代码语言:javascript
复制
# 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

构建程序并捕获所有输出:

代码语言:javascript
复制
# go build -v -x debug.go > debug_build.txt 2>&1

尝试运行它:

代码语言:javascript
复制
# ./debug
./debug: error while loading shared libraries: libMagickWand-6.Q16.so.2: cannot open shared object file: No such file or directory

我还通过strace运行程序来捕获所有系统调用,捕获如下。它显示程序没有在正确的位置查找libary文件。

当程序位于自定义位置时,我需要做些什么才能让它找到库呢?

如果手动设置CGO_CFLAGS和CGO_LDFLAGS,然后使用'no_pkgconfig‘选项集构建,则得到相同的结果。

代码语言:javascript
复制
# 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上使用“GoVersiongo1.6.2Linux/amd64 64”

debug.go源文件

代码语言:javascript
复制
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")
}

这是构建的输出:

代码语言:javascript
复制
WORK=/tmp/go-build568335569
command-line-arguments
mkdir -p $WORK/command-line-arguments/_obj/
mkdir -p $WORK/command-line-arguments/_obj/exe/
cd /home/github/golang/goworkspace/src/debug
pkg-config --cflags MagickWand MagickCore
pkg-config --libs MagickWand MagickCore
CGO_LDFLAGS="-g" "-O2" "-L/temp/imagemagick-temp/lib" "-lMagickWand-6.Q16" "-lMagickCore-6.Q16" /home/github/golang/go/pkg/tool/linux_amd64/cgo -objdir $WORK/command-line-arguments/_obj/ -importpath command-line-arguments -- -DMAGICKCORE_HDRI_ENABLE=0 -DMAGICKCORE_QUANTUM_DEPTH=16 -I/temp/imagemagick-temp/include/ImageMagick-6 -I $WORK/command-line-arguments/_obj/ debug.go
gcc -I . -fPIC -m64 -pthread -fmessage-length=0 -DMAGICKCORE_HDRI_ENABLE=0 -DMAGICKCORE_QUANTUM_DEPTH=16 -I/temp/imagemagick-temp/include/ImageMagick-6 -I $WORK/command-line-arguments/_obj/ -g -O2 -o $WORK/command-line-arguments/_obj/_cgo_main.o -c $WORK/command-line-arguments/_obj/_cgo_main.c
gcc -I . -fPIC -m64 -pthread -fmessage-length=0 -DMAGICKCORE_HDRI_ENABLE=0 -DMAGICKCORE_QUANTUM_DEPTH=16 -I/temp/imagemagick-temp/include/ImageMagick-6 -I $WORK/command-line-arguments/_obj/ -g -O2 -o $WORK/command-line-arguments/_obj/_cgo_export.o -c $WORK/command-line-arguments/_obj/_cgo_export.c
gcc -I . -fPIC -m64 -pthread -fmessage-length=0 -DMAGICKCORE_HDRI_ENABLE=0 -DMAGICKCORE_QUANTUM_DEPTH=16 -I/temp/imagemagick-temp/include/ImageMagick-6 -I $WORK/command-line-arguments/_obj/ -g -O2 -o $WORK/command-line-arguments/_obj/debug.cgo2.o -c $WORK/command-line-arguments/_obj/debug.cgo2.c
gcc -I . -fPIC -m64 -pthread -fmessage-length=0 -o $WORK/command-line-arguments/_obj/_cgo_.o $WORK/command-line-arguments/_obj/_cgo_main.o $WORK/command-line-arguments/_obj/_cgo_export.o $WORK/command-line-arguments/_obj/debug.cgo2.o -g -O2 -L/temp/imagemagick-temp/lib -lMagickWand-6.Q16 -lMagickCore-6.Q16
/home/github/golang/go/pkg/tool/linux_amd64/cgo -objdir $WORK/command-line-arguments/_obj/ -dynpackage main -dynimport $WORK/command-line-arguments/_obj/_cgo_.o -dynout $WORK/command-line-arguments/_obj/_cgo_import.go
cd $WORK
gcc -I . -fPIC -m64 -pthread -fmessage-length=0 -no-pie -c trivial.c
cd /home/github/golang/goworkspace/src/debug
gcc -I . -fPIC -m64 -pthread -fmessage-length=0 -o $WORK/command-line-arguments/_obj/_all.o $WORK/command-line-arguments/_obj/_cgo_export.o $WORK/command-line-arguments/_obj/debug.cgo2.o -g -O2 -L/temp/imagemagick-temp/lib -Wl,-r -nostdlib -Wl,--build-id=none
/home/github/golang/go/pkg/tool/linux_amd64/compile -o $WORK/command-line-arguments.a -trimpath $WORK -p main -buildid f97632daf57e18f83c78ba78cc2d1ac8f96a4d1f -D _/home/github/golang/goworkspace/src/debug -I $WORK -pack $WORK/command-line-arguments/_obj/_cgo_gotypes.go $WORK/command-line-arguments/_obj/debug.cgo1.go $WORK/command-line-arguments/_obj/_cgo_import.go
pack r $WORK/command-line-arguments.a $WORK/command-line-arguments/_obj/_all.o # internal
cd .
/home/github/golang/go/pkg/tool/linux_amd64/link -o $WORK/command-line-arguments/_obj/exe/a.out -L $WORK -extld=gcc -buildmode=exe -buildid=f97632daf57e18f83c78ba78cc2d1ac8f96a4d1f $WORK/command-line-arguments.a
cp $WORK/command-line-arguments/_obj/exe/a.out debug

这是strace捕获的输出,显示程序没有在正确的位置查找。

代码语言:javascript
复制
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 +++
EN

回答 1

Stack Overflow用户

发布于 2016-07-12 20:12:04

默认情况下,iMagick库设置为依赖pkg-config,以便使其与来自包管理器的标准ImageMagick安装兼容。它允许您使用构建标记告诉它不要使用pkg-config,而是依赖您自己提供的env来定位包含和lib。

这实际上是在项目自述文件中定义的。

构建标签 如果希望在构建时手动指定CGO_CFLAGS/CGO_LDFLAGS,例如用于静态构建或不使用pkg-config,则可以使用"no_pkgconfig“构建标记: go构建-tags no_pkgconfig gopkg.in/gographics/imagick.v2/imagick

在我自己的使用iMagick的项目中,我使用了带有自定义ImageMagick位置的自定义构建标记。

更新

既然您已经更新了您的问题,现在很明显,您的问题并不是真正的Go问题,而是一个标准的linux问题,它需要在运行时动态加载库(您可以看到关于共享库如何运行这里的详细信息)。

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

代码语言:javascript
复制
$ export LD_LIBRARY_PATH=/temp/imagemagick-temp/lib:$LD_LIBRARY_PATH

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

代码语言:javascript
复制
$ ldd ./debug

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

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/38296291

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档