重用来自不同项目的 SConstruct 的环境
Reusing Environment from a different project's SConstruct
我得到了一个完整的源存档(称之为 legacyProject
),其中有一个 SConstruct
构建脚本。这个构建脚本做了很多工作来创建一个很好的自定义 Environment
,它理解微控制器的自定义工具链。它还具有一些辅助函数,可以简化为相当大的构建矩阵生成 Program
语句。
我正在启动一个相关项目,该项目可以几乎逐字重用此 Environment
和相关代码。我不想只是将所有内容复制粘贴到一个新的 SConstruct 文件中,因为原始文件可能会收到补丁(更不用说它只是代码的重复)。目前这些项目在文件系统中是并排的:
myProject/
SConstruct
legacyProject/
SConstruct
我可能会重新排列它们,使 legacyProject
成为 myProject
的子目录,这样我就可以使用版本控制跟踪准确的修订。
myProject/
SConstruct
legacyProject/
SConstruct
有没有办法从 legacyProject/SConstruct
导入所有代码? 对于 Python 模块,这对于 import
来说很简单,但是我不知道 Scons 是否可行。我的尝试:
SConscript('legacyProject/SConstruct')
只是 returns None.
我建议将您想要共享的逻辑重新设计到您导入的 python 模块中,并在您的 SConstruct 中调用一些初始化。这将是最干净的方法(恕我直言)。
虽然您可以使用 pythons execfile()(我相信),但这是一种混乱的方式。
如果不将遗留 SConstruct 的某些功能重构到辅助文件中,我认为没有办法做到这一点。
如果您可以重构代码,那么可以使用三种可能的替代方法 - 一种是使用 SCons 中内置的现有 SConscript 机制,另一种是使用 python 模块,最后一种方法是使用站点目录选项。
通过 SConscripts 重用
假设项目结构如下:
.
├── common
│ └── SConscript
├── legacyProject
│ └── SConstruct
└── myProject
└── SConstruct
您的 SConstruct 文件将创建一个环境,然后执行 common/SConscript
,其中 returns 一个修改后的环境。例如,如果你想在公共目录中收集一些选项,你可能会得到如下内容:
# 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']
在以下情况下选择此方法:
- 您熟悉 SCons,但不太熟悉 Python
- 您不想将额外的标志传递给 scons 或设置环境变量
- 您试图不知道您正在使用 Python 的哪个安装
- 您没有使用变体目录
通过 Python 模块重复使用
如果您要将 scons 实用程序打包为 python 包,您可以采用两种方法。
首先是使用传统的Python打包技术。周围有一些很好的指南 - 我推荐 Python Packaging User Guide. To get this working you'll need to write a 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 or search for --site-dir=dir
in the 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
在以下情况下选择此方法:
- 您想更改两个项目的构建而不更改其中任何一个的代码。
我得到了一个完整的源存档(称之为 legacyProject
),其中有一个 SConstruct
构建脚本。这个构建脚本做了很多工作来创建一个很好的自定义 Environment
,它理解微控制器的自定义工具链。它还具有一些辅助函数,可以简化为相当大的构建矩阵生成 Program
语句。
我正在启动一个相关项目,该项目可以几乎逐字重用此 Environment
和相关代码。我不想只是将所有内容复制粘贴到一个新的 SConstruct 文件中,因为原始文件可能会收到补丁(更不用说它只是代码的重复)。目前这些项目在文件系统中是并排的:
myProject/
SConstruct
legacyProject/
SConstruct
我可能会重新排列它们,使 legacyProject
成为 myProject
的子目录,这样我就可以使用版本控制跟踪准确的修订。
myProject/
SConstruct
legacyProject/
SConstruct
有没有办法从 legacyProject/SConstruct
导入所有代码? 对于 Python 模块,这对于 import
来说很简单,但是我不知道 Scons 是否可行。我的尝试:
SConscript('legacyProject/SConstruct')
只是 returns None.
我建议将您想要共享的逻辑重新设计到您导入的 python 模块中,并在您的 SConstruct 中调用一些初始化。这将是最干净的方法(恕我直言)。
虽然您可以使用 pythons execfile()(我相信),但这是一种混乱的方式。
如果不将遗留 SConstruct 的某些功能重构到辅助文件中,我认为没有办法做到这一点。
如果您可以重构代码,那么可以使用三种可能的替代方法 - 一种是使用 SCons 中内置的现有 SConscript 机制,另一种是使用 python 模块,最后一种方法是使用站点目录选项。
通过 SConscripts 重用
假设项目结构如下:
.
├── common
│ └── SConscript
├── legacyProject
│ └── SConstruct
└── myProject
└── SConstruct
您的 SConstruct 文件将创建一个环境,然后执行 common/SConscript
,其中 returns 一个修改后的环境。例如,如果你想在公共目录中收集一些选项,你可能会得到如下内容:
# 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']
在以下情况下选择此方法:
- 您熟悉 SCons,但不太熟悉 Python
- 您不想将额外的标志传递给 scons 或设置环境变量
- 您试图不知道您正在使用 Python 的哪个安装
- 您没有使用变体目录
通过 Python 模块重复使用
如果您要将 scons 实用程序打包为 python 包,您可以采用两种方法。
首先是使用传统的Python打包技术。周围有一些很好的指南 - 我推荐 Python Packaging User Guide. To get this working you'll need to write a 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 or search for --site-dir=dir
in the 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
在以下情况下选择此方法:
- 您想更改两个项目的构建而不更改其中任何一个的代码。