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
相关产品推荐
相关产品推荐

