gem 'bcrypt-ruby'
报错:
Gem::Installer::ExtensionBuildError: ERROR: Failed to build gem native extension.
/home/sergio/.rvm/rubies/ruby-2.0.0-p195/bin/ruby extconf.rb
creating Makefile
make
compiling wrapper.c
In file included from wrapper.c:27:0:
/home/sergio/.rvm/rubies/ruby-2.0.0-p195/include/ruby-2.0.0/ruby/backward/util.h:2:2: 警告: #warning use "ruby/util.h" instead of bare "util.h" [-Wcpp]
wrapper.c: 在函数‘crypt_gensalt_rn’中:
wrapper.c:204:3: 错误: ‘EINVAL’未声明(在此函数内第一次使用)
wrapper.c:204:3: 附注: 每个未声明的标识符在其出现的函数内只报告一次
make: *** [wrapper.o] 错误 1
这都是个啥啊。。。
#1 楼 @luikore 3.0.1 源码里面有 errno.h,但是我系统的 errno.h 好像跟 kernel2.6 不一样,我是 kernel3.8,能否发一份 errno.h 到 [email protected] , thanks !
不管什么版本的 kernel, <errno.h>
里都有 EINVAL 的,这个问题实在诡异...
可能是 include 路径里带山寨版 <errno.h>
才造成的,就算你替换掉系统的应该也解决不了问题... 又或者是没把 glibc 认出来
你把 Gem 目录里的 Makefile 列出来看看
SHELL = /bin/sh
# V=0 quiet, V=1 verbose. other values don't work.
V = 0
Q1 = $(V:1=)
Q = $(Q1:0=@)
ECHO1 = $(V:1=@:)
ECHO = $(ECHO1:0=@echo)
#### Start of system configuration section. ####
srcdir = .
topdir = $(includedir)/$(RUBY_VERSION_NAME)
hdrdir = $(includedir)/$(RUBY_VERSION_NAME)
arch_hdrdir = $(rubyhdrdir)/$(arch)
PATH_SEPARATOR = :
VPATH = $(srcdir):$(arch_hdrdir)/ruby:$(hdrdir)/ruby
prefix = $(DESTDIR)/home/sergio/.rvm/rubies/ruby-2.0.0-p195
rubysitearchprefix = $(rubylibprefix)/$(sitearch)
rubyarchprefix = $(rubylibprefix)/$(arch)
rubylibprefix = $(libdir)/$(RUBY_BASE_NAME)
exec_prefix = $(prefix)
vendorarchhdrdir = $(vendorhdrdir)/$(sitearch)
sitearchhdrdir = $(sitehdrdir)/$(sitearch)
rubyarchhdrdir = $(rubyhdrdir)/$(arch)
vendorhdrdir = $(rubyhdrdir)/vendor_ruby
sitehdrdir = $(rubyhdrdir)/site_ruby
rubyhdrdir = $(includedir)/$(RUBY_VERSION_NAME)
vendorarchdir = $(vendorlibdir)/$(sitearch)
vendorlibdir = $(vendordir)/$(ruby_version)
vendordir = $(rubylibprefix)/vendor_ruby
sitearchdir = $(DESTDIR)./.gem.20130628-3540-8x0jp8
sitelibdir = $(DESTDIR)./.gem.20130628-3540-8x0jp8
sitedir = $(rubylibprefix)/site_ruby
rubyarchdir = $(rubylibdir)/$(arch)
rubylibdir = $(rubylibprefix)/$(ruby_version)
sitearchincludedir = $(includedir)/$(sitearch)
archincludedir = $(includedir)/$(arch)
sitearchlibdir = $(libdir)/$(sitearch)
archlibdir = $(libdir)/$(arch)
ridir = $(datarootdir)/$(RI_BASE_NAME)
mandir = $(datarootdir)/man
localedir = $(datarootdir)/locale
libdir = $(exec_prefix)/lib
psdir = $(docdir)
pdfdir = $(docdir)
dvidir = $(docdir)
htmldir = $(docdir)
infodir = $(datarootdir)/info
docdir = $(datarootdir)/doc/$(PACKAGE)
oldincludedir = $(DESTDIR)/usr/include
includedir = $(prefix)/include
localstatedir = $(prefix)/var
sharedstatedir = $(prefix)/com
sysconfdir = $(prefix)/etc
datadir = $(datarootdir)
datarootdir = $(prefix)/share
libexecdir = $(exec_prefix)/libexec
sbindir = $(exec_prefix)/sbin
bindir = $(exec_prefix)/bin
archdir = $(rubyarchdir)
CC = gcc
CXX = g++
LIBRUBY = $(LIBRUBY_SO)
LIBRUBY_A = lib$(RUBY_SO_NAME)-static.a
LIBRUBYARG_SHARED = -Wl,-R -Wl,$(libdir) -L$(libdir) -l$(RUBY_SO_NAME)
LIBRUBYARG_STATIC = -Wl,-R -Wl,$(libdir) -L$(libdir) -l$(RUBY_SO_NAME)-static
empty =
OUTFLAG = -o $(empty)
COUTFLAG = -o $(empty)
RUBY_EXTCONF_H =
cflags = $(optflags) $(debugflags) $(warnflags)
optflags = -O3 -fno-fast-math
debugflags = -ggdb3
warnflags = -Wall -Wextra -Wno-unused-parameter -Wno-parentheses -Wno-long-long -Wno-missing-field-initializers -Wunused-variable -Wpointer-arith -Wwrite-strings -Wdeclaration-after-statement -Wimplicit-function-declaration
CCDLFLAGS = -fPIC
CFLAGS = $(CCDLFLAGS) $(cflags) -fPIC $(ARCH_FLAG)
INCFLAGS = -I. -I$(arch_hdrdir) -I$(hdrdir)/ruby/backward -I$(hdrdir) -I$(srcdir)
DEFS =
CPPFLAGS = $(DEFS) $(cppflags)
CXXFLAGS = $(CCDLFLAGS) $(cxxflags) $(ARCH_FLAG)
ldflags = -L. -fstack-protector -rdynamic -Wl,-export-dynamic
dldflags =
ARCH_FLAG =
DLDFLAGS = $(ldflags) $(dldflags) $(ARCH_FLAG)
LDSHARED = $(CC) -shared
LDSHAREDXX = $(CXX) -shared
AR = ar
EXEEXT =
RUBY_INSTALL_NAME = ruby
RUBY_SO_NAME = ruby
RUBYW_INSTALL_NAME =
RUBY_VERSION_NAME = $(RUBY_BASE_NAME)-$(ruby_version)
RUBYW_BASE_NAME = rubyw
RUBY_BASE_NAME = ruby
arch = x86_64-linux
sitearch = $(arch)
ruby_version = 2.0.0
ruby = $(bindir)/ruby
RUBY = $(ruby)
ruby_headers = $(hdrdir)/ruby.h $(hdrdir)/ruby/defines.h $(arch_hdrdir)/ruby/config.h
RM = rm -f
RM_RF = $(RUBY) -run -e rm -- -rf
RMDIRS = rmdir --ignore-fail-on-non-empty -p
MAKEDIRS = /bin/mkdir -p
INSTALL = /usr/bin/install -c
INSTALL_PROG = $(INSTALL) -m 0755
INSTALL_DATA = $(INSTALL) -m 644
COPY = cp
TOUCH = exit >
#### End of system configuration section. ####
preload =
libpath = . $(libdir)
LIBPATH = -L. -L$(libdir) -Wl,-R$(libdir)
DEFFILE =
CLEANFILES = mkmf.log
DISTCLEANFILES =
DISTCLEANDIRS =
extout =
extout_prefix =
target_prefix =
LOCAL_LIBS =
LIBS = $(LIBRUBYARG_SHARED) -lpthread -lrt -ldl -lcrypt -lm -lc
ORIG_SRCS = wrapper.c crypt_blowfish.c bcrypt_ext.c crypt.c crypt_gensalt.c
SRCS = $(ORIG_SRCS)
OBJS = wrapper.o crypt_blowfish.o bcrypt_ext.o crypt.o crypt_gensalt.o
HDRS = $(srcdir)/ow-crypt.h $(srcdir)/crypt.h
TARGET = bcrypt_ext
TARGET_NAME = bcrypt_ext
TARGET_ENTRY = Init_$(TARGET_NAME)
DLLIB = $(TARGET).so
EXTSTATIC =
STATIC_LIB =
BINDIR = $(bindir)
RUBYCOMMONDIR = $(sitedir)$(target_prefix)
RUBYLIBDIR = $(sitelibdir)$(target_prefix)
RUBYARCHDIR = $(sitearchdir)$(target_prefix)
HDRDIR = $(rubyhdrdir)/ruby$(target_prefix)
ARCHHDRDIR = $(rubyhdrdir)/$(arch)/ruby$(target_prefix)
TARGET_SO = $(DLLIB)
CLEANLIBS = $(TARGET).so
CLEANOBJS = *.o *.bak
all: $(DLLIB)
static: $(STATIC_LIB)
.PHONY: all install static install-so install-rb
.PHONY: clean clean-so clean-static clean-rb
clean-static::
clean-rb-default::
clean-rb::
clean-so::
clean: clean-so clean-static clean-rb-default clean-rb
-$(Q)$(RM) $(CLEANLIBS) $(CLEANOBJS) $(CLEANFILES) .*.time
distclean-rb-default::
distclean-rb::
distclean-so::
distclean-static::
distclean: clean distclean-so distclean-static distclean-rb-default distclean-rb
-$(Q)$(RM) Makefile $(RUBY_EXTCONF_H) conftest.* mkmf.log
-$(Q)$(RM) core ruby$(EXEEXT) *~ $(DISTCLEANFILES)
-$(Q)$(RMDIRS) $(DISTCLEANDIRS) 2> /dev/null || true
realclean: distclean
install: install-so install-rb
install-so: $(DLLIB) ./.RUBYARCHDIR.time
$(INSTALL_PROG) $(DLLIB) $(RUBYARCHDIR)
clean-static::
-$(Q)$(RM) $(STATIC_LIB)
install-rb: pre-install-rb install-rb-default
install-rb-default: pre-install-rb-default
pre-install-rb: Makefile
pre-install-rb-default: Makefile
pre-install-rb-default:
$(ECHO) installing default bcrypt_ext libraries
./.RUBYARCHDIR.time:
$(Q) $(MAKEDIRS) $(RUBYARCHDIR)
$(Q) $(TOUCH) $@
site-install: site-install-so site-install-rb
site-install-so: install-so
site-install-rb: install-rb
.SUFFIXES: .c .m .cc .mm .cxx .cpp .C .o
.cc.o:
$(ECHO) compiling $(<)
$(Q) $(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(COUTFLAG)$@ -c $<
.mm.o:
$(ECHO) compiling $(<)
$(Q) $(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(COUTFLAG)$@ -c $<
.cxx.o:
$(ECHO) compiling $(<)
$(Q) $(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(COUTFLAG)$@ -c $<
.cpp.o:
$(ECHO) compiling $(<)
$(Q) $(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(COUTFLAG)$@ -c $<
.C.o:
$(ECHO) compiling $(<)
$(Q) $(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(COUTFLAG)$@ -c $<
.c.o:
$(ECHO) compiling $(<)
$(Q) $(CC) $(INCFLAGS) $(CPPFLAGS) $(CFLAGS) $(COUTFLAG)$@ -c $<
.m.o:
$(ECHO) compiling $(<)
$(Q) $(CC) $(INCFLAGS) $(CPPFLAGS) $(CFLAGS) $(COUTFLAG)$@ -c $<
$(DLLIB): $(OBJS) Makefile
$(ECHO) linking shared-object $(DLLIB)
-$(Q)$(RM) $(@)
$(Q) $(LDSHARED) -o $@ $(OBJS) $(LIBPATH) $(DLDFLAGS) $(LOCAL_LIBS) $(LIBS)
$(OBJS): $(HDRS) $(ruby_headers)
我在 ubuntu 上用这个 makefile 改下用户名可以编译成功。
再试试这个:
echo "#include <errno.h>\nint i=EINVAL;main(){};" | gcc -x c -
如果没输出,环境应该就是正常的...
<stdin>:1:19: 警告: #include 指示的末尾有多余的标识符 [默认启用]
/usr/lib/gcc/x86_64-linux-gnu/4.7/../../../x86_64-linux-gnu/crt1.o:在函数‘_start’中:
(.text+0x20):对‘main’未定义的引用
collect2: 错误: ld 返回 1
#5 楼 @luikore 好诡异,那个 EINVAL 我自己在 errno.h 定义为 22 就可以了,然后报另外一个错
compiling crypt_blowfish.c
crypt_blowfish.c: 在函数‘BF_crypt’中:
crypt_blowfish.c:585:3: 错误: ‘ERANGE’未声明(在此函数内第一次使用)
crypt_blowfish.c:585:3: 附注: 每个未声明的标识符在其出现的函数内只报告一次
crypt_blowfish.c: 在函数‘_crypt_gensalt_blowfish_rn’中:
crypt_blowfish.c:768:3: 错误: ‘ERANGE’未声明(在此函数内第一次使用)
make: *** [crypt_blowfish.o] 错误 1
这个我再在errno.h
中定义 ERANGE 为 32 就死活不出来,那个 c 还 include 了 string.h,我就到 string.h 里面定义 ERANGE 也没用。。。
使用内建 specs。
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-linux-gnu/4.7/lto-wrapper
目标:x86_64-linux-gnu
配置为:../src/configure -v --with-pkgversion='Ubuntu/Linaro 4.7.3-1ubuntu1' --with-bugurl=file:///usr/share/doc/gcc-4.7/README.Bugs --enable-languages=c,c++,go,fortran,objc,obj-c++ --prefix=/usr --program-suffix=-4.7 --enable-shared --enable-linker-build-id --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --with-gxx-include-dir=/usr/include/c++/4.7 --libdir=/usr/lib --enable-nls --with-sysroot=/ --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --enable-gnu-unique-object --enable-plugin --with-system-zlib --enable-objc-gc --with-cloog --enable-cloog-backend=ppl --disable-cloog-version-check --disable-ppl-version-check --enable-multiarch --disable-werror --with-arch-32=i686 --with-abi=m64 --with-multilib-list=m32,m64,mx32 --with-tune=generic --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu
线程模型:posix
gcc 版本 4.7.3 (Ubuntu/Linaro 4.7.3-1ubuntu1)
你可以在 gem 目录里 gem build bcrypt-ruby.gemspec
就出现一个 .gem
文件,然后 gem install 这个文件就可以了
就在 bcrypt-ruby-3.0.1 下面啊
gem build bcrypt-ruby.gemspec
mv bcrypt-ruby-3.0.1.gem .. # 这个目录会要被覆盖掉, 跳出去先
cd ..
gem ins bcrypt-ruby-3.0.1.gem
另外执行了 make install
可能会导致以后你装新的这个 gem 出问题的... 到时记得去 site_ruby 的目录把那个 so 找出来拆掉...
我的邮箱:
echo U2FsdGVkX18/nXhKLPwmczrKbSQD8J/3aXi/RWuQ+fmog2Z6Xw235yr6f1xcCDlg | openssl base64 -d | openssl aes-128-ecb -d -k hello
#31 楼 @luikore 昨天安装的bcrypt-ruby
还是用不了,我修改了下C_INCLUDE_PATH
,报错信息改变了,现在是另外一个。。这个不知道怎么解决了。
/usr/bin/ld: errno: TLS definition in /lib/x86_64-linux-gnu/libc.so.6 section .tbss mismatches non-TLS reference in wrapper.o
/lib/x86_64-linux-gnu/libc.so.6: 无法读取符号: 错误的值
collect2: 错误: ld 返回 1
make: *** [bcrypt_ext.so] 错误 1
#32 楼 @Shallow__pace 之前你做了多余的事情,make install 了
要在 ~/.rvm/rubies/ruby-p195/lib/ruby/site_ruby/
和 ~/.rvm/rubies/ruby-p195/lib/ruby/site_ruby/
里找 bcrypt_ext.so 删掉先...
然后就是... 你为什么改 C_INCLUDE_PATH ?
建议在命令行下搜,图形界面搜索坑死你... 那两个目录内容很少,在里面 tree -a
就可以了。
~/.rvm/rubies/ruby-2.0.0-p195/lib/ruby/site_ruby/2.0.0/x86_64-linux/bcrypt_ext.so
至少这个要删掉。
你不是 git clone 了么?改 ext/mri/extconf.rb 成下面这样然后 gem build 就好了
require 'mkmf'
$CFLAGS = "-I/usr/include #{$CFLAGS}" # 加这行就可以了
dir_config("bcrypt_ext")
create_makefile("bcrypt_ext")
#39 楼 @luikore 还是报刚才这个错误,官方 3.10 版本也是改动了这一部分去掉警告信息,加上你刚才改的,就变成了
require "mkmf"
have_header('ruby/util.h')
$CFLAGS = "-I/usr/include #{$CFLAGS}"
dir_config("bcrypt_ext")
create_makefile("bcrypt_ext")
然后 gem build bcrypt-ruby.gemspec
Successfully built RubyGem
Name: bcrypt-ruby
Version: 3.1.0
File: bcrypt-ruby-3.1.0.gem
然后 gem install -l bcrypt-ruby-3.1.0.gem
报错:
linking shared-object bcrypt_ext.so
/usr/bin/ld: errno: TLS definition in /lib/x86_64-linux-gnu/libc.so.6 section .tbss mismatches non-TLS reference in wrapper.o
/lib/x86_64-linux-gnu/libc.so.6: 无法读取符号: 错误的值
collect2: 错误: ld 返回 1
make: *** [bcrypt_ext.so] 错误 1
export LD_LIBRARY_PATH=/usr/lib
这样可以么?
大概你的问题根源是 .bash_profile 之类的出了问题,的把环境变量搞坏了...
还有一种可能...
errno 是 TLS 的,就是 thread local storage
或许你的 errno.h 里写了 extern int errno;
, 就变成 non-TLS reference 了,同名但不同 storage 所以产生了链接错误...
#44 楼 @luikore = = 网上买个装系统的 u 盘还几天才到,我又仔细看了下,最根本的问题就肯定就是一句/usr/bin/ld: errno: TLS definition in /lib/x86_64-linux-gnu/libc.so.6 section .tbss mismatches non-TLS reference in wrapper.o
要解决的话应该就是makefile
,我errno.h
应该没什么问题了.
你再确定一下$CFLAGS = "-I/usr/include #{$CFLAGS}" # 加这行就可以了
这句话对不对。。
网上说编译的时候加 -include /usr/include/errno.h
即可,我不太懂这句话是什么意思
makefile 可能和你的问题一点关系都没有,有一万种可能会导致 TLS 和 non-TLS 链到一起 (是不是 errno 都不一定)... pkg config 不对,gcc 坏了,ruby 安装时的环境不同,甚至某个毫无联系的包出问题都有可能...
preprend $CFLAGS
已经比较暴力了,结果必定是用到 /usr/include/errno.h
的。
最大的问题是别的机器上不可重现... 架空想办法已经到极限了...
#47 楼 @luikore 搞定啦。。。自己手动改了 makefile
,然后将 mri 目录下文件的 errno 代码全部删除掉,上传到我的 github,gem install bcrypt-ruby, github:xxxx'就可以了。。
现在就是用
annotate`的时候报这个错误
You don't have bcrypt-ruby installed in your application. Please add it to your Gemfile and run bundle install
Unable to annotate user.rb: can't activate bcrypt-ruby (~> 3.0.0), already activated bcrypt-ruby-3.1.0. Make sure all dependencies are added to Gemfile.
Nothing annotated.
这个错误怎么解决
#51 楼 @blacktulip #52 楼 @huobazi
违反 DRY 原则,annotate 更新不及时就容易隐藏一些 bug, 弄个编辑器插件显示表结构就够了
#54 楼 @blacktulip 原来没有么... textmate 加个一个命令就可以满足大部分 https://gist.github.com/luikore/5899132