Scons. Go recursive with Glob

谁都会走 提交于 2019-12-19 07:39:10

问题


I using scons for a few days and confused a bit. Why there is no built-in tools for building sources recursively starting from given root? Let me explain: I have such source disposition:

src
    Core
       folder1
       folder2
           subfolder2_1
    Std
       folder1

..and so on. This tree could be rather deeper.

Now I build this with such construction:

sources = Glob('./builds/Std/*/*.cpp')
sources = sources + Glob('./builds/Std/*.cpp')
sources = sources + Glob('./builds/Std/*/*/*.cpp')
sources = sources + Glob('./builds/Std/*/*/*/*.cpp')

and this looks not so perfect as at can be. Of cause, I can write some python code, but is there more suitable ways of doing this?


回答1:


Sure. You need to write python wrappers to walking through dirs. You can find many recipes on stackoverflow. Here is my simple function which returns list of subdirs in present dir (and ignore hide dirs starting with '.' - dot)

def getSubdirs(abs_path_dir) :  
    lst = [ name for name in os.listdir(abs_path_dir) if os.path.isdir(os.path.join(abs_path_dir, name)) and name[0] != '.' ]
    lst.sort()
    return lst

For example, i've dir modules what containts foo, bar, ice.

corePath = 'abs/path/to/modules'
modules = getSubdirs(corePath)
# modules = [bar, foo, ice]
for module in modules :
  sources += Glob(os.path.join(corePath, module, '*.cpp'))

You can improve getSubdirs function adding recurse and walking deeper to subdirs.




回答2:


As Torsten already said, there is no "internal" recursive Glob() in SCons. You need to write something yourself. My solution is:

import fnmatch
import os

matches = []
for root, dirnames, filenames in os.walk('src'):
  for filename in fnmatch.filter(filenames, '*.c'):
    matches.append(Glob(os.path.join(root, filename)[len(root)+1:]))

I want to stress that you need Glob() here (not glob.glob() from python) especially when you use VariantDir(). Also when you use VariantDir() don't forget to convert absolute paths to relative (in the example I achieve this using [len(root)+1:]).




回答3:


The Glob() SCons function doesnt have the ability to go recursive.

It would be much more efficient if you change your Python code to use the list.extend() function, like this:

sources = Glob('./builds/Std/*/*.cpp')
sources.extend(Glob('./builds/Std/*.cpp'))
sources.extend(Glob('./builds/Std/*/*/*.cpp'))
sources.extend(Glob('./builds/Std/*/*/*/*.cpp'))

Instead of trying to go recursive like you are, its quite common to have a SConscript script in each subdirectory and in the root SConstruct call each of them with the SConscript() function. This is called a SCons hierarchical build.




回答4:


I use this:

srcdir = './'
sources = [s for s in glob2.glob(srcdir + '**/*.cpp') if "/." not in s]


来源:https://stackoverflow.com/questions/10598026/scons-go-recursive-with-glob

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!