我有以下目录结构:
root/
SConstruct
item0/
SConstruct
unit0/
unit0.h
private/
unit0.c
test/
test_unit0.c
SConstruct
SConscript
unit1/
(repeat unit0 structure)
item1/
(repeat item0 structure)
我希望能够从root
运行scons来构建它下面的所有内容,并从root/item0
运行以构建它下面的所有内容等等。
顶级SConstruct看起来像:
SConscript('item0/SConstruct', duplicate=0)
SConscript('item1/SConstruct', duplicate=0)
项目级别SConstruct:
SConscript('unit0/SConstruct', duplicate=0)
SConscript('unit1/SConstruct', duplicate=0)
单元级SConstruct:
import os
proj_root = os.path.abspath('../../../../..')
proj_shared_path = os.path.join(proj_root,
os.path.normpath('trunk/sys/shared'))
env = Environment()
SConscript(
'SConscript',
variant_dir='output',
exports=['env', 'proj_shared_path'],
duplicate=0)
单元级SConscript(仅限重要的东西):
Import('*')
# Setup Repositories to access out-of-current-directory-tree files.
lib1_path = os.path.join(proj_shared_path, 'lib1')
env.Repository('#/../private', lib1_path)
# Set general compilation and link flags.
env.Append(
CFLAGS = '-Wall -Wextra -std=c99 -pedantic',
CPPPATH = ['#/../..', proj_shared_path])
# These are the files we don't need to run gcovr on.
non_cov_srcs = [
'testit.c',
'lib1.c'
]
# Create a 'coverage' environment to build files that we will run gcovr on.
cov = env.Clone()
cov.Append(CFLAGS = '--coverage -O0')
cov_srcs = cov.Object('unit0.c')
SideEffect('unit0.gcno', cov_srcs)
# Our unit test program combines all the sources we've listed so far.
test_exe = env.Program(
'test_unit0',
[cov_srcs, non_cov_srcs],
LIBS='gcov', LINKFLAGS='--coverage')
现在,当我从root/item0/unit0/test
运行scons时,这一切都正常。但是,当我从root
或root/item0
运行时,我会遇到各种类型的错误,例如下面的错误(从root/item0
运行):
scons: done reading SConscript files.
scons: Building targets ...
scons: *** [unit0\test\output\unit0.obj] Source 'unit0\test\unit0.c' not found, needed by target 'unit0\test\output\unit0.obj'.
scons: building terminated because of errors.
显然unit0\test\unit0.c
将不会被找到,因为它不存在,但我不确定为什么scons认为它必须存在,因为存储库被定义为'#/../private'
并且没有私有信息显示在错误消息中。
编辑我发现它可能正在寻找unit0\test\unit0.c
,因为unit0\test
是SConscript
的“根”目录。我还猜测#/../private
Repository
位置仅在从scons
运行unit0\test
时才是正确的。但是,当我尝试以任何其他方式指定Repository
时(包括使用os.path.abspath
构建的绝对路径(并验证为正确)),scons
似乎仍然不想要在那里寻找unit0.c
。那是为什么?
答案 0 :(得分:0)
在#scons IRC频道的@bdbaddog的帮助下,我能够确定以下内容:
variant_dir
SConstruct
和SConscript
位于同一目录中时,Repository
在从unit0/test
目录构建时最终实现了此目的。但是,我不知道为什么。要正确实现(1),Repository
不是正确的工具。相反,SConscript
应如下所示:
Import('*')
# Set general compilation and link flags.
env.Append(
CFLAGS = '-Wall -Wextra -std=c99 -pedantic',
CPPPATH = ['#/item0', '#/lib1'])
# These are the files we don't need to run gcovr on.
non_cov_objs = [
Object(target='testit', source='testit.c'),
Object(target='lib1', source='#/lib1/lib1.c'
]
# Create a 'coverage' environment to build files that we will run gcovr on.
cov = env.Clone()
cov.Append(CFLAGS = '--coverage -O0')
cov_objs = cov.Object(
target='unit0',
source='#/item0/unit0/private/unit0.c')
SideEffect('unit0.gcno', cov_srcs)
# Our unit test program combines all the sources we've listed so far.
test_exe = env.Program(
'test_unit0',
[cov_objs, non_cov_objs],
LIBS='gcov', LINKFLAGS='--coverage')
通过为每个target
指定source
和Object
,我可以根据{{1}中生成的目标文件(以及其他副作用)实现我想要的效果}}