不为 .cpp 文件调用 Scons 自定义依赖项扫描程序

Scons custom dependency scanner not called for .cpp files

我有一个包含以下文件的 scons 项目目录:

dep.txt
main.cpp
SConstruct

SConstruct的内容:

env = Environment()

def f_scan(node, env, path):
    print("[.] Scanner invoked. -> %s" % str(node))
    return env.File(["dep.txt"])

fscan = Scanner(function = f_scan, skeys = ['.o', '.cpp'])
env.Append(SCANNERS = fscan)

env.Program('main', ['main.cpp'])


main.cpp的内容:

#include <iostream>

using namespace std;

int main(){
    cout << 1 << endl;
    return 0;
}


dep.txt中的内容没有任何具体含义。


scons -Q 输出(如果 dep.txt 在上次构建后被更改):

[.] Scanner invoked. -> main.o
g++ -o main main.o

scons -Q 输出(如果 dep.txt 在上次构建后没有改变):

[.] Scanner invoked. -> main.o
scons: `.' is up to date.


我正在尝试为 .cpp 文件实施自定义扫描程序。我想在内置扫描仪检测到的文件之上为所有 .cpp 文件添加额外的依赖项。但我注意到扫描器从未调用过 .cpp 文件。但是,它会为 .o 个文件正确调用。

来自联机帮助页:https://scons.org/doc/production/HTML/scons-man.html#scanner_objects

Note that scons has a global SourceFileScanner object that is used by the Object, SharedObject and StaticObject builders to decide which scanner should be used for different file extensions. You can use the SourceFileScanner.add_scanner() method to add your own Scanner object to the SCons infrastructure that builds target programs or libraries from a list of source files of different types:

因此,如果您更改为:

env = Environment(CPPPATH=['.'])


def f_scan(node, env, path):
    print("[.] Scanner invoked. -> %s" % str(node))
    return env.File(["dep.txt"])

fscan = Scanner(f_scan)

SourceFileScanner.add_scanner('.cpp', fscan)
SourceFileScanner.add_scanner('.o', fscan)

env.Program('main', ['main.cpp'])

请注意,您不是添加到应用于 .cpp 和 .o 的扫描仪,而是替换它们。

所以如果我创建一个 x.h 并将 main.cpp 更改为:

#include <iostream>
#include "x.h"

using namespace std;

int main(){
    cout << 1 << endl;
    return 0;
}

你会看到这个:

% python ~/devel/scons/git/as_scons/scripts/scons.py --tree=prune
scons: Reading SConscript files ...
scons: done reading SConscript files.
scons: Building targets ...
[.] Scanner invoked. -> main.o
[.] Scanner invoked. -> main.cpp
g++ -o main.o -c -I. main.cpp
[.] Scanner invoked. -> main.o
g++ -o main main.o
+-.
  +-SConstruct
  +-dep.txt
  +-main
  | +-main.o
  | | +-main.cpp
  | | +-dep.txt
  | | +-/usr/bin/g++
  | +-dep.txt
  | +-/usr/bin/g++
  +-main.cpp
  +-[main.o]
scons: done building targets.

而没有您的自定义扫描仪:

% python ~/devel/scons/git/as_scons/scripts/scons.py --tree=prune
scons: Reading SConscript files ...
scons: done reading SConscript files.
scons: Building targets ...
g++ -o main main.o
+-.
  +-SConstruct
  +-main
  | +-main.o
  | | +-main.cpp
  | | +-x.h
  | | +-/usr/bin/g++
  | +-/usr/bin/g++
  +-main.cpp
  +-[main.o]
  +-x.h
scons: done building targets.

所以您可能想要的是仍然调用现有扫描仪并将您的文件添加到其中:

env = Environment(CPPPATH=['.'])


# get existing .cpp scanner
origin_cpp_scanner = SourceFileScanner.function['.cpp']

def f_scan(node, env, path):
    filename = str(node)
    print("[.] Scanner invoked. -> %s" % filename)
    if filename.endswith('.cpp'):
        current_files = origin_cpp_scanner(node, env, path)
    else:
        current_files = []
    print("Files:%s"%[str(f) for f in current_files])
    return current_files + env.File(["dep.txt"])


fscan = Scanner(f_scan)

SourceFileScanner.add_scanner('.cpp', fscan)
SourceFileScanner.add_scanner('.o', fscan)


env.Program('main', ['main.cpp'])

然后产生:

% python ~/devel/scons/git/as_scons/scripts/scons.py --tree=prune
scons: Reading SConscript files ...
scons: done reading SConscript files.
scons: Building targets ...
[.] Scanner invoked. -> main.o
Files:[]
[.] Scanner invoked. -> main.cpp
Files:['x.h']
g++ -o main.o -c -I. main.cpp
[.] Scanner invoked. -> main.o
Files:[]
g++ -o main main.o
+-.
  +-SConstruct
  +-dep.txt
  +-main
  | +-main.o
  | | +-main.cpp
  | | +-x.h
  | | +-dep.txt
  | | +-/usr/bin/g++
  | +-dep.txt
  | +-/usr/bin/g++
  +-main.cpp
  +-[main.o]
  +-x.h
scons: done building targets.