Scons PreAction 命令已打印但显然未执行

Scons PreAction Command is printed but apparently not executed

我正在使用 SCONS 构建一个大型项目,出于本主题(大故事)之外的原因,我需要在文件内的最终链接命令中传递对象文件选项。 例如:

gcc -o program.elf @objects_file.txt -T linker_file.ld

此命令有效,因为我已经对其进行了手动测试。但是现在我需要 运行 它嵌入到项目构建文件中。我的第一个 approach/idea 是通过以下方式将所有选项收集到一个文件中:

dbg_exe     = own_env.Program('../' + target_path, components)
own_env.AddPreAction(dbg_exe, 'echo \'$SOURCES\' > objects_file.txt')

注意:$sources 包含我需要的所有目标文件。 正如我所料,该命令似乎已执行,我看到终端中打印了该命令,但由于某种原因它尚未执行,因为我在任何地方都找不到 objects_file.txt。

奇怪的是,如果我在同一个终端中复制并粘贴打印的行,命令执行成功,所以我认为构造的语法是正确的。

我也尝试了一个更短的测试代码:

own_env.AddPreAction(dbg_exe, 'ls -l > salida_ls.txt')

...另一个惊喜,这次我在控制台中收到语法错误:

scons: done reading SConscript files.
scons: Building targets ...
ls -l > salida_ls.txt
ls: cannot access '>': No such file or directory
ls: cannot access 'salida_ls.txt': No such file or directory

一个简单的 'ls -l' 就可以了。

知道为什么这种 bash 命令不能按预期工作吗? > 重定向符号是否影响 SCONS?

一些可能有用的信息:

OS Windows10

Terminal mingw32

SCons v2.3.1

经过搜索发现,这与SPAWN构造变量的重新定义有关:

def w32api_spawn(sh, escape, cmd, args, e_env):
    
    print "CMD value" 
    print sh 
    print escape 
    print cmd
    print args
    print e_env
    print " ********************************** " 
    if cmd == "SHELL":
        return SCons.Platform.win32.spawn(sh,escape,args[1], args[1:],e_env)
    cmdline = cmd + ' ' + string.join(args[1:], ' ')
    startupinfo = subprocess.STARTUPINFO()
    startupinfo.dwFlags |= _subprocess.STARTF_USESHOWWINDOW
    
    proc = subprocess.Popen(
        cmdline, 
        stdin=subprocess.PIPE, 
        stdout=subprocess.PIPE, 
        stderr=subprocess.STDOUT, 
        startupinfo=startupinfo, 
        shell = False, 
        env = None
        )

    data, err = proc.communicate()
    
    print data
    rv = proc.wait()
    if rv:
        print "====="
        print err
        print "====="
    return rv

看来您需要换回该 Program() 的默认 SPAWN。

将这个添加到那个 SConscript 的顶部

from SCons.Platform.win32 import spawn

然后将上面粘贴的逻辑替换为:

dbg_exe     = own_env.Program('../' + target_path, components, SPAWN=spawn)
own_env.AddPreAction(dbg_exe, 'echo \'$SOURCES\' > objects_file.txt')

这假设您只在 win32 上构建。如果这不是真的,您需要有条件地将 SPAWN 添加到上面的 Program() 中,只有当您使用 win32 时。

最后我找到了解决方法 运行 一个 python 本地函数来构建我需要的文件。不幸的是,我没有更多时间解决这个问题,我没有找到真正的原因和解决方案,但很明显这与正常的 SCONS 执行无关,而是与 SPAWN 中执行的技巧有关。

scons_common.GenerateObjectsFile('../' + objects_file, 组件)