【CMake】检测系统环境
C++代码:
1 /** 2 * @file main.cpp 3 */ 4 #include <cstdlib> 5 #include <iostream> 6 #include <string> 7 #include "config.h" 8 9 #define STRINGIFY(x) #x 10 #define TOSTRING(x) STRINGIFY(x) 11 12 void say_hello() 13 { 14 std::string system_info; 15 #ifdef IS_WINDOWS 16 system_info = std::string("Hello from Windows!"); 17 #elif IS_LINUX 18 system_info = std::string("Hello from Linux!"); 19 #elif IS_MACOS 20 system_info = std::string("Hello from macOS!"); 21 #else 22 system_info = std::string("Hello from an unknown system!"); 23 #endif 24 std::cout << system_info << std::endl; 25 26 std::string compiler_info; 27 #ifdef IS_INTEL_CXX_COMPILER 28 // only compiled when Intel compiler is selected 29 // such compiler will not compile the other branches 30 compiler_info = std::string("Hello Intel compiler!"); 31 #elif IS_GNU_CXX_COMPILER 32 // only compiled when GNU compiler is selected 33 // such compiler will not compile the other branches 34 compiler_info = std::string("Hello GNU compiler!"); 35 #elif IS_PGI_CXX_COMPILER 36 // etc. 37 compiler_info = std::string("Hello PGI compiler!"); 38 #elif IS_XL_CXX_COMPILER 39 compiler_info = std::string("Hello XL compiler!"); 40 #else 41 compiler_info = std::string("Hello unknown compiler - have we met before?"); 42 #endif 43 std::cout << compiler_info << std::endl; 44 45 std::string arch_info(TOSTRING(ARCHITECTURE)); 46 arch_info += std::string(" architecture. "); 47 #ifdef IS_32_BIT_ARCH 48 arch_info += std::string("Compiled on a 32 bit host processor."); 49 #elif IS_64_BIT_ARCH 50 arch_info += std::string("Compiled on a 64 bit host processor."); 51 #else 52 arch_info += std::string("Neither 32 nor 64 bit, puzzling ..."); 53 #endif 54 std::cout << arch_info << std::endl; 55 56 std::cout << "Number of logical cores: " 57 << NUMBER_OF_LOGICAL_CORES << std::endl; 58 std::cout << "Number of physical cores: " 59 << NUMBER_OF_PHYSICAL_CORES << std::endl; 60 std::cout << "Total virtual memory in megabytes: " 61 << TOTAL_VIRTUAL_MEMORY << std::endl; 62 std::cout << "Available virtual memory in megabytes: " 63 << AVAILABLE_VIRTUAL_MEMORY << std::endl; 64 std::cout << "Total physical memory in megabytes: " 65 << TOTAL_PHYSICAL_MEMORY << std::endl; 66 std::cout << "Available physical memory in megabytes: " 67 << AVAILABLE_PHYSICAL_MEMORY << std::endl; 68 std::cout << "Processor is 64Bit: " 69 << IS_64BIT << std::endl; 70 std::cout << "Processor has floating point unit: " 71 << HAS_FPU << std::endl; 72 std::cout << "Processor supports MMX instructions: " 73 << HAS_MMX << std::endl; 74 std::cout << "Processor supports Ext. MMX instructions: " 75 << HAS_MMX_PLUS << std::endl; 76 std::cout << "Processor supports SSE instructions: " 77 << HAS_SSE << std::endl; 78 std::cout << "Processor supports SSE2 instructions: " 79 << HAS_SSE2 << std::endl; 80 std::cout << "Processor supports SSE FP instructions: " 81 << HAS_SSE_FP << std::endl; 82 std::cout << "Processor supports SSE MMX instructions: " 83 << HAS_SSE_MMX << std::endl; 84 std::cout << "Processor supports 3DNow instructions: " 85 << HAS_AMD_3DNOW << std::endl; 86 std::cout << "Processor supports 3DNow+ instructions: " 87 << HAS_AMD_3DNOW_PLUS << std::endl; 88 std::cout << "IA64 processor emulating x86 : " 89 << HAS_IA64 << std::endl; 90 std::cout << "OS name: " 91 << OS_NAME << std::endl; 92 std::cout << "OS sub-type: " 93 << OS_RELEASE << std::endl; 94 std::cout << "OS build ID: " 95 << OS_VERSION << std::endl; 96 std::cout << "OS platform: " 97 << OS_PLATFORM << std::endl; 98 } 99 100 int main() 101 { 102 say_hello(); 103 std::cout << "compiler name is " << COMPILER_NAME << std::endl; 104 return EXIT_SUCCESS; 105 }
1 /** 2 * @file config.h.in 3 */ 4 #ifndef CONFIG_H 5 #define CONFIG_H 6 7 #define NUMBER_OF_LOGICAL_CORES "@_NUMBER_OF_LOGICAL_CORES@" 8 #define NUMBER_OF_PHYSICAL_CORES "@_NUMBER_OF_PHYSICAL_CORES@" 9 #define TOTAL_VIRTUAL_MEMORY "@_TOTAL_VIRTUAL_MEMORY@" 10 #define AVAILABLE_VIRTUAL_MEMORY "@_AVAILABLE_VIRTUAL_MEMORY@" 11 #define TOTAL_PHYSICAL_MEMORY "@_TOTAL_PHYSICAL_MEMORY@" 12 #define AVAILABLE_PHYSICAL_MEMORY "@_AVAILABLE_PHYSICAL_MEMORY@" 13 #define IS_64BIT "@_IS_64BIT@" 14 #define HAS_FPU "@_HAS_FPU@" 15 #define HAS_MMX "@_HAS_MMX@" 16 #define HAS_MMX_PLUS "@_HAS_MMX_PLUS@" 17 #define HAS_SSE "@_HAS_SSE@" 18 #define HAS_SSE2 "@_HAS_SSE2@" 19 #define HAS_SSE_FP "@_HAS_SSE_FP@" 20 #define HAS_SSE_MMX "@_HAS_SSE_MMX@" 21 #define HAS_AMD_3DNOW "@_HAS_AMD_3DNOW@" 22 #define HAS_AMD_3DNOW_PLUS "@_HAS_AMD_3DNOW_PLUS@" 23 #define HAS_IA64 "@_HAS_IA64@" 24 #define OS_NAME "@_OS_NAME@" 25 #define OS_RELEASE "@_OS_RELEASE@" 26 #define OS_VERSION "@_OS_VERSION@" 27 #define OS_PLATFORM "@_OS_PLATFORM@" 28 29 #endif // CONFIG_H
CMakeLists.txt内容:
1 cmake_minimum_required(VERSION 3.21 FATAL_ERROR) 2 project(CmakeTest LANGUAGES CXX) 3 4 #add_executable(${PROJECT_NAME} main.cpp) 5 add_executable(${PROJECT_NAME} "") 6 7 # add_definitions:会修改编译整个项目的定义 8 # target_compile_definitions:将定义限制于一个特定的目标,以及通过PRIVATE|PUBLIC|INTERFACE限定符,限制这些定义可见性。 9 # PRIVATE:编译定义将只应用于给定的目标,而不应用于相关的其他目标。 10 # INTERFACE:对给定目标的编译定义将只应用于使用它的目标。 11 # PUBLIC:编译定义将应用于给定的目标和使用它的所有其他目标。 12 13 # 检测操作系统 14 if(CMAKE_SYSTEM_NAME STREQUAL "Linux") 15 target_compile_definitions(${PROJECT_NAME} PUBLIC "IS_LINUX") 16 endif() 17 if(CMAKE_SYSTEM_NAME STREQUAL "Darwin") 18 target_compile_definitions(${PROJECT_NAME} PUBLIC "IS_MACOS") 19 endif() 20 if(CMAKE_SYSTEM_NAME STREQUAL "Windows") 21 target_compile_definitions(${PROJECT_NAME} PUBLIC "IS_WINDOWS") 22 endif() 23 24 # 检测编译器 25 # CMAKE_<LANG>_COMPILER_ID不能保证为所有编译器或语言都定义 26 target_compile_definitions(${PROJECT_NAME} PUBLIC "COMPILER_NAME=\"${CMAKE_CXX_COMPILER_ID}\"") 27 28 if(CMAKE_CXX_COMPILER_ID MATCHES Intel) 29 target_compile_definitions(${PROJECT_NAME} PUBLIC "IS_INTEL_CXX_COMPILER") 30 endif() 31 if(CMAKE_CXX_COMPILER_ID MATCHES GNU) 32 target_compile_definitions(${PROJECT_NAME} PUBLIC "IS_GNU_CXX_COMPILER") 33 endif() 34 if(CMAKE_CXX_COMPILER_ID MATCHES PGI) 35 target_compile_definitions(${PROJECT_NAME} PUBLIC "IS_PGI_CXX_COMPILER") 36 endif() 37 if(CMAKE_CXX_COMPILER_ID MATCHES XL) 38 target_compile_definitions(${PROJECT_NAME} PUBLIC "IS_XL_CXX_COMPILER") 39 endif() 40 41 # 检测处理器体系 42 # 使用CMAKE_SIZEOF_VOID_P是检查当前CPU是否具有32位或64位架构的唯一“真正”可移植的方法 43 if(CMAKE_SIZEOF_VOID_P EQUAL 8) 44 target_compile_definitions(${PROJECT_NAME} PUBLIC "IS_64_BIT_ARCH") 45 message(STATUS "Target is 64 bits") 46 else() 47 target_compile_definitions(${PROJECT_NAME} PUBLIC "IS_32_BIT_ARCH") 48 message(STATUS "Target is 32 bits") 49 endif() 50 51 if(CMAKE_HOST_SYSTEM_PROCESSOR MATCHES "i386") 52 message(STATUS "i386 architecture detected") 53 elseif(CMAKE_HOST_SYSTEM_PROCESSOR MATCHES "i686") 54 message(STATUS "i686 architecture detected") 55 elseif(CMAKE_HOST_SYSTEM_PROCESSOR MATCHES "AMD64") 56 message(STATUS "AMD64 architecture detected") 57 elseif(CMAKE_HOST_SYSTEM_PROCESSOR MATCHES "x86_64") 58 message(STATUS "x86_64 architecture detected") 59 else() 60 message(STATUS "host processor architecture is unknown") 61 endif() 62 target_compile_definitions(${PROJECT_NAME} PUBLIC "ARCHITECTURE=${CMAKE_HOST_SYSTEM_PROCESSOR}") 63 64 target_sources(${PROJECT_NAME} 65 PRIVATE 66 main.cpp 67 ) 68 target_include_directories(${PROJECT_NAME} 69 PRIVATE 70 ${PROJECT_BINARY_DIR} 71 ) 72 73 foreach(key 74 IN ITEMS 75 NUMBER_OF_LOGICAL_CORES 76 NUMBER_OF_PHYSICAL_CORES 77 TOTAL_VIRTUAL_MEMORY 78 AVAILABLE_VIRTUAL_MEMORY 79 TOTAL_PHYSICAL_MEMORY 80 AVAILABLE_PHYSICAL_MEMORY 81 IS_64BIT 82 HAS_FPU 83 HAS_MMX 84 HAS_MMX_PLUS 85 HAS_SSE 86 HAS_SSE2 87 HAS_SSE_FP 88 HAS_SSE_MMX 89 HAS_AMD_3DNOW 90 HAS_AMD_3DNOW_PLUS 91 HAS_IA64 92 OS_NAME 93 OS_RELEASE 94 OS_VERSION 95 OS_PLATFORM 96 ) 97 cmake_host_system_information(RESULT _${key} QUERY ${key}) 98 endforeach() 99 100 configure_file(config.h.in config.h @ONLY)