首页 > 解决方案 > Scons PreAction 命令已打印但显然未执行

问题描述

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

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

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

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?

一些可能有用的信息:

操作系统 Windows10

终端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

标签: scons

解决方案


看起来您需要换回该 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 上构建。如果不是这样,则仅当您使用 win32 时,您才需要有条件地将 SPAWN 添加到您的 Program() 中。


推荐阅读