【问题标题】:Real Hierarchical Builds with SCons?使用 SCons 进行真正的分层构建?
【发布时间】:2012-03-30 21:11:45
【问题描述】:

所以我在这里阅读了有关分层构建的问题,例如:Creating a Hierarchical Build with SCons

我想对两个独立的存储库进行真正的分层构造,它们都使用我使用 mercurial 设置为子存储库的 scons。下面是说明我想要做什么的文件布局。

所需的布局:

project_root/  (new project that builds bar app using the libfoo built from source)

    libfoo_subrepo/  (standalone project repo from bitbucket)
        src/
            SConscript
            libfoo.c
            libfoo.h
        test/
            SConscript
            test_foo.c
        SConstruct

    barapp_subrepo/  (standalone project repo from bitbucket that uses libfoo)
        src/
            SConscript
            bar.c
            bar.h
        test/
            SConscript
            test_bar.c
        SConstruct

    test/
        SConscript
        test_bar_with_foo.c
    SConstruct

所以我有两个单独的 repos,都使用 scons。第一个 libfoo 可以独立克隆并使用 scons 构建。在 libfoo 根目录下运行 scons 时,它会在 src/ 中构建一个 libfoo 的静态库,并在 test/ 中构建一个与 src/ 中的静态库链接的单元测试可执行文件。

第二个 repo 有依赖于 libfoo 的 bar 应用程序。它也可以独立克隆,如果在构建系统上安装了 libfoo,则可以使用 scons 构建它。

我想要做的是设置一个新的 repo (project_root),它使用 mercurial 将 libfoo 和 bar app repos 设置为 subrepos。所以当你克隆这个新的 repo 时,它会自动拉下 bar 应用程序及其依赖项 libfoo。然后我希望能够在这个新仓库的根目录中运行 scons 并让它在 libfoo_subrepo/ 根目录中执行 scons 来构建 libfoo 和它的单元测试。然后我希望它在 barapp_subrepo/ 根目录中运行 scons 来构建 bar 并告诉它链接到 libfoo_subrepo/src/ 中的 libfoo 静态库。最后,我希望它在 tests/ 中构建一些新的单元测试,它们同时使用 libfoo 静态库和来自 bar app 的源文件来测试 bar app 和 libfoo 组合在一起时。

据我阅读 scons 文档可知,我需要为“subrepo”创建一个自定义构建器,该构建器将在子 shell 中运行 scons。然后我可以将 libfoo.subrepo 和 barapp.subrepo 添加到 project_root/ 目录以及一些如何装配它,以便当构建器执行构建 libfoo.subrepo 的命令时,它将源名称转换为执行 scons 的路径.

building 'libfoo.subrepo' translates into executing 'cd libfoo_subrepo; scons'

在我看来 scons 不能递归地构建独立的 scons 项目。我读过的所有内容都假设您能够在子文件夹中创建 SConscript 文件,然后让根 SConstruct 文件依赖于 SConscript 文件。请告诉我有一种方法可以用 scons 做我想做的事。我不想回去做。

谢谢。

【问题讨论】:

    标签: python build scons build-script


    【解决方案1】:

    我不确定您为什么需要制作自定义构建器,如果我理解正确,我认为您需要的一切都可以使用 SCons 及其内置构建器完成。

    要按照您的说明进行操作,您确实需要 3 个单独的 SConstruct 文件,才能进行 3 个单独的构建。我还将添加 3 个 SConscript 文件并将它们全部制作如下:

    编辑:在本例中,最好在 SConstruct 脚本中创建 Environment()

    project_root/SConstruct

    # This SConstruct orchestrates building 3 subdirs
    
    import os
    
    subdirs = ['libfoo_subrepo', 'barapp_subrepo', 'test']
    env = Environment()
    
    for subdir in subdirs:
        SConscript(os.path.join(subdir, 'SConscript'), exports = ['env'])
    

    libfoo_subrepo/SConstruct

    # This SConstruct does nothing more than load the SConscript in this dir
    # The Environment() is created in the SConstruct script
    # This dir can be built standalone by executing scons here, or together
    # by executing scons in the parent directory
    env = Environment()
    SConscript('SConscript', exports = ['env'])
    

    libfoo_subrepo/SConscript

    # This SConstruct orchestrates building 2 subdirs
    import os
    
    Import('env')
    subdirs = ['src', 'test']
    
    for subdir in subdirs:
        SConscript(os.path.join(subdir, 'SConscript'), exports = ['env'])
    

    barapp_subrepo/SConstruct

    # This SConstruct does nothing more than load the SConscript in this dir
    # The Environment() is created in the SConstruct script
    # This dir can be build standalone by executing scons here, or together
    # by executing scons in the parent directory
    env = Environment()
    SConscript('SConscript', exports = ['env'])
    

    barapp_subrepo/SConscript

    # This SConstruct orchestrates building 2 subdirs
    import os
    
    Import('env')
    subdirs = ['src', 'test']
    
    for subdir in subdirs:
        SConscript(os.path.join(subdir, 'SConscript'), exports = ['env'])
    

    我希望每个文件中的 cmets 都能解释其用途。

    希望这会有所帮助。

    【讨论】:

    • 如果您使用此解决方案在子目录中进行了构建,然后从顶层进行了重建,它不会再次重建整个子目录吗?
    • @GeoffreyIrving,说得好。根据项目的大小,这可能无关紧要。但是可以通过为根构建和子目录构建指定 scons db 文件或使用不同的变体目录来避免您提到的内容。
    • 万一现在有人发现了这个,你现在可以简单地做SConscript(dirs=subdirs, exports=["env"]),而不是手动循环
    【解决方案2】:
    SConscript(dirs=['src', 'doc'])
    

    【讨论】:

    • 这没有提供问题的答案。要批评或要求作者澄清,请在他们的帖子下方发表评论 - 您可以随时评论自己的帖子,一旦您有足够的reputation,您就可以comment on any post
    • @CTravel 为什么你认为这是一个澄清或批评,而不是(至少试图)一个答案?
    • @MathiasMüller 更多的是评论而不是答案,他需要解释他的答案而不是仅仅发布一些代码。
    • @CTravel 我看到许多只包含代码但在我看来是有效的答案。这不是评论,而是答案——尽管不是很有用,但这就是反对票的目的。
    • +1,我同意你的说法。谢谢你把它带给我。
    猜你喜欢
    • 1970-01-01
    • 2014-08-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-09-10
    • 2011-05-01
    • 1970-01-01
    • 2019-10-02
    相关资源
    最近更新 更多