如何在SCons中实现类似CMake INTERFACE的仅头文件C++库?
SCons实现仅头文件C++库(等效CMake INTERFACE功能)
SCons本身没有内置的INTERFACE库标识,但可以通过封装构造环境配置的方式实现完全等效的依赖自动传递效果,具体做法如下:
核心思路
将仅头文件库自身的头文件路径、依赖库的编译/链接配置全部封装到独立的配置方法中,使用该库的目标只需要调用对应方法,即可自动继承所有依赖配置,无需手动添加fmt、boost等第三方依赖的路径。
具体实现步骤
- 封装仅头文件库的依赖配置
在你的顶层SConstruct或者对应的SCons配置脚本中,定义该库的专属配置方法:
def add_libonlyheader(env): # 添加自身头文件搜索路径 env.Append(CPPPATH = ['#/libonlyheader/include']) # 自动添加依赖的fmt库配置 env.Append(CPPPATH = ['#/third_party/fmt/include']) # 自动添加依赖的boost库配置,需要链接的boost组件也可以同步添加到LIBS、LIBPATH中 env.Append( CPPPATH = ['#/third_party/boost/include'], LIBS = ['boost_system', 'boost_filesystem'], # 按需添加需要链接的boost组件 LIBPATH = ['#/third_party/boost/lib'] ) # 如果fmt、boost是通过当前SCons工程构建的,还可以添加依赖声明,自动触发依赖构建 # env.Depends(env, [fmt_build_target, boost_build_target]) # env.Append(LIBS = [fmt_build_target])
- 使用仅头文件库
构建依赖该库的可执行文件或者其他库时,仅需要调用上述封装的方法即可:
# 初始化目标的构造环境 prog_env = Environment() # 引入libonlyheader的所有依赖配置 add_libonlyheader(prog_env) # 直接编译目标,无需额外配置fmt、boost路径 prog_env.Program('my_app', sources = ['main.cpp', 'util.cpp'])
进阶封装方案
如果你的工程有多个仅头文件库需要管理,还可以把所有接口库的配置统一存放到字典中,通过统一方法加载,更接近CMake的target_link_libraries使用体验:
INTERFACE_LIBS = { 'libonlyheader': add_libonlyheader, 'other_header_lib': add_other_header_lib } def link_interface_libs(env, lib_names): for lib in lib_names: INTERFACE_LIBS[lib](env) # 使用示例 link_interface_libs(prog_env, ['libonlyheader', 'other_header_lib'])
以上方案完全可以实现依赖的自动传递,和CMake INTERFACE库的使用效果一致。
内容的提问来源于stack exchange,提问作者fakedrake
相关产品推荐
相关产品推荐

