2013-10-25 29 views
2

. :사용 SCons는 내가 그런 일을 할 것입니다 손에서을 noweb 입력 파일에서 문서 파일 (또는 소스 파일)을 생성 ** NW</p> <p>을, 나도 싶습니다를 noweb를 사용

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"를 가지고 있습니다. 는 지금은

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 

이 도구는 cpp-를 생성 $ MYPROJECT/site_scons/site_tools/tangle.py ""우리가 여기 (noweb.py. 에서 간체) "는 SCons는 도구"tangle.py "를 정의 . NW-파일에서

을 제기하지만

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 target dropped)

글을 읽고 프로그래밍하는 데 scons 사용법을 알고 있습니까?

읽어 주셔서 감사합니다.


레너드

답변

1
을 얻을 것이다,이 두 번째 예에서

$ 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. 

: 여기

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') 

는 출력

다음은 내가 만든 도구입니다.env.Program()에 noweb 파일을 허용하려면 env['BUILDERS']['Object'].src_builder을 사용합니다.

# 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. 
1

은 실제로 cpp 파일을 컴파일하지 않고 object 파일을 추가하려는 것 같다.

상황을 정리하는 데 도움이되는 작은 예제를 만들었습니다. 기본적으로 Builder에 대한 호출에서 접미어와 src_suffix를 구성 했으므로 소스와 대상이 SCons에 의해 올바르게 설정되고 에미 터가 필요하지 않습니다.

$ 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. 

내가했던하여 cc 파일을 생성하고 컴파일 할 수있는 빌더를 얻기 위해 다음과 같은,하지만이 object 파일을 청소 나던 : 여기

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: *** [main.cc] Multiple ways to build the same target were specified for: main.o (from ['main.nw'] and from ['main.cc']) 
+0

안녕 브래디는 답변 주셔서 감사합니다. 에미 터를 사용하는 것은 잘못된 접근이었습니다. env.tangle ("myfile.nw")의 출력을 프로그램 (..)의 입력으로 사용하는 방법은 제가 찾던 아이디어입니다. Simple doing Program (env.tangle ("myfile.nw"))이 작업을 수행합니다. SCons를 사용하여 noweb 프로젝트를 컴파일 할 수 있습니다. 이제는 어떻게 문서를 생성하는지 알아 내려고합니다. 우리는 단 하나의 \ begin {document} ... \ end {document} 쌍을 가진 계층 적 LaTex "only"를 가지고있다. __ 안부, Leonard – Leonard7E

+0

@ Leonard7E, 그게 듣기 좋네. 문서와 관련해서는 아마도 다른 질문 일 것입니다. – Brady