如何在SConscript中依赖其他模块构建生成的gtest.h头文件
解决方案
核心问题
你使用的Require不是SCons中用于声明文件依赖的接口,且直接使用字符串路径声明依赖不会被SCons识别,必须基于SCons的节点(Node)体系传递依赖关系。
第一步:修改Gtest子模块的SConscript,导出构建目标
在Gtest的SConscript中,将Command生成的目标存为变量并导出,方便其他SConscript引用:
env2 = env.Clone() def buildGtest(target, source, env): # 假设目录下已有CMake文件完成构建逻辑 subprocess.run(['cmake', '../'], cwd='build/') subprocess.run(['make'], cwd='build/') # 注意目标路径要和实际生成路径完全一致,不能简写为gtest.h gtest_targets = env2.Command(['build/include/gtest/gtest.h', 'build/libgtest.a', 'build/libgtest_main.a'], [], buildGtest) # 导出目标节点供外部SConscript引用 Return('gtest_targets')
第二步:修改顶层SConstruct,接收并传递Gtest目标
调用Gtest的SConscript时接住返回的目标节点,存入环境传递给单元测试的SConscript:
# 接收Gtest SConscript返回的目标节点 gtest_targets = env.SConscript('{path to Gtest}/SConscript', exports='env') # 存入全局环境,方便后续SConscript读取 env['GTEST_TARGETS'] = gtest_targets env.SConscript('{path to my unit test}/SConscript', exports='env')
第三步:修改单元测试SConscript,显式声明依赖
用Depends接口声明目标对象依赖Gtest的构建产物,替换原有的Require语句:
env2 = env.Clone() # 导入全局环境中存储的Gtest目标节点 Import('GTEST_TARGETS') env2.Append(CPPPATH='{path to gtest}/build/include') test1_obj = env2.Object(target = 'test1.o', source = 'test1.cpp') # 显式声明test1.o依赖Gtest的所有构建产物 env2.Depends(test1_obj, GTEST_TARGETS)
可选简化方案(无需跨SConscript传参)
如果不想修改顶层和Gtest的配置,也可以在单元测试SConscript中直接把路径转为节点后声明依赖,只要路径和Gtest的Command中声明的目标路径完全一致即可:
env2 = env.Clone() env2.Append(CPPPATH='{path to gtest}/build/include') # 把gtest.h路径转为SCons节点 gtest_h = env2.File('{path to gtest}/build/include/gtest/gtest.h') test1_obj = env2.Object(target = 'test1.o', source = 'test1.cpp') env2.Depends(test1_obj, gtest_h)
补充说明
- Gtest的
Command中如果源列表为空,SCons只会在目标文件不存在时执行构建,如果需要修改Gtest的源码/CMake配置时自动重编,可以把Gtest的CMakeLists.txt等配置文件加到Command的source列表中。 - 不要使用
Require声明文件依赖,该接口的作用是加载SCons的内置工具/配置,和构建依赖无关。
内容的提问来源于stack exchange,提问作者Maxthecat
相关产品推荐
相关产品推荐

