如何解决"scons:警告:为目标指定了两种不同的环境"

Gre*_*ill 26 scons

假设我有一个如下所示的SConstruct文件:

env = Environment()

env.Program("a", ["a.c", "util.c"])
env.Program("b", ["b.c", "util.c"])
Run Code Online (Sandbox Code Playgroud)

此版本正常工作,没有SCons警告消息.但是,如果我修改它以为每个构建指定不同的Program(实际的库不相关):

env.Program("a", ["a.c", "util.c"], LIBS="m")
env.Program("b", ["b.c", "util.c"], LIBS="c")
Run Code Online (Sandbox Code Playgroud)

然后我收到警告:

scons: warning: Two different environments were specified for target util.o,
        but they appear to have the same action: $CC -o $TARGET -c $CFLAGS $CCFLAGS $_CCCOMCOM $SOURCES

这似乎是由Program构建器自动创建用于构建的新环境引起的,即使它只是LIBS不同的变量(因此只有链接步骤需要具有不同的环境).我可以通过以下方式解决这个问题:

util = env.Object("util.c")
env.Program("a", ["a.c"] + util, LIBS="m")
env.Program("b", ["b.c"] + util, LIBS="c")
Run Code Online (Sandbox Code Playgroud)

这使用单个Object构建器进行构建util.c,然后在每个Program构建中使用预编译的目标文件,从而避免警告.但是,这不应该是必要的.有没有更优雅的方法来解决这个问题?或者这实际上是SCons中应该修复的错误?

上下文:我将近2000个C源文件编译成大约20个库和120个具有大量共享源的可执行文件.我SConstruct使用我编写的转换脚本从以前的专有构建系统创建了该文件.SCons为使用我当前的完整版本生成大约450个"两个不同的环境"警告消息SConstruct.

Gre*_*ill 19

我找到了一种解决方法,不涉及创建额外的变量来保存目标文件节点:

env.Program("a", ["a.c", env.Object("util.c")], LIBS="m")
env.Program("b", ["b.c", env.Object("util.c")], LIBS="c")
Run Code Online (Sandbox Code Playgroud)

这隔离util.c了单个环境中的构建.尽管指定了两次,但每次都指定一次Program,SCons不会对此发出警告,因为它是使用相同env对象构建的相同源.当然,在这种情况下,SCons只编译一次源.


Fla*_*hão 9

您可以使用Split函数和自定义帮助程序来简化大型项目的构建过程:

def create_objs(SRCS, path=""):
    return [env.Object(path+src+".cpp") for src in SRCS]

prg1 = Split("file_1 file_2 file_N")
prg2 = Split("file_2 file_5 file_8")

env.Program("a", create_objs(prg1), LIBS="x")
env.Program("b", create_objs(prg2), LIBS="y")
Run Code Online (Sandbox Code Playgroud)

目标文件只创建一次,它们可以在多个构建中使用.希望这可以帮助...