2010-02-11 31 views
8

Sto tentando di ottenere SCons per creare una libreria condivisa. Uno degli elementi che vanno nella .so è una lib statica .a.SCons per creare una libreria condivisa (.so) con una libreria statica (.a)

Ho una linea simile:

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

E su eseguirlo, ottengo questo errore:

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

Tuttavia, so che una libreria condivisa può essere fatta dal .a attraverso un Comando come:

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

Qualsiasi idea su come far funzionare questo o qualsiasi soluzione alternativa sarebbe molto appr eciated.


questione connessa: Come faccio ad avere scons per mettere una stringa aggiuntiva -shared sulla riga di comando LINK per la chiamata Program()? Se potessi fare questo, penso che soddisferebbe le mie esigenze.

risposta

1

Questo problema non è specifico per gli scons. Per creare una libreria condivisa, avrai bisogno di oggetti compilati con codice indipendente dalla posizione (-fPIC). La soluzione migliore è rendere la libreria condivisa fuori dai file sorgente compilati con le giuste opzioni.

In SCons, è possibile definire un elenco di destinazioni utilizzate per compilare sia libMine.a che libShared.so.


Aggiornamento: riguarda la seconda domanda, il costruttore SharedLibrary potrebbe fare quello che ti serve:

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

In caso contrario, LINKFLAGS imposta i flag passati a un comando di collegamento.

+0

Penso che tu abbia ragione che il file .a ha file .o NON creati usando -fPIC. Comunque g ++ -m32 -shared ... funziona ancora in qualche modo. – xavjuan

+1

Sono tornato indietro e ho inserito i file in .a con -fPIC, ma questo non mi è sembrato di aiuto. – xavjuan

+0

I LINKFLAGS sono stati utili. grazie. – xavjuan

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

Questo dovrebbe funzionare.

+0

Questo funziona ma non crea dipendenza da 'libMine.a' – shoosh

+0

@shoosh Sì, lo fa. Il builder 'SharedLibrary' usa' ProgramScanner' per cercare le dipendenze specificate tramite 'LIBS'. –

0

Ho lo stesso problema in Cygwin. Ho superato le opzioni '-fPIC' a GCC durante la creazione degli oggetti ed ho ottenuto il seguente avviso:

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

Ho anche passato '-shared' al comando di collegamento. E finalmente ho avuto l'errore

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

Sembra scons non consente di creare in modo direttamente dal file OBJ o lib, e si può creare sia il modo da un elenco di file sorgenti (utilizzando SharedLibrary()) o file sorgente + opzione 'LIBS' come dice dummytaurus. Sono curioso di questo.

10

Prova a impostare env['STATIC_AND_SHARED_OBJECTS_ARE_THE_SAME']=1 nel tuo SConstruct.

+0

Questo è il magico voodoo che lo fa funzionare. – shoosh

+1

Questo "voodoo magico" ha funzionato anche per me. Sono sorpreso perché non ho visto alcuna differenza nelle opzioni di compilazione del comando dopo l'aggiunta di a SConstruct. Spero che lo stregone che ha inventato questa magia lo spieghi a noi mortali. –

+1

Il builder SharedLibrary verifica se tutti i file oggetto dati sono stati creati con il builder SharedObject (e quindi con -fPIC). env ['STATIC_AND_SHARED_OBJECTS_ARE_THE_SAME'] = 1 disabilita questo controllo. Devi decidere da solo se questa è effettivamente una buona idea ... – ElektroKraut

1

Il problema è nella funzione SharedFlagChecker (Default.py), che verifica solo un flag interno "condiviso". La documentazione di SCons porta a credere che mantenga la distinzione tra oggetti condivisi e oggetti statici tramite il suffisso (SHOBJSUFFIX), ma non così. La correzione è facile.Nel file scons-local.../SCons/Default.py trovare la SharedFlagChecker e modificare:

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: ...") 

Ora oggetti realizzati tramite la SharedObject costruttore sarà collegabile in una libreria condivisa.

+0

Dovresti usare env ['STATIC_AND_SHARED_OBJECTS_ARE_THE_SAME'] = Vero e non modificare il codice per disabilitarlo .. È nella pagina di manuale. – bdbaddog

Problemi correlati