2012-03-21 2 views
7

Мы оцениваем работу scons как системы сборки, и у меня возникает проблема размещения нашей старой системы. В некоторых наших подкаталогах исходного кода у нас есть файл «sources.lib», в котором перечислены имена файлов C++, которые необходимо скомпилировать для сборки целевой библиотеки этого каталога. Но есть дополнительные файлы C++ в одном каталоге, поэтому я не могу просто использовать Glob(), чтобы найти соответствующие.Знаете ли вы, что в каком каталоге хранится файл SConscript?

Как узнать, в каком каталоге находится файл SConscript? os.getcwd() всегда возвращает каталог сборки. Несмотря на то, что в документации указано, что пути в SConscript относятся к исходному каталогу (иначе Glob ('*. Cpp') не будет работать), просто выполнение open ('sources.lib) не выполняется, поскольку оно ищет файл в каталоге сборки. Наконец, среда сборки в этом файле SConscript не содержит фактического текущего исходного каталога.

Редактировать От this reply это выглядит как

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

возвращает правильное имя файла и каталог, но он не скажет вам, если она существует (необходимо использовать os.path.isfile для этого). Также представляется, что

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

сообщит вам, где находится файл SConstruct.

Пример При определении, какие исходные файлы для компиляции для библиотеки, я не хочу использовать

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

, но вместо этого предпочел бы построить функцию, которая сначала проверяет наличие «sources.lib «и если этого не существует, используйте globbing. Так я определяю свою библиотеку, как так

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

и делает функцию, которая считывает файл, если он существует

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)

Это похоже на работу. Я не знал о File.srcnode(). Abspath до сегодняшнего дня.

+0

Чтобы определить, существует ли файл, вы можете использовать os.path.exists() – Brady

+0

Я не понимаю вашу проблему, создать небольшой пример, иллюстрирующий это. – Torsten

+0

Ваш вопрос спас меня :) 'Dir ('.'). Srcnode(). Abspath' работал для меня. Я использую эту опцию 'env.SConscriptChdir (0)', чтобы избежать слайдов каталога. Благодаря! – Destroyica

ответ

2

Есть 3 типа путей в SCons:

  1. относительно корня SConstruct символом '#' на пути
  2. по отношению к SConscript не используется '#'.
  3. Абсолютный путь.Я думаю, что это само за себя :)

Если вам придется иметь дело с путями вне директории, где SConscript есть, вы должны использовать «#»

Он должен работать в обоих направлениях в этом примере , но путь с '#' кажется более четко и интуитивно мне:

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

Надеется, что это помогает,

Brady

+0

В соответствии с документацией относительный путь по умолчанию относится к файлу curretn SConstruct, а не к тому, где были выполнены scons. –

+0

Вы абсолютно правы, я просто испытал его. Извините за беспорядок, я исправлю свой ответ. У меня была проблема с этим однажды, и я был убежден, что это было относительно того, где были выполнены счёты, например, если вы находитесь в субдире и используете «scons -u», но это, похоже, не так. Спасибо за исправление. – Brady

+1

Но как насчет * текущего * SConscript, в отличие от SConscript, который на самом деле вызывает строителя? В моем случае я пытаюсь настроить общую среду, которая будет использоваться многими подмодулями - это включает добавление 'include /' dir в текущий каталог SConscript в CPPPATH. –

4

Я использую следующий код:

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

Не делает ли 'os.path.dirname (__ файл __)' то же самое? – tutuca

+2

Нет, потому что scons включает в себя SConscripts каким-то образом таким образом, что '__file__' всегда ссылается на корневой скрипт, даже в включенные скрипты. – olpa

+0

Хорошее обходное решение. Я все еще думаю, что 'Dir ('.'). Srcnode(). Abspath' - лучшее решение. – gg349

Смежные вопросы