什么相当于 Makefile 的 SConstruct 包含?

Whats the equivalent of Makefile's include for SConstruct?

我正在尝试找到在 SConstruct 中复制 Makefile 包含的最佳方法。我想出了一个解决方案,但它很乱,依赖于用户传递特定的命令行参数,肯定不是最好的选择。

我的文件结构是这样的:

Working_Dir/
   |-> includes/
   |    |-> filename.mk
   |    |-> filename.py
   |-> Makefile
   |-> main.c
   |-> SConstruct

这些是我文件的内容

生成文件

all: main.o
    echo "Version is: $(VERSION)"
    gcc $^ -o main

include includes/filename.mk

filename.mk

VERSION := "1.6.2"

%.o: %.c
    gcc -c -o $@ $<

S构造

import filename

env=Environment()
filename.Init(env)

#Create new builder
prog = Builder(action=["gcc $SOURCE -o $TARGET"])

#Add the builder
builder = { "Prog": prog}
env.Append(BUILDERS=builder)

print "Version is: " + env['VERSION']
env.Prog(target = "main", source = "main.o")

filename.py

from SCons.Script import *  # Needed so we can use scons stuff like builders

def Init(env):
    #Make builder
    obj = Builder(action="gcc -c -o $TARGET $SOURCE")

    #Add stuff
    env.Append(BUILDERS= {'Obj': obj})
    env.Append(VERSION= "1.6.2")

(忽略 SCons 有自己的 Object builder 的事实,这只是我为更大的项目学习的一个简化示例)

使用 makefile 进行编译 运行 make 并且对于 SCons scons --site-dir="includes" 因为我包含的文件不在标准路径中。据我所知,site_dir 选项是在 scons as seen here 中包含您自己的 code/builders 的唯一方法。另请注意,SConscript 文件不是我想要的,因为当您调用它们时,它们会在自己的目录中执行指令,而不仅仅是将变量和构建器加载到调用者中。

我希望用户可以 运行 scons 并且它有效。我读过我可以在第 10.1.1 节中将这些设置全局设置到我的 bash 配置文件 as seen here,但我不想这样做,因为我不希望我系统上的每个 SCons 项目都默认使用这个目录。我还查看了 SetOption() 函数,但它的功能有限,实际上根本不允许您设置此特定参数。

我能想到的唯一解决方案是开始使用 GetOption('site_dir'),如果它不是我期望的目录,我将使用所有相同的参数调用一个新的 SCons 调用,但现在使用正确 site_dir 选项。

然而,这感觉非常贫民窟,我觉得我缺少更好的解决方案。有更好的解决方案吗?

编辑:

我使用这个 "includes" 目录而不是 "site_scons" 目录的原因是因为在我较大的项目中 "includes" 目录与项目不在同一个目录中,它在一个完全不同的目录中(该目录的路径是已知的)。 filename.py 将用于我依赖它的多个 SCons 项目,但并不是我机器上的每个 SCons 项目都应该使用它(即它不应该是全局的)。

我自己想出来的。我只是将文件作为普通 python 模块加载,如最佳答案 here 所示。我专门使用了 Python 2 答案,因为似乎 SCons 在我的系统上配置为使用 python 2.

多亏了这个,我能够从我计算机上的任何地方加载任何 python 文件,包括 scons 相关代码,这正是我想要的。

对于那些好奇的人,这是我需要添加的代码

file_path = "/path/to/my/file/filename.py"

import imp
extra_stuff = imp.load_source('filename', file_path)

env=Environment()
extra_stuff.Init(env)