CMake:探究编译和编译命令

编程入门 行业动态 更新时间:2024-10-16 18:33:25

CMake:探究编译和编译<a href=https://www.elefans.com/category/jswz/34/1771323.html style=命令"/>

CMake:探究编译和编译命令

CMake:探究编译和编译命令

  • 导言
  • 项目结构
  • 相关源码
  • 结果

导言

本篇通过展示如何使用来自对应的Check<LANG>SourceCompiles.cmake标准模块的check_<lang>_source_compiles函数,以评估给定编译器是否可以将预定义的代码编译成可执行文件。该命令可帮助确定:

  • 编译器支持所需的特性。
  • 链接器工作正常,并理解特定的标志。
  • 可以使用find_package找到的包含目录和库。

我们将展示如何检测OpenMP 4.5标准的循环特性,以便在C++可执行文件中使用。使用一个C++源文件,来探测编译器是否支持这样的特性。CMake提供了一个附加命令try_compile来探究编译。

项目结构

├── CMakeLists.txt
└── task_loop.cpp

项目地址:

相关源码

CMakeLists.txt

cmake_minimum_required(VERSION 3.10 FATAL_ERROR)project(test LANGUAGES CXX)set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_EXTENSIONS OFF)
set(CMAKE_CXX_STANDARD_REQUIRED ON)find_package(OpenMP)if(OpenMP_FOUND)# this will get wiped unless you run cmake with --debug-trycompileset(scratch_dir ${CMAKE_CURRENT_BINARY_DIR}/omp_try_compile)try_compile(omp_task_loop_test_1${scratch_dir}SOURCES${CMAKE_CURRENT_SOURCE_DIR}/task_loop.cppLINK_LIBRARIESOpenMP::OpenMP_CXX)message(STATUS "Result of try_compile: ${omp_task_loop_test_1}")include(CheckCXXSourceCompiles)file(READ ${CMAKE_CURRENT_SOURCE_DIR}/task_loop.cpp snippet)set(CMAKE_REQUIRED_LIBRARIES OpenMP::OpenMP_CXX)check_cxx_source_compiles("${snippet}" omp_task_loop_test_2)unset(CMAKE_REQUIRED_LIBRARIES)message(STATUS "Result of check_cxx_source_compiles: ${omp_task_loop_test_2}")
else()message(STATUS "OpenMP not found: no test for taskloop is run")
endif()

方式一

set(scratch_dir ${CMAKE_CURRENT_BINARY_DIR}/omp_try_compile)

如果找到OpenMP,再检查所需的特性是否可用。为此,设置了一个临时目录,try_compile将在这个目录下来生成中间文件。我们把它放在前面步骤中引入的if语句中。如果我们构建时使用如下命令,则会在omp_try_compile文件夹中产生中间文件。

cmake .. --debug-trycompile

try_compile(omp_task_loop_test_1${scratch_dir}SOURCES${CMAKE_CURRENT_SOURCE_DIR}/task_loop.cppLINK_LIBRARIESOpenMP::OpenMP_CXX)message(STATUS "Result of try_compile: ${omp_task_loop_test_1}")

调用try_compile生成一个小项目,以尝试编译源文件task_loop.cpp。编译成功或失败的状态,将保存到omp_task_loop_test_1变量中。需要为这个示例编译设置适当的编译器标志、包括目录和链接库。因为使用导入的目标OpenMP::OpenMP_CXX,所以只需将LINK_LIBRARIES选项设置为OpenMP::OpenMP_CXX即可。如果编译成功,则任务循环特性可用,我们打印一条消息。

方式二

include(CheckCXXSourceCompiles)

要使用check_cxx_source_compiles函数,需要包含CheckCXXSourceCompiles.cmake模块文件。其他语言也有类似的模块文件,C(CheckCSourceCompiles.cmake)和Fortran(CheckFortranSourceCompiles.cmake)。

file(READ ${CMAKE_CURRENT_SOURCE_DIR}/task_loop.cpp snippet)

复制源文件的内容,通过file(READ ...)命令读取内容到一个变量中,试图编译和连接这个变量。

set(CMAKE_REQUIRED_LIBRARIES OpenMP::OpenMP_CXX)

设置了CMAKE_REQUIRED_LIBRARIES。对于下一步正确调用编译器是必需的。注意使用导入的OpenMP::OpenMP_CXX目标,它还将设置正确的编译器标志和包含目录。

check_cxx_source_compiles("${snippet}" omp_task_loop_test_2)

使用代码片段作为参数,调用check_cxx_source_compiles函数。检查结果将保存到omp_task_loop_test_2变量中。

unset(CMAKE_REQUIRED_LIBRARIES)
message(STATUS "Result of check_cxx_source_compiles: ${omp_task_loop_test_2}"

调用check_cxx_source_compiles并向用户打印消息之前,取消变量的设置。

task_loop.cpp

#include <cmath>
#include <iostream>void LongRunningTask() {double number = 5.0;double result = std::pow(number, 2);std::cout << "长时间运行的任务结果:" << result << std::endl;
}void LoopBody(int i, int j) {double calculation_result = std::sin(i) * std::cos(j);std::cout << "在循环体中计算结果:" << calculation_result << std::endl;
}void ParallelWork() {int i, j;
#pragma omp taskgroup{
#pragma omp taskLongRunningTask();  #pragma omp taskloop private(j) grainsize(500) nogroupfor (i = 0; i < 10000; i++) {  for (j = 0; j < i; j++) {LoopBody(i, j);}}}
}int main() {ParallelWork();return 0;
}

结果

$ mkdir -p build
$ cd build
$ cmake ..
-- ...
-- Found OpenMP_CXX: -fopenmp (found version "4.5")
-- Found OpenMP: TRUE (found version "4.5")
-- Result of try_compile: TRUE
-- Performing Test omp_taskloop_test_2
-- Performing Test omp_taskloop_test_2 - Success
-- Result of check_cxx_source_compiles: 1

最后,祝大家变得更强!!!

更多推荐

CMake:探究编译和编译命令

本文发布于:2023-11-30 13:17:42,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1650623.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:命令   CMake

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!