7월 032014
 

윈도우에서 레일즈로 프로그래밍하면서 뭔가 한 번에 되는 것이 없다는 것을 자주 느끼곤 하는데, rmagick 이라는 gem을 설치할 때도 마찬가지 였다. rmagick은 오픈소스 이미지 프로세싱 라이브러리로 유명한 ImageMagick라는 라이브러리를 루비에서도 쓸 수 있게 wrapping한 gem이다. 전부가 그런 것은 아니고 C나 C++로 만들어진 대다수의 오픈소스 라이브러리는 크로스 컴파일을 지원하지만, 제일 컴파일하고 실행하기 좋은 환경은 리눅스 환경일 것이다. 어쨋든 rmagick을 윈도우에서 써야하는 이상 Gemfile에 rmagick을 넣고 bundle을 돌렸다. 역시나 에러 발생. 이런쪽 문제가 발생하면 구글에게 물어보라고 했던가, 검색하자마자 스택오버플로우 글 하나를 첫번째로 띄어주었다[1]. 글을 읽어보니 이전 포스팅에서 확인한 것과 같이 라이브러리를 설치해야한다는 것이였다. 별 생각없이 다운로드 받아서 실행해본 결과 역시나 실패. [1][2]의 글을 좀 열심히 읽어보니 라이브러리를 설치한 디렉토리에 빈칸이 있으면 안된다는 것이었다. “Program files”폴더에 설치 됬으니 당연히 빈칸이 들어갈 수 밖에… 지우고 다시 설치하였다. 그랬는데도 컴파일이 되지 않았다. 무엇 때문인지 하고 봤더니 ” c:\ImageMagick-6.8.0-3-Q16″에 “-“기호나 “.” 같은 특수문자 때문인듯 했다. 그래서 시키는 대로 “c:\ImageMagick” 폴더에 설치를 했다. 그랬더니 gem 설치가 성공하는 듯 했다. 하지만 이렇게 성공했다면 여기에 글을 남기지는 않았을 것이다. 역시나 안됬다. 에러를 뿌리면서 안됬는데 아래의 에러가 발생한다.

Building native extensions with: '--with-opt-lib=c:/ImageMagick/lib --with-opt-include=c:/ImageMagic
k/include'
This could take a while...
ERROR:  Error installing rmagick:
        ERROR: Failed to build gem native extension.

    C:/Ruby200/bin/ruby.exe extconf.rb --with-opt-lib=c:/ImageMagick/lib --with-opt-include=c:/Image
Magick/include
checking for Ruby version >= 1.8.5... yes
checking for stdint.h... yes
checking for sys/types.h... yes
checking for wand/MagickWand.h... yes
checking for snprintf() in assert.h,ctype.h,stdio.h,stdlib.h,math.h,time.h,stdint.h,sys/types.h,wand
/MagickWand.h... yes
checking for AcquireImage() in assert.h,ctype.h,stdio.h,stdlib.h,math.h,time.h,stdint.h,sys/types.h,
wand/MagickWand.h... yes
checking for AffinityImage() in assert.h,ctype.h,stdio.h,stdlib.h,math.h,time.h,stdint.h,sys/types.h
,wand/MagickWand.h... no
checking for AffinityImages() in assert.h,ctype.h,stdio.h,stdlib.h,math.h,time.h,stdint.h,sys/types.
h,wand/MagickWand.h... no
checking for AutoGammaImageChannel() in assert.h,ctype.h,stdio.h,stdlib.h,math.h,time.h,stdint.h,sys
/types.h,wand/MagickWand.h... yes
checking for AutoLevelImageChannel() in assert.h,ctype.h,stdio.h,stdlib.h,math.h,time.h,stdint.h,sys
/types.h,wand/MagickWand.h... yes
checking for BlueShiftImage() in assert.h,ctype.h,stdio.h,stdlib.h,math.h,time.h,stdint.h,sys/types.
h,wand/MagickWand.h... yes
checking for ConstituteComponentTerminus() in assert.h,ctype.h,stdio.h,stdlib.h,math.h,time.h,stdint
.h,sys/types.h,wand/MagickWand.h... no
checking for DeskewImage() in assert.h,ctype.h,stdio.h,stdlib.h,math.h,time.h,stdint.h,sys/types.h,w
and/MagickWand.h... yes
checking for EncipherImage() in assert.h,ctype.h,stdio.h,stdlib.h,math.h,time.h,stdint.h,sys/types.h
,wand/MagickWand.h... yes
checking for EqualizeImageChannel() in assert.h,ctype.h,stdio.h,stdlib.h,math.h,time.h,stdint.h,sys/
types.h,wand/MagickWand.h... yes
checking for FloodfillPaintImage() in assert.h,ctype.h,stdio.h,stdlib.h,math.h,time.h,stdint.h,sys/t
ypes.h,wand/MagickWand.h... yes
checking for FunctionImageChannel() in assert.h,ctype.h,stdio.h,stdlib.h,math.h,time.h,stdint.h,sys/
types.h,wand/MagickWand.h... yes
checking for GetAuthenticIndexQueue() in assert.h,ctype.h,stdio.h,stdlib.h,math.h,time.h,stdint.h,sy
s/types.h,wand/MagickWand.h... yes
checking for GetAuthenticPixels() in assert.h,ctype.h,stdio.h,stdlib.h,math.h,time.h,stdint.h,sys/ty
pes.h,wand/MagickWand.h... yes
checking for GetImageAlphaChannel() in assert.h,ctype.h,stdio.h,stdlib.h,math.h,time.h,stdint.h,sys/
types.h,wand/MagickWand.h... yes
checking for GetVirtualPixels() in assert.h,ctype.h,stdio.h,stdlib.h,math.h,time.h,stdint.h,sys/type
s.h,wand/MagickWand.h... yes
checking for LevelImageColors() in assert.h,ctype.h,stdio.h,stdlib.h,math.h,time.h,stdint.h,sys/type
s.h,wand/MagickWand.h... no
checking for LevelColorsImageChannel() in assert.h,ctype.h,stdio.h,stdlib.h,math.h,time.h,stdint.h,s
ys/types.h,wand/MagickWand.h... yes
checking for LevelizeImageChannel() in assert.h,ctype.h,stdio.h,stdlib.h,math.h,time.h,stdint.h,sys/
types.h,wand/MagickWand.h... yes
checking for LiquidRescaleImage() in assert.h,ctype.h,stdio.h,stdlib.h,math.h,time.h,stdint.h,sys/ty
pes.h,wand/MagickWand.h... yes
checking for MagickLibAddendum() in assert.h,ctype.h,stdio.h,stdlib.h,math.h,time.h,stdint.h,sys/typ
es.h,wand/MagickWand.h... yes
checking for OpaquePaintImageChannel() in assert.h,ctype.h,stdio.h,stdlib.h,math.h,time.h,stdint.h,s
ys/types.h,wand/MagickWand.h... yes
checking for QueueAuthenticPixels() in assert.h,ctype.h,stdio.h,stdlib.h,math.h,time.h,stdint.h,sys/
types.h,wand/MagickWand.h... yes
checking for RemapImage() in assert.h,ctype.h,stdio.h,stdlib.h,math.h,time.h,stdint.h,sys/types.h,wa
nd/MagickWand.h... yes
checking for RemoveImageArtifact() in assert.h,ctype.h,stdio.h,stdlib.h,math.h,time.h,stdint.h,sys/t
ypes.h,wand/MagickWand.h... yes
checking for SelectiveBlurImageChannel() in assert.h,ctype.h,stdio.h,stdlib.h,math.h,time.h,stdint.h
,sys/types.h,wand/MagickWand.h... yes
checking for SetImageAlphaChannel() in assert.h,ctype.h,stdio.h,stdlib.h,math.h,time.h,stdint.h,sys/
types.h,wand/MagickWand.h... yes
checking for SetImageArtifact() in assert.h,ctype.h,stdio.h,stdlib.h,math.h,time.h,stdint.h,sys/type
s.h,wand/MagickWand.h... yes
checking for SetMagickMemoryMethods() in assert.h,ctype.h,stdio.h,stdlib.h,math.h,time.h,stdint.h,sy
s/types.h,wand/MagickWand.h... yes
checking for SparseColorImage() in assert.h,ctype.h,stdio.h,stdlib.h,math.h,time.h,stdint.h,sys/type
s.h,wand/MagickWand.h... yes
checking for SyncAuthenticPixels() in assert.h,ctype.h,stdio.h,stdlib.h,math.h,time.h,stdint.h,sys/t
ypes.h,wand/MagickWand.h... yes
checking for TransformImageColorspace() in assert.h,ctype.h,stdio.h,stdlib.h,math.h,time.h,stdint.h,
sys/types.h,wand/MagickWand.h... yes
checking for TransparentPaintImage() in assert.h,ctype.h,stdio.h,stdlib.h,math.h,time.h,stdint.h,sys
/types.h,wand/MagickWand.h... yes
checking for TransparentPaintImageChroma() in assert.h,ctype.h,stdio.h,stdlib.h,math.h,time.h,stdint
.h,sys/types.h,wand/MagickWand.h... yes
checking for QueryMagickColorname() new signature... yes
checking for Image.type in assert.h,ctype.h,stdio.h,stdlib.h,math.h,time.h,stdint.h,sys/types.h,wand
/MagickWand.h... yes
checking for DrawInfo.kerning in assert.h,ctype.h,stdio.h,stdlib.h,math.h,time.h,stdint.h,sys/types.
h,wand/MagickWand.h... yes
checking for DrawInfo.interline_spacing in assert.h,ctype.h,stdio.h,stdlib.h,math.h,time.h,stdint.h,
sys/types.h,wand/MagickWand.h... yes
checking for DrawInfo.interword_spacing in assert.h,ctype.h,stdio.h,stdlib.h,math.h,time.h,stdint.h,
sys/types.h,wand/MagickWand.h... yes
checking for DitherMethod in assert.h,ctype.h,stdio.h,stdlib.h,math.h,time.h,stdint.h,sys/types.h,wa
nd/MagickWand.h... yes
checking for MagickFunction in assert.h,ctype.h,stdio.h,stdlib.h,math.h,time.h,stdint.h,sys/types.h,
wand/MagickWand.h... yes
checking for ImageLayerMethod in assert.h,ctype.h,stdio.h,stdlib.h,math.h,time.h,stdint.h,sys/types.
h,wand/MagickWand.h... yes
checking for long double in assert.h,ctype.h,stdio.h,stdlib.h,math.h,time.h,stdint.h,sys/types.h,wan
d/MagickWand.h... yes
checking for AlphaChannelType.CopyAlphaChannel... yes
checking for AlphaChannelType.BackgroundAlphaChannel... yes
checking for CompositeOperator.BlurCompositeOp... yes
checking for CompositeOperator.DistortCompositeOp... yes
checking for CompositeOperator.LinearBurnCompositeOp... yes
checking for CompositeOperator.LinearDodgeCompositeOp... yes
checking for CompositeOperator.MathematicsCompositeOp... yes
checking for CompositeOperator.PegtopLightCompositeOp... yes
checking for CompositeOperator.PinLightCompositeOp... yes
checking for CompositeOperator.VividLightCompositeOp... yes
checking for CompressionType.DXT1Compression... yes
checking for CompressionType.DXT3Compression... yes
checking for CompressionType.DXT5Compression... yes
checking for CompressionType.ZipSCompression... yes
checking for CompressionType.PizCompression... yes
checking for CompressionType.Pxr24Compression... yes
checking for CompressionType.B44Compression... yes
checking for CompressionType.B44ACompression... yes
checking for DistortImageMethod.BarrelDistortion... yes
checking for DistortImageMethod.BarrelInverseDistortion... yes
checking for DistortImageMethod.BilinearForwardDistortion... yes
checking for DistortImageMethod.BilinearReverseDistortion... yes
checking for DistortImageMethod.DePolarDistortion... yes
checking for DistortImageMethod.PolarDistortion... yes
checking for DistortImageMethod.PolynomialDistortion... yes
checking for DistortImageMethod.ShepardsDistortion... yes
checking for DitherMethod.NoDitherMethod... yes
checking for FilterTypes.KaiserFilter... yes
checking for FilterTypes.WelshFilter... yes
checking for FilterTypes.ParzenFilter... yes
checking for FilterTypes.LagrangeFilter... yes
checking for FilterTypes.BohmanFilter... yes
checking for FilterTypes.BartlettFilter... yes
checking for FilterTypes.SentinelFilter... yes
checking for MagickEvaluateOperator.PowEvaluateOperator... yes
checking for MagickEvaluateOperator.LogEvaluateOperator... yes
checking for MagickEvaluateOperator.ThresholdEvaluateOperator... yes
checking for MagickEvaluateOperator.ThresholdBlackEvaluateOperator... yes
checking for MagickEvaluateOperator.ThresholdWhiteEvaluateOperator... yes
checking for MagickEvaluateOperator.GaussianNoiseEvaluateOperator... yes
checking for MagickEvaluateOperator.ImpulseNoiseEvaluateOperator... yes
checking for MagickEvaluateOperator.LaplacianNoiseEvaluateOperator... yes
checking for MagickEvaluateOperator.MultiplicativeNoiseEvaluateOperator... yes
checking for MagickEvaluateOperator.PoissonNoiseEvaluateOperator... yes
checking for MagickEvaluateOperator.UniformNoiseEvaluateOperator... yes
checking for MagickEvaluateOperator.CosineEvaluateOperator... yes
checking for MagickEvaluateOperator.SineEvaluateOperator... yes
checking for MagickEvaluateOperator.AddModulusEvaluateOperator... yes
checking for MagickFunction.ArcsinFunction... yes
checking for MagickFunction.ArctanFunction... yes
checking for MagickFunction.PolynomialFunction... yes
checking for MagickFunction.SinusoidFunction... yes
checking for ImageLayerMethod.FlattenLayer... yes
checking for ImageLayerMethod.MergeLayer... yes
checking for ImageLayerMethod.MosaicLayer... yes
checking for ImageLayerMethod.TrimBoundsLayer... yes
checking for VirtualPixelMethod.HorizontalTileVirtualPixelMethod... yes
checking for VirtualPixelMethod.VerticalTileVirtualPixelMethod... yes
checking for VirtualPixelMethod.HorizontalTileEdgeVirtualPixelMethod... yes
checking for VirtualPixelMethod.VerticalTileEdgeVirtualPixelMethod... yes
checking for VirtualPixelMethod.CheckerTileVirtualPixelMethod... yes
checking for ruby/io.h... yes
checking for rb_frame_this_func() in ruby.h,ruby/io.h... yes
creating extconf.h
creating Makefile


======================================================================
Thu 03Jul14 22:29:32
This installation of RMagick 2.13.2 is configured for
Ruby 2.0.0 (i386-mingw32) and ImageMagick 6.8.9
======================================================================



make "DESTDIR="
generating RMagick2-i386-mingw32.def
compiling rmagick.c
In file included from rmagick.c:13:0:
rmagick.h:81:2: error: #error Specified QuantumDepth is not supported.
rmagick.c: In function 'Magick_colors':
rmagick.c:40:5: warning: implicit declaration of function 'GetExceptionInfo' [-Wimplicit-function-de
claration]
rmagick.c:42:5: warning: passing argument 2 of 'GetColorInfoList' from incompatible pointer type [en
abled by default]
In file included from c:/ImageMagick/include/magick/image.h:21:0,
                 from c:/ImageMagick/include/magick/draw.h:22,
                 from c:/ImageMagick/include/magick/fx.h:21,
                 from c:/ImageMagick/include/magick/accelerate.h:21,
                 from c:/ImageMagick/include/magick/MagickCore.h:73,
                 from rmagick.h:47,
                 from rmagick.c:13:
c:/ImageMagick/include/magick/color.h:75:5: note: expected 'size_t *' but argument is of type 'long
unsigned int *'
rmagick.c: In function 'Magick_fonts':
rmagick.c:90:5: warning: passing argument 2 of 'GetTypeInfoList' from incompatible pointer type [ena
bled by default]
In file included from c:/ImageMagick/include/magick/draw.h:24:0,
                 from c:/ImageMagick/include/magick/fx.h:21,
                 from c:/ImageMagick/include/magick/accelerate.h:21,
                 from c:/ImageMagick/include/magick/MagickCore.h:73,
                 from rmagick.h:47,
                 from rmagick.c:13:
c:/ImageMagick/include/magick/type.h:98:5: note: expected 'size_t *' but argument is of type 'long u
nsigned int *'
rmagick.c: In function 'Magick_init_formats':
rmagick.c:178:5: warning: passing argument 2 of 'GetMagickInfoList' from incompatible pointer type [
enabled by default]
In file included from c:/ImageMagick/include/magick/MagickCore.h:118:0,
                 from rmagick.h:47,
                 from rmagick.c:13:
c:/ImageMagick/include/magick/magick.h:135:5: note: expected 'size_t *' but argument is of type 'lon
g unsigned int *'
make: *** [rmagick.o] Error 1


Gem files will remain installed in C:/Ruby200/lib/ruby/gems/2.0.0/gems/rmagick-2.13.2 for inspection
.
Results logged to C:/Ruby200/lib/ruby/gems/2.0.0/gems/rmagick-2.13.2/ext/RMagick/gem_make.out

또 열심히 구글링을 했더니 [3]의 문서를 발견하였다. 문서를 간단히 살펴보니 imagemagick 라이브러리의 버젼에 따라서 컴파일이 안된다는 말로 간단히 요약할 수 있었다. 직접 컴파일해서 연동하는 방법도 써있으니 필요하신분은 참고하시면 될 듯. 어쨋든 되는 버젼을 확인해보니 ‘ImageMagick-6.8.7-8-Q16-x86-dll’에서는 컴파일이 가능하다고 하여 다운로드 받아서 위와 같은 방법으로 실행해 보니 문제 없이 설치할 수 있었다. 이상으로 문제 해결!

– 필자는 Ruby 2.0 x86에서 테스트 했으며, ImageMagick라이브러리도 x86으로 준비하였음. 전에 64bit로 무리하게 진행하다가 고생한 선례가 있어 그나마 편하게 가고 싶으시면 x86을 추천함.

 

요 약


1. http://ftp.sunet.se/pub/multimedia/graphics/ImageMagick/binaries/ 에서 ImageMagick-6.8.7.8-Q16-x86-dll.exe 을 다운로드.

2. ImageMagick 설치시 경로를 “c:\ImageMagick” 으로 할 것. 그리고 설치시 체크하는 곳에서 “Add application directory to your path system”, “Install development headers and libraries for C and C++” 항목을 체크표시 할 것

3. rails 폴더에서 “gem install rmagick –platform=ruby — –with-opt-lib=c:/ImageMagick/lib –with-opt-include=c:/ImageMagick/include” 라고 명령 실행!

 

참고자료


[1] StackOverflow(I cant install gem on windows), http://stackoverflow.com/questions/4873276/i-cant-install-rmagick-gem-on-windows
[2] shubham’s blog(installing rmagick gem on windows 7), http://shoobm.wordpress.com/2013/01/03/installing-rmagick-gem-on-windows-7/
[3] 君の瞳はまるでルビー – Ruby 関連まとめサイト(RMagick を Windows 7 にインストールする方法), http://www.ownway.info/Ruby/index.php?rmagick%2Fhowtoinstall%2Fwindows