To generate a Visual Studio project a list of headers and a list of sources are required, but the builtin FindSourceFiles will only find sources, not headers used by those sources. These can be entered manually, or automatically grabbed from the output of a SharedLibrary/StaticLibrary/Program/Object builder so that they will automatically be updated when the targets change (perhaps by configuration, perhaps by adding new sources to the target).

Here is the code to provide such a functionality, and an example on how it can be used:

importSConsdefFindAllSourceFiles(self,target):def_find_sources(tgt,src,hdr,all):foritemintgt:ifSCons.Util.is_List(item):_find_sources(item,src,hdr,all)else:ifitem.abspathinall:continueall[item.abspath]=Trueifitem.path.endswith('.c'):ifnotitem.exists():item=item.srcnode()src.append(item.abspath)elifitem.path.endswith('.h'):ifnotitem.exists():item=item.srcnode()hdr.append(item.abspath)else:lst=item.children(scan=1)_find_sources(lst,src,hdr,all)sources=[]headers=[]_find_sources(target,sources,headers,{})returnsources,headersfromSCons.Script.SConscriptimportSConsEnvironment# just do this onceSConsEnvironment.FindAllSourceFiles=FindAllSourceFilesenv=Environment()prog=env.Program('foo',['main.c','foo.c','bar.c'])sources,headers=env.FindAllSourceFiles(prog)env.MSVSProject(...,...,srcs=sources,incs=headers,...,...)

This version adds .c-files to sources and .h-files to headers, append checks for whatever sources you have ('.cpp', '.cc', '.hpp' for example). Worth noting is that it adds a performance penalty compared to having a static list of headers/sources, but in some cases it makes very much sense in having generated Visual Studio projects. The penalty is of course related to the number of files in the project, how many diffrent file types that should be included, but should be very low for most projects.

NOTE: As of SCons snapshot release 20070918 implicit command dependencies are enabled. This will add more nodes (dependencies on the tools) to be processed thus degrading the performance quite a bit. To disable this, do the following:

env = Environment(IMPLICIT_COMMAND_DEPENDENCIES = 0)

Here is a more general version that accepts a list of file extensions as argument. It's slightly slower than the above version (may have room for improvements) but still much faster than the SCons FindSourceFiles. Failsafe input checks should be added.

defFindAllSourceFiles(self,target,*args):def_find_sources(ptrns,tgt,all):foritemintgt:ifSCons.Util.is_List(item):_find_sources(ptrns,item,all)else:ifitem.abspathinall:continueall[item.abspath]=Trueforpattern,lstinptrns.items():ifpattern.match(item.path):ifnotitem.exists():item=item.srcnode()lst.append(item.abspath)breakelse:lst=item.children(scan=1)_find_sources(ptrns,lst,all)patterns={}forarginargs:patterns[re.compile('.+\\.('+'|'.join(arg)+')$',re.IGNORECASE)]=[]_find_sources(patterns,target,{})returnpatterns.values()fromSCons.Script.SConscriptimportSConsEnvironment# just do this onceSConsEnvironment.FindAllSourceFiles=FindAllSourceFilesenv=Environment()prog=env.Program('foo',['main.c','foo.c','bar.c','baz.s'])sources,headers=env.FindAllSourceFiles(lib,['c','s'],['h'])