如何使用多个使用存储库的 SConstruct 文件从树中的不同位置进行构建?
How do I build from different locations in my tree with multiple SConstruct files that use Repositories?
我有以下目录结构:
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
运行 时,我会收到各种类型的错误,如下所示 (运行 from 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'
并且在那里错误消息中没有显示私人。
edit 我发现它可能在寻找 unit0\test\unit0.c
因为 unit0\test
是 [=26= 的 "root" 目录].我还猜测 #/../private
Repository
位置只有在 scons
是 unit0\test
的 运行 时才是正确的。但是,当我尝试以任何其他方式指定 Repository
时(包括使用 os.path.abspath
构建的绝对路径(并验证为正确)),scons
似乎仍然不想要在那里寻找 unit0.c
。这是为什么?
在#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')
通过为每个 Object
指定 target
和 source
,我可以根据在 variant_dir
.
我有以下目录结构:
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
运行 时,我会收到各种类型的错误,如下所示 (运行 from 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'
并且在那里错误消息中没有显示私人。
edit 我发现它可能在寻找 unit0\test\unit0.c
因为 unit0\test
是 [=26= 的 "root" 目录].我还猜测 #/../private
Repository
位置只有在 scons
是 unit0\test
的 运行 时才是正确的。但是,当我尝试以任何其他方式指定 Repository
时(包括使用 os.path.abspath
构建的绝对路径(并验证为正确)),scons
似乎仍然不想要在那里寻找 unit0.c
。这是为什么?
在#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')
通过为每个 Object
指定 target
和 source
,我可以根据在 variant_dir
.