Scons是否知道SConscript文件所在的目录?

11
我们正在评估scons作为一个构建系统,但我在适应我们旧有系统时遇到了问题。在一些源代码子目录中,我们有一个"sources.lib"文件,其中列出了需要编译以组装该目录的目标库的C++文件的名称。但是,在同一目录中还有其他C++文件,因此我不能只使用Glob()查找适当的文件。
怎样才能找到SConscript文件所在的目录?os.getcwd()总是返回构建目录。即使文档规定SConscript中的路径是相对于源目录的(否则Glob('*.cpp')将无法正常工作),仅仅执行open('sources.lib')也会失败,因为它在构建目录中查找该文件。最后,该SConscript文件中的构建环境也不包含实际的当前源目录。 编辑 根据这个回答,看起来......
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):
# 用于分配给目标的源文件列表 sources = [] # srcFile = 'sources.lib' # 失败 # srcFile = os.path.join(os.getcwd(), 'sources.lib') # 失败 srcFile = File('sources.lib').srcnode().abspath # 成功
# 查找 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 这个方法。


要确定文件是否存在,您可以使用os.path.exists()。 - Brady
我不明白你的问题,请创建一个小例子来说明它。 - Torsten
你的问题救了我 :) Dir('.').srcnode().abspath 对我有用。我使用选项 env.SConscriptChdir(0) 来避免目录幻灯片。谢谢! - Destroyica
我也是!我想要基于当前的SConscript位置形成一个额外的Python导入路径(用于sys.path.append),但os.path.dirname(os.path.abspath(file))不起作用(没有定义__file__),但是你的Dir('.')方法很好用。 - Evgen
2个回答

5
我使用以下代码:
this_sconscript_file = (lambda x:x).func_code.co_filename
code_base = os.path.dirname(this_sconscript_file)

os.path.dirname(__file__) 不是做同样的事情吗? - tutuca
3
不行,因为scons以某种方式包含SConscripts,使得__file__始终引用根脚本,甚至在包含的脚本中也是如此。 - olpa
好的解决方法。我仍然认为 Dir('.').srcnode().abspath 是一个更好的解决方案。 - gg349
作为一个小的后续,使用Python 3时,您需要将func_code替换为__code__,以便完整命令变为(lambda x:x).__code__.co_filename - chrisb2244

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

根据文档,相对路径的默认值是当前 SConstruct 文件的路径,而不是执行 scons 命令的路径。 - edA-qa mort-ora-y
你说得完全正确,我也刚测试过了。抱歉让你感到困惑,我会纠正我的答案。我曾经遇到过这个问题,并认为它与 scons 的执行位置有关,例如如果你在子目录中使用 "scons -u",但现在看来并非如此。感谢您的矫正。 - Brady
2
但是关于当前的SConscript,相对于实际调用构建器的SConscript呢?在我的情况下,我正在尝试设置通用环境,以供许多子模块使用 - 这包括在当前的SConscript目录下添加一个“include/”目录到CPPPATH中。 - Jonathon Reinhart
您IP地址为143.198.54.68,由于运营成本限制,当前对于免费用户的使用频率限制为每个IP每72小时10次对话,如需解除限制,请点击左下角设置图标按钮(手机用户先点击左上角菜单按钮)。 - Brady

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接