目录
一、检测操作系统
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: