2010-02-11 23 views
8

Estoy tratando de hacer que SCons haga una biblioteca compartida. Uno de los elementos que entran en .so es .a lib estática.SCons para hacer una biblioteca compartida (.so) con una biblioteca estática (.a)

tengo una línea como:

env_2.SharedLibrary('libstuff.so', \ 
    Split("""stuff.cxx mylib/libMine.a""") 

Y al ejecutarlo, me sale este error:

scons: *** Source file: mylib/libMine.a \ 
is static and is not compatible with shared target: libstuff.so 

Sin embargo, sé que una biblioteca compartida se puede hacer de la .a a través de una comando como:

g++ -m32 -shared -o libstuff.so stuff.o mylib/libMine.a 

Cualquier idea sobre cómo funciona esto o cualquier solución alternativa sería muy útil eciated.


pregunta relacionada: ¿Cómo llego scons poner una cadena adicional -shared en la línea de comandos LINK para la llamada Program()? Si pudiera hacer esto, creo que satisfaría mis necesidades.

Respuesta

1

Este problema no es específico de scons. Para compilar una biblioteca compartida, necesitará objetos compilados con código independiente de posición (-fPIC). Su mejor opción es hacer que la biblioteca compartida salga de los archivos fuente compilados con las opciones correctas.

En SCons, puede definir una lista de objetivos que se utilizan para compilar libMine.a y libShared.so.


actualización: a su segunda pregunta, el constructor SharedLibrary podría hacer lo que necesita:

SharedLibrary('foo', ['f1.c', 'f2.c', 'f3.c']) 

Si no es así, LINKFLAGS establece los indicadores pasaron a un comando de enlace.

+0

Creo que tiene razón en que el .a no tiene archivos .o utilizando -fPIC. Sin embargo, el g ++ -m32 -shared ... todavía funciona de alguna manera. – xavjuan

+1

Volví e hice que los archivos que entran en .a se compilaran con -fPIC, pero eso no pareció ayudar. – xavjuan

+0

LINKFLAGS fue útil. Gracias. – xavjuan

0
env_2.SharedLibrary('libstuff.so', Split("""stuff.cxx"""), LIBS='libMine.a', LIBPATH='mylib') 

Esto debería funcionar.

+0

Esto funciona pero no crea una dependencia a 'libMine.a' – shoosh

+0

@shoosh Sí, lo hace. El constructor 'SharedLibrary' usa' ProgramScanner' para buscar dependencias especificadas mediante 'LIBS'. –

0

Tengo el mismo problema en cygwin. Pasé opciones '-fPIC' gcc a la hora de construir los objetos y obtuvo la siguiente advertencia:

warning: -fPIC ignored for target (all code is position independent)

También pasé '-shared' al comando de enlazado. Y finalmente me dieron el error

"***.lib is static and is not compatible with shared target: myso.dll"

Parece scons no permite crear de manera directamente de los archivos OBJ o lib, y uno puede crear el modo de una lista de archivos de fuentes (usando SharedLibrary()) o archivo fuente + opción 'LIBS' como dummytaurus dice. Tengo curiosidad sobre eso.

10

Intente configurar env['STATIC_AND_SHARED_OBJECTS_ARE_THE_SAME']=1 en su SConstruct.

+0

Este es el vudú mágico que lo hace funcionar. – shoosh

+1

Este 'mágico vudú' funcionó para mí también. Estoy sorprendido porque no vi ninguna diferencia en las opciones del comando de compilación después de agregar el a SConstruct. Espero que el brujo que inventó esta magia nos lo explique a los mortales. –

+1

El constructor SharedLibrary comprueba si todos los archivos de objeto dados se crearon con el constructor SharedObject (y por lo tanto con -fPIC). env ['STATIC_AND_SHARED_OBJECTS_ARE_THE_SAME'] = 1 deshabilita esta comprobación. Debes decidir si realmente es una buena idea ... – ElektroKraut

1

El problema está en la función SharedFlagChecker (Default.py), que solo comprueba una marca interna "compartida". La documentación de SCons lo lleva a creer que mantiene la distinción entre objetos compartidos y objetos estáticos a través del sufijo (SHOBJSUFFIX), pero no es así. La solución es fácil.En el archivo scons-local.../SCons/Default.py encontrar el SharedFlagChecker y editar:

def SharedFlagChecker(source, target, env): 
    same = env.subst('$STATIC_AND_SHARED_OBJECTS_ARE_THE_SAME') 
    if same == '0' or same == '' or same == 'False': 
     for src in source: 
      try: 
       shared = src.attributes.shared 
      except AttributeError: 
       # Replace this line: shared = None 
       shared = env.Dictionary()['SHOBJSUFFIX'] == src.suffix 
      if not shared: 
       raise SCons.Errors.UserError("Source file: ...") 

Ahora objetos hechos a través de la constructora se SharedObject poder asociarse en una biblioteca compartida.

+0

Debes usar env ['STATIC_AND_SHARED_OBJECTS_ARE_THE_SAME'] = True y no hackear el código para deshabilitarlo ... Está en la página de manual. – bdbaddog

Cuestiones relacionadas