import{_ as r}from"./ValaxyMain.vue_vue_type_style_index_0_lang-bf8ee3fd.js";import{_ as d,p as u,c as _,w as e,o as C,a as l,b as n,d as s,e as h,r as o,f as D}from"./app-4433fae6.js";import"./YunFooter.vue_vue_type_script_setup_true_lang-80290804.js";import"./YunCard.vue_vue_type_style_index_0_lang-e4df850e.js";import"./YunPageHeader.vue_vue_type_script_setup_true_lang-80be03ea.js";const _s=JSON.parse('{"title":"Parallel201-1.现代 CMake 进阶指南","description":"","frontmatter":{"title":"Parallel201-1.现代 CMake 进阶指南","toc":true,"date":"2022-03-12T17:20:45.000Z","tags":["Cpp","CMake"],"categories":["笔记","Parallel101"],"cover":null},"headers":[{"level":2,"title":"命令行小技巧","slug":"命令行小技巧","link":"#命令行小技巧","children":[{"level":3,"title":"CMake 命令行构建流程 (-B)","slug":"cmake-命令行构建流程-b","link":"#cmake-命令行构建流程-b","children":[]},{"level":3,"title":"指定配置变量 (-D、-G)","slug":"指定配置变量-d、-g","link":"#指定配置变量-d、-g","children":[]}]},{"level":2,"title":"添加源文件","slug":"添加源文件","link":"#添加源文件","children":[{"level":3,"title":"多个源文件","slug":"多个源文件","link":"#多个源文件","children":[]},{"level":3,"title":"项目配置变量","slug":"项目配置变量","link":"#项目配置变量","children":[]},{"level":3,"title":"一份标准 CMakeLists.txt","slug":"一份标准-cmakelists-txt","link":"#一份标准-cmakelists-txt","children":[]}]},{"level":2,"title":"链接库文件","slug":"链接库文件","link":"#链接库文件","children":[]}],"relativePath":"pages/posts/note/parallel/Parallel201-1.md","path":"/home/runner/work/YlYZ/YlYZ/pages/posts/note/parallel/Parallel201-1.md","lastUpdated":1686297441000}'),c=JSON.parse('{"title":"Parallel201-1.现代 CMake 进阶指南","description":"","frontmatter":{"title":"Parallel201-1.现代 CMake 进阶指南","toc":true,"date":"2022-03-12T17:20:45.000Z","tags":["Cpp","CMake"],"categories":["笔记","Parallel101"],"cover":null},"headers":[{"level":2,"title":"命令行小技巧","slug":"命令行小技巧","link":"#命令行小技巧","children":[{"level":3,"title":"CMake 命令行构建流程 (-B)","slug":"cmake-命令行构建流程-b","link":"#cmake-命令行构建流程-b","children":[]},{"level":3,"title":"指定配置变量 (-D、-G)","slug":"指定配置变量-d、-g","link":"#指定配置变量-d、-g","children":[]}]},{"level":2,"title":"添加源文件","slug":"添加源文件","link":"#添加源文件","children":[{"level":3,"title":"多个源文件","slug":"多个源文件","link":"#多个源文件","children":[]},{"level":3,"title":"项目配置变量","slug":"项目配置变量","link":"#项目配置变量","children":[]},{"level":3,"title":"一份标准 CMakeLists.txt","slug":"一份标准-cmakelists-txt","link":"#一份标准-cmakelists-txt","children":[]}]},{"level":2,"title":"链接库文件","slug":"链接库文件","link":"#链接库文件","children":[]}],"relativePath":"pages/posts/note/parallel/Parallel201-1.md","path":"/home/runner/work/YlYZ/YlYZ/pages/posts/note/parallel/Parallel201-1.md","lastUpdated":1686297441000}'),m={name:"pages/posts/note/parallel/Parallel201-1.md",data(){return{data:c,frontmatter:c.frontmatter}},setup(){u("pageData",c)}},A=l("p",null,"Parallel201 笔记 + 课后作业,课程传送门:",-1),y={id:"命令行小技巧",tabindex:"-1"},k=l("p",null,"古代 CMake 指的是 CMake2.x 版本,现代 CMake 已经到了 3.x 版本,许多地方得到了简化",-1),F=l("blockquote",null,[l("p",null,"PS:本文提到的构建一般指编译")],-1),E={id:"cmake-命令行构建流程-b",tabindex:"-1"},g=l("p",null,"CMake 2.x",-1),f=l("div",{class:"language-cmake"},[l("span",{class:"copy"}),l("pre",{class:"shiki material-theme-palenight",tabindex:"0"},[l("code",null,[l("span",{class:"line"},[l("span",{style:{color:"#A6ACCD"}},"mkdir -p build")]),s(` `),l("span",{class:"line"},[l("span",{style:{color:"#A6ACCD"}},"cd build")]),s(` `),l("span",{class:"line"},[l("span",{style:{color:"#A6ACCD"}},"cmake .. "),l("span",{style:{color:"#676E95","font-style":"italic"}},"#依据上层目录的CMakeLists.txt在build目录下生成makefile、.slu等")]),s(` `),l("span",{class:"line"},[l("span",{style:{color:"#A6ACCD"}},"make -j4 "),l("span",{style:{color:"#676E95","font-style":"italic"}},"#make根据makefile四核心并行构建可执行文件")]),s(` `),l("span",{class:"line"},[l("span",{style:{color:"#A6ACCD"}},"sudo make install "),l("span",{style:{color:"#676E95","font-style":"italic"}},"#make根据makefile将生成的文件放到指定的位置")]),s(` `),l("span",{class:"line"},[l("span",{style:{color:"#A6ACCD"}}," "),l("span",{style:{color:"#676E95","font-style":"italic"}},"#make clean 可以清除make生成的构建文件")]),s(` `),l("span",{class:"line"})])])],-1),b=l("p",null,"CMake 3.x",-1),R=l("div",{class:"language-cmake"},[l("span",{class:"copy"}),l("pre",{class:"shiki material-theme-palenight",tabindex:"0"},[l("code",null,[l("span",{class:"line"},[l("span",{style:{color:"#A6ACCD"}},"cmake -B build "),l("span",{style:{color:"#676E95","font-style":"italic"}},"#在build目录下生成makefile、.slu等")]),s(` `),l("span",{class:"line"},[l("span",{style:{color:"#A6ACCD"}},"cmake --build build -j4 "),l("span",{style:{color:"#676E95","font-style":"italic"}},"#make -C build -j4, build为makefile所在目录, windows上会调用别的构建系统")]),s(` `),l("span",{class:"line"},[l("span",{style:{color:"#A6ACCD"}},"cmake --build build --"),l("span",{style:{color:"#89DDFF"}},"target"),l("span",{style:{color:"#A6ACCD"}}," install")]),s(` `),l("span",{class:"line"})])])],-1),x={id:"指定配置变量-d、-g",tabindex:"-1"},O=l("p",null,"cmake -B build 为配置阶段,生成 makefile、.slu, 在这个阶段可以指定一些生成规则",-1),N=l("ul",null,[l("li",null,[l("code",null,"-D"),s(":设置缓存变量,下一次 cmake -B build 时,之前的 -D 添加仍然会被保留")])],-1),M=l("blockquote",null,[l("p",null,"格式:-D VAR=VAL")],-1),I=l("div",{class:"language-cmake"},[l("span",{class:"copy"}),l("pre",{class:"shiki material-theme-palenight",tabindex:"0"},[l("code",null,[l("span",{class:"line"},[l("span",{style:{color:"#676E95","font-style":"italic"}},"#使用Release模式构建")]),s(` `),l("span",{class:"line"},[l("span",{style:{color:"#A6ACCD"}},"cmake -B build -DCMAKE_BUILD_TYPE=Release")]),s(` `),l("span",{class:"line"}),s(` `),l("span",{class:"line"},[l("span",{style:{color:"#676E95","font-style":"italic"}},"#指定安装路径/opt/openvdb-8.0(会安装到 /opt/openvdb-8.0/lib/libopenvdb.so)")]),s(` `),l("span",{class:"line"},[l("span",{style:{color:"#A6ACCD"}},"cmake -B build -DCMAKE_INSTALL_PREFIX=/opt/openvdb-8.0")]),s(` `),l("span",{class:"line"})])])],-1),P=l("ul",null,[l("li",null,[l("code",null,"-G"),s(":指定使用的构建系统")])],-1),v=l("div",{class:"language-cmake"},[l("span",{class:"copy"}),l("pre",{class:"shiki material-theme-palenight",tabindex:"0"},[l("code",null,[l("span",{class:"line"},[l("span",{style:{color:"#676E95","font-style":"italic"}},"#使用Ninja来进行构建")]),s(` `),l("span",{class:"line"},[l("span",{style:{color:"#A6ACCD"}},"cmake -GNinja -B build")]),s(` `),l("span",{class:"line"})])])],-1),L=l("blockquote",null,[l("p",null,"Ninja 是现代化的构建系统,跨平台,可多核心构建,速度优于 make;但是 CUDA toolkit 在 windows 上只允许用 MSBuild 进行构建")],-1),B={id:"添加源文件",tabindex:"-1"},S=l("p",null,"目录结构:",-1),U=l("div",{class:"language-"},[l("span",{class:"copy"}),l("pre",{class:"shiki material-theme-palenight",tabindex:"0"},[l("code",null,[l("span",{class:"line"},[l("span",{style:{color:"#A6ACCD"}},"--------------------")]),s(` `),l("span",{class:"line"},[l("span",{style:{color:"#A6ACCD"}}," - main.cpp")]),s(` `),l("span",{class:"line"},[l("span",{style:{color:"#A6ACCD"}}," - CMakeLists.txt")]),s(` `),l("span",{class:"line"},[l("span",{style:{color:"#A6ACCD"}})])])])],-1),T=l("p",null,"添加一个可执行文件 main 为构建目标,main 由 main.cpp 构建而成",-1),G=l("div",{class:"language-cmake"},[l("span",{class:"copy"}),l("pre",{class:"shiki material-theme-palenight",tabindex:"0"},[l("code",null,[l("span",{class:"line"},[l("span",{style:{color:"#89DDFF"}},"add_executable"),l("span",{style:{color:"#A6ACCD"}},"(main main.cpp)")]),s(` `),l("span",{class:"line"})])])],-1),j=l("p",null,"或者先添加一个可执行文件,然后添加源文件",-1),X=l("div",{class:"language-cmake"},[l("span",{class:"copy"}),l("pre",{class:"shiki material-theme-palenight",tabindex:"0"},[l("code",null,[l("span",{class:"line"},[l("span",{style:{color:"#89DDFF"}},"add_executable"),l("span",{style:{color:"#A6ACCD"}},"(main main.cpp)")]),s(` `),l("span",{class:"line"},[l("span",{style:{color:"#89DDFF"}},"target_sources"),l("span",{style:{color:"#A6ACCD"}},"(main PUBLIC main.cpp)")]),s(` `),l("span",{class:"line"})])])],-1),V={id:"多个源文件",tabindex:"-1"},w=l("p",null,"目录结构:",-1),$=l("div",{class:"language-"},[l("span",{class:"copy"}),l("pre",{class:"shiki material-theme-palenight",tabindex:"0"},[l("code",null,[l("span",{class:"line"},[l("span",{style:{color:"#A6ACCD"}},"--------------------")]),s(` `),l("span",{class:"line"},[l("span",{style:{color:"#A6ACCD"}}," - main.cpp")]),s(` `),l("span",{class:"line"},[l("span",{style:{color:"#A6ACCD"}}," - other.cpp")]),s(` `),l("span",{class:"line"},[l("span",{style:{color:"#A6ACCD"}}," - other.h")]),s(` `),l("span",{class:"line"},[l("span",{style:{color:"#A6ACCD"}}," - CMakeLists.txt")]),s(` `),l("span",{class:"line"},[l("span",{style:{color:"#A6ACCD"}})])])])],-1),Y={id:"一个个手动添加",tabindex:"-1"},J=l("div",{class:"language-cmake"},[l("span",{class:"copy"}),l("pre",{class:"shiki material-theme-palenight",tabindex:"0"},[l("code",null,[l("span",{class:"line"},[l("span",{style:{color:"#89DDFF"}},"add_executable"),l("span",{style:{color:"#A6ACCD"}},"(main main.cpp other.cpp)")]),s(` `),l("span",{class:"line"})])])],-1),K={id:"通过变量的方式",tabindex:"-1"},q=l("div",{class:"language-cmake"},[l("span",{class:"copy"}),l("pre",{class:"shiki material-theme-palenight",tabindex:"0"},[l("code",null,[l("span",{class:"line"},[l("span",{style:{color:"#89DDFF"}},"add_executable"),l("span",{style:{color:"#A6ACCD"}},"(main)")]),s(` `),l("span",{class:"line"},[l("span",{style:{color:"#89DDFF"}},"set"),l("span",{style:{color:"#A6ACCD"}},"(sources main.cpp other.cpp)")]),s(` `),l("span",{class:"line"},[l("span",{style:{color:"#89DDFF"}},"target_sources"),l("span",{style:{color:"#A6ACCD"}},"(main PUBLIC ${sources})")]),s(` `),l("span",{class:"line"})])])],-1),H=l("p",null,[s("main.cpp 中有"),l("code",null,'#include "other.h"'),s("所以上面不写 other.h 也是能正常构建的")],-1),z=l("p",null,'但是写上更好,写上之后 VS 的"Header Files"一栏就会出现 other.h 了',-1),W=l("p",null,"Tips:",-1),Z=l("ul",null,[l("li",null,"变量相当于文本替换,支持嵌套,且字符串中的${}也会发生替换")],-1),Q={id:"glob-实现批量添加源文件",tabindex:"-1"},ll=l("p",null,"使用 GLOB 自动查找当前目录下指定扩展名的文件",-1),sl=l("p",null,"GLOB 选项将会为所有匹配查询表达式的文件生成一个文件 list,并将该 list 存储进变量 variable 里",-1),el=l("div",{class:"language-cmake"},[l("span",{class:"copy"}),l("pre",{class:"shiki material-theme-palenight",tabindex:"0"},[l("code",null,[l("span",{class:"line"},[l("span",{style:{color:"#89DDFF"}},"add_executable"),l("span",{style:{color:"#A6ACCD"}},"(main)")]),s(` `),l("span",{class:"line"},[l("span",{style:{color:"#89DDFF"}},"file"),l("span",{style:{color:"#A6ACCD"}},"(GLOB sources *.cpp *.h)")]),s(` `),l("span",{class:"line"},[l("span",{style:{color:"#89DDFF"}},"target_sources"),l("span",{style:{color:"#A6ACCD"}},"(main PUBLIC ${sources})")]),s(` `),l("span",{class:"line"})])])],-1),al=l("p",null,"上面的 sources 变量只会在第一次 cmake -B build 时被赋值,之后如果不更改 CMakeLists.txt, 它就一直不变,即使创建了新的.cpp 文件",-1),nl=l("p",null,"为了让它每次 cmake -B build 时都会更新,加上 CONFIGURE_DEPENDS",-1),tl=l("div",{class:"language-cmake"},[l("span",{class:"copy"}),l("pre",{class:"shiki material-theme-palenight",tabindex:"0"},[l("code",null,[l("span",{class:"line"},[l("span",{style:{color:"#89DDFF"}},"add_executable"),l("span",{style:{color:"#A6ACCD"}},"(main)")]),s(` `),l("span",{class:"line"},[l("span",{style:{color:"#89DDFF"}},"file"),l("span",{style:{color:"#A6ACCD"}},"(GLOB sources CONFIGURE_DEPENDS *.cpp *.h)")]),s(` `),l("span",{class:"line"},[l("span",{style:{color:"#89DDFF"}},"target_sources"),l("span",{style:{color:"#A6ACCD"}},"(main PUBLIC ${sources})")]),s(` `),l("span",{class:"line"})])])],-1),ol=l("p",null,"另外 GLOB 只会搜索当前目录下的.cpp、.h, 如果源文件在子目录就不会被找到",-1),cl=l("p",null,"需要写子目录的查询表达式",-1),il=l("div",{class:"language-cmake"},[l("span",{class:"copy"}),l("pre",{class:"shiki material-theme-palenight",tabindex:"0"},[l("code",null,[l("span",{class:"line"},[l("span",{style:{color:"#89DDFF"}},"add_executable"),l("span",{style:{color:"#A6ACCD"}},"(main)")]),s(` `),l("span",{class:"line"},[l("span",{style:{color:"#89DDFF"}},"file"),l("span",{style:{color:"#A6ACCD"}},"(GLOB sources CONFIGURE_DEPENDS *.cpp *.h 子目录/*.cpp 子目录/*.h)")]),s(` `),l("span",{class:"line"},[l("span",{style:{color:"#89DDFF"}},"target_sources"),l("span",{style:{color:"#A6ACCD"}},"(main PUBLIC ${sources})")]),s(` `),l("span",{class:"line"})])])],-1),pl=l("p",null,"或者使用 GLOB_RECURSE, 这样会找到子目录下的.cpp、.h",-1),rl=l("p",null,[s("但也会找到 build 目录下 cmake 构建时用于测试的临时.cpp 文件,所以推荐将源码全放在 src 文件夹下,然后使用 src/"),l("em",null,".cpp、src/"),s(".h")],-1),dl=l("div",{class:"language-cmake"},[l("span",{class:"copy"}),l("pre",{class:"shiki material-theme-palenight",tabindex:"0"},[l("code",null,[l("span",{class:"line"},[l("span",{style:{color:"#676E95","font-style":"italic"}},"#add_executable(main)")]),s(` `),l("span",{class:"line"},[l("span",{style:{color:"#676E95","font-style":"italic"}},"#file(GLOB_RECURSE sources CONFIGURE_DEPENDS *.cpp *.h)")]),s(` `),l("span",{class:"line"},[l("span",{style:{color:"#676E95","font-style":"italic"}},"#target_sources(main PUBLIC ${sources})")]),s(` `),l("span",{class:"line"}),s(` `),l("span",{class:"line"},[l("span",{style:{color:"#89DDFF"}},"add_executable"),l("span",{style:{color:"#A6ACCD"}},"(main)")]),s(` `),l("span",{class:"line"},[l("span",{style:{color:"#89DDFF"}},"file"),l("span",{style:{color:"#A6ACCD"}},"(GLOB_RECURSE sources CONFIGURE_DEPENDS src/*.cpp src/*.h)")]),s(` `),l("span",{class:"line"},[l("span",{style:{color:"#89DDFF"}},"target_sources"),l("span",{style:{color:"#A6ACCD"}},"(main PUBLIC ${sources})")]),s(` `),l("span",{class:"line"})])])],-1),ul=l("blockquote",null,[l("p",null,"文件名查询表达式与正则表达式类似。如果为一个表达式指定了 RELATIVE 标志,返回的结果将会是相对于给定路径的相对路径。")],-1),_l=l("p",null,"文件名查询表达式的例子:",-1),Cl=l("div",{class:"language-"},[l("span",{class:"copy"}),l("pre",{class:"shiki material-theme-palenight",tabindex:"0"},[l("code",null,[l("span",{class:"line"},[l("span",{style:{color:"#A6ACCD"}},"*.cxx - 匹配所有后缀名为 cxx 的文件")]),s(` `),l("span",{class:"line"},[l("span",{style:{color:"#A6ACCD"}},"*.vt? - 匹配所有后缀名为 vta,...,vtz 的文件")]),s(` `),l("span",{class:"line"},[l("span",{style:{color:"#A6ACCD"}},"f[3-5].txt - 匹配 f3.txt, f4.txt, f5.txt 文件")]),s(` `),l("span",{class:"line"},[l("span",{style:{color:"#A6ACCD"}})])])])],-1),hl={id:"aux-source-directory-自动收集需要的文件后缀名",tabindex:"-1"},Dl=l("div",{class:"language-cmake"},[l("span",{class:"copy"}),l("pre",{class:"shiki material-theme-palenight",tabindex:"0"},[l("code",null,[l("span",{class:"line"},[l("span",{style:{color:"#89DDFF"}},"add_executable"),l("span",{style:{color:"#A6ACCD"}},"(main)")]),s(` `),l("span",{class:"line"},[l("span",{style:{color:"#89DDFF"}},"aux_source_directory"),l("span",{style:{color:"#A6ACCD"}},"(. sources)")]),s(` `),l("span",{class:"line"},[l("span",{style:{color:"#89DDFF"}},"aux_source_directory"),l("span",{style:{color:"#A6ACCD"}},"(子目录 sources)")]),s(` `),l("span",{class:"line"},[l("span",{style:{color:"#89DDFF"}},"target_sources"),l("span",{style:{color:"#A6ACCD"}},"(main PUBLIC ${sources})")]),s(` `),l("span",{class:"line"})])])],-1),ml={id:"项目配置变量",tabindex:"-1"},Al={id:"cmake-build-type-项目构建类型",tabindex:"-1"},yl=l("div",{class:"language-cmake"},[l("span",{class:"copy"}),l("pre",{class:"shiki material-theme-palenight",tabindex:"0"},[l("code",null,[l("span",{class:"line"},[l("span",{style:{color:"#89DDFF"}},"cmake_minimum_required"),l("span",{style:{color:"#A6ACCD"}},"(VERSION 3.15)")]),s(` `),l("span",{class:"line"}),s(` `),l("span",{class:"line"},[l("span",{style:{color:"#89DDFF"}},"project"),l("span",{style:{color:"#A6ACCD"}},"(hellocmake LANGUAGES CXX)")]),s(` `),l("span",{class:"line"}),s(` `),l("span",{class:"line"},[l("span",{style:{color:"#89DDFF"}},"set"),l("span",{style:{color:"#A6ACCD"}},"(CMAKE_BUILD_TYPE Release)")]),s(` `),l("span",{class:"line"}),s(` `),l("span",{class:"line"},[l("span",{style:{color:"#89DDFF"}},"add_executable"),l("span",{style:{color:"#A6ACCD"}},"(main main.cpp)")]),s(` `),l("span",{class:"line"})])])],-1),kl=l("p",null,"项目构建类型与对应的编译器参数 (以 g++为例)",-1),Fl=l("ul",null,[l("li",null,[l("p",null,[s("Debug: "),l("code",null,"-O0 -g")])]),l("li",null,[l("p",null,[s("Release: "),l("code",null,"-O3 -DNDEBUG")])]),l("li",null,[l("p",null,[s("MinSizeRel: "),l("code",null,"-Os -DNDEBUG")])]),l("li",null,[l("p",null,[s("RelWithDebInfo: "),l("code",null,"-O2 -g -DNDEBUG")])])],-1),El=l("p",null,"NDEBUG 是一个 c 语言的一个宏,如果#define NDEBUG 将会移除 assert(), -DNDEBUG 就相当于定义这个宏",-1),gl=l("p",null,[l("strong",null,"这个写法就跟 cmake -B build -DVAR=VAL 一样")],-1),fl=l("p",null,"Tips: 如何设定变量的默认值",-1),bl=l("ul",null,[l("li",null,[l("p",null,"默认情况下,CMAKE_BUILD_TYPE 未指定的话会默认为 Debug, 若想默认为 Release:"),l("div",{class:"language-cmake"},[l("span",{class:"copy"}),l("pre",{class:"shiki material-theme-palenight",tabindex:"0"},[l("code",null,[l("span",{class:"line"},[l("span",{style:{color:"#89DDFF"}},"if"),l("span",{style:{color:"#A6ACCD"}}," ("),l("span",{style:{color:"#89DDFF"}},"NOT"),l("span",{style:{color:"#A6ACCD"}}," CMAKE_BUILD_TYPE)")]),s(` `),l("span",{class:"line"},[l("span",{style:{color:"#89DDFF"}}," set"),l("span",{style:{color:"#A6ACCD"}},"(CMAKE_BUILD_TYPE Release)")]),s(` `),l("span",{class:"line"},[l("span",{style:{color:"#89DDFF"}},"endif"),l("span",{style:{color:"#A6ACCD"}},"()")]),s(` `),l("span",{class:"line"})])])])])],-1),Rl={id:"project-初始化,项目名",tabindex:"-1"},xl=l("p",null,"project 可以命名项目,并把当前目录作为项目根目录,并提供一系列可用的变量",-1),Ol=l("ul",null,[l("li",null,[l("p",null,"PROJECT_NAME: 当前项目名")]),l("li",null,[l("p",null,"PROJECT_SOURCE_DIR: 当前项目源码目录,表示最近一次调用 project 的 CMakeLists.txt 所在的源码目录")]),l("li",null,[l("p",null,[s("PROJECT_BINARY_DIR: 二进制文件的生成目录,由"),l("code",null,"cmake -B"),s("指定,PROJECT_BINARY_DIR 会变成指定的目录路径")])]),l("li",null,[l("p",null,"PROJECT_IS_TOP_LEVEL: 可以判断当前项目是不是顶层的项目,BOOL 类型")]),l("li",null,[l("p",null,"CMAKE_PROJECT_NAME: 根项目名")]),l("li",null,[l("p",null,"CMAKE_SOURCE_DIR: 根项目源码目录")]),l("li",null,[l("p",null,"CMAKE_BINARY_DIR: 根项目二进制文件生成目录")]),l("li",null,[l("p",null,"CMAKE_CURRENT_SOURCE_DIR: 当前 CMakeLists.txt 所在源码目录")]),l("li",null,[l("p",null,"CMAKE_CURRENT_BINARY_DIR: 当前 CMakeLists.txt 构建的二进制文件生成目录")])],-1),Nl=l("p",null,"详情:",-1),Ml=l("p",null,[s("可以在子模块里使用 project 命令,将当前目录作为一个独立的子项目,这样一来 PROJECT_SOURCE_DIR 就会是子模块的源码目录而不是外层了。CMake 会认为这个子模块是个独立的项目,会额外做一些初始化,他的构建目录 PROJECT_BINARY_DIR 也会变成 "),l("code",null,"build/<源码相对路径>"),s(", 如在 MSVC 上会看见 build/mylib/mylib.vcxproj 的生成。")],-1),Il={id:"project-初始化,languages-字段",tabindex:"-1"},Pl=l("p",null,"指定项目所用的语言",-1),vl=l("div",{class:"language-cmake"},[l("span",{class:"copy"}),l("pre",{class:"shiki material-theme-palenight",tabindex:"0"},[l("code",null,[l("span",{class:"line"},[l("span",{style:{color:"#89DDFF"}},"cmake_minimum_required"),l("span",{style:{color:"#A6ACCD"}},"(VERSION 3.15)")]),s(` `),l("span",{class:"line"}),s(` `),l("span",{class:"line"},[l("span",{style:{color:"#89DDFF"}},"project"),l("span",{style:{color:"#A6ACCD"}},"(hellocmake LANGUAGES CXX)")]),s(` `),l("span",{class:"line"}),s(` `),l("span",{class:"line"},[l("span",{style:{color:"#676E95","font-style":"italic"}},"#或者, 这样可以把enable_language放到if里, 某些情况下才启用某些语言")]),s(` `),l("span",{class:"line"},[l("span",{style:{color:"#676E95","font-style":"italic"}},"#project(hellocmake LANGUAGES NONE)")]),s(` `),l("span",{class:"line"},[l("span",{style:{color:"#676E95","font-style":"italic"}},"#enable_language(CXX)")]),s(` `),l("span",{class:"line"}),s(` `),l("span",{class:"line"},[l("span",{style:{color:"#89DDFF"}},"add_executable"),l("span",{style:{color:"#A6ACCD"}},"(main main.cpp)")]),s(` `),l("span",{class:"line"})])])],-1),Ll=l("p",null,"支持的语言:",-1),Bl=l("ul",null,[l("li",null,"C:C 语言"),l("li",null,"CXX:C++语言"),l("li",null,"ASM:汇编语言"),l("li",null,"Fortran:古老的编程语言"),l("li",null,"CUDA:英伟达的 CUDA(3.8 版本新增)"),l("li",null,"OBJC:苹果的 Objective-C(3.16 版本新增)"),l("li",null,"OBJCXX:苹果的 Objective-C++(3.16 版本新增)"),l("li",null,"ISPC:一种因特尔的自动 SIMD 编程语言(3.18 版本新增)"),l("li",null,"如果不指定 LANGUAGES,默认为 C 和 CXX。")],-1),Sl={id:"project-初始化,version-字段",tabindex:"-1"},Ul=l("div",{class:"language-cmake"},[l("span",{class:"copy"}),l("pre",{class:"shiki material-theme-palenight",tabindex:"0"},[l("code",null,[l("span",{class:"line"},[l("span",{style:{color:"#89DDFF"}},"cmake_minimum_required"),l("span",{style:{color:"#A6ACCD"}},"(VERSION 3.15)")]),s(` `),l("span",{class:"line"}),s(` `),l("span",{class:"line"},[l("span",{style:{color:"#89DDFF"}},"project"),l("span",{style:{color:"#A6ACCD"}},"(hellocmake LANGUAGES CXX VERSION 1.2.3)")]),s(` `),l("span",{class:"line"}),s(` `),l("span",{class:"line"},[l("span",{style:{color:"#89DDFF"}},"add_executable"),l("span",{style:{color:"#A6ACCD"}},"(main main.cpp)")]),s(` `),l("span",{class:"line"})])])],-1),Tl=l("ul",null,[l("li",null,"project(项目名 VERSION x.y.z) 可以把当前项目的版本号设定为 x.y.z"),l("li",null,"之后可以通过 PROJECT_VERSION 来获取当前项目的版本号"),l("li",null,"PROJECT_VERSION_MAJOR 获取 x(主版本号)"),l("li",null,"PROJECT_VERSION_MINOR 获取 y(次版本号)"),l("li",null,"PROJECT_VERSION_PATCH 获取 z(补丁版本号)")],-1),Gl={id:"project-初始化,其他字段",tabindex:"-1"},jl=l("img",{src:"https://s2.loli.net/2022/03/28/Wx4Jr8GCTKyp2Oi.png",alt:"",width:"250"},null,-1),Xl=l("img",{src:"https://s2.loli.net/2022/03/28/gXBpumt1yaLrcM4.png",alt:"",width:"250"},null,-1),Vl=l("p",null,[s("定义"),l("code",null,"PROJECT_DESCRIPTION"),s("、"),l("code",null,"PROJECT_HOMEPAGE_URL"),s("变量")],-1),wl=l("img",{src:"https://s2.loli.net/2022/03/28/2vbDwjMqRtko3IT.png",alt:"",width:"250"},null,-1),$l=l("img",{src:"https://s2.loli.net/2022/03/28/yDu4qNALrs6BI9V.png",alt:"",width:"250"},null,-1),Yl=l("p",null,[s("定义"),l("code",null,"项目名_VERSION"),s("、"),l("code",null,"项目名_SOURCE_DIR"),s("、"),l("code",null,"项目名_BINARY_DIR"),s("变量")],-1),Jl={id:"设置-c-标准",tabindex:"-1"},Kl=l("p",null,[s("为了跨平台不要使用"),l("code",null,"set(CMAKE_CXX_FLAGS -std=c++17)"),s("这种方式")],-1),ql=l("div",{class:"language-cmake"},[l("span",{class:"copy"}),l("pre",{class:"shiki material-theme-palenight",tabindex:"0"},[l("code",null,[l("span",{class:"line"},[l("span",{style:{color:"#89DDFF"}},"cmake_minimum_required"),l("span",{style:{color:"#A6ACCD"}},"(VERSION 3.15)")]),s(` `),l("span",{class:"line"}),s(` `),l("span",{class:"line"},[l("span",{style:{color:"#676E95","font-style":"italic"}},"#使用C++17")]),s(` `),l("span",{class:"line"},[l("span",{style:{color:"#89DDFF"}},"set"),l("span",{style:{color:"#A6ACCD"}},"(CMAKE_CXX_STANDARD 17)")]),s(` `),l("span",{class:"line"},[l("span",{style:{color:"#676E95","font-style":"italic"}},"#如果编译器不支持C++17就报错, 设置为OFF, 不支持17的话会按14来编译")]),s(` `),l("span",{class:"line"},[l("span",{style:{color:"#89DDFF"}},"set"),l("span",{style:{color:"#A6ACCD"}},"(CMAKE_CXX_STANDARD_REQUIRED "),l("span",{style:{color:"#89DDFF"}},"ON"),l("span",{style:{color:"#A6ACCD"}},")")]),s(` `),l("span",{class:"line"},[l("span",{style:{color:"#676E95","font-style":"italic"}},"#为了跨平台关闭GCC扩展语法")]),s(` `),l("span",{class:"line"},[l("span",{style:{color:"#89DDFF"}},"set"),l("span",{style:{color:"#A6ACCD"}},"(CMAKE_CXX_EXTENSIONS "),l("span",{style:{color:"#89DDFF"}},"OFF"),l("span",{style:{color:"#A6ACCD"}},")")]),s(` `),l("span",{class:"line"}),s(` `),l("span",{class:"line"},[l("span",{style:{color:"#89DDFF"}},"project"),l("span",{style:{color:"#A6ACCD"}},"(hellocmake)")]),s(` `),l("span",{class:"line"})])])],-1),Hl={id:"cmake-minimum-required-指定最低所需的-cmake-版本",tabindex:"-1"},zl=l("div",{class:"language-cmake"},[l("span",{class:"copy"}),l("pre",{class:"shiki material-theme-palenight",tabindex:"0"},[l("code",null,[l("span",{class:"line"},[l("span",{style:{color:"#676E95","font-style":"italic"}},"#最低需要cmake版本为3.15")]),s(` `),l("span",{class:"line"},[l("span",{style:{color:"#676E95","font-style":"italic"}},"#cmake_minimum_required(VERSION 3.15)")]),s(` `),l("span",{class:"line"}),s(` `),l("span",{class:"line"},[l("span",{style:{color:"#676E95","font-style":"italic"}},"#需要cmake版本为3.15到3.20")]),s(` `),l("span",{class:"line"},[l("span",{style:{color:"#89DDFF"}},"cmake_minimum_required"),l("span",{style:{color:"#A6ACCD"}},"(VERSION 3.15...3.22)")]),s(` `),l("span",{class:"line"}),s(` `),l("span",{class:"line"},[l("span",{style:{color:"#89DDFF"}},"project"),l("span",{style:{color:"#A6ACCD"}},"(hellocmake)")]),s(` `),l("span",{class:"line"})])])],-1),Wl=l("p",null,[s("使用"),l("code",null,"cmake --version"),s("指令可以获取当前 cmake 版本号")],-1),Zl={id:"一份标准-cmakelists-txt",tabindex:"-1"},Ql=l("div",{class:"language-cmake CMakeLists.txt"},[l("span",{class:"copy"}),l("pre",{class:"shiki material-theme-palenight",tabindex:"0"},[l("code",null,[l("span",{class:"line"},[l("span",{style:{color:"#89DDFF"}},"cmake_minimum_required"),l("span",{style:{color:"#A6ACCD"}},"(version 3.15)")]),s(` `),l("span",{class:"line"}),s(` `),l("span",{class:"line"},[l("span",{style:{color:"#89DDFF"}},"set"),l("span",{style:{color:"#A6ACCD"}},"(CMAKE_CXX_STANDARD 17)")]),s(` `),l("span",{class:"line"},[l("span",{style:{color:"#89DDFF"}},"set"),l("span",{style:{color:"#A6ACCD"}},"(CMAKE_CXX_STANDARD_REQUIRED "),l("span",{style:{color:"#89DDFF"}},"ON"),l("span",{style:{color:"#A6ACCD"}},")")]),s(` `),l("span",{class:"line"}),s(` `),l("span",{class:"line"},[l("span",{style:{color:"#89DDFF"}},"project"),l("span",{style:{color:"#A6ACCD"}},"(zeno LANGUAGES C CXX)")]),s(` `),l("span",{class:"line"}),s(` `),l("span",{class:"line"},[l("span",{style:{color:"#89DDFF"}},"if"),l("span",{style:{color:"#A6ACCD"}}," (PROJECT_BINARY_DIR "),l("span",{style:{color:"#89DDFF"}},"STREQUAL"),l("span",{style:{color:"#A6ACCD"}}," PROJECT_SOURCE_DIR)")]),s(` `),l("span",{class:"line"},[l("span",{style:{color:"#89DDFF"}}," message"),l("span",{style:{color:"#A6ACCD"}},"(WARNING "),l("span",{style:{color:"#C3E88D"}},'"The binary directory of CMake cannot be the same as source directory!"'),l("span",{style:{color:"#A6ACCD"}},")")]),s(` `),l("span",{class:"line"},[l("span",{style:{color:"#89DDFF"}},"endif"),l("span",{style:{color:"#A6ACCD"}},"()")]),s(` `),l("span",{class:"line"}),s(` `),l("span",{class:"line"},[l("span",{style:{color:"#89DDFF"}},"if"),l("span",{style:{color:"#A6ACCD"}}," ("),l("span",{style:{color:"#89DDFF"}},"NOT"),l("span",{style:{color:"#A6ACCD"}}," CMAKE_BUILD_TYPE)")]),s(` `),l("span",{class:"line"},[l("span",{style:{color:"#89DDFF"}}," set"),l("span",{style:{color:"#A6ACCD"}},"(CMAKE_BUILD_TYPE Release)")]),s(` `),l("span",{class:"line"},[l("span",{style:{color:"#89DDFF"}},"endif"),l("span",{style:{color:"#A6ACCD"}},"()")]),s(` `),l("span",{class:"line"}),s(` `),l("span",{class:"line"},[l("span",{style:{color:"#676E95","font-style":"italic"}},"# Set to True when the target system is Windows, including Win64.")]),s(` `),l("span",{class:"line"}),s(` `),l("span",{class:"line"},[l("span",{style:{color:"#89DDFF"}},"if"),l("span",{style:{color:"#A6ACCD"}}," (WIN32)")]),s(` `),l("span",{class:"line"},[l("span",{style:{color:"#676E95","font-style":"italic"}},"# Add -D define flags to the compilation of source files.eg: gcc -DNOMINMAX")]),s(` `),l("span",{class:"line"},[l("span",{style:{color:"#89DDFF"}}," add_definitions"),l("span",{style:{color:"#A6ACCD"}},"(-DNOMINMAX -D_USE_MATH_DEFINES)")]),s(` `),l("span",{class:"line"},[l("span",{style:{color:"#89DDFF"}},"endif"),l("span",{style:{color:"#A6ACCD"}},"()")]),s(` `),l("span",{class:"line"}),s(` `),l("span",{class:"line"},[l("span",{style:{color:"#676E95","font-style":"italic"}},"# Set to true when the compiler is some version of Microsoft Visual C++ or another compiler simulating the Visual C++ cl command-line syntax.")]),s(` `),l("span",{class:"line"},[l("span",{style:{color:"#89DDFF"}},"if"),l("span",{style:{color:"#A6ACCD"}}," ("),l("span",{style:{color:"#89DDFF"}},"NOT"),l("span",{style:{color:"#A6ACCD"}}," MSVC)")]),s(` `),l("span",{class:"line"},[l("span",{style:{color:"#89DDFF"}}," find_program"),l("span",{style:{color:"#A6ACCD"}},"(CCACHE_PROGRAM ccache)")]),s(` `),l("span",{class:"line"},[l("span",{style:{color:"#89DDFF"}}," if"),l("span",{style:{color:"#A6ACCD"}}," (CCACHE_PROGRAM)")]),s(` `),l("span",{class:"line"},[l("span",{style:{color:"#89DDFF"}}," message"),l("span",{style:{color:"#A6ACCD"}},"(STATUS "),l("span",{style:{color:"#C3E88D"}},'"Found CCache: ${CCACHE_PROGRAM}"'),l("span",{style:{color:"#A6ACCD"}},")")]),s(` `),l("span",{class:"line"},[l("span",{style:{color:"#89DDFF"}}," set_property"),l("span",{style:{color:"#A6ACCD"}},"(GLOBAL PROPERTY RULE_LAUNCH_COMPILE ${CCACHE_PROGRAM})")]),s(` `),l("span",{class:"line"},[l("span",{style:{color:"#89DDFF"}}," set_property"),l("span",{style:{color:"#A6ACCD"}},"(GLOBAL PROPERTY RULE_LAUNCH_LINK ${CCACHE_PROGRAM})")]),s(` `),l("span",{class:"line"},[l("span",{style:{color:"#89DDFF"}}," endif"),l("span",{style:{color:"#A6ACCD"}},"()")]),s(` `),l("span",{class:"line"},[l("span",{style:{color:"#89DDFF"}},"endif"),l("span",{style:{color:"#A6ACCD"}},"()")]),s(` `),l("span",{class:"line"})])])],-1),ls=l("ol",null,[l("li",null,"如果生成二进制文件的文件夹和存储源码的文件夹是同一个文件夹,那么将会产生警告"),l("li",null,"默认使用 Release 模式构建"),l("li",null,[s("标准库在"),l("code",null,""),s("头中定义了两个模板函数 std::min() 和 std::max() 但在 windows 上无法使用,因为 windows 的"),l("code",null,""),s("中定义了两个传统的宏 min/max, 所以用-DNOMINMAX 来去除定义")]),l("li",null,"如果可以的话使用 ccache 来加速编译")],-1),ss={id:"链接库文件",tabindex:"-1"},es=l("p",null,"链接库可以简单理解为里面包含了一系列的函数,你可以方便的在自己的项目里调用他们,只要引入了对应的头文件 (函数声明)",-1);function as(t,ns,ts,os,i,cs){const a=D,p=r;return C(),_(p,{frontmatter:i.frontmatter,data:i.data},{"main-content-md":e(()=>[A,l("ul",null,[l("li",null,[n(a,{href:"https://www.bilibili.com/video/BV16P4y1g7MH/?spm_id_from=333.788",target:"_blank",rel:"noreferrer"},{default:e(()=>[s("https://www.bilibili.com/video/BV16P4y1g7MH/?spm_id_from=333.788")]),_:1})])]),h(" more "),l("h2",y,[s("命令行小技巧 "),n(a,{class:"header-anchor",href:"#命令行小技巧","aria-hidden":"true"},{default:e(()=>[s("#")]),_:1})]),k,F,l("h3",E,[s("CMake 命令行构建流程 (-B) "),n(a,{class:"header-anchor",href:"#cmake-命令行构建流程-b","aria-hidden":"true"},{default:e(()=>[s("#")]),_:1})]),g,f,b,R,l("h3",x,[s("指定配置变量 (-D、-G) "),n(a,{class:"header-anchor",href:"#指定配置变量-d、-g","aria-hidden":"true"},{default:e(()=>[s("#")]),_:1})]),O,N,M,I,P,v,L,l("h2",B,[s("添加源文件 "),n(a,{class:"header-anchor",href:"#添加源文件","aria-hidden":"true"},{default:e(()=>[s("#")]),_:1})]),S,U,T,G,j,X,l("h3",V,[s("多个源文件 "),n(a,{class:"header-anchor",href:"#多个源文件","aria-hidden":"true"},{default:e(()=>[s("#")]),_:1})]),w,$,l("h4",Y,[s("一个个手动添加 "),n(a,{class:"header-anchor",href:"#一个个手动添加","aria-hidden":"true"},{default:e(()=>[s("#")]),_:1})]),J,l("h4",K,[s("通过变量的方式 "),n(a,{class:"header-anchor",href:"#通过变量的方式","aria-hidden":"true"},{default:e(()=>[s("#")]),_:1})]),q,H,z,W,Z,l("h4",Q,[s("GLOB 实现批量添加源文件 "),n(a,{class:"header-anchor",href:"#glob-实现批量添加源文件","aria-hidden":"true"},{default:e(()=>[s("#")]),_:1})]),ll,sl,el,al,nl,tl,ol,cl,il,pl,rl,dl,ul,_l,Cl,l("h4",hl,[s("aux_source_directory 自动收集需要的文件后缀名 "),n(a,{class:"header-anchor",href:"#aux-source-directory-自动收集需要的文件后缀名","aria-hidden":"true"},{default:e(()=>[s("#")]),_:1})]),Dl,l("h3",ml,[s("项目配置变量 "),n(a,{class:"header-anchor",href:"#项目配置变量","aria-hidden":"true"},{default:e(()=>[s("#")]),_:1})]),l("h4",Al,[s("CMAKE_BUILD_TYPE, 项目构建类型 "),n(a,{class:"header-anchor",href:"#cmake-build-type-项目构建类型","aria-hidden":"true"},{default:e(()=>[s("#")]),_:1})]),yl,kl,Fl,El,gl,fl,bl,l("h4",Rl,[s("project 初始化,项目名 "),n(a,{class:"header-anchor",href:"#project-初始化,项目名","aria-hidden":"true"},{default:e(()=>[s("#")]),_:1})]),xl,Ol,Nl,l("ul",null,[l("li",null,[n(a,{href:"https://cmake.org/cmake/help/latest/command/project.html",target:"_blank",rel:"noreferrer"},{default:e(()=>[s("https://cmake.org/cmake/help/latest/command/project.html")]),_:1})])]),Ml,l("h4",Il,[s("project 初始化,LANGUAGES 字段 "),n(a,{class:"header-anchor",href:"#project-初始化,languages-字段","aria-hidden":"true"},{default:e(()=>[s("#")]),_:1})]),Pl,vl,Ll,Bl,l("h4",Sl,[s("project 初始化,VERSION 字段 "),n(a,{class:"header-anchor",href:"#project-初始化,version-字段","aria-hidden":"true"},{default:e(()=>[s("#")]),_:1})]),Ul,Tl,l("h4",Gl,[s("project 初始化,其他字段 "),n(a,{class:"header-anchor",href:"#project-初始化,其他字段","aria-hidden":"true"},{default:e(()=>[s("#")]),_:1})]),jl,Xl,Vl,wl,$l,Yl,l("h4",Jl,[s("设置 C++标准 "),n(a,{class:"header-anchor",href:"#设置-c-标准","aria-hidden":"true"},{default:e(()=>[s("#")]),_:1})]),Kl,ql,l("h4",Hl,[s("cmake_minimum_required, 指定最低所需的 CMake 版本 "),n(a,{class:"header-anchor",href:"#cmake-minimum-required-指定最低所需的-cmake-版本","aria-hidden":"true"},{default:e(()=>[s("#")]),_:1})]),zl,Wl,l("h3",Zl,[s("一份标准 CMakeLists.txt "),n(a,{class:"header-anchor",href:"#一份标准-cmakelists-txt","aria-hidden":"true"},{default:e(()=>[s("#")]),_:1})]),Ql,ls,l("p",null,[n(a,{href:"https://blog.csdn.net/fuyajun01/article/details/8891749",target:"_blank",rel:"noreferrer"},{default:e(()=>[s("CMake 常见变量——Project 和 CMake 相关信息")]),_:1})]),l("h2",ss,[s("链接库文件 "),n(a,{class:"header-anchor",href:"#链接库文件","aria-hidden":"true"},{default:e(()=>[s("#")]),_:1})]),es]),"main-header":e(()=>[o(t.$slots,"main-header")]),"main-header-after":e(()=>[o(t.$slots,"main-header-after")]),"main-nav":e(()=>[o(t.$slots,"main-nav")]),"main-content":e(()=>[o(t.$slots,"main-content")]),"main-content-after":e(()=>[o(t.$slots,"main-content-after")]),"main-nav-before":e(()=>[o(t.$slots,"main-nav-before")]),"main-nav-after":e(()=>[o(t.$slots,"main-nav-after")]),comment:e(()=>[o(t.$slots,"comment")]),footer:e(()=>[o(t.$slots,"footer")]),aside:e(()=>[o(t.$slots,"aside")]),"aside-custom":e(()=>[o(t.$slots,"aside-custom")]),default:e(()=>[o(t.$slots,"default")]),_:3},8,["frontmatter","data"])}const Cs=d(m,[["render",as]]);export{_s as __pageData,Cs as default};