You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

CMake配置src/include结构C++项目遇xtensor头文件缺失问题求助

问题

我在为如下目录结构的C++项目编写CMakeLists.txt时遇到编译错误,主文件为solver_fullyParallelized_shtns_3D.cpp:

$ tree
.
├── CMakeLists.txt
├── include
│   ├── GPS_global_vars.hpp
│   ├── absorber_fns.hpp
│   ├── distribution_fns.hpp
│   ├── laser_field.hpp
│   ├── matrix_transposition_fns.hpp
│   ├── matrix_vector_prods_for_propagation.hpp
│   ├── shtns_transforms_fns.hpp
│   ├── utility_fns_C_CPP.hpp
│   └── utility_fns_GPS.hpp
└── src
    ├── absorber_fns.cpp
    ├── distribution_fns.cpp
    ├── laser_field.cpp
    ├── matrix_transposition_fns.cpp
    ├── matrix_vector_prods_for_propagation.cpp
    ├── shtns_transforms_fns.cpp
    ├── solver_fullyParallelized_shtns_3D.cpp
    ├── utility_fns_C_CPP.cpp
    └── utility_fns_GPS.cpp

2 directories, 19 files

src目录下部分.cpp文件包含#include <xtensor/xarray.hpp>,我已为可执行文件TDSE_solver配置了xtensor相关头文件路径,但编译时出现错误:

distribution_fns.cpp:7:10: fatal error: xtensor/xarray.hpp: No such file or directory
    7 | #include <xtensor/xarray.hpp> 

当前完整CMakeLists.txt如下:

cmake_minimum_required(VERSION 3.10)
project(TDSE_solver)

# For ARCHER2:
set(CMAKE_C_COMPILER "cc")
set(CMAKE_CXX_COMPILER "CC")

# For inline variables in CPP
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED True)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -O3 -pedantic -Wshadow")

# OpenMP
find_package(OpenMP REQUIRED)

set(SOURCES
src/absorber_fns.cpp
src/distribution_fns.cpp
src/laser_field.cpp
src/matrix_transposition_fns.cpp
src/matrix_vector_prods_for_propagation.cpp
src/shtns_transforms_fns.cpp
src/solver_fullyParallelized_shtns_3D.cpp
src/utility_fns_C_CPP.cpp
src/utility_fns_GPS.cpp)

add_executable(TDSE_solver src/solver_fullyParallelized_shtns_3D.cpp)
target_include_directories(TDSE_solver PUBLIC include)


# xtensor
target_include_directories(TDSE_solver PUBLIC "/work/e281/e281/ouatu_i/trial_Carrays_IntelMKL_Xtensor_SHTNS_CrayFFTW/xtensor_all/xtensor_install_dir/include/")
target_include_directories(TDSE_solver PUBLIC "/work/e281/e281/ouatu_i/trial_Carrays_IntelMKL_Xtensor_SHTNS_CrayFFTW/xtensor_all/xtl_install_dir/include/")
target_include_directories(TDSE_solver PUBLIC "/work/e281/e281/ouatu_i/TDSE_3D_Telnov/xtensor_io_install/include/")

add_library(absorber_fns STATIC src/absorber_fns.cpp)
add_library(distribution_fns STATIC src/distribution_fns.cpp)
add_library(laser_field STATIC src/laser_field.cpp)
add_library(matrix_transposition_fns STATIC src/matrix_transposition_fns.cpp)
add_library(matrix_vector_prods_for_propagation STATIC src/matrix_vector_prods_for_propagation.cpp)
add_library(shtns_transforms_fns STATIC src/shtns_transforms_fns.cpp)
add_library(utility_fns_C_CPP STATIC src/utility_fns_C_CPP.cpp)
add_library(utility_fns_GPS STATIC src/utility_fns_GPS.cpp)

if(OpenMP_CXX_FOUND)
target_link_libraries(
TDSE_solver 
PUBLIC OpenMP::OpenMP_CXX
absorber_fns 
distribution_fns 
laser_field 
matrix_transposition_fns 
matrix_vector_prods_for_propagation
shtns_transforms_fns
utility_fns_C_CPP
utility_fns_GPS)
endif()

请问哪里配置错误?该如何解决?

错误原因与解决方案

错误原因

你仅为可执行文件TDSE_solver添加了xtensor头文件路径,但编译静态库(如distribution_fns)时,CMake不会自动继承可执行文件的依赖配置。这些静态库的源文件需要xtensor头文件,但编译阶段无法找到对应路径,因此报错。

解决方案

有两种简洁的修复方式,任选其一即可:

方式一:为所有静态库统一配置头文件路径

通过定义公共变量共享依赖配置,避免重复代码:

# 定义公共包含目录
set(PUBLIC_INCLUDES
    include
    "/work/e281/e281/ouatu_i/trial_Carrays_IntelMKL_Xtensor_SHTNS_CrayFFTW/xtensor_all/xtensor_install_dir/include/"
    "/work/e281/e281/ouatu_i/trial_Carrays_IntelMKL_Xtensor_SHTNS_CrayFFTW/xtensor_all/xtl_install_dir/include/"
    "/work/e281/e281/ouatu_i/TDSE_3D_Telnov/xtensor_io_install/include/"
)

# 为可执行文件设置
add_executable(TDSE_solver src/solver_fullyParallelized_shtns_3D.cpp)
target_include_directories(TDSE_solver PUBLIC ${PUBLIC_INCLUDES})

# 为每个静态库设置
add_library(absorber_fns STATIC src/absorber_fns.cpp)
target_include_directories(absorber_fns PUBLIC ${PUBLIC_INCLUDES})

add_library(distribution_fns STATIC src/distribution_fns.cpp)
target_include_directories(distribution_fns PUBLIC ${PUBLIC_INCLUDES})

# 其余静态库按上述格式添加target_include_directories配置

方式二:直接将所有源文件编译进可执行文件(更简便)

利用已定义的SOURCES变量,将所有源文件直接传入add_executable,无需单独创建静态库,所有源文件将共享可执行文件的头文件配置:

# 替换原有的add_executable和静态库创建代码
add_executable(TDSE_solver ${SOURCES})
target_include_directories(TDSE_solver PUBLIC include)

# xtensor配置保持不变
target_include_directories(TDSE_solver PUBLIC "/work/e281/e281/ouatu_i/trial_Carrays_IntelMKL_Xtensor_SHTNS_CrayFFTW/xtensor_all/xtensor_install_dir/include/")
target_include_directories(TDSE_solver PUBLIC "/work/e281/e281/ouatu_i/trial_Carrays_IntelMKL_Xtensor_SHTNS_CrayFFTW/xtensor_all/xtl_install_dir/include/")
target_include_directories(TDSE_solver PUBLIC "/work/e281/e281/ouatu_i/TDSE_3D_Telnov/xtensor_io_install/include/")

# OpenMP链接配置保持不变
if(OpenMP_CXX_FOUND)
target_link_libraries(TDSE_solver PUBLIC OpenMP::OpenMP_CXX)
endif()

这种方式省去了创建多个静态库的步骤,适合中小型项目,所有源文件将使用相同的头文件路径与编译选项。

内容的提问来源于stack exchange,提问作者velenos14

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.02 18:54:55