【问题标题】:Make target depend on future unknown target使目标依赖于未来的未知目标
【发布时间】:2017-08-23 13:08:32
【问题描述】:

我希望我的目标依赖于另一个在我指定依赖目标时我不知道其名称或路径的目标。由于某些原因,当第二个目标已知时,我不能在以后使用Depends

是否可以制作某种占位符,以便以后设置?我想像

target1 = <placeholder_of_some_sort>
target2 = Program(files + [target1])

# Set target1 later
target1 = Object(...)

但是,这不起作用,因为 scons 会查找占位符依赖项。

编辑:

这个例子展示了我试图解决的问题的本质。 实际上,我有一个庞大而复杂的构建系统,其中包含数十个 SConscript 文件以分层方式调用其他 SConscript 文件。 我根据某些用户输入生成一个或多个目标:

for x in user_input:
    targets.append(env.SConscript(daughter_sconscript))

生成的目标是相互独立的 ...除了丑陋的边缘情况,根据某些用户输入,其中一个调用 到其中一个子 SConscript 文件生成一个额外的目标文件,稍后使用 在另一个对同一个子 SConscript 文件的调用中。

生成目标的顺序取决于用户输入(用户类型scons 1 2 3 vs scons 3 2 1),因此无法保证 额外的对象被描述给 SCons,而对 SConscript 的调用需要 该对象被执行。所以我想告诉 Scons “嘿,我知道这个目标需要 一个目标文件,但它还没有被描述”。

我可以在 SConstruct 文件中硬编码额外对象文件的名称:

extra_object = File("path")

for x in user_input:
    targets.append(env.SConscript(daughter_sconscript, exports = {"extras": extra_object}))

但是这让我的 SConstruct 的细节变得杂乱无章。我想让它尽可能集中, 并让女儿 sconscript 负责命名和路径。

谢谢!

【问题讨论】:

  • 如果您不知道target1 将拥有哪个文件(名称),您如何保证可重现的构建?您能否扩展您的问题并举例说明您在终端中为(简化的)构建过程执行的步骤?在上面的示例中使用Object 有点误导,因为显而易见的解决方案是设置target2 after target1。但这不是你想要的,我猜?
  • 您的程序语句很奇怪。您没有指定目标,只指定源。请在您的示例中修复。应该是 Program('programname',).
  • @dirkbaechle 我已经详细说明了一点,谢谢!
  • @bdbaddog 可以只指定来源。来自 scons 手册:“当目标与源共享相同的基本名称并且仅后缀不同,并且如果构建器方法具有为目标文件类型定义的后缀,则可以完全省略目标参数,并且 scons 将从源文件名推导出目标文件名。” source
  • 您正在迭代for x in user_input,但不要使用x...这令人困惑。此外,您似乎使用 SConscript 通过聚合 SConscript 的返回值来编译目标列表。您不必这样做来获得正确的依赖关系,SCons 可以为您找出正确的顺序。所以我真的很想看到这个问题的 MWE,因为在这一点上我认为你的一般构建设置可能过于复杂。最终可能会证明没有实际问题......

标签: scons


【解决方案1】:

首先我不会使用 DefaultEnvironment(当你使用 Program 而不是 env.Program() 时你会得到什么)

env=Environment()
env.Program('program_name',files + env['SOME_TARGET_NAME'])

.... later assuming shared env

env['SOME_TARGETNAME'] = env.SharedObject('fun_source.c')

这能解决你的问题吗?或者你有不同的使用模式。

更常见的工作流程是创建一个库(假设它位于不同的目录中),然后将其(按名称)与程序链接

顶级 SConstruct:

env=Environment()
env.SConscript('program/SConscript', exports='env')
env.SConscript('other_dir/SConscript', exports='env')

程序/SConscript:

Import('env')
env.Program('program_name',files+env['SOME_TARGET_NAME'])
or
env.Program('program_name',files,LIBPATH='#/other_dir',LIBS=['otherlib'])

other_dir/SConscript

Import('env')
env['SOME_TARGETNAME'] = env.SharedObject('fun_source.c')
or
env.StaticLibrary('otherlib',['fun_source.c'])

【讨论】:

  • 感谢您的回复。我试过你的例子,但它不起作用。我收到一个 KeyError,因为我的环境中没有定义“SOME_TARGET_NAME”。我更喜欢库解决方案,但它不能解决我的问题,因为我在指定依赖库的目标时不知道要链接的库的名称。
  • 我想我不明白你怎么不知道哪个库?您还可以链接到名称保存在变量中的库。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-02-24
  • 1970-01-01
  • 2020-05-25
  • 1970-01-01
相关资源
最近更新 更多