我收到了一个已完成的源存档(称为legacyProject
),其中包含SConstruct
构建脚本。这个构建脚本做了很多工作来创建一个很好的自定义Environment
,它可以理解微控制器的自定义工具链。它还有一些辅助函数,可以简化为相当大的构建矩阵生成Program
语句。
我正在开始一个相关的项目,几乎可以逐字地重用这个Environment
及相关代码。我不想只是将所有内容复制粘贴到新的SConstruct文件中,因为原始版本可能会收到补丁(更不用说它只是重复代码)。目前,这些项目在文件系统中是并排的:
myProject/
SConstruct
legacyProject/
SConstruct
我可能会重新安排它们,以便legacyProject
是myProject
的子目录,因此我可以通过版本控制跟踪确切的修订。
myProject/
SConstruct
legacyProject/
SConstruct
有没有办法从legacyProject/SConstruct
导入所有代码?使用Python模块,这对于import
来说是微不足道的,但我不知道这是否可行与Scons。我的尝试:
SConscript('legacyProject/SConstruct')
只返回无。
答案 0 :(得分:2)
如果不将旧版SConstruct中的某些功能重构为帮助文件,我不相信有办法做到这一点。
如果你可以重构代码,那么有三种可能的替代方法可用 - 一种是使用SCons内置的现有SConscript机制,另一种是使用python模块,最后一种方法是使用site-dir选项。
通过SConscripts重复使用
假设项目结构如下:
.
├── common
│ └── SConscript
├── legacyProject
│ └── SConstruct
└── myProject
└── SConstruct
您的SConstruct文件将创建一个环境,然后执行common/SConscript
,它返回一个修改过的环境。例如,如果您想在公共目录中收集一些选项,最终可能会出现以下内容:
# common/SConscript
Import('env')
env['CCFLAGS'] = '-Wall -Wextra -pedantic'
Return('env')
和
# myProject/SConstruct (similar for legacy/SConstruct)
env = Environment()
print 'before:', env['CCFLAGS']
env = SConscript('../common/SConscript', exports = 'env')
print 'after:', env['CCFLAGS']
选择此方法:
通过Python模块重用
如果您要将scons实用程序打包为python包,则可以使用两条路径。
首先是使用传统的Python封装技术。有一些很好的指南 - 我推荐Python Packaging User Guide。为了实现这一目标,您需要编写setup.py,并使用pip
或python setup.py install
进行安装
使这个棘手的是你可以有多个并行安装的Python和SCons,它们通过你的PATH环境变量巧妙地耦合。这可能意味着在一台机器上工作的东西可能无法在另一台机器上运行。
一种更常见的方法是修改python用于在SConstructs中搜索模块的路径 - 从Python角度来看糟糕的做法,但稍微更易于维护,特别是如果您的构建机器很复杂。
假设项目结构如下:
.
├── common
│ └── __init__.py
├── legacyProject
│ └── SConstruct
└── myProject
└── SConscript
你的python模块可以非常简单:
# common/__init__.py
def set_warning_flags(env):
env['CCFLAGS'] = '-Wall -Wextra -pedantic'
和
# myProject/SConstruct
import sys
sys.path.insert(0, '..')
import common
env = Environment()
print 'before:', env['CCFLAGS']
common.set_warning_flags(env)
print 'after:', env['CCFLAGS']
选择此方法:
通过site-dir / site-init重用
如果要动态添加功能到多个SConstructs而不更改它们,可以使用SCons支持的内置可扩展性(请参阅用户手册Where To Put Your Custom Builders and Tools中的部分或搜索--site-dir=dir
在SCons Man Page
在这种情况下,您将拥有:
.
├── common
│ └── site_init.py
├── legacyProject
│ └── SConstruct
└── myProject
└── SConstruct
site_init.py
的位置:
# common/site_init.py
def set_warning_flags(env):
env['CCFLAGS'] = '-Wall -Wextra -pedantic'
SConstruct是:
env = Environment()
print 'before:', env['CCFLAGS']
set_warning_flags(env)
print 'after:', env['CCFLAGS']
但您需要使用以下命令调用SCons(来自myProject / legacyProject目录)
scons --site-dir=../common
选择此方法:
答案 1 :(得分:0)
我建议将要共享的逻辑重新设计到导入的python模块中,并在SConstruct中调用一些初始化。这将是最干净的方法(恕我直言)。
虽然你可以使用pythons execfile()(我相信),但这是一个混乱的方法。