使用noweb,我想从noweb输入文件生成文档文件(或源文件)**。nw
从手上我会做那样的事情:
notangle my_program.nw > my_program.cpp
g++ -c my_program.o my_program.cpp
ln -o myapp ... my_program.o ...
现在我想问一下我是否可以使用scons来实现自动化。
想象一下,我的项目目录是$ MYPROJECT。我们有“$ MYPROJECT / SConstruct”。 现在我定义了一个scons工具“tangle.py”(简称为“noweb.py”)。 这里我们有“$ MYPROJECT / site_scons / site_tools / tangle.py”
import SCons.Builder
def cpp_emit (target,source, env):
# I dont know what to do here ... please help
return (target,source)
# Tangle to .cpp
__noweb_tangle_builder = SCons.Builder.Builder(
action='/usr/bin/notangle $SOURCES >$TARGET',
suffix='.cpp',
src_suffix='.nw',
emitter=cpp_emit)
# -----------------------
def generate(env):
env['BUILDERS']['tangle']= __noweb_tangle_builder
def exists(env):
return 1
此工具从nw文件生成cpp文件。
但是,如果我做了像
这样的事情def cpp_emit (target,source, env):
new_source=target[0].name
new_target=new_source.rstrip(".cpp")+".o"
target.append(new_target)
source.append(new_source)
return (target, source)
我进入了一个依赖圈子。 SCons将查找并中止错误消息。
做......
def cpp_emit (target,source, env):
new_source=target[0].name
# someprogram.cpp -> someprogram.o
new_target=new_source.rstrip(".cpp")+".o"
# lets avoid dependency cycle
t = []
t.append(new_target)
source.append(new_source)
# oops, we dropped target test.cpp. It wont be generated.
return (t, source)
...该工具将停止从nw文件生成cpp文件。 (Cpp目标下降)
您是否知道使用scons进行文字编程的工作方式?
谢谢你的阅读。伦纳德
答案 0 :(得分:1)
似乎您尝试添加object
文件而不实际编译cpp
文件。
我做了一个小例子,应该有助于澄清情况。基本上,由于您在对Builder的调用中配置了后缀和src_suffix,因此SCons正确设置了源和目标,并且您不需要发射器。
def cpp_emit (target,source, env):
for t in target:
print 'Emitter target: %s' % (t)
for s in source:
print 'Emitter source: %s' % (s.name)
return (target,source)
# Tangle to .cpp
builder = Builder(
action='/home/notroot/projects/sandbox/Emitter/builder.sh $SOURCES $TARGET',
suffix='.cc',
src_suffix='.nw',
emitter=cpp_emit)
env = Environment()
env['BUILDERS']['tangle'] = builder
tangleTarget = env.tangle(target='main.cc', source='main.nw')
env.Object(source=tangleTarget)
这是输出:
$ scons
scons: Reading SConscript files ...
Emitter target: main.cc
Emitter source: main.nw
scons: done reading SConscript files.
scons: Building targets ...
/home/notroot/projects/sandbox/Emitter/builder.sh main.nw main.cc
g++ -o main.o -c main.cc
scons: done building targets.
$ scons -c
scons: Reading SConscript files ...
Emitter target: main.cc
Emitter source: main.nw
scons: done reading SConscript files.
scons: Cleaning targets ...
Removed main.cc
Removed main.o
scons: done cleaning targets.
我做了以下操作让Builder生成cc
文件并进行编译,但它不会清除object
文件。
import os
def cpp_emit(target,source, env):
for s in source:
print 'Emitter source: %s' % (s.name)
for t in target:
print 'Emitter target: %s' % (t)
return (target,source)
def build_function(target, source, env):
# Code to build "target" from "source"
for t in target:
print 'Builder target: %s' % (t.name)
for s in source:
print 'Builder source: %s' % (s.name)
buildStr='/home/notroot/projects/sandbox/Emitter/builder.sh %s %s' % (source[0].name, target[0].name)
os.system(buildStr)
trgt = env.Object(source=target[0])
# return 0 or None upon success
return None
# Tangle to .cc and .o
builder = Builder(
action=build_function,
suffix='.cc',
src_suffix='.nw',
emitter=cpp_emit)
env = Environment()
env['BUILDERS']['tangle'] = builder
tangleTarget = env.tangle(target='main.cc', source='main.nw')
这是输出:
$ scons
scons: Reading SConscript files ...
Emitter source: main.nw
Emitter target: main.cc
scons: done reading SConscript files.
scons: Building targets ...
build_function(["main.cc"], ["main.nw"])
Builder target: main.cc
Builder source: main.nw
scons: done building targets.
$ scons -c
scons: Reading SConscript files ...
Emitter source: main.nw
Emitter target: main.cc
scons: done reading SConscript files.
scons: Cleaning targets ...
Removed main.cc
scons: done cleaning targets.
在第二个示例中,如果将目标文件添加为目标,则会出现以下错误(正确地说是这样)
scons: *** [main.cc] Multiple ways to build the same target were specified for: main.o (from ['main.nw'] and from ['main.cc'])
答案 1 :(得分:1)
这是我创建的工具。请注意使用env['BUILDERS']['Object'].src_builder
允许env.Program()
接受noweb文件。
# site_cons/site_tools/tangle.py
import SCons.Builder
__all__=['generate', 'exists']
tangle_builder = SCons.Builder.Builder(
action='$NOTANGLE $SOURCES > $TARGET',
suffix = '.cpp',
src_suffix = '.nw')
def generate(env):
env['NOTANGLE'] = exists(env)
env['BUILDERS']['Tangle'] = tangle_builder
if 'Object' in env['BUILDERS']:
env['BUILDERS']['Object'].src_builder.append('Tangle')
def exists(env):
if 'NOTANGLE' in env:
return env['NOTANGLE']
return env.WhereIs('notangle')
及其用途:
# SConstruct
env = Environment(tools=['default', 'tangle'])
env.Program('my_program.nw')
以上是SConstruct的输出:
$ scons -Q
/usr/bin/notangle my_program.nw > my_program.cpp
g++ -o my_program.o -c my_program.cpp
g++ -o my_program my_program.o
$ scons -c
scons: Reading SConscript files ...
scons: done reading SConscript files.
scons: Cleaning targets ...
Removed my_program.cpp
Removed my_program.o
Removed my_program
scons: done cleaning targets.