2012-01-12 5 views
6

Estoy intentando escribir una extensión de Ruby, y he estado compilando satisfactoriamente mi archivo de objeto compartido nmatrix.so todo el día. Pero luego, de repente, comienza a producir nmatrix.bundle en su lugar, sin ningún archivo .so en absoluto.¿Cómo causé que gcc produjera un .blundle en lugar de .so?

No me está dando ningún error de enlazador, así que no puedo imaginarme por qué. Tampoco cambié nada en my Makefile or extconf.rb. He estado usando constantemente Ruby 1.9.3p0 a través de rvm.

He intentado hacer un git stash save con mi trabajo para el día y la compilación de algo que sé debería funcionar sin errores de enlace (algo que produce un .so) anterior. Desafortunadamente, eso también produce un archivo .bundle.

Claramente he hecho algo, tal vez haya instalado algo inadvertidamente, lo que ha cambiado algunos ajustes críticos de GCC. Esto es totalmente posible, ya que pasé la mayor parte del día tratando de construir LAPACK y ATLAS, y también instalé homebrew en algún momento.

He descubierto que hay una solución alternativa. Cómo cambio de estas dos líneas:

DLLIB = $(TARGET).bundle 
# ... 
LDSHARED = $(CC) -dynamic -bundle 

a

DLLIB = $(TARGET).so 
# ... 
LDSHARED = $(CC) -dynamic 

y después la biblioteca compila y cargas correctamente. Sin embargo, no tengo el más mínimo cambio en extconf.rb (o en otro lugar) que hubiera provocado que se genere automáticamente este archivo Makefile con .bundle en lugar de .so.

La pregunta es: ¿cómo exactamente causé esto y qué debo hacer para restaurarlo?

+2

¿Puedes incluir tu 'Makefile'? – sarnold

+0

Hecho. El Makefile se genera automáticamente usando 'rvm ruby ​​extconf.rb', por lo que he incluido' extconf.rb' también. –

Respuesta

2

Parece que el problema proviene del uso de LLVM gcc, que no funciona bien con Xcode 4.2.

He instalado gcc regular, así que vuelva a instalar Rubí de la siguiente manera:

export CC=/usr/bin/gcc-4.2 
rvm install 1.9.3 

La mayoría de las direcciones parecen decir el uso rvm install 1.9.3 --enable-shared lugar, pero esa bandera adicional parece ser el origen del problema.

En cualquier caso, parece que ahora puedo cargar .bundle archivos.

+0

No olvide marcar su respuesta como "Aceptada" si resuelve el problema. – sarnold

3

El C extensions RubyGems Guide tiene una descripción general del proceso de construcción.

Las líneas críticas en su archivo extconf.rb están cerca de los extremos:

require "mkmf" 
# ... 
create_makefile("nmatrix") 

Esto genera los Makefile para usted. El Makefile se genera utilizando los valores de configuración almacenados en la matriz RbConfig::CONFIG[]; el valor de configuración que más te interesa es RbConfig::CONFIG['DLEXT']:

$ ruby -e "require 'rbconfig'; puts RbConfig::CONFIG['DLEXT'];" 
so 

Para ver fácilmente toda la configuración, busque el archivo rbconfig.rb; mina está ubicada en /usr/lib/ruby/1.8/x86_64-linux/rbconfig.rb, y voy a incluir las primeras líneas aquí:

# This file was created by mkconfig.rb when ruby was built. Any 
# changes made to this file will be lost the next time ruby is built. 

module Config 
    RUBY_VERSION == "1.8.7" or 
    raise "ruby lib version (1.8.7) doesn't match executable version (#{RUBY_VERSION})" 

    TOPDIR = File.dirname(__FILE__).chomp!("/lib/ruby/1.8/x86_64-linux") 
    DESTDIR = '' unless defined? DESTDIR 
    CONFIG = {} 
    CONFIG["DESTDIR"] = DESTDIR 
    CONFIG["INSTALL"] = '/usr/bin/install -c' 
    CONFIG["EXEEXT"] = "" 
    CONFIG["prefix"] = (TOPDIR || DESTDIR + "/usr") 
    ... 
    CONFIG["DLEXT"] = "so" 
    CONFIG["LDSHARED"] = "$(CC) -shared" 
    CONFIG["CCDLFLAGS"] = " -fPIC" 
    ... 

Así, alguna versión de su archivo rbconfig.rb se ha construido cuando otra versión de Rubí se construyó el que sugiere que las extensiones de enlace dinámico deben tener una extensión diferente Esta podría ser una característica de rvm (de la que aún necesito obtener más información) o esta podría ser una diferencia entre Ruby, suministrado por Apple, y Ruby autocompuesto. Puede ver en el encabezado de comentario del archivo que puede hacer fácilmente el cambio en rbconfig.rb usted mismo, pero será volado la próxima vez que reconstruya o instale un Ruby de construcción diferente.

(Por cierto, pensé que la extensión era .dylib, pero hace mucho tiempo que no uso OS X también.)

+0

¡Rock! Probaré esto la próxima vez que tenga mi MBA. Muchas gracias. –

+0

Bien, entonces la compilación funciona ahora, pero 'rake compile' aún falla, aparentemente en la operación de copia: ' ¡rake abortado! No existe ese archivo o directorio - tmp/x86_64-darwin11.2.0/nmatrix/1.9.3/nmatrix.bundle' Ya he cambiado 'rbconfig.rb', por lo que no estoy seguro de dónde buscar. –

Cuestiones relacionadas