CMake I 检测操作系统&设置预处理器

本文介绍如何使用CMake检测操作系统和编译器类型,并据此定义预处理器宏。通过具体示例展示了如何编写跨平台的CMakeLists.txt文件,实现针对不同操作系统和编译器的条件编译。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

目录

一、检测操作系统

1.CMake命令

(1)CMAKE_SYSTEM_NAME

(2)CMAKE_CXX_COMPILER_ID

二、设置预处理器

1.CMake命令

(1)target_compile_definitions

(2)add_definitions

三、源码

1.处理与平台相关的源代码

(1)CMakeLists.txt

(2)helloworld.cpp

(3)配置

2.处理与平台相关的源代码

(1)CMakeLists.txt

(2)helloworld.exe

(3)配置及构建


一、检测操作系统

1.CMake命令

(1)CMAKE_SYSTEM_NAME

        CMake为目标操作系统定义了 CMAKE_SYSTEM_NAME ,因此不需要使用定制命令、工具或脚本来查询操作系统信息。该变量在macOS上设置为“Darwin”,在Linux和 Windows上,它分别计算为“Linux”和“Windows”。(注意:首字母大写

if(CMAKE_SYSTEM_NAME STREQUAL "Linux")
	message(STATUS "Configuring on Linux.")

(2)CMAKE_CXX_COMPILER_ID

       参考文章CMake I 获取/设置编译器_该用户还没想到好的昵称的博客-CSDN博客

if(CMAKE_CXX_COMPILER_ID MATCHES MSVC)
	target_compile_definitions(helloworldexe PUBLIC "IS_MSVC_CXX_COMPILER")
endif()

二、设置预处理器

1.CMake命令

(1)target_compile_definitions

target_compile_definitions(<target>
  <INTERFACE|PUBLIC|PRIVATE> [items1...]
  [<INTERFACE|PUBLIC|PRIVATE> [items2...] ...])

        编译给定的 <target> 时使用指定的编译定义。<target> 必须是 add_executable() 或者 add_library() 创建的,并且不是一个输入目标。所以,一定要注意add_executable等函数的使用顺序。

add_executable(helloworldexe helloworld.cpp)
if(CMAKE_SYSTEM_NAME STREQUAL "Linux")
	target_compile_definitions(helloworldexe PUBLIC "IS_LINUX")

(2)add_definitions

add_definitions(-DFOO -DBAR ...)

        为源文件的编译添加由-D定义的标志。那些以 -D 或 /D 开头的标志,看起来像预处理器定义的flag,会被自动加到当前路径的 COMPILE_DEFINITIONS 属性中。

        使用 add_definitions 会修改编译整个项目的定义(所以不用特别在意add_executable与其的使用顺序),而 target_compile_definitions 将定义限制于一个特定的目标,以及通过 PRIVATE|PUBLIC|INTERFACE 限定符,限制这些定义可见性。

if(CMAKE_SYSTEM_NAME STREQUAL "Windows")
	add_definitions(-DIS_WINDOWS)

三、源码

1.处理与平台相关的源代码

(1)CMakeLists.txt

cmake_minimum_required(VERSION 3.5 FATAL_ERROR)

project(getOSInfo LANGUAGES CXX)

add_executable(helloworldexe helloworld.cpp)

if(CMAKE_SYSTEM_NAME STREQUAL "Linux")
	target_compile_definitions(helloworldexe PUBLIC "IS_LINUX")
	message(STATUS "Configuring on Linux.")
elseif(CMAKE_SYSTEM_NAME STREQUAL "AIX")
	target_compile_definitions(helloworldexe PUBLIC "IS_AIX")
	message(STATUS "Configuring on UNIX.")
elseif(CMAKE_SYSTEM_NAME STREQUAL "Darwin")
	target_compile_definitions(helloworldexe PUBLIC "IS_DARWIN")
	message(STATUS "Configuring on macOS.")
elseif(CMAKE_SYSTEM_NAME STREQUAL "Windows")
	target_compile_definitions(helloworldexe PUBLIC "IS_WINDOWS")
	message(STATUS "Configuring on windows.")
else()
	message(STATUS "Configuring on ${CMAKE_SYSTEM_NAME}")
endif()

(2)helloworld.cpp

#include <cstdlib>
#include <iostream>
#include <string>

std::string SayHello()
{
#ifdef IS_WINDOWS
	return std::string("hello from windows");
#elif IS_LINUX
	return std::string("hello from linux");
#elif IS_AIX	
	return std::string("hello from unix");
#elif IS_DARWIN	
	return std::string("hello from macOS");
#else 
	return std::string("hello from an unknown system");
#endif
}

int main()
{
	std::cout<<SayHello()<<std::endl;
	return EXIT_SUCCESS;
}

(3)配置

         使用VS打开项目,可以看到预处理器有IS_WINDOWS的宏:

2.处理与平台相关的源代码

(1)CMakeLists.txt

cmake_minimum_required(VERSION 3.5 FATAL_ERROR)

project(GetCompilerInfo LANGUAGES CXX)

add_executable(helloworldexe helloworld.cpp)

target_compile_definitions(helloworldexe PUBLIC "COMPILER_NAME=\"${CMAKE_CXX_COMPILER_ID}\"")
message(STATUS "CMAKE_CXX_COMPILER_ID is ${CMAKE_CXX_COMPILER_ID}")

if(CMAKE_CXX_COMPILER_ID MATCHES Intel)
	target_compile_definitions(helloworldexe PUBLIC "IS_INTEL_CXX_COMPILER")
endif()
if(CMAKE_CXX_COMPILER_ID MATCHES GNU)
	target_compile_definitions(helloworldexe PUBLIC "IS_GNU_CXX_COMPILER")
endif()
if(CMAKE_CXX_COMPILER_ID MATCHES PGI)
	target_compile_definitions(helloworldexe PUBLIC "IS_PGI_CXX_COMPILER")
endif()
if(CMAKE_CXX_COMPILER_ID MATCHES XL)
	target_compile_definitions(helloworldexe PUBLIC "IS_XL_CXX_COMPILER")
endif()
if(CMAKE_CXX_COMPILER_ID MATCHES MSVC)
	target_compile_definitions(helloworldexe PUBLIC "IS_MSVC_CXX_COMPILER")
endif()

(2)helloworld.exe

#include <cstdlib>
#include <iostream>
#include <string>

std::string SayHello()
{
#ifdef IS_INTEL_CXX_COMPILER
	return std::string("Hello Intel compiler!");
#elif IS_GNU_CXX_COMPILER
	return std::string("Hello GNU compiler!");
#elif IS_PGI_CXX_COMPILER
	return std::string("Hello PGI compiler!");
#elif IS_XL_CXX_COMPILER
	return std::string("Hello XL compiler!");
#elif IS_MSVC_CXX_COMPILER
	return std::string("Hello MSVC compiler!");
#else 
	return std::string("Hello unknown compiler - have we met before?");
#endif
}
int main()
{
	std::cout<<SayHello()<<std::endl;
	std::cout<<"compiler name is:"<<COMPILER_NAME<<std::endl;
	return EXIT_SUCCESS;
}

(3)配置及构建

         使用VS打开项目,可以看到预处理器有COMPILER_NAME="MSVC"与IS_MSVC_CXX_COMPILER两个宏: 

 运行VS:

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

烫青菜

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值