CMake基础教程二

news2024/11/25 4:36:52
常用 
环境变量 SET(ENV{VAR} VALUE)

**常用变量:**

| 变量名                        | 含义                                                                  |
| ----------------------------- | --------------------------------------------------------------------- |
| **PROJECT_NAME**              | `project`命令中写的项目名                                             |
| **CMAKE_VERSION**             | 当前使用 CMake 的版本                                                 |
| **CMAKE_SOURCE_DIR**          | 工程顶层目录,即入口 CMakeLists 文件所在路径                          |
| **PROJECT_SOURCE_DIR**        | 同**CMAKE_SOURCE_DIR**                                                |
| **CMAKE_BINARY_DIR**          | 工程编译发生的目录,即执行 cmake 命令进行项目配置的目录,一般为 build |
| **PROJECT_BINARY_DIR**        | 同**CMAKE_BINARY_DIR**                                                |
| **CMAKE_CURRENT_SOURCE_DIR**  | 当前处理的 CMakeLists.txt 所在的路径                                  |
| **CMAKE_CURRRENT_BINARY_DIR** | 当前处理的 CMakeLists.txt 中生成目标文件所在编译目录                  |
| **CMAKE_CURRENT_LIST_FILE**   | 输出调用这个变量的 CMakeLists.txt 文件的完整路径                      |
| **CMAKE_CURRENT_LIST_DIR**    | 当前处理的 CMakeLists.txt 文件所在目录的路径                          |
| **CMAKE_INSTALL_PREFIX**      | 指定`make install`命令执行时包安装路径                                |
| **CMAKE_MODULE_PATH**         | `find_package`命令搜索包路径**之一**,默认为空                        |

**编译配置相关变量:**

| 变量名                 | 含义                                                                              |
| ---------------------- | --------------------------------------------------------------------------------- |
| **CMAKE_BUILD_TYPE**   | 编译选项,Release 或者 Debug,如`set(CMAKE_BUILD_TYPE "Release")`                 |
| **CMAKE_CXX_FLAGS**    | 编译标志,设置 C++11 编译,`set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")` |
| **CMAKE_CXX_STANDARD** | 也可以设置 C++11 编译,`set(CMAKE_CXX_STANDARD 11)`                               |

list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake")

# 依赖库fetch
include(FetchContent)
FetchContent_Declare(
 googletest
 GIT_REPOSITORY https://github.com/google/googletest.git
 GIT_TAG release-1.8.0
)
FetchContent_GetProperties(googletest)
if(NOT googletest_POPULATED)
 FetchContent_Populate(googletest)
 # ...
 # adds the targets: gtest, gtest_main, gmock, gmock_main
 add_subdirectory(
   ${googletest_SOURCE_DIR}
   ${googletest_BINARY_DIR}
   )
 # ...
endif()

# 检测系统
if(CMAKE_SYSTEM_NAME STREQUAL "Linux")
message(STATUS "Configuring on/for Linux")
elseif(CMAKE_SYSTEM_NAME STREQUAL "Darwin")
message(STATUS "Configuring on/for macOS")
elseif(CMAKE_SYSTEM_NAME STREQUAL "Windows")
message(STATUS "Configuring on/for Windows")
elseif(CMAKE_SYSTEM_NAME STREQUAL "AIX")
message(STATUS "Configuring on/for IBM AIX")
else()
message(STATUS "Configuring on/for ${CMAKE_SYSTEM_NAME}")
endif()
  
#ifdef IS_32_BIT_ARCH
  return arch_info + std::string("Compiled on a 32 bit host processor.");
#elif IS_64_BIT_ARCH
  return arch_info + std::string("Compiled on a 64 bit host processor.");
#else
  return arch_info + std::string("Neither 32 nor 64 bit, puzzling ...");
#endif

if(CMAKE_SIZEOF_VOID_P EQUAL 8)
 target_compile_definitions(arch-dependent PUBLIC "IS_64_BIT_ARCH")
 message(STATUS "Target is 64 bits")
else()
 target_compile_definitions(arch-dependent PUBLIC "IS_32_BIT_ARCH")
 message(STATUS "Target is 32 bits")
endif()

if(CMAKE_HOST_SYSTEM_PROCESSOR MATCHES "i386")
message(STATUS "i386 architecture detected")
elseif(CMAKE_HOST_SYSTEM_PROCESSOR MATCHES "i686")
message(STATUS "i686 architecture detected")
elseif(CMAKE_HOST_SYSTEM_PROCESSOR MATCHES "x86_64")
message(STATUS "x86_64 architecture detected")
else()
message(STATUS "host processor architecture is unknown")
endif()
target_compile_definitions(arch-dependent
 PUBLIC "ARCHITECTURE=${CMAKE_HOST_SYSTEM_PROCESSOR}"
 )
 
#外部检测
execute_process(
 COMMAND
	${PYTHON_EXECUTABLE} "-c" "print('Hello, world!')"
 RESULT_VARIABLE _status
 OUTPUT_VARIABLE _hello_world
 ERROR_QUIET
 OUTPUT_STRIP_TRAILING_WHITESPACE
 )
 
message(STATUS "RESULT_VARIABLE is: ${_status}")
message(STATUS "OUTPUT_VARIABLE is: ${_hello_world}")
cmake -D PYTHON_EXECUTABLE=/custom/location/python ..
cmake -D BOOST_INCLUDEDIR=/custom/boost/include -DBOOST_LIBRARYDIR=/custom/boost/lib

#配置生成源码
#include <stdio.h>
#include <unistd.h>

void print_info(void)
{
  printf("\n");
  printf("Configuration and build information\n");
  printf("-----------------------------------\n");
  printf("\n");
  printf("Who compiled | %s\n", "@_user_name@");
  printf("Compilation hostname | %s\n", "@_host_name@");
  printf("Fully qualified domain name | %s\n", "@_fqdn@");
  printf("Operating system | %s\n",
         "@_os_name@, @_os_release@, @_os_version@");
  printf("Platform | %s\n", "@_os_platform@");
  printf("Processor info | %s\n",
         "@_processor_name@, @_processor_description@");
  printf("CMake version | %s\n", "@CMAKE_VERSION@");
  printf("CMake generator | %s\n", "@CMAKE_GENERATOR@");
  printf("Configuration time | %s\n", "@_configuration_time@");
  printf("Fortran compiler | %s\n", "@CMAKE_Fortran_COMPILER@");
  printf("C compiler | %s\n", "@CMAKE_C_COMPILER@");
  printf("\n");

  fflush(stdout);
}
configure_file(print_info.c.in print_info.c @ONLY)
target_sources(example
 PRIVATE
   example.f90
   ${CMAKE_CURRENT_BINARY_DIR}/print_info.c
 )
 
# 生成SDK
include(GNUInstallDirs)
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY
${PROJECT_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR})
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY
${PROJECT_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR})
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY
${PROJECT_BINARY_DIR}/${CMAKE_INSTALL_BINDIR})

# Offer the user the choice of overriding the installation directories
set(INSTALL_LIBDIR ${CMAKE_INSTALL_LIBDIR} CACHE PATH "Installation directory for libraries")
set(INSTALL_BINDIR ${CMAKE_INSTALL_BINDIR} CACHE PATH "Installation directory for executables")
set(INSTALL_INCLUDEDIR ${CMAKE_INSTALL_INCLUDEDIR} CACHE PATH "Installation directory for header files")
if(WIN32 AND NOT CYGWIN)
set(DEF_INSTALL_CMAKEDIR CMake)
else()
set(DEF_INSTALL_CMAKEDIR share/cmake/${PROJECT_NAME})
endif()
set(INSTALL_CMAKEDIR ${DEF_INSTALL_CMAKEDIR} CACHE PATH "Installation directory for CMake files")

# Report to user
foreach(p LIB BIN INCLUDE CMAKE)
 file(TO_NATIVE_PATH ${CMAKE_INSTALL_PREFIX}/${INSTALL_${p}DIR} _path )
 message(STATUS "Installing ${p} components to ${_path}")
 unset(_path)
endforeach()

# rpath
file(RELATIVE_PATH _rel ${CMAKE_INSTALL_PREFIX}/${INSTALL_BINDIR} ${CMAKE_INSTALL_PREFIX})
if(APPLE)
set(_rpath "@loader_path/${_rel}")
else()
set(_rpath "\$ORIGIN/${_rel}")
endif()
file(TO_NATIVE_PATH "${_rpath}/${INSTALL_LIBDIR}" message_RPATH)

set_target_properties(hello-world_wDSO
 PROPERTIES
   MACOSX_RPATH ON
   SKIP_BUILD_RPATH OFF
   BUILD_WITH_INSTALL_RPATH OFF
   INSTALL_RPATH "${message_RPATH}"
   INSTALL_RPATH_USE_LINK_PATH ON
 )
 
install(
 TARGETS
   message-shared
   hello-world_wDSO
 ARCHIVE
   DESTINATION ${INSTALL_LIBDIR}
   COMPONENT lib
 RUNTIME
   DESTINATION ${INSTALL_BINDIR}
   COMPONENT bin
 LIBRARY
   DESTINATION ${INSTALL_LIBDIR}
   COMPONENT lib
 PUBLIC_HEADER
   DESTINATION ${INSTALL_INCLUDEDIR}/message
   COMPONENT dev
 )
 
if(WIN32 OR MINGW)
  list(APPEND CPACK_GENERATOR "NSIS")
  set(CPACK_NSIS_PACKAGE_NAME "message")
  set(CPACK_NSIS_CONTACT "robertdr")
  set(CPACK_NSIS_ENABLE_UNINSTALL_BEFORE_INSTALL ON)
endif()
message(STATUS "CPack generators: ${CPACK_GENERATOR}")
include(CPack)
set(CPACK_SOURCE_GENERATOR "TGZ;ZIP")
set(CPACK_SOURCE_IGNORE_FILES
    /.git
    /dist
    /.*build.*
    /\\\\.DS_Store
)
set(CMAKE_EXPORT_PACKAGE_REGISTRY ON)
export(PACKAGE MyLib)

#交叉编译
set(CMAKE_SYSTEM_NAME Windows)
set(CMAKE_SYSTEM_PROCESSOR arm)
set(CMAKE_C_COMPILER i686-w64-mingw32-gcc)
set(CMAKE_CXX_COMPILER i686-w64-mingw32-g++)
set(CMAKE_C_COMPILER clang)
set(CMAKE_CXX_COMPILER clang++)
set(CMAKE_Fortran_COMPILER i686-w64-mingw32-gfortran)

#submodule
find_package(Git QUIET)
if(GIT_FOUND AND EXISTS "${PROJECT_SOURCE_DIR}/.git")
# Update submodules as needed
    option(GIT_SUBMODULE "Check submodules during build" ON)
    if(GIT_SUBMODULE)
        message(STATUS "Submodule update")
        execute_process(COMMAND ${GIT_EXECUTABLE} submodule update --init --recursive
                        WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
                        RESULT_VARIABLE GIT_SUBMOD_RESULT)
        if(NOT GIT_SUBMOD_RESULT EQUAL "0")
            message(FATAL_ERROR "git submodule update --init --recursive failed with ${GIT_SUBMOD_RESULT}, please checkout submodules")
        endif()
    endif()
endif()

if(NOT EXISTS "${PROJECT_SOURCE_DIR}/extern/repo/CMakeLists.txt")
    message(FATAL_ERROR "The submodules were not downloaded! GIT_SUBMODULE was turned off or failed. Please update submodules and try again.")
endif()
参考 

https://github.com/wx-chevalier/CMake-Notes

CMake基础教程_cmake -b build-CSDN博客


创作不易,小小的支持一下吧!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1992722.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Bitwise 首席投资官:忽略短期的市场波动,关注加密货币的发展前景

原文标题&#xff1a;《The Crypto Market Sell-Off: What Happened and Where We Go From Here》撰文&#xff1a;Matt Hougan&#xff0c;Bitwise 首席投资官编译&#xff1a;Chris&#xff0c;Techub News 加密货币市场在周末经历了大幅下跌。从上周五下午 4 点到周一早上 7…

2024年下软考报名全流程+备考指南(八月最新版)

2024年下半年软考备考&#xff0c;一定要知道这几点&#xff01; 2024年下半年软考报名已迫在眉睫&#xff0c;不知不觉间&#xff0c;留给下半年考试小伙伴们的复习时间只有三个月。备考的小伙伴们准备好了吗&#xff1f;这些全程重点&#xff0c;请务必收藏保存&#xff0c;…

C/C++数字与字符串互相转换

前言&#xff1a; 在C/C程序中&#xff0c;会需要把数字与字符串做出互相转换的操作&#xff0c;用于实现程序想要的效果。下面将介绍多种方法实现数字与字符串互相转换。 字符串转为数字 一、利用ASCII 我们知道每个字符都有一个ASCII码&#xff0c;利用这一点可以将字符-0…

vue文件style标签变成黄色,media query is expected

效果如下图所示&#xff0c;红色波浪线&#xff0c;鼠标放上去提示 media query is expected 对比其他文件后发现是引入scss文件后后面少了分号&#xff0c;导致报错&#xff0c;加上分号&#xff0c;效果如下图&#xff0c;完美解决~

文件操作常用函数及makefile的使用

文件操作中常用函数 1. getpwuid 定义: struct passwd *getpwuid(uid_t uid);功能: 根据用户ID&#xff08;UID&#xff09;返回与之对应的passwd结构体指针&#xff0c;该结构体包含用户的详细信息。常用字段: pw_name: 用户名。pw_uid: 用户ID。pw_gid: 用户的组ID。pw_dir…

Qt实现类似淘宝商品看板的界面,带有循环翻页以及点击某页跳转的功能

效果如下&#xff1a; #ifndef ModelDashboardGroup_h__ #define ModelDashboardGroup_h__#include <QGridLayout> #include <QLabel> #include <QPushButton> #include <QWidget>#include <QLabel> #include <QWidget> #include <QMou…

Jenkins保姆笔记(3)——Jenkins拉取Git代码、编译、打包、远程多服务器部署Spring Boot项目

前面我们介绍过&#xff1a; Jenkins保姆笔记&#xff08;1&#xff09;——基于Java8的Jenkins安装部署 Jenkins保姆笔记&#xff08;2&#xff09;——基于Java8的Jenkins插件安装 本篇主要介绍基于Java8的Jenkins第一个Hello World项目&#xff0c;一起实践下Jenkins拉…

第十九节 大语言模型与多模态大模型loss计算

文章目录 前言一、大语言模型loss计算1、loss计算代码解读2、构建模型输入内容与label标签二、多模态大模型loss计算方法1、多模态loss计算代码解读2、多模态输入内容2、大语言模型输入内容3、图像embending如何嵌入文本embeding前言 如果看了我前面文章,想必你基本对整个代码…

Java学习Day24:基础篇14:多线程

1.程序、进程和线程 程序 进程 进程(process)是程序的一次执行过程&#xff0c;或是一个正在执行的程序。是一个动态的过程&#xff1a;有它自身的产 生、存在和消亡的过程。 如&#xff1a; 运行中的QQ运行中的音乐播放器视频播放器等&#xff1b;程序是静态的&#xff0c…

写给小白程序员的一封信

文章目录 1.编程小白如何成为大神&#xff1f;大学新生的最佳入门攻略2.程序员的练级攻略3.编程语言的选择4.熟悉Linux5.学会git6.知道在哪寻求帮助7.多结交朋友8.参加开源项目9.坚持下去 1.编程小白如何成为大神&#xff1f;大学新生的最佳入门攻略 编程已成为当代大学生的必…

音视频开发,最新学习心得与感悟

音视频技术的知识海洋浩瀚无垠&#xff0c;自学之路显得尤为崎岖&#xff0c;技术门槛的存在是毋庸置疑的事实。 对于渴望踏入这一行业的初学者而言&#xff0c;学习资源的匮乏成为了一道难以逾越的障碍。 本次文章主要是给大家分享音视频开发进阶学习路线&#xff0c;虽然我…

三大口诀不一样的代码,小小的制表符和换行符玩的溜呀

# 小案例&#xff0c;打印输出加法口诀 for i in range(1,10):for j in range(1,10):if j>i:breakprint(f"{j}{i}{ji}".strip(),end\t)print() print(\n) for i in range(1,10):for j in range(1,10):if j>i:breakprint(f"{j}x{i}{j*i}",end\t)print…

[Spring] Spring AOP

&#x1f338;个人主页:https://blog.csdn.net/2301_80050796?spm1000.2115.3001.5343 &#x1f3f5;️热门专栏: &#x1f9ca; Java基本语法(97平均质量分)https://blog.csdn.net/2301_80050796/category_12615970.html?spm1001.2014.3001.5482 &#x1f355; Collection与…

【Linux】sudo提升权限(入门)

相关专栏&#xff1a;《Linux》 目录 1. sudo功能介绍 2. 任何人都能用 sudo 吗&#xff1f; &#xff08;1&#xff09;查看配置文件/etc/sudoers &#xff08;2&#xff09;修改/etc/sudoers提权 3. 改变sudo输入密码时间 4. 显示sudo 密码 5.常见 sudo 命令 -k 参数 …

ajax part4

图片上传 <!DOCTYPE html> <lang"en"><head>cmeta charset"UTF-8><meta http-equiv"X-UA-Compatibleb content" IEedge"><meta name"viewportR content" wiclthdevic6-widths initial-scalel. 0"&…

做报表用什么工具?不想再用Excel了!!!

一、什么是中国式报表&#xff1f; 不知道大家现在还是使用Excel来制作报表&#xff0c;然后跟领导汇报工作吗&#xff1f;虽然Excel功能很强大&#xff0c;但是用Excel做过中国式报表的小伙伴一定知道它的制作过程有多复杂。 中国式报表可以用一句话简单概括&#xff1a;格式…

C++笔试强训11

文章目录 一、选择题1-5题6-10题 二、编程题题目一题目二 一、选择题 1-5题 A. 不是任何一个函数都可定义成内联函数&#xff1a;这是正确的。因为内联函数需要在编译时展开&#xff0c;如果函数体过大或包含复杂的控制结构&#xff08;如循环、递归等&#xff09;&#xff0c…

Linux/C 高级——分文件编程

1.头文件&#xff1a;.h结尾的文件 头文件引用、宏定义、重命名typedef、结构体、共用体、枚举的定义、函数声明、外部引用extern。 一般全局变量不会定义在头文件中 2.源文件&#xff1a;.c结尾的文件 包含main函数的.c文件&#xff1a;main函数 包含子函数的.c文件&#xff1…

【LLM】-17-会话存储

目录 1、会话存储类型 2、版本代码说明 3、对话缓存存储 3.1、示例代码 3.2、响应response说明 3.3、流式输出 3.4、添加提示词模板 3.5、指定回答语言 4、限制令牌数存储 4.1、trim_messages 4.1.1、自定义tokens计数器 4.1.2、自定义tokens计数器 4.2、完整chat…

HookNet- 用于病理全切片图像的多分辨率语义分割模型|顶刊精析·24-08-08

小罗碎碎念 今天分享的这篇文章是关于一种名为HookNet的新型语义分割模型&#xff0c;它专为病理学全切片图像设计&#xff0c;于2021年发表于《Med Image Anal》&#xff0c;目前IF10.7。 作者角色姓名单位&#xff08;中文翻译&#xff09;第一作者Mart van Rijthoven荷兰Ra…