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

CMake生成VS解决方案编译成功后未找到输出的libShadows库文件

问题:CMake生成VS解决方案编译成功但无库文件输出

我使用CMake项目生成Visual Studio解决方案后执行编译操作,编译流程显示成功但始终找不到生成的库文件,检索整个项目文件夹,未发现任何库文件输出,相关配置和日志如下:

项目根目录CMake配置

cmake_minimum_required(VERSION 3.22)
project(ShadowContainers)

set(CMAKE_CXX_STANDARD 23)
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR})
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR})
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR})

include_directories(include/)

add_subdirectory(library)

...

library子目录CMake配置

add_library(libShadows shadows.tpp ../include/shadows.hpp)
set_target_properties(libShadows PROPERTIES LINKER_LANGUAGE CXX) # a tpp and an hpp aren't enough to make the system certain it's c++
target_compile_features(libShadows PRIVATE cxx_std_23)

MSBuild输出日志片段

Done Building Project "C:\Users\[..]\projects\Shadow Array\library\libShadows.vcxproj" (default targets).

Done Building Project "C:\Users\[..]\projects\Shadow Array\library\libShadows.vcxproj.metaproj" (default targets).

即便libShadows是项目内唯一构建目标,在整个项目目录下也无法检索到对应输出文件。

补充说明

尝试了两种不同的编译流程,均得到相同结果,仅VS和CMake生成的中间文件存放位置有区别,两种方式都没有库文件输出:

  • 常规编译流程(工作目录为项目根目录):
cmake .
msbuild ShadowContainers.sln
  • 独立build目录编译流程(工作目录同样为项目根目录):
mkdir build
cd build
cmake ..
cmake --build .

原因分析与解决方案

核心诱发原因

add_library调用没有传入任何可编译的源文件(.cpp/.cc等实现文件),仅传入了模板实现文件.tpp和头文件.hpp,这类文件不会被MSVC编译器单独编译生成目标文件,最终链接阶段没有任何输入目标文件,自然不会生成.lib静态库或者.dll动态库文件。
手动设置LINKER_LANGUAGE CXX只是强制CMake跳过了「未检测到可编译C源文件」的报错检查,相当于告诉CMake「我确定这是C目标,你别报错」,但实际编译阶段没有任何需要编译的单元,构建系统会判定目标无实际产出,直接标记构建完成,不会抛错。

排查步骤

  1. 打开生成的libShadows.vcxproj项目文件,查看其中的ClCompile条目,会发现里面没有任何被标记为需要编译的源文件,只有被标记为ClInclude的头文件/tpp文件,这就是没有产出的直接证据。
  2. 把MSBuild的输出日志级别调到详细,重新编译,会看到libShadows目标完全没有执行编译、链接的相关步骤,只有项目加载完成的标记。

修复方案

根据项目类型选择对应处理方式:

  • 如果要做纯头文件/模板库:不需要编译生成二进制库文件,把add_library改成接口库即可:
    add_library(libShadows INTERFACE)
    target_include_directories(libShadows INTERFACE ${PROJECT_SOURCE_DIR}/include)
    target_compile_features(libShadows INTERFACE cxx_std_23)
    
    接口库不会产出任何二进制文件,仅用来传递头文件路径、编译特性等依赖属性,其他目标链接这个库的时候会自动拿到对应的头文件包含路径和C++标准配置。
  • 如果要做需要编译的静态/动态库:把对应功能的.cpp实现文件加入add_library的源文件列表,不要只传头文件和tpp文件。比如存在shadows.cpp实现文件,就改成:
    add_library(libShadows shadows.cpp shadows.tpp ../include/shadows.hpp)
    target_compile_features(libShadows PRIVATE cxx_std_23)
    
    有了可编译的cpp文件后,编译器会先把cpp编译成obj目标文件,再链接生成对应的lib库文件,输出到之前设置的CMAKE_ARCHIVE_OUTPUT_DIRECTORY路径下。

额外注意:用MSVC编译的时候,默认编译的是Debug配置,未修改输出路径规则时,Debug版本的库会放在<build目录>/Debug/下,Release版本在<build目录>/Release/下,之前设置的三个全局输出目录变量会覆盖这个默认规则,把所有配置的产出都放到build根目录,修复源文件问题后直接去build根目录查找即可。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.30 15:51:22