scons 종속성에 문제가 있으며 변형 디렉터리가있는 계층 구조 빌드에서 에 문제가 있습니다.변형 된 디렉터리가있는 계층 적 빌드에서 scons 종속성 문제
임 2 SConscript 디렉토리 아래에 하위 디렉토리 (moduleA 및 moduleB) 등으로 구성되어 감소 된 환경에서 문제를 재현 할 수는 다음과 같습니다 여기
.
|-- SConstruct
|-- file.conf
|-- moduleA
| |-- SConscript
| `-- conf2cc
`-- moduleB
|-- SConscript
`-- fileB.cc
가해야할 일들의 흐름입니다 : conf2cc 입력 : $ projRootDir/file.conf 출력 : moduleA/$ variantDir/source.cc
- moduleA 쉘 스크립트를 실행 bmoduleA.a
- moduleB은/source.cc moduleB가 라이브러리에 moduleB/source.cc 및 moduleB/fileB.cc을 컴파일 할 필요가
- libmoduleB.a moduleB에 moduleA/$ variantDir가/source.cc을 복사 할 필요가
여기에서 몇 가지 일을 잘못하고 있다는 전적으로 가능합니다. 예를 들어, 나는 는 moduleA 명령()에서 $ TARGET/$ 소스를 사용하지 않는 임 알고 있지만 목적에 그게 전부는 스크립트는 절대 경로 이름을 필요로하기 때문에, 그리고 SCons는이 선도 '#의'
문제를 제거 나던 모듈 B에서 Command() 빌더 (위의 3 단계)가 실행되지 않습니다.
Sconstruct
import os
env = Environment()
env['variantDir'] = 'linux' # for this example, just make variantDir = linux
modules = ['moduleA', 'moduleB']
for dir in modules:
SConscript(
os.path.join(dir, 'SConscript'),
variant_dir = os.path.join(dir, env['variantDir']),
exports = ['env'],
duplicate = 0)
moduleA/Sconscript
import os
Import('env')
scriptInput = '#file.conf'
sourceFile = os.path.join('#moduleA', env['variantDir'], 'source.cc')
conf2ccScript = File('#moduleA/conf2cc').abspath
# The script needs abspaths for input and output, not the scons '#' prepended
# the script syntax is: script <inputFile> <outputFile>
cmd = '%s %s %s' % (conf2ccScript, File(scriptInput).abspath, File(sourceFile).abspath)
# Generate source.cc file based on file.conf
conf2ccNode = env.Command(target = sourceFile,
source = scriptInput,
action = cmd)
libNode = env.Library(target = 'moduleA', source = sourceFile)
env.Depends(libNode, conf2ccNode)
가 moduleB/Sconscript 여기
import os
Import('env')
sourceFiles = ['fileB.cc', 'source.cc']
# Get the source.cc file
externalSourceFile = os.path.join('#moduleA', env['variantDir'], 'source.cc')
sourceTarget = os.path.join('#moduleB', 'source.cc')
cmdNode = env.Command(target = sourceTarget,
source = externalSourceFile,
action = Copy('$TARGET', '$SOURCE'))
libNode = env.Library(target = 'moduleB', source = sourceFiles)
env.Depends(libNode, cmdNode)
출력 할 때이다 : 여기 는 SConstruct 및 SConscript 파일들이다 나는 scons를 실행합니다 : 어떤 도움을 주시면 대단히 감사하겠습니다!
브래디
[email protected]:~/projects/sconsTest/sconsTestHierDeps$ scons
scons: Reading SConscript files ...
scons: done reading SConscript files.
scons: Building targets ...
/home/notroot/projects/sconsTest/sconsTestHierDeps/moduleA/conf2cc /home/notroot/projects/sconsTest/sconsTestHierDeps/file.conf /home/notroot/projects/sconsTest/sconsTestHierDeps/moduleA/linux/source.cc
g++ -o moduleA/linux/source.o -c moduleA/linux/source.cc
ar rc moduleA/linux/libmoduleA.a moduleA/linux/source.o
ranlib moduleA/linux/libmoduleA.a
g++ -o moduleB/linux/fileB.o -c moduleB/fileB.cc
scons: *** [moduleB/linux/source.o] Source `moduleB/source.cc' not found, needed by target `moduleB/linux/source.o'.
scons: building terminated because of errors.
우수! 그것은 예상대로 작동합니다. SCons는 명시 적으로 Depends() 함수를 사용하여 암시 적 종속성을 나열하는 대신 암시 적 종속성을 파악합니다. 고마워! – Brady
하나의주의 사항 : 그러나 moduleB/source.cc에 대한 오브젝트 파일은 moduleB에 있고 variantBody에 대한 variant_dir에는 없습니다. 반면에 fileB.o는 실제로 variant_dir에 있습니다. 왜 그런가요? 어떻게하면 source.o를 variant_dir에 넣을 수 있습니까? 다음 – Brady
는 I는 moduleB source.cc의 파일을 지정하여 알아 냈다 : 'sourceTarget os.path.join = ('#의 moduleB'ENV [ 'variantDir', 'source.cc') '이 이제 소스 .cc 및 source.o 파일은 variant_dir에 저장됩니다. – Brady