在本地可以使用cout输出,但是实际编译不会存在任何代码

实现思路

  1. CMake 层:定义开关选项,控制是否添加编译宏;

  2. C++ 层:封装一个自定义输出类 / 函数,通过编译宏判断:

  • 开启时:转发调用std::cout实现输出;

  • 关闭时:定义空实现,编译器会直接优化掉这部分代码。

1.CMakeLists.txt 配置

# 定义开关选项,默认开启自定义输出功能
option(ENABLE_CUSTOM_LOG "Enable custom log output (like std::cout)" ON)

# 假设你的目标名称是 car_move_cmd(可替换为你的实际目标名)
add_executable(car_move_cmd main.cpp custom_log.hpp)

# 根据开关添加编译宏
if(ENABLE_CUSTOM_LOG)
    target_compile_definitions(car_move_cmd PUBLIC ENABLE_CUSTOM_LOG)
endif()

2.custom_log.hpp

#ifndef CUSTOM_LOG_HPP
#define CUSTOM_LOG_HPP

#include <iostream>
#include <string>


#ifdef ENABLE_CUSTOM_LOG
#define CUSTOM_LOG(message) std::cout << "[CustomLog] " << message << std::endl
template <typename... Args>
inline void custom_log(Args&&... args) {
    (std::cout << ... << args) << std::endl;
}
#else
#define CUSTOM_LOG(message) ((void)0)
template <typename... Args>
inline void custom_log(Args&&... args) {
    (void)sizeof...(args);
}
#endif

#endif // CUSTOM_LOG_HPP

3.mian.cpp中的使用

#include "custom_log.hpp"

int main() {
    // 方式1:
    CUSTOM_LOG("程序启动");
    CUSTOM_LOG("当前数值:" << 123 << ",字符串:" << "test");

    // 方式2:
    custom_log("[Info] 位置信息:x=", 10.5, " y=", 20.8);
    custom_log("调试信息:", "使用实际位置变换");

    int a = 5, b = 8;
    CUSTOM_LOG("计算结果:" << a + b);

    return 0;
}
  • CMake 配置

    • option(ENABLE_CUSTOM_LOG ... ON):定义开关,默认开启;

    • target_compile_definitions:开启时向目标添加ENABLE_CUSTOM_LOG宏,关闭时不添加。

  • C++ 封装核心

    • 开启状态

      • CUSTOM_LOG直接展开为std::cout语句;

      • 函数custom_log使用 C++17 的折叠表达式(std::cout << ... << args),支持任意数量、任意类型的参数(和std::cout用法完全一致)。

    • 关闭状态

      • CUSTOM_LOG展开为((void)0)(空语句);

      • 函数custom_log仅做参数占位(无实际逻辑),编译器会将这些空调用直接优化掉,不会生成任何汇编代码。

4.编译使用

  • 默认开启(编译输出代码)

    bash

    运行

    cmake ..
    make
    ./car_move_cmd  # 会输出所有CUSTOM_LOG/custom_log的内容
    
  • 关闭(跳过输出代码编译)

    bash

    运行

    cmake -DENABLE_CUSTOM_LOG=OFF ..
    make
    ./car_move_cmd  # 无任何自定义输出,且编译后的二进制体积更小