node-canvas static build 静态编译记录

node-canvas静态编译记录

最近因为项目的原因,需要使用node来在后台拼接图片,自然的想到了我们熟悉的canvas,在github上搜了一下,果然有https://github.com/Automattic/node-canvas

安装步骤:

  • brew install pkg-config cairo pango libpng jpeg giflib
  • npm install canvas
  • node-gyp rebuild --target=1.7.11 --arch=x64 --dist-url=https://atom.io/download/electron,因为需要再electron中使用,所以需要重新编译

然后再写业务代码,唰唰写完搞定,打包测试,在自己电脑上测试,没问题。把打好的包给同事,结果报错了。。。。仔细查看后发现提示的是

Error: dlopen(/var/folders/j9/k9fvdp7s2fjfqt2fx6dfdl_c0000gn/T/.com.upchat.app.r3uafh, 1): Library not loaded: /usr/local/opt/pixman/lib/libpixman-1.0.dylib
 Referenced from: /var/folders/j9/k9fvdp7s2fjfqt2fx6dfdl_c0000gn/T/.com.upchat.app.r3uafh
 Reason: image not found

就知道没那么容易,想了下自己电脑上安装了pixman,但是同事的mac上没有安装,那应该就是canvas这个库编译的时候用的动态链接,没有把相关的依赖库打进去。

(这里用的canvas版本是1.6.11,os是mac)
先看一下binding.gyp,我截取了引用库的部分

{ # 'OS!="win"'
     'libraries': [
       '<!@(pkg-config pixman-1 --libs)',
       '<!@(pkg-config cairo --libs)',
       '<!@(pkg-config libpng --libs)'
     ],
     'include_dirs': [
       '<!@(pkg-config cairo --cflags-only-I | sed s/-I//g)',
       '<!@(pkg-config libpng --cflags-only-I | sed s/-I//g)'
     ]
   }],
}

我们可以看到一个是库libraries和include_dirs,分代表引用的库和头文件,对于库我们看到用到的是pkg-config

在shell中输入pkg-config pixman-1 --libs可以看到-L/usr/local/Cellar/pixman/0.34.0_1/lib -lpixman-1 其中-L 代表搜索的位置 -l 代表库的名字,在/usr/local/Cellar/pixman/0.34.0_1/lib中会有一个pkgconfig文件夹,里面有一个pixman-1.pc的文件,文件内容

prefix=/usr/local/Cellar/pixman/0.34.0_1
exec_prefix=${prefix}
libdir=${exec_prefix}/lib
includedir=${prefix}/include

Name: Pixman
Description: The pixman library (version 1)
Version: 0.34.0
Libs: -L${libdir} -lpixman-1
Libs.private:
Cflags: -I${includedir}/pixman-1

系统默认使用的动态库libpixman-1.dylib,但是很明显我们需要的是静态库libpixman-1.a

第一种办法是使用static选项,然后修改pixman-1.pc的文件,但是这种办法我没成功,参考https://stackoverflow.com/questions/27586503/how-to-use-pkg-config-to-link-a-library-statically

还有一种办法是直接修改binding.gyp,直接用路径的方式

{ # 'OS!="win"'
     'libraries': [
       '/usr/local/Cellar/pixman/0.34.0_1/lib/libpixman-1.a',
       '/usr/local/Cellar/libpng/1.6.34/lib/libpng16.a',
       '/usr/local/Cellar/cairo/1.14.12/lib/libcairo.a',
       '/usr/local/Cellar/glib/2.54.2/lib/libgobject-2.0.a',
       '/usr/local/Cellar/libffi/3.2.1/lib/libffi.a',
       '/usr/local/Cellar/glib/2.54.2/lib/libglib-2.0.a',
       '/usr/local/opt/gettext/lib/libintl.a',
       '/usr/local/Cellar/pcre/8.41/lib/libpcre.a',
       '/usr/local/Cellar/fontconfig/2.12.6/lib/libfontconfig.a',
       '/usr/local/opt/freetype/lib/libfreetype.a',
       '/usr/local/Cellar/libpng/1.6.34/lib/libpng16.a',
     ],
     'include_dirs': [
       '<!@(pkg-config cairo --cflags-only-I | sed s/-I//g)',
       '<!@(pkg-config libpng --cflags-only-I | sed s/-I//g)'
     ]
   }],
}

这里有一点需要注意,就是有些库,不仅仅需要自己本身,它还有一些依赖库,例如我们运行pkg-config pangocairo --libs,结果:

-L/usr/local/Cellar/pango/1.40.14/lib -L/usr/local/Cellar/harfbuzz/1.7.2_2/lib -L/usr/local/Cellar/graphite2/1.3.10/lib -L/usr/local/Cellar/pango/1.40.14/lib -L/usr/local/Cellar/cairo/1.14.12/lib -L/usr/local/Cellar/glib/2.54.2/lib -L/usr/local/Cellar/libffi/3.2.1/lib -L/usr/local/Cellar/glib/2.54.2/lib -L/usr/local/opt/gettext/lib -L/usr/local/Cellar/pcre/8.41/lib -L/usr/local/Cellar/pixman/0.34.0_1/lib -L/usr/local/Cellar/fontconfig/2.12.6/lib -L/usr/local/opt/freetype/lib -L/usr/local/Cellar/libpng/1.6.32/lib -L/usr/local/Cellar/libpng/1.6.34/lib -lpangocairo-1.0 -lpangoft2-1.0 -lharfbuzz -lm -framework ApplicationServices -lgraphite2 -lpango-1.0 -lm -lcairo -lz -lgobject-2.0 -lffi -lglib-2.0 -lintl -Wl,-framework -Wl,CoreFoundation -lpcre -lintl -Wl,-framework -Wl,CoreFoundation -liconv -Wl,-framework,Carbon -Wl,-framework,Foundation -lpcre -D_THREAD_SAFE -pthread -lpixman-1 -lfontconfig -lexpat -lfreetype -lz -lbz2 -lpng16 -lz -lpng16 -lz

看到这里,我是崩溃的,需要去引用这些库。。。所以其实最好的办法是用第一种,但是目前来看没有成功,有些pkgconfig的配置文件是没有private那个选项的。。。如果有谁成功了,麻烦指点一下

猜你喜欢

转载自blog.csdn.net/lihangxiaoji/article/details/81297342