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

为何CMake的install(TARGETS)未指定PUBLIC_HEADER仍安装libjxl头文件?

问题描述

我使用CMake 3.31.6执行以下命令:

install(TARGETS ${PROJECT_NAME} RUNTIME DESTINATION "$<TARGET_FILE_DIR:${PROJECT_NAME}>")

发现该命令自动安装了依赖库libjxl的include目录及其中的C++头文件(示例:-- Installing: C:/code/texture-streaming/decoder/bin/x64/release/include/jxl/decode_cxx.h)。我原本认为必须使用PUBLIC_HEADER参数才会安装头文件,但当前仅指定了RUNTIME目标,对此现象存在疑问。

以下是我的CMake配置文件:

根目录CMakeLists.txt

cmake_minimum_required(VERSION 3.21)

project(jpegxl-decoder VERSION 0.0.1 LANGUAGES CXX)

set(CMAKE_CXX_STANDARD 23)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)

if(MSVC)
    add_compile_options(
        /permissive- 
        /Zc:preprocessor
    )
endif()

add_subdirectory(extern)
add_subdirectory(app)

app/CMakeLists.txt

project(app)

add_executable(${PROJECT_NAME} app.cpp)
target_link_libraries(${PROJECT_NAME} PUBLIC jxl)
install(TARGETS ${PROJECT_NAME} RUNTIME DESTINATION "$<TARGET_FILE_DIR:${PROJECT_NAME}>")

extern/CMakeLists.txt

include(FetchContent)

set(BUILD_TESTING OFF CACHE BOOL "")
set(JPEGXL_ENABLE_TOOLS OFF CACHE BOOL "")

FetchContent_Declare(
  Libjxl
  GIT_REPOSITORY https://github.com/libjxl/libjxl.git
  GIT_TAG        v0.11.1
)

FetchContent_MakeAvailable(Libjxl)
原因解析

这事儿和你写的install命令无关,核心原因是libjxl自身的CMake配置里已经定义了完整的安装规则。

你通过FetchContent_MakeAvailable把libjxl作为子项目引入构建,而libjxl的CMakeLists.txt中已经写好了针对自身库目标的install逻辑,其中就包含头文件的安装步骤——这和你是否在自己的install命令里指定PUBLIC_HEADER完全没关系。

当你执行cmake --install时,CMake会默认执行所有加入项目的install规则,包括子项目libjxl里预定义的规则。哪怕你只在自己的命令里指定了RUNTIME目标,libjxl的头文件安装步骤照样会被触发执行。

如果想避免安装libjxl的头文件,可以试试这些办法:

  • 拉取libjxl时,设置对应的CMake开关禁用它的安装规则(可以查libjxl的CMake文档,看是否有类似JPEGXL_SKIP_INSTALL这类选项);
  • 开启CMAKE_SKIP_INSTALL_ALL_DEPENDENCY变量,让CMake跳过依赖项的安装操作;
  • 不用FetchContent拉源码构建,改用find_package引入预编译好的libjxl库。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.13 16:05:58