CMake跨目录引入头文件及函数未定义链接错误解决问询
首先你的头文件引入配置已经生效了——如果头文件找不到,编译阶段就会直接报fatal error: h.hpp: No such file or directory的错误,不会走到链接阶段。你现在遇到的是链接阶段符号未定义错误,原因是func函数的实现文件include/h.cpp没有被加入到CMake的编译链路中,编译器没有编译这个文件,链接时自然找不到对应的函数实现。
解决方案
方案1:直接把h.cpp加入可执行目标的源文件列表
如果h.cpp只被少数几个目标用到,可以直接修改CMakeLists.txt中的add_executable配置,把h.cpp加入每个用到它的目标的源文件列表:
add_executable(a ${CMAKE_CURRENT_SOURCE_DIR}/src/a.cpp ${CMAKE_CURRENT_SOURCE_DIR}/include/h.cpp) add_executable(b ${CMAKE_CURRENT_SOURCE_DIR}/src/b.cpp ${CMAKE_CURRENT_SOURCE_DIR}/include/h.cpp) add_executable(c ${CMAKE_CURRENT_SOURCE_DIR}/src/c.cpp ${CMAKE_CURRENT_SOURCE_DIR}/include/h.cpp)
方案2:把公共代码编译为库(更适合多目标复用场景)
如果h.cpp会被多个可执行目标复用,更推荐把它编译为独立的静态/动态库,避免重复编译,也方便统一管理,完整修改后的CMakeLists.txt参考如下:
cmake_minimum_required(VERSION 3.17) set(CMAKE_TOOLCHAIN_FILE ${CMAKE_CURRENT_SOURCE_DIR}/vcpkg/scripts/buildsystems/vcpkg.cmake CACHE STRING "Vcpkg toolchain file") project(proj) find_package(fmt CONFIG REQUIRED) find_package(CUDAToolkit REQUIRED) # 编译公共代码为静态库 add_library(common STATIC ${CMAKE_CURRENT_SOURCE_DIR}/include/h.cpp) # 给公共库配置头文件目录,所有依赖common的目标会自动继承这个头文件路径 target_include_directories(common PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include) # 给公共库链接依赖 target_link_libraries(common PUBLIC fmt::fmt CUDA::nvrtc CUDA::cuda_driver CUDA::cudart) add_executable(a ${CMAKE_CURRENT_SOURCE_DIR}/src/a.cpp) target_link_libraries(a PRIVATE common) add_executable(b ${CMAKE_CURRENT_SOURCE_DIR}/src/b.cpp) target_link_libraries(b PRIVATE common) add_executable(c ${CMAKE_CURRENT_SOURCE_DIR}/src/c.cpp) target_link_libraries(c PRIVATE common)
额外建议
通常.cpp实现文件不建议放在include目录下,include目录一般只存放对外暴露的头文件(.h/.hpp后缀),实现文件建议移动到src目录下,项目结构会更清晰。
内容的提问来源于stack exchange,提问作者user2793618
相关产品推荐
相关产品推荐

