2012-03-21 11 views
7

Stiamo valutando gli scons come un sistema di compilazione e sto riscontrando un problema nel nostro vecchio sistema. In alcune delle sottodirectory del nostro codice sorgente, abbiamo un file "sources.lib" che elenca i nomi dei file C++ che devono essere compilati per assemblare la libreria di destinazione di quella directory. Ma ci sono altri file C++ nella stessa directory, quindi non posso semplicemente usare Glob() per trovare quelli appropriati.Gli scons sanno in quale directory risiede un file SConscript?

Come individuare la directory in cui risiede un file SConscript? os.getcwd() restituisce sempre la directory di build. Anche se la documentazione afferma che i percorsi in uno SConscript sono relativi alla directory di origine (oppure che Glob ('*. Cpp') non funzionerebbe), solo facendo un open ('sources.lib') fallisce perché cerca il file nella directory di build. Infine, l'ambiente di compilazione in quel file SConscript non contiene la directory di origine corrente attuale.

Modifica Da this reply Sembra

File('sources.lib').srcnode().abspath 

restituisce il corretto nome del file e directory, ma che non vi dirà se esiste (deve utilizzare os.path.isfile per questo). Sembra anche che

Dir('.').srcnode().abspath 

vi dirà dove si trova il file SConstruct.

Esempio Quando si definisce quale sorgente file da compilare per una libreria, non voglio usare

lib = env.SharedLibrary('mylib', Glob('*.cpp')) 

ma invece preferiscono costruire una funzione che controlla innanzitutto per l'esistenza di "sources.lib "e se non esiste, usa il globbing. Così sto definendo la mia libreria in questo modo

lib = env.SharedLibrary('mylib', env.getSources('*.cpp')) 

e fare una funzione che legge il file se esiste

def getSources(self, pattern): 

    # list of source files to assign to a target 
    sources = [] 
    # srcFile = 'sources.lib' # failed 
    # srcFile = os.path.join(os.getcwd(), 'sources.lib') # failed 
    srcFile = File('sources.lib').srcnode().abspath # works 

    # look for sources.lib 
    try: 
     infile = open(srcFile,'r') 
    except IOError: 
     #print "Globbing to get sources" 
     sources = Glob(pattern, strings=True) 
    else: 
     #print "Reading sources.lib" 
     for line in infile.readlines(): 
      line = line.rstrip('\n\r') 
      if line != '': 
       sources.append(line) 

    return sources 

buildEnv.AddMethod(getSources)

Questo sembra funzionare. Non sapevo di File.srcnode(). Abspath fino ad oggi.

+0

per determinare se esiste un file, è possibile utilizzare os.path.exists() – Brady

+0

non capisco il problema, creare piccolo esempio che illustrano esso. – Torsten

+0

La tua domanda mi ha salvato :) 'Dir ('.'). Srcnode(). Abspath' ha funzionato per me. Io uso questa opzione 'env.SConscriptChdir (0)' per evitare la directory "diapositive". Grazie! – Destroyica

risposta

2

Ci sono 3 tipi di percorsi in SCons:

  1. Rispetto al SConstruct radice anteponendo '#' per il percorso
  2. Rispetto al SConscript non utilizzare il '#'.
  3. Percorso assoluto.Penso che questo si spiega da sé :)

Se è necessario affrontare con percorsi al di fuori della directory in cui lo SConscript è, si dovrebbe usare il '#'

Dovrebbe funzionare in entrambe le direzioni in questo esempio , ma il percorso con il '#' sembra più esplicito e intuitivo per me:

./SConstruct 
./dirA/SConscript - use '#dirA/sources.lib' OR 'sources.lib' 
./dirB/SConscript - use '#dirB/sources.lib' OR 'sources.lib' 

Spero che questo aiuti,

Brady

+0

In base alla documentazione, il percorso relativo predefinito è al file SConstruct curretn e non a dove sono stati eseguiti gli scons. –

+0

Hai perfettamente ragione, l'ho appena testato. Scusa per la confusione, correggerò la mia risposta. Ho avuto un problema con questa volta ed ero convinto che fosse relativo a da dove venivano eseguiti gli scons, per esempio se ti trovi in ​​una sottodirectory e usi 'scons -u', ma sembra che non sia così. Grazie per la correzione. – Brady

+1

Ma per quanto riguarda lo * Script * corrente *, al contrario dello SConscript che in realtà chiama un costruttore? Nel mio caso sto provando a configurare l'ambiente comune per essere usato da molti sotto-moduli - questo include l'aggiunta di una directory 'include /' nella directory SConscript corrente a CPPPATH. –

4

Io uso il seguente codice:

this_sconscript_file = (lambda x:x).func_code.co_filename 
code_base = os.path.dirname(this_sconscript_file) 
+0

Non 'os.path.dirname (__ file __)' fa la stessa cosa? – tutuca

+2

No, perché scons include in qualche modo SConscripts in questo modo, che '__file__' fa sempre riferimento allo script di root, anche negli script inclusi. – olpa

+0

Buona soluzione. Continuo a pensare che 'Dir ('.'). Srcnode(). Abspath' è una soluzione migliore. – gg349

Problemi correlati