2

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を使用する有効な方法を知っていますか?

読んでくれてありがとう。


レナード

4

2 に答える 2

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.

この 2 番目の例では、オブジェクト ファイルをターゲットとして追加すると、次のエラーが発生します (当然のことです)。

scons: *** [main.cc] Multiple ways to build the same target were specified for: main.o  (from ['main.nw'] and from ['main.cc'])
于 2013-10-26T12:42:55.350 に答える