пятница, 22 июля 2011 г.

SCons раздельная сборка + рекурсивное сканирование

Продолжаю репосты из своего старого блога. Также спасибо chexov - без него мне бы прикрутить highlight.js было бы сложнее.

Итак,  не так давно копаясь в Glob(), обнаружил что функция рекурсивного сканирования файлов по шаблонам отсутствует, что огорчает. Было найдено несколько велосипедов, но ни один не устроил (не работали или не могли исключать файлы). Также хотелось файлы сборки аккуратно сложить в папку build. В результате сделал такие два скрипта:

SConstruct


import platform
import os

def get_mingw_environment():
     mingw=ARGUMENTS.get('MINGW_TOOLCHAIN_PATH',"C:\\MinGW")
     env = Environment(tools = ['mingw'], ENV = os.environ)
     if mingw.endswith('\\') :
        env.PrependENVPath('PATH', mingw+'\\bin')
        env.PrependENVPath('LIB',  mingw+'\\lib')
     else:
        env.PrependENVPath('PATH', mingw+'bin')
        env.PrependENVPath('LIB',  mingw+'lib')
     return env

  
if platform.system() == 'Windows':
    use_mingw=ARGUMENTS.get('USE_MINGW',"NO")
    if use_mingw=="NO":
      env = Environment(ENV = os.environ)
    else:
      env=get_mingw_environment()
else:
     env = Environment(ENV = os.environ)


SConscript('SConstruct.me',build_dir='build',exports='env',duplicate=0)

Данный скрипт, создает "среду", используя пример из предыдущего скрипта после чего выполняет задание в SConstruct.me, который и собирает программу, при этом указывая папку для сборки и экспортируя в него переменную "среды".

Сам SConstruct.me уже осуществляет сканирование и сборку программы:


import os
import fnmatch

def merge_list(list1,list2):
    if list2 is not None:
       for item in list2:
           list1.append(item)

def is_matches(filename,include,excludes):
    match = False
    for pattern in include: 
       if fnmatch.fnmatchcase(filename, pattern):
           match=True
           break
    if match and excludes is not None:
        for pattern in excludes:
            if fnmatch.fnmatchcase(filename, pattern):
                match = False
                break
    return match

def merge_path(a,b):
     if (a=='.') or (a==''):
          return b
     if (b=='.') or (b==''):
       return a
     return a+"/"+b

def get_files(src_dir,abs_path,include,excludes=None):
    files = []
    for file in os.listdir(merge_path(abs_path,src_dir)):
       tpath=merge_path(src_dir,file)
       if os.path.isdir(merge_path(abs_path,tpath)):
          merge_list(files,get_files(tpath,abs_path,include,excludes))
       else:
          if (is_matches(tpath,include,excludes)):
              files.append(tpath)
    return files     
# Данная процедура осуществляет рекуррентный спуск из паки src_dir используя 
# шаблоны include и исключая файлы подпадающие под шаблоны exclude
def get_files_recursive(src_dir,include,excludes=None):
    return get_files(src_dir,Dir(src_dir).srcnode().abspath,include,excludes)
 
Import('env')
#  Здесь и "собирается новая программа, приведено чисто для примера"
env.Program('progr',get_files_recursive('.',["*.cpp"],["*/bomb.cpp"]), LIBS=['m'], LIBPATH=['.'],INCDIR=['.']);

Комментариев нет:

Отправить комментарий