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

CMake中PUBLIC/PRIVATE/INTERFACE关键字使用场景示例咨询

CMake 三个依赖关键字对应场景示例

1. PRIVATE:依赖仅用于库实现,未出现在头文件

场景说明:依赖的所有内容都只在库的.cpp/.c等实现文件中使用,对外暴露的头文件完全不涉及该依赖的任何类型、函数、宏定义。
示例代码:

  • 头文件 math_utils.h
#pragma once
// 完全不涉及spdlog的任何内容
int add(int a, int b);
  • 实现文件 math_utils.cpp
#include "math_utils.h"
// 仅在实现中引入spdlog依赖
#include <spdlog/spdlog.h>

int add(int a, int b) {
    spdlog::info("调用add方法,参数a={}, b={}", a, b);
    return a + b;
}
  • CMakeLists.txt 片段
add_library(math_utils math_utils.cpp math_utils.h)
# spdlog仅实现用,用PRIVATE
target_link_libraries(math_utils PRIVATE spdlog::spdlog)

说明:这种情况下,链接math_utils的其他目标不需要知道spdlog的存在,也不会继承spdlog的头文件路径、链接选项

2. PUBLIC:依赖同时用于库的实现和头文件

场景说明:依赖的内容不仅在实现中用到,对外暴露的头文件也用到了该依赖的类型、函数、宏,所有使用该库的目标都需要访问该依赖的内容。
示例代码:

  • 头文件 custom_button.h
#pragma once
// 头文件中用到Qt的QPushButton类型,必须引入Qt头文件
#include <QPushButton>

class CustomButton : public QPushButton {
    Q_OBJECT
public:
    explicit CustomButton(QWidget* parent = nullptr);
};
  • 实现文件 custom_button.cpp
#include "custom_button.h"

CustomButton::CustomButton(QWidget* parent) : QPushButton(parent) {
    // 实现中也用到Qt的接口
    setText("自定义按钮");
}
  • CMakeLists.txt 片段
add_library(ui_widgets custom_button.cpp custom_button.h)
# Qt依赖头文件和实现都用,用PUBLIC
target_link_libraries(ui_widgets PUBLIC Qt::Widgets)

说明:链接ui_widgets的其他目标会自动继承Qt::Widgets的头文件路径、链接选项,因为要编译用到custom_button.h的代码时,必须能找到QPushButton的定义

3. INTERFACE:依赖仅用于库的头文件,未被实现使用

场景说明:依赖的内容只出现在对外暴露的头文件中,库自身的实现完全没有用到该依赖的任何功能,仅使用该库的目标需要访问该依赖的内容。
示例代码:

  • 头文件 callback_registry.h
#pragma once
// 头文件中用到absl::FunctionRef类型
#include <absl/functional/function_ref.h>
#include <functional>

class CallbackRegistry {
public:
    void register_callback(absl::FunctionRef<void(int)> cb);
private:
    std::function<void(int)> m_stored_cb;
};
  • 实现文件 callback_registry.cpp
#include "callback_registry.h"
// 实现中没有引入任何absl的头文件,也没有调用absl的任何接口
void CallbackRegistry::register_callback(absl::FunctionRef<void(int)> cb) {
    // 仅做类型转换,absl::FunctionRef的隐式转换由编译器处理
    m_stored_cb = cb;
}
  • CMakeLists.txt 片段
add_library(callback_registry callback_registry.cpp callback_registry.h)
# absl仅头文件用到,实现没用,用INTERFACE
target_link_libraries(callback_registry INTERFACE abseil::absl_function_ref)

说明:这种情况下,callback_registry自身编译的时候不需要链接absl的对应库,只有使用callback_registry的目标,在编译包含callback_registry.h的代码时,需要找到absl的头文件,因此会继承该依赖


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.28 07:36:04