mirror of
https://gitee.com/yanmu_ym/cpp.git
synced 2026-02-04 01:53:15 +08:00
3428 lines
268 KiB
HTML
3428 lines
268 KiB
HTML
<!DOCTYPE html>
|
||
<html lang="en">
|
||
<head>
|
||
<meta charset="UTF-8">
|
||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||
<title></title>
|
||
<link rel="stylesheet" href="style.css">
|
||
<style>
|
||
@font-face {
|
||
font-family: octicons-link;
|
||
src: url(data:font/woff;charset=utf-8;base64,d09GRgABAAAAAAZwABAAAAAACFQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABEU0lHAAAGaAAAAAgAAAAIAAAAAUdTVUIAAAZcAAAACgAAAAoAAQAAT1MvMgAAAyQAAABJAAAAYFYEU3RjbWFwAAADcAAAAEUAAACAAJThvmN2dCAAAATkAAAABAAAAAQAAAAAZnBnbQAAA7gAAACyAAABCUM+8IhnYXNwAAAGTAAAABAAAAAQABoAI2dseWYAAAFsAAABPAAAAZwcEq9taGVhZAAAAsgAAAA0AAAANgh4a91oaGVhAAADCAAAABoAAAAkCA8DRGhtdHgAAAL8AAAADAAAAAwGAACfbG9jYQAAAsAAAAAIAAAACABiATBtYXhwAAACqAAAABgAAAAgAA8ASm5hbWUAAAToAAABQgAAAlXu73sOcG9zdAAABiwAAAAeAAAAME3QpOBwcmVwAAAEbAAAAHYAAAB/aFGpk3jaTY6xa8JAGMW/O62BDi0tJLYQincXEypYIiGJjSgHniQ6umTsUEyLm5BV6NDBP8Tpts6F0v+k/0an2i+itHDw3v2+9+DBKTzsJNnWJNTgHEy4BgG3EMI9DCEDOGEXzDADU5hBKMIgNPZqoD3SilVaXZCER3/I7AtxEJLtzzuZfI+VVkprxTlXShWKb3TBecG11rwoNlmmn1P2WYcJczl32etSpKnziC7lQyWe1smVPy/Lt7Kc+0vWY/gAgIIEqAN9we0pwKXreiMasxvabDQMM4riO+qxM2ogwDGOZTXxwxDiycQIcoYFBLj5K3EIaSctAq2kTYiw+ymhce7vwM9jSqO8JyVd5RH9gyTt2+J/yUmYlIR0s04n6+7Vm1ozezUeLEaUjhaDSuXHwVRgvLJn1tQ7xiuVv/ocTRF42mNgZGBgYGbwZOBiAAFGJBIMAAizAFoAAABiAGIAznjaY2BkYGAA4in8zwXi+W2+MjCzMIDApSwvXzC97Z4Ig8N/BxYGZgcgl52BCSQKAA3jCV8CAABfAAAAAAQAAEB42mNgZGBg4f3vACQZQABIMjKgAmYAKEgBXgAAeNpjYGY6wTiBgZWBg2kmUxoDA4MPhGZMYzBi1AHygVLYQUCaawqDA4PChxhmh/8ODDEsvAwHgMKMIDnGL0x7gJQCAwMAJd4MFwAAAHjaY2BgYGaA4DAGRgYQkAHyGMF8NgYrIM3JIAGVYYDT+AEjAwuDFpBmA9KMDEwMCh9i/v8H8sH0/4dQc1iAmAkALaUKLgAAAHjaTY9LDsIgEIbtgqHUPpDi3gPoBVyRTmTddOmqTXThEXqrob2gQ1FjwpDvfwCBdmdXC5AVKFu3e5MfNFJ29KTQT48Ob9/lqYwOGZxeUelN2U2R6+cArgtCJpauW7UQBqnFkUsjAY/kOU1cP+DAgvxwn1chZDwUbd6CFimGXwzwF6tPbFIcjEl+vvmM/byA48e6tWrKArm4ZJlCbdsrxksL1AwWn/yBSJKpYbq8AXaaTb8AAHja28jAwOC00ZrBeQNDQOWO//sdBBgYGRiYWYAEELEwMTE4uzo5Zzo5b2BxdnFOcALxNjA6b2ByTswC8jYwg0VlNuoCTWAMqNzMzsoK1rEhNqByEyerg5PMJlYuVueETKcd/89uBpnpvIEVomeHLoMsAAe1Id4AAAAAAAB42oWQT07CQBTGv0JBhagk7HQzKxca2sJCE1hDt4QF+9JOS0nbaaYDCQfwCJ7Au3AHj+LO13FMmm6cl7785vven0kBjHCBhfpYuNa5Ph1c0e2Xu3jEvWG7UdPDLZ4N92nOm+EBXuAbHmIMSRMs+4aUEd4Nd3CHD8NdvOLTsA2GL8M9PODbcL+hD7C1xoaHeLJSEao0FEW14ckxC+TU8TxvsY6X0eLPmRhry2WVioLpkrbp84LLQPGI7c6sOiUzpWIWS5GzlSgUzzLBSikOPFTOXqly7rqx0Z1Q5BAIoZBSFihQYQOOBEdkCOgXTOHA07HAGjGWiIjaPZNW13/+lm6S9FT7rLHFJ6fQbkATOG1j2OFMucKJJsxIVfQORl+9Jyda6Sl1dUYhSCm1dyClfoeDve4qMYdLEbfqHf3O/AdDumsjAAB42mNgYoAAZQYjBmyAGYQZmdhL8zLdDEydARfoAqIAAAABAAMABwAKABMAB///AA8AAQAAAAAAAAAAAAAAAAABAAAAAA==) format('woff');
|
||
}
|
||
|
||
.markdown-body .octicon {
|
||
display: inline-block;
|
||
fill: currentColor;
|
||
vertical-align: text-bottom;
|
||
}
|
||
|
||
.markdown-body .anchor {
|
||
float: left;
|
||
line-height: 1;
|
||
margin-left: -20px;
|
||
padding-right: 4px;
|
||
}
|
||
|
||
.markdown-body .anchor:focus {
|
||
outline: none;
|
||
}
|
||
|
||
.markdown-body h1 .octicon-link,
|
||
.markdown-body h2 .octicon-link,
|
||
.markdown-body h3 .octicon-link,
|
||
.markdown-body h4 .octicon-link,
|
||
.markdown-body h5 .octicon-link,
|
||
.markdown-body h6 .octicon-link {
|
||
color: #1b1f23;
|
||
vertical-align: middle;
|
||
visibility: hidden;
|
||
}
|
||
|
||
.markdown-body h1:hover .anchor,
|
||
.markdown-body h2:hover .anchor,
|
||
.markdown-body h3:hover .anchor,
|
||
.markdown-body h4:hover .anchor,
|
||
.markdown-body h5:hover .anchor,
|
||
.markdown-body h6:hover .anchor {
|
||
text-decoration: none;
|
||
}
|
||
|
||
.markdown-body h1:hover .anchor .octicon-link,
|
||
.markdown-body h2:hover .anchor .octicon-link,
|
||
.markdown-body h3:hover .anchor .octicon-link,
|
||
.markdown-body h4:hover .anchor .octicon-link,
|
||
.markdown-body h5:hover .anchor .octicon-link,
|
||
.markdown-body h6:hover .anchor .octicon-link {
|
||
visibility: visible;
|
||
}
|
||
|
||
.markdown-body {
|
||
-ms-text-size-adjust: 100%;
|
||
-webkit-text-size-adjust: 100%;
|
||
color: #24292e;
|
||
line-height: 1.5;
|
||
font-family: -apple-system,BlinkMacSystemFont,Segoe UI,Helvetica,Arial,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol;
|
||
font-size: 16px;
|
||
line-height: 1.5;
|
||
word-wrap: break-word;
|
||
}
|
||
|
||
.markdown-body .pl-c {
|
||
color: #6a737d;
|
||
}
|
||
|
||
.markdown-body .pl-c1,
|
||
.markdown-body .pl-s .pl-v {
|
||
color: #005cc5;
|
||
}
|
||
|
||
.markdown-body .pl-e,
|
||
.markdown-body .pl-en {
|
||
color: #6f42c1;
|
||
}
|
||
|
||
.markdown-body .pl-s .pl-s1,
|
||
.markdown-body .pl-smi {
|
||
color: #24292e;
|
||
}
|
||
|
||
.markdown-body .pl-ent {
|
||
color: #22863a;
|
||
}
|
||
|
||
.markdown-body .pl-k {
|
||
color: #d73a49;
|
||
}
|
||
|
||
.markdown-body .pl-pds,
|
||
.markdown-body .pl-s,
|
||
.markdown-body .pl-s .pl-pse .pl-s1,
|
||
.markdown-body .pl-sr,
|
||
.markdown-body .pl-sr .pl-cce,
|
||
.markdown-body .pl-sr .pl-sra,
|
||
.markdown-body .pl-sr .pl-sre {
|
||
color: #032f62;
|
||
}
|
||
|
||
.markdown-body .pl-smw,
|
||
.markdown-body .pl-v {
|
||
color: #e36209;
|
||
}
|
||
|
||
.markdown-body .pl-bu {
|
||
color: #b31d28;
|
||
}
|
||
|
||
.markdown-body .pl-ii {
|
||
background-color: #b31d28;
|
||
color: #fafbfc;
|
||
}
|
||
|
||
.markdown-body .pl-c2 {
|
||
background-color: #d73a49;
|
||
color: #fafbfc;
|
||
}
|
||
|
||
.markdown-body .pl-c2:before {
|
||
content: "^M";
|
||
}
|
||
|
||
.markdown-body .pl-sr .pl-cce {
|
||
color: #22863a;
|
||
font-weight: 700;
|
||
}
|
||
|
||
.markdown-body .pl-ml {
|
||
color: #735c0f;
|
||
}
|
||
|
||
.markdown-body .pl-mh,
|
||
.markdown-body .pl-mh .pl-en,
|
||
.markdown-body .pl-ms {
|
||
color: #005cc5;
|
||
font-weight: 700;
|
||
}
|
||
|
||
.markdown-body .pl-mi {
|
||
color: #24292e;
|
||
font-style: italic;
|
||
}
|
||
|
||
.markdown-body .pl-mb {
|
||
color: #24292e;
|
||
font-weight: 700;
|
||
}
|
||
|
||
.markdown-body .pl-md {
|
||
background-color: #ffeef0;
|
||
color: #b31d28;
|
||
}
|
||
|
||
.markdown-body .pl-mi1 {
|
||
background-color: #f0fff4;
|
||
color: #22863a;
|
||
}
|
||
|
||
.markdown-body .pl-mc {
|
||
background-color: #ffebda;
|
||
color: #e36209;
|
||
}
|
||
|
||
.markdown-body .pl-mi2 {
|
||
background-color: #005cc5;
|
||
color: #f6f8fa;
|
||
}
|
||
|
||
.markdown-body .pl-mdr {
|
||
color: #6f42c1;
|
||
font-weight: 700;
|
||
}
|
||
|
||
.markdown-body .pl-ba {
|
||
color: #586069;
|
||
}
|
||
|
||
.markdown-body .pl-sg {
|
||
color: #959da5;
|
||
}
|
||
|
||
.markdown-body .pl-corl {
|
||
color: #032f62;
|
||
text-decoration: underline;
|
||
}
|
||
|
||
.markdown-body details {
|
||
display: block;
|
||
}
|
||
|
||
.markdown-body summary {
|
||
display: list-item;
|
||
}
|
||
|
||
.markdown-body a {
|
||
background-color: transparent;
|
||
}
|
||
|
||
.markdown-body a:active,
|
||
.markdown-body a:hover {
|
||
outline-width: 0;
|
||
}
|
||
|
||
.markdown-body strong {
|
||
font-weight: inherit;
|
||
font-weight: bolder;
|
||
}
|
||
|
||
.markdown-body h1 {
|
||
font-size: 2em;
|
||
margin: .67em 0;
|
||
}
|
||
|
||
.markdown-body img {
|
||
border-style: none;
|
||
}
|
||
|
||
.markdown-body code,
|
||
.markdown-body kbd,
|
||
.markdown-body pre {
|
||
font-family: monospace,monospace;
|
||
font-size: 1em;
|
||
}
|
||
|
||
.markdown-body hr {
|
||
box-sizing: content-box;
|
||
height: 0;
|
||
overflow: visible;
|
||
}
|
||
|
||
.markdown-body input {
|
||
font: inherit;
|
||
margin: 0;
|
||
}
|
||
|
||
.markdown-body input {
|
||
overflow: visible;
|
||
}
|
||
|
||
.markdown-body [type=checkbox] {
|
||
box-sizing: border-box;
|
||
padding: 0;
|
||
}
|
||
|
||
.markdown-body * {
|
||
box-sizing: border-box;
|
||
}
|
||
|
||
.markdown-body input {
|
||
font-family: inherit;
|
||
font-size: inherit;
|
||
line-height: inherit;
|
||
}
|
||
|
||
.markdown-body a {
|
||
color: #0366d6;
|
||
text-decoration: none;
|
||
}
|
||
|
||
.markdown-body a:hover {
|
||
text-decoration: underline;
|
||
}
|
||
|
||
.markdown-body strong {
|
||
font-weight: 600;
|
||
}
|
||
|
||
.markdown-body hr {
|
||
background: transparent;
|
||
border: 0;
|
||
border-bottom: 1px solid #dfe2e5;
|
||
height: 0;
|
||
margin: 15px 0;
|
||
overflow: hidden;
|
||
}
|
||
|
||
.markdown-body hr:before {
|
||
content: "";
|
||
display: table;
|
||
}
|
||
|
||
.markdown-body hr:after {
|
||
clear: both;
|
||
content: "";
|
||
display: table;
|
||
}
|
||
|
||
.markdown-body table {
|
||
border-collapse: collapse;
|
||
border-spacing: 0;
|
||
}
|
||
|
||
.markdown-body td,
|
||
.markdown-body th {
|
||
padding: 0;
|
||
}
|
||
|
||
.markdown-body details summary {
|
||
cursor: pointer;
|
||
}
|
||
|
||
.markdown-body h1,
|
||
.markdown-body h2,
|
||
.markdown-body h3,
|
||
.markdown-body h4,
|
||
.markdown-body h5,
|
||
.markdown-body h6 {
|
||
margin-bottom: 0;
|
||
margin-top: 0;
|
||
}
|
||
|
||
.markdown-body h1 {
|
||
font-size: 32px;
|
||
}
|
||
|
||
.markdown-body h1,
|
||
.markdown-body h2 {
|
||
font-weight: 600;
|
||
}
|
||
|
||
.markdown-body h2 {
|
||
font-size: 24px;
|
||
}
|
||
|
||
.markdown-body h3 {
|
||
font-size: 20px;
|
||
}
|
||
|
||
.markdown-body h3,
|
||
.markdown-body h4 {
|
||
font-weight: 600;
|
||
}
|
||
|
||
.markdown-body h4 {
|
||
font-size: 16px;
|
||
}
|
||
|
||
.markdown-body h5 {
|
||
font-size: 14px;
|
||
}
|
||
|
||
.markdown-body h5,
|
||
.markdown-body h6 {
|
||
font-weight: 600;
|
||
}
|
||
|
||
.markdown-body h6 {
|
||
font-size: 12px;
|
||
}
|
||
|
||
.markdown-body p {
|
||
margin-bottom: 10px;
|
||
margin-top: 0;
|
||
}
|
||
|
||
.markdown-body blockquote {
|
||
margin: 0;
|
||
}
|
||
|
||
.markdown-body ol,
|
||
.markdown-body ul {
|
||
margin-bottom: 0;
|
||
margin-top: 0;
|
||
padding-left: 0;
|
||
}
|
||
|
||
.markdown-body ol ol,
|
||
.markdown-body ul ol {
|
||
list-style-type: lower-roman;
|
||
}
|
||
|
||
.markdown-body ol ol ol,
|
||
.markdown-body ol ul ol,
|
||
.markdown-body ul ol ol,
|
||
.markdown-body ul ul ol {
|
||
list-style-type: lower-alpha;
|
||
}
|
||
|
||
.markdown-body dd {
|
||
margin-left: 0;
|
||
}
|
||
|
||
.markdown-body code,
|
||
.markdown-body pre {
|
||
font-family: SFMono-Regular,Consolas,Liberation Mono,Menlo,Courier,monospace;
|
||
font-size: 12px;
|
||
}
|
||
|
||
.markdown-body pre {
|
||
margin-bottom: 0;
|
||
margin-top: 0;
|
||
}
|
||
|
||
.markdown-body input::-webkit-inner-spin-button,
|
||
.markdown-body input::-webkit-outer-spin-button {
|
||
-webkit-appearance: none;
|
||
appearance: none;
|
||
margin: 0;
|
||
}
|
||
|
||
.markdown-body .border {
|
||
border: 1px solid #e1e4e8!important;
|
||
}
|
||
|
||
.markdown-body .border-0 {
|
||
border: 0!important;
|
||
}
|
||
|
||
.markdown-body .border-bottom {
|
||
border-bottom: 1px solid #e1e4e8!important;
|
||
}
|
||
|
||
.markdown-body .rounded-1 {
|
||
border-radius: 3px!important;
|
||
}
|
||
|
||
.markdown-body .bg-white {
|
||
background-color: #fff!important;
|
||
}
|
||
|
||
.markdown-body .bg-gray-light {
|
||
background-color: #fafbfc!important;
|
||
}
|
||
|
||
.markdown-body .text-gray-light {
|
||
color: #6a737d!important;
|
||
}
|
||
|
||
.markdown-body .mb-0 {
|
||
margin-bottom: 0!important;
|
||
}
|
||
|
||
.markdown-body .my-2 {
|
||
margin-bottom: 8px!important;
|
||
margin-top: 8px!important;
|
||
}
|
||
|
||
.markdown-body .pl-0 {
|
||
padding-left: 0!important;
|
||
}
|
||
|
||
.markdown-body .py-0 {
|
||
padding-bottom: 0!important;
|
||
padding-top: 0!important;
|
||
}
|
||
|
||
.markdown-body .pl-1 {
|
||
padding-left: 4px!important;
|
||
}
|
||
|
||
.markdown-body .pl-2 {
|
||
padding-left: 8px!important;
|
||
}
|
||
|
||
.markdown-body .py-2 {
|
||
padding-bottom: 8px!important;
|
||
padding-top: 8px!important;
|
||
}
|
||
|
||
.markdown-body .pl-3,
|
||
.markdown-body .px-3 {
|
||
padding-left: 16px!important;
|
||
}
|
||
|
||
.markdown-body .px-3 {
|
||
padding-right: 16px!important;
|
||
}
|
||
|
||
.markdown-body .pl-4 {
|
||
padding-left: 24px!important;
|
||
}
|
||
|
||
.markdown-body .pl-5 {
|
||
padding-left: 32px!important;
|
||
}
|
||
|
||
.markdown-body .pl-6 {
|
||
padding-left: 40px!important;
|
||
}
|
||
|
||
.markdown-body .f6 {
|
||
font-size: 12px!important;
|
||
}
|
||
|
||
.markdown-body .lh-condensed {
|
||
line-height: 1.25!important;
|
||
}
|
||
|
||
.markdown-body .text-bold {
|
||
font-weight: 600!important;
|
||
}
|
||
|
||
.markdown-body:before {
|
||
content: "";
|
||
display: table;
|
||
}
|
||
|
||
.markdown-body:after {
|
||
clear: both;
|
||
content: "";
|
||
display: table;
|
||
}
|
||
|
||
.markdown-body>:first-child {
|
||
margin-top: 0!important;
|
||
}
|
||
|
||
.markdown-body>:last-child {
|
||
margin-bottom: 0!important;
|
||
}
|
||
|
||
.markdown-body a:not([href]) {
|
||
color: inherit;
|
||
text-decoration: none;
|
||
}
|
||
|
||
.markdown-body blockquote,
|
||
.markdown-body dl,
|
||
.markdown-body ol,
|
||
.markdown-body p,
|
||
.markdown-body pre,
|
||
.markdown-body table,
|
||
.markdown-body ul {
|
||
margin-bottom: 16px;
|
||
margin-top: 0;
|
||
}
|
||
|
||
.markdown-body hr {
|
||
background-color: #e1e4e8;
|
||
border: 0;
|
||
height: .25em;
|
||
margin: 24px 0;
|
||
padding: 0;
|
||
}
|
||
|
||
.markdown-body blockquote {
|
||
border-left: .25em solid #dfe2e5;
|
||
color: #6a737d;
|
||
padding: 0 1em;
|
||
}
|
||
|
||
.markdown-body blockquote>:first-child {
|
||
margin-top: 0;
|
||
}
|
||
|
||
.markdown-body blockquote>:last-child {
|
||
margin-bottom: 0;
|
||
}
|
||
|
||
.markdown-body kbd {
|
||
background-color: #fafbfc;
|
||
border: 1px solid #c6cbd1;
|
||
border-bottom-color: #959da5;
|
||
border-radius: 3px;
|
||
box-shadow: inset 0 -1px 0 #959da5;
|
||
color: #444d56;
|
||
display: inline-block;
|
||
font-size: 11px;
|
||
line-height: 10px;
|
||
padding: 3px 5px;
|
||
vertical-align: middle;
|
||
}
|
||
|
||
.markdown-body h1,
|
||
.markdown-body h2,
|
||
.markdown-body h3,
|
||
.markdown-body h4,
|
||
.markdown-body h5,
|
||
.markdown-body h6 {
|
||
font-weight: 600;
|
||
line-height: 1.25;
|
||
margin-bottom: 16px;
|
||
margin-top: 24px;
|
||
}
|
||
|
||
.markdown-body h1 {
|
||
font-size: 2em;
|
||
}
|
||
|
||
.markdown-body h1,
|
||
.markdown-body h2 {
|
||
border-bottom: 1px solid #eaecef;
|
||
padding-bottom: .3em;
|
||
}
|
||
|
||
.markdown-body h2 {
|
||
font-size: 1.5em;
|
||
}
|
||
|
||
.markdown-body h3 {
|
||
font-size: 1.25em;
|
||
}
|
||
|
||
.markdown-body h4 {
|
||
font-size: 1em;
|
||
}
|
||
|
||
.markdown-body h5 {
|
||
font-size: .875em;
|
||
}
|
||
|
||
.markdown-body h6 {
|
||
color: #6a737d;
|
||
font-size: .85em;
|
||
}
|
||
|
||
.markdown-body ol,
|
||
.markdown-body ul {
|
||
padding-left: 2em;
|
||
}
|
||
|
||
.markdown-body ol ol,
|
||
.markdown-body ol ul,
|
||
.markdown-body ul ol,
|
||
.markdown-body ul ul {
|
||
margin-bottom: 0;
|
||
margin-top: 0;
|
||
}
|
||
|
||
.markdown-body li {
|
||
word-wrap: break-all;
|
||
}
|
||
|
||
.markdown-body li>p {
|
||
margin-top: 16px;
|
||
}
|
||
|
||
.markdown-body li+li {
|
||
margin-top: .25em;
|
||
}
|
||
|
||
.markdown-body dl {
|
||
padding: 0;
|
||
}
|
||
|
||
.markdown-body dl dt {
|
||
font-size: 1em;
|
||
font-style: italic;
|
||
font-weight: 600;
|
||
margin-top: 16px;
|
||
padding: 0;
|
||
}
|
||
|
||
.markdown-body dl dd {
|
||
margin-bottom: 16px;
|
||
padding: 0 16px;
|
||
}
|
||
|
||
.markdown-body table {
|
||
display: block;
|
||
overflow: auto;
|
||
width: 100%;
|
||
}
|
||
|
||
.markdown-body table th {
|
||
font-weight: 600;
|
||
}
|
||
|
||
.markdown-body table td,
|
||
.markdown-body table th {
|
||
border: 1px solid #dfe2e5;
|
||
padding: 6px 13px;
|
||
}
|
||
|
||
.markdown-body table tr {
|
||
background-color: #fff;
|
||
border-top: 1px solid #c6cbd1;
|
||
}
|
||
|
||
.markdown-body table tr:nth-child(2n) {
|
||
background-color: #f6f8fa;
|
||
}
|
||
|
||
.markdown-body img {
|
||
background-color: #fff;
|
||
box-sizing: content-box;
|
||
max-width: 100%;
|
||
}
|
||
|
||
.markdown-body img[align=right] {
|
||
padding-left: 20px;
|
||
}
|
||
|
||
.markdown-body img[align=left] {
|
||
padding-right: 20px;
|
||
}
|
||
|
||
.markdown-body code {
|
||
background-color: rgba(27,31,35,.05);
|
||
border-radius: 3px;
|
||
font-size: 85%;
|
||
margin: 0;
|
||
padding: .2em .4em;
|
||
}
|
||
|
||
.markdown-body pre {
|
||
word-wrap: normal;
|
||
}
|
||
|
||
.markdown-body pre>code {
|
||
background: transparent;
|
||
border: 0;
|
||
font-size: 100%;
|
||
margin: 0;
|
||
padding: 0;
|
||
white-space: pre;
|
||
word-break: normal;
|
||
}
|
||
|
||
.markdown-body .highlight {
|
||
margin-bottom: 16px;
|
||
}
|
||
|
||
.markdown-body .highlight pre {
|
||
margin-bottom: 0;
|
||
word-break: normal;
|
||
}
|
||
|
||
.markdown-body .highlight pre,
|
||
.markdown-body pre {
|
||
background-color: #f6f8fa;
|
||
border-radius: 3px;
|
||
font-size: 85%;
|
||
line-height: 1.45;
|
||
overflow: auto;
|
||
padding: 16px;
|
||
}
|
||
|
||
.markdown-body pre code {
|
||
background-color: transparent;
|
||
border: 0;
|
||
display: inline;
|
||
line-height: inherit;
|
||
margin: 0;
|
||
max-width: auto;
|
||
overflow: visible;
|
||
padding: 0;
|
||
word-wrap: normal;
|
||
}
|
||
|
||
.markdown-body .commit-tease-sha {
|
||
color: #444d56;
|
||
display: inline-block;
|
||
font-family: SFMono-Regular,Consolas,Liberation Mono,Menlo,Courier,monospace;
|
||
font-size: 90%;
|
||
}
|
||
|
||
.markdown-body .blob-wrapper {
|
||
border-bottom-left-radius: 3px;
|
||
border-bottom-right-radius: 3px;
|
||
overflow-x: auto;
|
||
overflow-y: hidden;
|
||
}
|
||
|
||
.markdown-body .blob-wrapper-embedded {
|
||
max-height: 240px;
|
||
overflow-y: auto;
|
||
}
|
||
|
||
.markdown-body .blob-num {
|
||
-moz-user-select: none;
|
||
-ms-user-select: none;
|
||
-webkit-user-select: none;
|
||
color: rgba(27,31,35,.3);
|
||
cursor: pointer;
|
||
font-family: SFMono-Regular,Consolas,Liberation Mono,Menlo,Courier,monospace;
|
||
font-size: 12px;
|
||
line-height: 20px;
|
||
min-width: 50px;
|
||
padding-left: 10px;
|
||
padding-right: 10px;
|
||
text-align: right;
|
||
user-select: none;
|
||
vertical-align: top;
|
||
white-space: nowrap;
|
||
width: 1%;
|
||
}
|
||
|
||
.markdown-body .blob-num:hover {
|
||
color: rgba(27,31,35,.6);
|
||
}
|
||
|
||
.markdown-body .blob-num:before {
|
||
content: attr(data-line-number);
|
||
}
|
||
|
||
.markdown-body .blob-code {
|
||
line-height: 20px;
|
||
padding-left: 10px;
|
||
padding-right: 10px;
|
||
position: relative;
|
||
vertical-align: top;
|
||
}
|
||
|
||
.markdown-body .blob-code-inner {
|
||
color: #24292e;
|
||
font-family: SFMono-Regular,Consolas,Liberation Mono,Menlo,Courier,monospace;
|
||
font-size: 12px;
|
||
overflow: visible;
|
||
white-space: pre;
|
||
word-wrap: normal;
|
||
}
|
||
|
||
.markdown-body .pl-token.active,
|
||
.markdown-body .pl-token:hover {
|
||
background: #ffea7f;
|
||
cursor: pointer;
|
||
}
|
||
|
||
.markdown-body kbd {
|
||
background-color: #fafbfc;
|
||
border: 1px solid #d1d5da;
|
||
border-bottom-color: #c6cbd1;
|
||
border-radius: 3px;
|
||
box-shadow: inset 0 -1px 0 #c6cbd1;
|
||
color: #444d56;
|
||
display: inline-block;
|
||
font: 11px SFMono-Regular,Consolas,Liberation Mono,Menlo,Courier,monospace;
|
||
line-height: 10px;
|
||
padding: 3px 5px;
|
||
vertical-align: middle;
|
||
}
|
||
|
||
.markdown-body :checked+.radio-label {
|
||
border-color: #0366d6;
|
||
position: relative;
|
||
z-index: 1;
|
||
}
|
||
|
||
.markdown-body .tab-size[data-tab-size="1"] {
|
||
-moz-tab-size: 1;
|
||
tab-size: 1;
|
||
}
|
||
|
||
.markdown-body .tab-size[data-tab-size="2"] {
|
||
-moz-tab-size: 2;
|
||
tab-size: 2;
|
||
}
|
||
|
||
.markdown-body .tab-size[data-tab-size="3"] {
|
||
-moz-tab-size: 3;
|
||
tab-size: 3;
|
||
}
|
||
|
||
.markdown-body .tab-size[data-tab-size="4"] {
|
||
-moz-tab-size: 4;
|
||
tab-size: 4;
|
||
}
|
||
|
||
.markdown-body .tab-size[data-tab-size="5"] {
|
||
-moz-tab-size: 5;
|
||
tab-size: 5;
|
||
}
|
||
|
||
.markdown-body .tab-size[data-tab-size="6"] {
|
||
-moz-tab-size: 6;
|
||
tab-size: 6;
|
||
}
|
||
|
||
.markdown-body .tab-size[data-tab-size="7"] {
|
||
-moz-tab-size: 7;
|
||
tab-size: 7;
|
||
}
|
||
|
||
.markdown-body .tab-size[data-tab-size="8"] {
|
||
-moz-tab-size: 8;
|
||
tab-size: 8;
|
||
}
|
||
|
||
.markdown-body .tab-size[data-tab-size="9"] {
|
||
-moz-tab-size: 9;
|
||
tab-size: 9;
|
||
}
|
||
|
||
.markdown-body .tab-size[data-tab-size="10"] {
|
||
-moz-tab-size: 10;
|
||
tab-size: 10;
|
||
}
|
||
|
||
.markdown-body .tab-size[data-tab-size="11"] {
|
||
-moz-tab-size: 11;
|
||
tab-size: 11;
|
||
}
|
||
|
||
.markdown-body .tab-size[data-tab-size="12"] {
|
||
-moz-tab-size: 12;
|
||
tab-size: 12;
|
||
}
|
||
|
||
.markdown-body .task-list-item {
|
||
list-style-type: none;
|
||
}
|
||
|
||
.markdown-body .task-list-item+.task-list-item {
|
||
margin-top: 3px;
|
||
}
|
||
|
||
.markdown-body .task-list-item input {
|
||
margin: 0 .2em .25em -1.6em;
|
||
vertical-align: middle;
|
||
}
|
||
|
||
.markdown-body hr {
|
||
border-bottom-color: #eee;
|
||
}
|
||
|
||
.markdown-body .pl-0 {
|
||
padding-left: 0!important;
|
||
}
|
||
|
||
.markdown-body .pl-1 {
|
||
padding-left: 4px!important;
|
||
}
|
||
|
||
.markdown-body .pl-2 {
|
||
padding-left: 8px!important;
|
||
}
|
||
|
||
.markdown-body .pl-3 {
|
||
padding-left: 16px!important;
|
||
}
|
||
|
||
.markdown-body .pl-4 {
|
||
padding-left: 24px!important;
|
||
}
|
||
|
||
.markdown-body .pl-5 {
|
||
padding-left: 32px!important;
|
||
}
|
||
|
||
.markdown-body .pl-6 {
|
||
padding-left: 40px!important;
|
||
}
|
||
|
||
.markdown-body .pl-7 {
|
||
padding-left: 48px!important;
|
||
}
|
||
|
||
.markdown-body .pl-8 {
|
||
padding-left: 64px!important;
|
||
}
|
||
|
||
.markdown-body .pl-9 {
|
||
padding-left: 80px!important;
|
||
}
|
||
|
||
.markdown-body .pl-10 {
|
||
padding-left: 96px!important;
|
||
}
|
||
|
||
.markdown-body .pl-11 {
|
||
padding-left: 112px!important;
|
||
}
|
||
|
||
.markdown-body .pl-12 {
|
||
padding-left: 128px!important;
|
||
}
|
||
|
||
/*# sourceURL=webpack://./node_modules/github-markdown-css/github-markdown.css */
|
||
/*# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8uL25vZGVfbW9kdWxlcy9naXRodWItbWFya2Rvd24tY3NzL2dpdGh1Yi1tYXJrZG93bi5jc3MiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7RUFDRSwwQkFBMEI7RUFDMUIsMkRBQXF0RTtBQUN2dEU7O0FBRUE7RUFDRSxxQkFBcUI7RUFDckIsa0JBQWtCO0VBQ2xCLDJCQUEyQjtBQUM3Qjs7QUFFQTtFQUNFLFdBQVc7RUFDWCxjQUFjO0VBQ2Qsa0JBQWtCO0VBQ2xCLGtCQUFrQjtBQUNwQjs7QUFFQTtFQUNFLGFBQWE7QUFDZjs7QUFFQTs7Ozs7O0VBTUUsY0FBYztFQUNkLHNCQUFzQjtFQUN0QixrQkFBa0I7QUFDcEI7O0FBRUE7Ozs7OztFQU1FLHFCQUFxQjtBQUN2Qjs7QUFFQTs7Ozs7O0VBTUUsbUJBQW1CO0FBQ3JCOztBQUVBO0VBQ0UsMEJBQTBCO0VBQzFCLDhCQUE4QjtFQUM5QixjQUFjO0VBQ2QsZ0JBQWdCO0VBQ2hCLGtJQUFrSTtFQUNsSSxlQUFlO0VBQ2YsZ0JBQWdCO0VBQ2hCLHFCQUFxQjtBQUN2Qjs7QUFFQTtFQUNFLGNBQWM7QUFDaEI7O0FBRUE7O0VBRUUsY0FBYztBQUNoQjs7QUFFQTs7RUFFRSxjQUFjO0FBQ2hCOztBQUVBOztFQUVFLGNBQWM7QUFDaEI7O0FBRUE7RUFDRSxjQUFjO0FBQ2hCOztBQUVBO0VBQ0UsY0FBYztBQUNoQjs7QUFFQTs7Ozs7OztFQU9FLGNBQWM7QUFDaEI7O0FBRUE7O0VBRUUsY0FBYztBQUNoQjs7QUFFQTtFQUNFLGNBQWM7QUFDaEI7O0FBRUE7RUFDRSx5QkFBeUI7RUFDekIsY0FBYztBQUNoQjs7QUFFQTtFQUNFLHlCQUF5QjtFQUN6QixjQUFjO0FBQ2hCOztBQUVBO0VBQ0UsYUFBYTtBQUNmOztBQUVBO0VBQ0UsY0FBYztFQUNkLGdCQUFnQjtBQUNsQjs7QUFFQTtFQUNFLGNBQWM7QUFDaEI7O0FBRUE7OztFQUdFLGNBQWM7RUFDZCxnQkFBZ0I7QUFDbEI7O0FBRUE7RUFDRSxjQUFjO0VBQ2Qsa0JBQWtCO0FBQ3BCOztBQUVBO0VBQ0UsY0FBYztFQUNkLGdCQUFnQjtBQUNsQjs7QUFFQTtFQUNFLHlCQUF5QjtFQUN6QixjQUFjO0FBQ2hCOztBQUVBO0VBQ0UseUJBQXlCO0VBQ3pCLGNBQWM7QUFDaEI7O0FBRUE7RUFDRSx5QkFBeUI7RUFDekIsY0FBYztBQUNoQjs7QUFFQTtFQUNFLHlCQUF5QjtFQUN6QixjQUFjO0FBQ2hCOztBQUVBO0VBQ0UsY0FBYztFQUNkLGdCQUFnQjtBQUNsQjs7QUFFQTtFQUNFLGNBQWM7QUFDaEI7O0FBRUE7RUFDRSxjQUFjO0FBQ2hCOztBQUVBO0VBQ0UsY0FBYztFQUNkLDBCQUEwQjtBQUM1Qjs7QUFFQTtFQUNFLGNBQWM7QUFDaEI7O0FBRUE7RUFDRSxrQkFBa0I7QUFDcEI7O0FBRUE7RUFDRSw2QkFBNkI7QUFDL0I7O0FBRUE7O0VBRUUsZ0JBQWdCO0FBQ2xCOztBQUVBO0VBQ0Usb0JBQW9CO0VBQ3BCLG1CQUFtQjtBQUNyQjs7QUFFQTtFQUNFLGNBQWM7RUFDZCxlQUFlO0FBQ2pCOztBQUVBO0VBQ0Usa0JBQWtCO0FBQ3BCOztBQUVBOzs7RUFHRSxnQ0FBZ0M7RUFDaEMsY0FBYztBQUNoQjs7QUFFQTtFQUNFLHVCQUF1QjtFQUN2QixTQUFTO0VBQ1QsaUJBQWlCO0FBQ25COztBQUVBO0VBQ0UsYUFBYTtFQUNiLFNBQVM7QUFDWDs7QUFFQTtFQUNFLGlCQUFpQjtBQUNuQjs7QUFFQTtFQUNFLHNCQUFzQjtFQUN0QixVQUFVO0FBQ1o7O0FBRUE7RUFDRSxzQkFBc0I7QUFDeEI7O0FBRUE7RUFDRSxvQkFBb0I7RUFDcEIsa0JBQWtCO0VBQ2xCLG9CQUFvQjtBQUN0Qjs7QUFFQTtFQUNFLGNBQWM7RUFDZCxxQkFBcUI7QUFDdkI7O0FBRUE7RUFDRSwwQkFBMEI7QUFDNUI7O0FBRUE7RUFDRSxnQkFBZ0I7QUFDbEI7O0FBRUE7RUFDRSx1QkFBdUI7RUFDdkIsU0FBUztFQUNULGdDQUFnQztFQUNoQyxTQUFTO0VBQ1QsY0FBYztFQUNkLGdCQUFnQjtBQUNsQjs7QUFFQTtFQUNFLFdBQVc7RUFDWCxjQUFjO0FBQ2hCOztBQUVBO0VBQ0UsV0FBVztFQUNYLFdBQVc7RUFDWCxjQUFjO0FBQ2hCOztBQUVBO0VBQ0UseUJBQXlCO0VBQ3pCLGlCQUFpQjtBQUNuQjs7QUFFQTs7RUFFRSxVQUFVO0FBQ1o7O0FBRUE7RUFDRSxlQUFlO0FBQ2pCOztBQUVBOzs7Ozs7RUFNRSxnQkFBZ0I7RUFDaEIsYUFBYTtBQUNmOztBQUVBO0VBQ0UsZUFBZTtBQUNqQjs7QUFFQTs7RUFFRSxnQkFBZ0I7QUFDbEI7O0FBRUE7RUFDRSxlQUFlO0FBQ2pCOztBQUVBO0VBQ0UsZUFBZTtBQUNqQjs7QUFFQTs7RUFFRSxnQkFBZ0I7QUFDbEI7O0FBRUE7RUFDRSxlQUFlO0FBQ2pCOztBQUVBO0VBQ0UsZUFBZTtBQUNqQjs7QUFFQTs7RUFFRSxnQkFBZ0I7QUFDbEI7O0FBRUE7RUFDRSxlQUFlO0FBQ2pCOztBQUVBO0VBQ0UsbUJBQW1CO0VBQ25CLGFBQWE7QUFDZjs7QUFFQTtFQUNFLFNBQVM7QUFDWDs7QUFFQTs7RUFFRSxnQkFBZ0I7RUFDaEIsYUFBYTtFQUNiLGVBQWU7QUFDakI7O0FBRUE7O0VBRUUsNEJBQTRCO0FBQzlCOztBQUVBOzs7O0VBSUUsNEJBQTRCO0FBQzlCOztBQUVBO0VBQ0UsY0FBYztBQUNoQjs7QUFFQTs7RUFFRSw0RUFBNEU7RUFDNUUsZUFBZTtBQUNqQjs7QUFFQTtFQUNFLGdCQUFnQjtFQUNoQixhQUFhO0FBQ2Y7O0FBRUE7O0VBRUUsd0JBQXdCO0VBQ3hCLGdCQUFnQjtFQUNoQixTQUFTO0FBQ1g7O0FBRUE7RUFDRSxtQ0FBbUM7QUFDckM7O0FBRUE7RUFDRSxtQkFBbUI7QUFDckI7O0FBRUE7RUFDRSwwQ0FBMEM7QUFDNUM7O0FBRUE7RUFDRSw0QkFBNEI7QUFDOUI7O0FBRUE7RUFDRSxnQ0FBZ0M7QUFDbEM7O0FBRUE7RUFDRSxtQ0FBbUM7QUFDckM7O0FBRUE7RUFDRSx3QkFBd0I7QUFDMUI7O0FBRUE7RUFDRSwwQkFBMEI7QUFDNUI7O0FBRUE7RUFDRSw0QkFBNEI7RUFDNUIseUJBQXlCO0FBQzNCOztBQUVBO0VBQ0UseUJBQXlCO0FBQzNCOztBQUVBO0VBQ0UsMkJBQTJCO0VBQzNCLHdCQUF3QjtBQUMxQjs7QUFFQTtFQUNFLDJCQUEyQjtBQUM3Qjs7QUFFQTtFQUNFLDJCQUEyQjtBQUM3Qjs7QUFFQTtFQUNFLDZCQUE2QjtFQUM3QiwwQkFBMEI7QUFDNUI7O0FBRUE7O0VBRUUsNEJBQTRCO0FBQzlCOztBQUVBO0VBQ0UsNkJBQTZCO0FBQy9COztBQUVBO0VBQ0UsNEJBQTRCO0FBQzlCOztBQUVBO0VBQ0UsNEJBQTRCO0FBQzlCOztBQUVBO0VBQ0UsNEJBQTRCO0FBQzlCOztBQUVBO0VBQ0UseUJBQXlCO0FBQzNCOztBQUVBO0VBQ0UsMkJBQTJCO0FBQzdCOztBQUVBO0VBQ0UsMEJBQTBCO0FBQzVCOztBQUVBO0VBQ0UsV0FBVztFQUNYLGNBQWM7QUFDaEI7O0FBRUE7RUFDRSxXQUFXO0VBQ1gsV0FBVztFQUNYLGNBQWM7QUFDaEI7O0FBRUE7RUFDRSx1QkFBdUI7QUFDekI7O0FBRUE7RUFDRSwwQkFBMEI7QUFDNUI7O0FBRUE7RUFDRSxjQUFjO0VBQ2QscUJBQXFCO0FBQ3ZCOztBQUVBOzs7Ozs7O0VBT0UsbUJBQW1CO0VBQ25CLGFBQWE7QUFDZjs7QUFFQTtFQUNFLHlCQUF5QjtFQUN6QixTQUFTO0VBQ1QsYUFBYTtFQUNiLGNBQWM7RUFDZCxVQUFVO0FBQ1o7O0FBRUE7RUFDRSxnQ0FBZ0M7RUFDaEMsY0FBYztFQUNkLGNBQWM7QUFDaEI7O0FBRUE7RUFDRSxhQUFhO0FBQ2Y7O0FBRUE7RUFDRSxnQkFBZ0I7QUFDbEI7O0FBRUE7RUFDRSx5QkFBeUI7RUFDekIseUJBQXlCO0VBQ3pCLDRCQUE0QjtFQUM1QixrQkFBa0I7RUFDbEIsa0NBQWtDO0VBQ2xDLGNBQWM7RUFDZCxxQkFBcUI7RUFDckIsZUFBZTtFQUNmLGlCQUFpQjtFQUNqQixnQkFBZ0I7RUFDaEIsc0JBQXNCO0FBQ3hCOztBQUVBOzs7Ozs7RUFNRSxnQkFBZ0I7RUFDaEIsaUJBQWlCO0VBQ2pCLG1CQUFtQjtFQUNuQixnQkFBZ0I7QUFDbEI7O0FBRUE7RUFDRSxjQUFjO0FBQ2hCOztBQUVBOztFQUVFLGdDQUFnQztFQUNoQyxvQkFBb0I7QUFDdEI7O0FBRUE7RUFDRSxnQkFBZ0I7QUFDbEI7O0FBRUE7RUFDRSxpQkFBaUI7QUFDbkI7O0FBRUE7RUFDRSxjQUFjO0FBQ2hCOztBQUVBO0VBQ0UsaUJBQWlCO0FBQ25COztBQUVBO0VBQ0UsY0FBYztFQUNkLGdCQUFnQjtBQUNsQjs7QUFFQTs7RUFFRSxpQkFBaUI7QUFDbkI7O0FBRUE7Ozs7RUFJRSxnQkFBZ0I7RUFDaEIsYUFBYTtBQUNmOztBQUVBO0VBQ0Usb0JBQW9CO0FBQ3RCOztBQUVBO0VBQ0UsZ0JBQWdCO0FBQ2xCOztBQUVBO0VBQ0UsaUJBQWlCO0FBQ25COztBQUVBO0VBQ0UsVUFBVTtBQUNaOztBQUVBO0VBQ0UsY0FBYztFQUNkLGtCQUFrQjtFQUNsQixnQkFBZ0I7RUFDaEIsZ0JBQWdCO0VBQ2hCLFVBQVU7QUFDWjs7QUFFQTtFQUNFLG1CQUFtQjtFQUNuQixlQUFlO0FBQ2pCOztBQUVBO0VBQ0UsY0FBYztFQUNkLGNBQWM7RUFDZCxXQUFXO0FBQ2I7O0FBRUE7RUFDRSxnQkFBZ0I7QUFDbEI7O0FBRUE7O0VBRUUseUJBQXlCO0VBQ3pCLGlCQUFpQjtBQUNuQjs7QUFFQTtFQUNFLHNCQUFzQjtFQUN0Qiw2QkFBNkI7QUFDL0I7O0FBRUE7RUFDRSx5QkFBeUI7QUFDM0I7O0FBRUE7RUFDRSxzQkFBc0I7RUFDdEIsdUJBQXVCO0VBQ3ZCLGVBQWU7QUFDakI7O0FBRUE7RUFDRSxrQkFBa0I7QUFDcEI7O0FBRUE7RUFDRSxtQkFBbUI7QUFDckI7O0FBRUE7RUFDRSxvQ0FBb0M7RUFDcEMsa0JBQWtCO0VBQ2xCLGNBQWM7RUFDZCxTQUFTO0VBQ1Qsa0JBQWtCO0FBQ3BCOztBQUVBO0VBQ0UsaUJBQWlCO0FBQ25COztBQUVBO0VBQ0UsdUJBQXVCO0VBQ3ZCLFNBQVM7RUFDVCxlQUFlO0VBQ2YsU0FBUztFQUNULFVBQVU7RUFDVixnQkFBZ0I7RUFDaEIsa0JBQWtCO0FBQ3BCOztBQUVBO0VBQ0UsbUJBQW1CO0FBQ3JCOztBQUVBO0VBQ0UsZ0JBQWdCO0VBQ2hCLGtCQUFrQjtBQUNwQjs7QUFFQTs7RUFFRSx5QkFBeUI7RUFDekIsa0JBQWtCO0VBQ2xCLGNBQWM7RUFDZCxpQkFBaUI7RUFDakIsY0FBYztFQUNkLGFBQWE7QUFDZjs7QUFFQTtFQUNFLDZCQUE2QjtFQUM3QixTQUFTO0VBQ1QsZUFBZTtFQUNmLG9CQUFvQjtFQUNwQixTQUFTO0VBQ1QsZUFBZTtFQUNmLGlCQUFpQjtFQUNqQixVQUFVO0VBQ1YsaUJBQWlCO0FBQ25COztBQUVBO0VBQ0UsY0FBYztFQUNkLHFCQUFxQjtFQUNyQiw0RUFBNEU7RUFDNUUsY0FBYztBQUNoQjs7QUFFQTtFQUNFLDhCQUE4QjtFQUM5QiwrQkFBK0I7RUFDL0IsZ0JBQWdCO0VBQ2hCLGtCQUFrQjtBQUNwQjs7QUFFQTtFQUNFLGlCQUFpQjtFQUNqQixnQkFBZ0I7QUFDbEI7O0FBRUE7RUFDRSxzQkFBc0I7RUFDdEIscUJBQXFCO0VBQ3JCLHlCQUF5QjtFQUN6Qix3QkFBd0I7RUFDeEIsZUFBZTtFQUNmLDRFQUE0RTtFQUM1RSxlQUFlO0VBQ2YsaUJBQWlCO0VBQ2pCLGVBQWU7RUFDZixrQkFBa0I7RUFDbEIsbUJBQW1CO0VBQ25CLGlCQUFpQjtFQUNqQixpQkFBaUI7RUFDakIsbUJBQW1CO0VBQ25CLG1CQUFtQjtFQUNuQixTQUFTO0FBQ1g7O0FBRUE7RUFDRSx3QkFBd0I7QUFDMUI7O0FBRUE7RUFDRSwrQkFBK0I7QUFDakM7O0FBRUE7RUFDRSxpQkFBaUI7RUFDakIsa0JBQWtCO0VBQ2xCLG1CQUFtQjtFQUNuQixrQkFBa0I7RUFDbEIsbUJBQW1CO0FBQ3JCOztBQUVBO0VBQ0UsY0FBYztFQUNkLDRFQUE0RTtFQUM1RSxlQUFlO0VBQ2YsaUJBQWlCO0VBQ2pCLGdCQUFnQjtFQUNoQixpQkFBaUI7QUFDbkI7O0FBRUE7O0VBRUUsbUJBQW1CO0VBQ25CLGVBQWU7QUFDakI7O0FBRUE7RUFDRSx5QkFBeUI7RUFDekIseUJBQXlCO0VBQ3pCLDRCQUE0QjtFQUM1QixrQkFBa0I7RUFDbEIsa0NBQWtDO0VBQ2xDLGNBQWM7RUFDZCxxQkFBcUI7RUFDckIsMEVBQTBFO0VBQzFFLGlCQUFpQjtFQUNqQixnQkFBZ0I7RUFDaEIsc0JBQXNCO0FBQ3hCOztBQUVBO0VBQ0UscUJBQXFCO0VBQ3JCLGtCQUFrQjtFQUNsQixVQUFVO0FBQ1o7O0FBRUE7RUFDRSxnQkFBZ0I7RUFDaEIsV0FBVztBQUNiOztBQUVBO0VBQ0UsZ0JBQWdCO0VBQ2hCLFdBQVc7QUFDYjs7QUFFQTtFQUNFLGdCQUFnQjtFQUNoQixXQUFXO0FBQ2I7O0FBRUE7RUFDRSxnQkFBZ0I7RUFDaEIsV0FBVztBQUNiOztBQUVBO0VBQ0UsZ0JBQWdCO0VBQ2hCLFdBQVc7QUFDYjs7QUFFQTtFQUNFLGdCQUFnQjtFQUNoQixXQUFXO0FBQ2I7O0FBRUE7RUFDRSxnQkFBZ0I7RUFDaEIsV0FBVztBQUNiOztBQUVBO0VBQ0UsZ0JBQWdCO0VBQ2hCLFdBQVc7QUFDYjs7QUFFQTtFQUNFLGdCQUFnQjtFQUNoQixXQUFXO0FBQ2I7O0FBRUE7RUFDRSxpQkFBaUI7RUFDakIsWUFBWTtBQUNkOztBQUVBO0VBQ0UsaUJBQWlCO0VBQ2pCLFlBQVk7QUFDZDs7QUFFQTtFQUNFLGlCQUFpQjtFQUNqQixZQUFZO0FBQ2Q7O0FBRUE7RUFDRSxxQkFBcUI7QUFDdkI7O0FBRUE7RUFDRSxlQUFlO0FBQ2pCOztBQUVBO0VBQ0UsMkJBQTJCO0VBQzNCLHNCQUFzQjtBQUN4Qjs7QUFFQTtFQUNFLHlCQUF5QjtBQUMzQjs7QUFFQTtFQUNFLHlCQUF5QjtBQUMzQjs7QUFFQTtFQUNFLDJCQUEyQjtBQUM3Qjs7QUFFQTtFQUNFLDJCQUEyQjtBQUM3Qjs7QUFFQTtFQUNFLDRCQUE0QjtBQUM5Qjs7QUFFQTtFQUNFLDRCQUE0QjtBQUM5Qjs7QUFFQTtFQUNFLDRCQUE0QjtBQUM5Qjs7QUFFQTtFQUNFLDRCQUE0QjtBQUM5Qjs7QUFFQTtFQUNFLDRCQUE0QjtBQUM5Qjs7QUFFQTtFQUNFLDRCQUE0QjtBQUM5Qjs7QUFFQTtFQUNFLDRCQUE0QjtBQUM5Qjs7QUFFQTtFQUNFLDRCQUE0QjtBQUM5Qjs7QUFFQTtFQUNFLDZCQUE2QjtBQUMvQjs7QUFFQTtFQUNFLDZCQUE2QjtBQUMvQiIsInNvdXJjZVJvb3QiOiIifQ== */
|
||
</style>
|
||
<style>
|
||
/**
|
||
* prism.js default theme for JavaScript, CSS and HTML
|
||
* Based on dabblet (http://dabblet.com)
|
||
* @author Lea Verou
|
||
*/
|
||
|
||
code[class*="language-"],
|
||
pre[class*="language-"] {
|
||
color: black;
|
||
background: none;
|
||
text-shadow: 0 1px white;
|
||
font-family: Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace;
|
||
font-size: 1em;
|
||
text-align: left;
|
||
white-space: pre;
|
||
word-spacing: normal;
|
||
word-break: normal;
|
||
word-wrap: normal;
|
||
line-height: 1.5;
|
||
|
||
-moz-tab-size: 4;
|
||
-o-tab-size: 4;
|
||
tab-size: 4;
|
||
|
||
-webkit-hyphens: none;
|
||
-moz-hyphens: none;
|
||
-ms-hyphens: none;
|
||
hyphens: none;
|
||
}
|
||
|
||
pre[class*="language-"]::-moz-selection, pre[class*="language-"] ::-moz-selection,
|
||
code[class*="language-"]::-moz-selection, code[class*="language-"] ::-moz-selection {
|
||
text-shadow: none;
|
||
background: #b3d4fc;
|
||
}
|
||
|
||
pre[class*="language-"]::selection, pre[class*="language-"] ::selection,
|
||
code[class*="language-"]::selection, code[class*="language-"] ::selection {
|
||
text-shadow: none;
|
||
background: #b3d4fc;
|
||
}
|
||
|
||
@media print {
|
||
code[class*="language-"],
|
||
pre[class*="language-"] {
|
||
text-shadow: none;
|
||
}
|
||
}
|
||
|
||
/* Code blocks */
|
||
pre[class*="language-"] {
|
||
padding: 1em;
|
||
margin: .5em 0;
|
||
overflow: auto;
|
||
}
|
||
|
||
:not(pre) > code[class*="language-"],
|
||
pre[class*="language-"] {
|
||
background: #f5f2f0;
|
||
}
|
||
|
||
/* Inline code */
|
||
:not(pre) > code[class*="language-"] {
|
||
padding: .1em;
|
||
border-radius: .3em;
|
||
white-space: normal;
|
||
}
|
||
|
||
.token.comment,
|
||
.token.prolog,
|
||
.token.doctype,
|
||
.token.cdata {
|
||
color: slategray;
|
||
}
|
||
|
||
.token.punctuation {
|
||
color: #999;
|
||
}
|
||
|
||
.token.namespace {
|
||
opacity: .7;
|
||
}
|
||
|
||
.token.property,
|
||
.token.tag,
|
||
.token.boolean,
|
||
.token.number,
|
||
.token.constant,
|
||
.token.symbol,
|
||
.token.deleted {
|
||
color: #905;
|
||
}
|
||
|
||
.token.selector,
|
||
.token.attr-name,
|
||
.token.string,
|
||
.token.char,
|
||
.token.builtin,
|
||
.token.inserted {
|
||
color: #690;
|
||
}
|
||
|
||
.token.operator,
|
||
.token.entity,
|
||
.token.url,
|
||
.language-css .token.string,
|
||
.style .token.string {
|
||
color: #9a6e3a;
|
||
/* This background color was intended by the author of this theme. */
|
||
background: hsla(0, 0%, 100%, .5);
|
||
}
|
||
|
||
.token.atrule,
|
||
.token.attr-value,
|
||
.token.keyword {
|
||
color: #07a;
|
||
}
|
||
|
||
.token.function,
|
||
.token.class-name {
|
||
color: #DD4A68;
|
||
}
|
||
|
||
.token.regex,
|
||
.token.important,
|
||
.token.variable {
|
||
color: #e90;
|
||
}
|
||
|
||
.token.important,
|
||
.token.bold {
|
||
font-weight: bold;
|
||
}
|
||
.token.italic {
|
||
font-style: italic;
|
||
}
|
||
|
||
.token.entity {
|
||
cursor: help;
|
||
}
|
||
|
||
/*# sourceURL=webpack://./node_modules/prismjs/themes/prism.css */
|
||
/*# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8uL25vZGVfbW9kdWxlcy9wcmlzbWpzL3RoZW1lcy9wcmlzbS5jc3MiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7RUFJRTs7QUFFRjs7Q0FFQyxZQUFZO0NBQ1osZ0JBQWdCO0NBQ2hCLHdCQUF3QjtDQUN4QixzRUFBc0U7Q0FDdEUsY0FBYztDQUNkLGdCQUFnQjtDQUNoQixnQkFBZ0I7Q0FDaEIsb0JBQW9CO0NBQ3BCLGtCQUFrQjtDQUNsQixpQkFBaUI7Q0FDakIsZ0JBQWdCOztDQUVoQixnQkFBZ0I7Q0FDaEIsY0FBYztDQUNkLFdBQVc7O0NBRVgscUJBQXFCO0NBQ3JCLGtCQUFrQjtDQUNsQixpQkFBaUI7Q0FDakIsYUFBYTtBQUNkOztBQUVBOztDQUVDLGlCQUFpQjtDQUNqQixtQkFBbUI7QUFDcEI7O0FBRUE7O0NBRUMsaUJBQWlCO0NBQ2pCLG1CQUFtQjtBQUNwQjs7QUFFQTtDQUNDOztFQUVDLGlCQUFpQjtDQUNsQjtBQUNEOztBQUVBLGdCQUFnQjtBQUNoQjtDQUNDLFlBQVk7Q0FDWixjQUFjO0NBQ2QsY0FBYztBQUNmOztBQUVBOztDQUVDLG1CQUFtQjtBQUNwQjs7QUFFQSxnQkFBZ0I7QUFDaEI7Q0FDQyxhQUFhO0NBQ2IsbUJBQW1CO0NBQ25CLG1CQUFtQjtBQUNwQjs7QUFFQTs7OztDQUlDLGdCQUFnQjtBQUNqQjs7QUFFQTtDQUNDLFdBQVc7QUFDWjs7QUFFQTtDQUNDLFdBQVc7QUFDWjs7QUFFQTs7Ozs7OztDQU9DLFdBQVc7QUFDWjs7QUFFQTs7Ozs7O0NBTUMsV0FBVztBQUNaOztBQUVBOzs7OztDQUtDLGNBQWM7Q0FDZCxvRUFBb0U7Q0FDcEUsaUNBQWlDO0FBQ2xDOztBQUVBOzs7Q0FHQyxXQUFXO0FBQ1o7O0FBRUE7O0NBRUMsY0FBYztBQUNmOztBQUVBOzs7Q0FHQyxXQUFXO0FBQ1o7O0FBRUE7O0NBRUMsaUJBQWlCO0FBQ2xCO0FBQ0E7Q0FDQyxrQkFBa0I7QUFDbkI7O0FBRUE7Q0FDQyxZQUFZO0FBQ2IiLCJzb3VyY2VSb290IjoiIn0= */
|
||
</style>
|
||
<style>
|
||
|
||
</style>
|
||
<style>
|
||
.markdown-body {
|
||
font-family: -apple-system,Segoe UI,Helvetica,Arial,sans-serif,Apple Color Emoji,Segoe UI Emoji;
|
||
box-sizing: border-box;
|
||
min-width: 200px;
|
||
max-width: 980px;
|
||
margin: 0 auto;
|
||
padding: 45px;
|
||
}
|
||
|
||
@media not print {
|
||
.markdown-body {
|
||
padding: 45px;
|
||
}
|
||
|
||
@media (max-width: 767px) {
|
||
.markdown-body {
|
||
padding: 15px;
|
||
}
|
||
}
|
||
}
|
||
|
||
.hf-container {
|
||
color: #24292e;
|
||
line-height: 1.3;
|
||
}
|
||
|
||
.markdown-body .highlight pre,
|
||
.markdown-body pre {
|
||
white-space: pre-wrap;
|
||
}
|
||
.markdown-body table {
|
||
display: table;
|
||
}
|
||
.markdown-body img[data-align="center"] {
|
||
display: block;
|
||
margin: 0 auto;
|
||
}
|
||
.markdown-body img[data-align="right"] {
|
||
display: block;
|
||
margin: 0 0 0 auto;
|
||
}
|
||
.markdown-body li.task-list-item {
|
||
list-style-type: none;
|
||
}
|
||
.markdown-body li > [type=checkbox] {
|
||
margin: 0 0 0 -1.3em;
|
||
}
|
||
.markdown-body input[type="checkbox"] ~ p {
|
||
margin-top: 0;
|
||
display: inline-block;
|
||
}
|
||
.markdown-body ol ol,
|
||
.markdown-body ul ol {
|
||
list-style-type: decimal;
|
||
}
|
||
.markdown-body ol ol ol,
|
||
.markdown-body ol ul ol,
|
||
.markdown-body ul ol ol,
|
||
.markdown-body ul ul ol {
|
||
list-style-type: decimal;
|
||
}
|
||
</style>
|
||
<style>.markdown-body a.footnote-ref {
|
||
text-decoration: none;
|
||
}
|
||
|
||
.footnotes {
|
||
font-size: .85em;
|
||
opacity: .8;
|
||
}
|
||
|
||
.footnotes li[role="doc-endnote"] {
|
||
position: relative;
|
||
}
|
||
|
||
.footnotes .footnote-back {
|
||
position: absolute;
|
||
font-family: initial;
|
||
top: .2em;
|
||
right: 1em;
|
||
text-decoration: none;
|
||
}
|
||
|
||
.inline-math.invalid,
|
||
.multiple-math.invalid {
|
||
color: rgb(255, 105, 105);
|
||
}
|
||
|
||
.toc-container {
|
||
width: 100%;
|
||
}
|
||
|
||
.toc-container .toc-title {
|
||
font-weight: 700;
|
||
font-size: 1.2em;
|
||
margin-bottom: 0;
|
||
}
|
||
|
||
.toc-container li,
|
||
.toc-container ul,
|
||
.toc-container ul li {
|
||
list-style: none !important;
|
||
}
|
||
|
||
.toc-container > ul {
|
||
padding-left: 0;
|
||
}
|
||
|
||
.toc-container ul li span {
|
||
display : flex;
|
||
}
|
||
|
||
.toc-container ul li span a {
|
||
color: inherit;
|
||
text-decoration: none;
|
||
}
|
||
.toc-container ul li span a:hover {
|
||
color: inherit;
|
||
text-decoration: none;
|
||
}
|
||
|
||
.toc-container ul li span span.dots {
|
||
flex: 1;
|
||
height: 0.65em;
|
||
margin: 0 10px;
|
||
border-bottom: 2px dotted black;
|
||
}
|
||
|
||
/*# sourceURL=webpack://./src/muya/lib/assets/styles/exportStyle.css */
|
||
/*# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8uL3NyYy9tdXlhL2xpYi9hc3NldHMvc3R5bGVzL2V4cG9ydFN0eWxlLmNzcyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTtFQUNFLHFCQUFxQjtBQUN2Qjs7QUFFQTtFQUNFLGdCQUFnQjtFQUNoQixXQUFXO0FBQ2I7O0FBRUE7RUFDRSxrQkFBa0I7QUFDcEI7O0FBRUE7RUFDRSxrQkFBa0I7RUFDbEIsb0JBQW9CO0VBQ3BCLFNBQVM7RUFDVCxVQUFVO0VBQ1YscUJBQXFCO0FBQ3ZCOztBQUVBOztFQUVFLHlCQUF5QjtBQUMzQjs7QUFFQTtFQUNFLFdBQVc7QUFDYjs7QUFFQTtFQUNFLGdCQUFnQjtFQUNoQixnQkFBZ0I7RUFDaEIsZ0JBQWdCO0FBQ2xCOztBQUVBOzs7RUFHRSwyQkFBMkI7QUFDN0I7O0FBRUE7RUFDRSxlQUFlO0FBQ2pCOztBQUVBO0VBQ0UsY0FBYztBQUNoQjs7QUFFQTtFQUNFLGNBQWM7RUFDZCxxQkFBcUI7QUFDdkI7QUFDQTtFQUNFLGNBQWM7RUFDZCxxQkFBcUI7QUFDdkI7O0FBRUE7RUFDRSxPQUFPO0VBQ1AsY0FBYztFQUNkLGNBQWM7RUFDZCwrQkFBK0I7QUFDakMiLCJzb3VyY2VSb290IjoiIn0= */</style>
|
||
<style>.markdown-body{}pre.front-matter{display:none!important;}</style>
|
||
</head>
|
||
<body>
|
||
<article class="markdown-body"><div class="toc-container"><p class="toc-title">目录</p><ul class="toc-list"><li><span><a class="toc-h1" href="#预备知识">预备知识</a><span class="dots"></span></span><ul><li><span><a class="toc-h2" href="#cmake是什么">CMake是什么</a><span class="dots"></span></span></li><li><span><a class="toc-h2" href="#环境搭建与学习准备">环境搭建与学习准备</a><span class="dots"></span></span></li><li><span><a class="toc-h2" href="#前置条件">前置条件</a><span class="dots"></span></span><ul><li><span><a class="toc-h3" href="#ubuntu安装cmake">Ubuntu安装CMake</a><span class="dots"></span></span></li><li><span><a class="toc-h3" href="#windows安装cmake">Windows安装CMake</a><span class="dots"></span></span></li><li><span><a class="toc-h3" href="#学习材料">学习材料</a><span class="dots"></span></span></li></ul></li></ul></li><li><span><a class="toc-h1" href="#cmake-tutorial">CMake Tutorial</a><span class="dots"></span></span><ul><li><span><a class="toc-h2" href="#第一步-起点">第一步 起点</a><span class="dots"></span></span><ul><li><span><a class="toc-h3" href="#练习1--最简单的cmake项目">练习1 最简单的CMake项目</a><span class="dots"></span></span></li><li><span><a class="toc-h3" href="#练习2-指定c标准">练习2 指定C++标准</a><span class="dots"></span></span></li><li><span><a class="toc-h3" href="#练习3-添加版本号和配置头文件">练习3 添加版本号和配置头文件</a><span class="dots"></span></span></li></ul></li><li><span><a class="toc-h2" href="#第二步-加个库">第二步 加个库</a><span class="dots"></span></span><ul><li><span><a class="toc-h3" href="#练习1-创建库文件">练习1 创建库文件</a><span class="dots"></span></span></li><li><span><a class="toc-h3" href="#练习2-库文件可选编译">练习2 库文件可选编译</a><span class="dots"></span></span></li></ul></li><li><span><a class="toc-h2" href="#第三步-添加使用依赖">第三步 添加使用依赖</a><span class="dots"></span></span><ul><li><span><a class="toc-h3" href="#练习1-为库添加使用依赖">练习1 为库添加使用依赖</a><span class="dots"></span></span></li></ul></li><li><span><a class="toc-h2" href="#第四步-生成器表达式">第四步 生成器表达式</a><span class="dots"></span></span><ul><li><span><a class="toc-h3" href="#练习1-用接口库设置c标准">练习1 用接口库设置C++标准</a><span class="dots"></span></span></li><li><span><a class="toc-h3" href="#练习2-添加编译警告选项">练习2 添加编译警告选项</a><span class="dots"></span></span></li></ul></li><li><span><a class="toc-h2" href="#第五步-安装与测试">第五步 安装与测试</a><span class="dots"></span></span><ul><li><span><a class="toc-h3" href="#练习1-安装规则">练习1 安装规则</a><span class="dots"></span></span></li><li><span><a class="toc-h3" href="#练习2-测试支持">练习2 测试支持</a><span class="dots"></span></span></li></ul></li><li><span><a class="toc-h2" href="#第六步-添加测试面板支持">第六步 添加测试面板支持</a><span class="dots"></span></span><ul><li><span><a class="toc-h3" href="#练习1-发送测试结果到测试面板">练习1 发送测试结果到测试面板</a><span class="dots"></span></span></li></ul></li><li><span><a class="toc-h2" href="#第七步-添加系统特性检查">第七步 添加系统特性检查</a><span class="dots"></span></span><ul><li><span><a class="toc-h3" href="#练习1-评估依赖可用性">练习1 评估依赖可用性</a><span class="dots"></span></span></li></ul></li><li><span><a class="toc-h2" href="#第八步-添加自定义命令及用自定义命令生成文件">第八步 添加自定义命令及用自定义命令生成文件</a><span class="dots"></span></span></li><li><span><a class="toc-h2" href="#第九步-打包安装程序">第九步 打包安装程序</a><span class="dots"></span></span></li><li><span><a class="toc-h2" href="#第十步-选择静态链接库或动态链接库">第十步 选择静态链接库或动态链接库</a><span class="dots"></span></span></li><li><span><a class="toc-h2" href="#第十一步-添加导出配置">第十一步 添加导出配置</a><span class="dots"></span></span></li><li><span><a class="toc-h2" href="#第十二步-打包调试版和发行版">第十二步 打包调试版和发行版</a><span class="dots"></span></span></li><li><span><a class="toc-h2" href="#练习-cmake-gui的使用">练习 cmake-gui的使用</a><span class="dots"></span></span></li></ul></li><li><span><a class="toc-h1" href="#cmake基础知识补充">CMake基础知识补充</a><span class="dots"></span></span><ul><li><span><a class="toc-h2" href="#cmake命令使用">CMake命令使用</a><span class="dots"></span></span><ul><li><span><a class="toc-h3" href="#创建项目构建系统">创建项目构建系统</a><span class="dots"></span></span></li><li><span><a class="toc-h3" href="#构建项目">构建项目</a><span class="dots"></span></span></li><li><span><a class="toc-h3" href="#安装">安装</a><span class="dots"></span></span></li><li><span><a class="toc-h3" href="#运行脚本">运行脚本</a><span class="dots"></span></span></li><li><span><a class="toc-h3" href="#运行命令行工具">运行命令行工具</a><span class="dots"></span></span></li></ul></li><li><span><a class="toc-h2" href="#cmake指令">CMake指令</a><span class="dots"></span></span><ul><li><span><a class="toc-h3" href="#脚本指令">脚本指令</a><span class="dots"></span></span><ul><li><span><a class="toc-h4" href="#message">message</a><span class="dots"></span></span></li><li><span><a class="toc-h4" href="#变量定义与取消">变量定义与取消</a><span class="dots"></span></span></li><li><span><a class="toc-h4" href="#条件判断">条件判断</a><span class="dots"></span></span></li><li><span><a class="toc-h4" href="#循环">循环</a><span class="dots"></span></span></li><li><span><a class="toc-h4" href="#字符串操作">字符串操作</a><span class="dots"></span></span></li><li><span><a class="toc-h4" href="#列表操作">列表操作</a><span class="dots"></span></span></li><li><span><a class="toc-h4" href="#数学表达式">数学表达式</a><span class="dots"></span></span></li><li><span><a class="toc-h4" href="#系统信息查询">系统信息查询</a><span class="dots"></span></span></li><li><span><a class="toc-h4" href="#函数">函数</a><span class="dots"></span></span></li><li><span><a class="toc-h4" href="#宏定义">宏定义</a><span class="dots"></span></span></li><li><span><a class="toc-h4" href="#configure_file">configure_file</a><span class="dots"></span></span></li><li><span><a class="toc-h4" href="#文件操作">文件操作</a><span class="dots"></span></span></li><li><span><a class="toc-h4" href="#路径操作">路径操作</a><span class="dots"></span></span></li><li><span><a class="toc-h4" href="#文件查找">文件查找</a><span class="dots"></span></span></li><li><span><a class="toc-h4" href="#find_package">find_package</a><span class="dots"></span></span></li></ul></li><li><span><a class="toc-h3" href="#项目指令">项目指令</a><span class="dots"></span></span><ul><li><span><a class="toc-h4" href="#add_dependencies">add_dependencies</a><span class="dots"></span></span></li><li><span><a class="toc-h4" href="#add_custom_target">add_custom_target</a><span class="dots"></span></span></li><li><span><a class="toc-h4" href="#属性设置">属性设置</a><span class="dots"></span></span></li><li><span><a class="toc-h4" href="#添加预编译定义">添加预编译定义</a><span class="dots"></span></span></li><li><span><a class="toc-h4" href="#添加编译选项">添加编译选项</a><span class="dots"></span></span></li><li><span><a class="toc-h4" href="#mark_as_advanced">mark_as_advanced</a><span class="dots"></span></span></li><li><span><a class="toc-h4" href="#target_sources">target_sources</a><span class="dots"></span></span></li></ul></li><li><span><a class="toc-h3" href="#生成器表达式">生成器表达式</a><span class="dots"></span></span></li></ul></li></ul></li><li><span><a class="toc-h1" href="#下一步">下一步</a><span class="dots"></span></span></li></ul></div><h1 class="atx" id="预备知识">预备知识</h1>
|
||
<h2 class="atx" id="cmake是什么">CMake是什么</h2>
|
||
<p>CMake是一个管理代码构建的工具。与平台和构建系统无关。最初CMake只用于生成不同版本的Makefile。现在CMake可以生成不同构建工具构建文件,也可以生成不同IDE(如Visual Studio、XCode)的项目文件。</p>
|
||
<p>CMake也可以在一定程度上简化C/C++第三方库的引入与使用流程。</p>
|
||
<p>CMake主要用于构建C或C++程序,但是也可以用于其他语言程序的构建。</p>
|
||
<p>**** </p>
|
||
<h2 class="atx" id="环境搭建与学习准备">环境搭建与学习准备</h2>
|
||
<h2 class="atx" id="前置条件">前置条件</h2>
|
||
<p>如果是用Linux学习,需要先安装GCC、make等工具。Ubuntu上安装命令如下:</p>
|
||
<pre><code class="fenced-code-block language-shell"><span class="token function">sudo</span> <span class="token function">apt</span> <span class="token function">install</span> gcc g++ <span class="token function">make</span></code></pre>
|
||
<p> </p>
|
||
<p>如果是用Windows,需要先装有编译工具。建议安装MinGW环境进行学习(用Visual Studio也可以,但是用来学习cmake的话感觉有点笨重),本课程用的编译工具是MinGW,能和课程工具保持一致最好。</p>
|
||
<p>MinGW常用有以下两个版本,选择其中一个即可。<strong>w64devkit提供的工具更多,操作更接近Linux</strong>。所以推荐用w64devkit。</p>
|
||
<p>w64devkit:<a href="https://github.com/skeeto/w64devkit/releases">https://github.com/skeeto/w64devkit/releases</a></p>
|
||
<p>mingw-builds:<a href="https://github.com/niXman/mingw-builds-binaries/releases">https://github.com/niXman/mingw-builds-binaries/releases</a></p>
|
||
<blockquote>
|
||
<p>最好会GCC与Make的基本用法。但不会也没关系,影响不大。</p>
|
||
</blockquote>
|
||
<p> </p>
|
||
<h3 class="atx" id="ubuntu安装cmake">Ubuntu安装CMake</h3>
|
||
<pre><code class="fenced-code-block language-shell"><span class="token function">sudo</span> <span class="token function">apt</span> <span class="token function">install</span> cmake</code></pre>
|
||
<p> </p>
|
||
<h3 class="atx" id="windows安装cmake">Windows安装CMake</h3>
|
||
<p>cmake官网:<a href="https://cmake.org/">https://cmake.org/</a></p>
|
||
<p>下载安装包,直接下载msi版本。安装时将添加到系统环境变量勾选。</p>
|
||
<p><img alt="" src="img/install.png"></p>
|
||
<p>安装完成之后测试</p>
|
||
<pre><code class="fenced-code-block language-shell">cmake --version</code></pre>
|
||
<p> </p>
|
||
<p> </p>
|
||
<h3 class="atx" id="学习材料">学习材料</h3>
|
||
<p>1、官方文档:<a href="https://cmake.org/cmake/help/latest/">https://cmake.org/cmake/help/latest/</a></p>
|
||
<p>2、tutorial代码:<a href="https://cmake.org/cmake/help/latest/_downloads/987664e19bf1c78e58910f17f64df29f/cmake-3.26.4-tutorial-source.zip">https://cmake.org/cmake/help/latest/_downloads/987664e19bf1c78e58910f17f64df29f/cmake-3.26.4-tutorial-source.zip</a></p>
|
||
<p> </p>
|
||
<p> </p>
|
||
<h1 class="atx" id="cmake-tutorial">CMake Tutorial</h1>
|
||
<h2 class="atx" id="第一步-起点">第一步 起点</h2>
|
||
<h3 class="atx" id="练习1--最简单的cmake项目">练习1 最简单的CMake项目</h3>
|
||
<p><strong><code>CMakeLists.txt</code></strong></p>
|
||
<pre><code class="fenced-code-block language-cmake"><span class="token comment"># TODO 1: 设置CMake最低版本要求为 3.10</span>
|
||
<span class="token keyword">cmake_minimum_required</span><span class="token punctuation">(</span><span class="token property">VERSION</span> <span class="token number">3.10</span><span class="token punctuation">)</span>
|
||
|
||
<span class="token comment"># TODO 2: 创建一个名为Tutorial的项目</span>
|
||
<span class="token keyword">project</span><span class="token punctuation">(</span>Tutorial<span class="token punctuation">)</span>
|
||
|
||
<span class="token comment"># TODO 3: 为项目添加一个叫做 Tutorial 的可执行文件</span>
|
||
<span class="token comment"># Hint: 一定要指定源文件 tutorial.cxx</span>
|
||
<span class="token keyword">add_executable</span><span class="token punctuation">(</span>Tutorial tutorial.cxx<span class="token punctuation">)</span></code></pre>
|
||
<p><strong>要点</strong></p>
|
||
<p> ①<mark>cmake_minimum_required</mark></p>
|
||
<p>用于指定所需cmake最低版本</p>
|
||
<p>用法与示例:</p>
|
||
<pre><code class="fenced-code-block language-cmake"><span class="token comment"># 用法</span>
|
||
<span class="token keyword">cmake_minimum_required</span><span class="token punctuation">(</span><span class="token property">VERSION</span> <版本号<span class="token punctuation">></span><span class="token punctuation">)</span>
|
||
<span class="token comment"># 示例</span>
|
||
<span class="token keyword">cmake_minimum_required</span><span class="token punctuation">(</span><span class="token property">VERSION</span> <span class="token number">3.10</span><span class="token punctuation">)</span></code></pre>
|
||
<p>如果当前使用的cmake版本低于所指定的版本,则会报错并且终止执行。</p>
|
||
<p>②<mark>project</mark></p>
|
||
<p>指定项目名称</p>
|
||
<p>用法与示例:</p>
|
||
<pre><code class="fenced-code-block language-cmake"><span class="token comment"># 用法</span>
|
||
<span class="token keyword">project</span><span class="token punctuation">(</span><项目名<span class="token punctuation">></span><span class="token punctuation">)</span>
|
||
<span class="token comment"># 示例 指定项目名称为Tutorial</span>
|
||
<span class="token keyword">project</span><span class="token punctuation">(</span>Tutorial<span class="token punctuation">)</span></code></pre>
|
||
<p>③<mark>add_executable</mark></p>
|
||
<p>利用指定的源文件在项目中添加可执行文件</p>
|
||
<p>用法与示例:</p>
|
||
<pre><code class="fenced-code-block language-cmake"><span class="token comment"># 用法 源文件可以有多个,用空格隔开</span>
|
||
<span class="token keyword">add_executable</span><span class="token punctuation">(</span><可执行文件名<span class="token punctuation">></span> <源文件列表<span class="token punctuation">></span><span class="token punctuation">)</span>
|
||
<span class="token comment"># 示例 可执行文件名为Tutorial,用到的源文件为tutorial.cxx</span>
|
||
<span class="token keyword">add_executable</span><span class="token punctuation">(</span>Tutorial tutorial.cxx<span class="token punctuation">)</span></code></pre>
|
||
<p>④<mark>cmake命令常用执行方法</mark></p>
|
||
<pre><code class="fenced-code-block language-shell"><span class="token comment"># 用法</span>
|
||
cmake -G <span class="token operator"><</span>生成器名称<span class="token operator">></span> <span class="token operator"><</span>CMakeLists.txt所在的目录<span class="token operator">></span></code></pre>
|
||
<p>如果使用默认生成器,则-G这部分可以省略,具体支持哪些生成器可以用cmake --help查看</p>
|
||
<blockquote>
|
||
<p>扩展:设置环境变量CMAKE_GENERATOR可以指定默认生成器,简化cmake命令的执行</p>
|
||
</blockquote>
|
||
<p> </p>
|
||
<p><strong>课后练习</strong></p>
|
||
<ol>
|
||
<li>自行准备一个或多个源文件,多练习几遍cmake项目的创建与生成可执行文件流程,直到能默写出CMakeLists.txt中的内容并且熟练通过cmake构建出可执行文件。</li>
|
||
<li>配置CMAKE_GENERATOR环境变量并修改不同值,通过cmake --help命令查看该变量对默认Generator(生成器)的影响。</li>
|
||
<li>如果电脑上有多套环境或工具(例如有MinGW与Visual Studio或CodeBlocks),修改-G指定不同生成器,尝试生成不同工具对应的项目。</li>
|
||
</ol>
|
||
<p> </p>
|
||
<p> </p>
|
||
<h3 class="atx" id="练习2-指定c标准">练习2 指定C++标准</h3>
|
||
<p><strong><code>CMakeLists.txt</code></strong></p>
|
||
<pre><code class="fenced-code-block language-cmake"><span class="token comment"># TODO 1: 设置CMake最低版本要求为 3.10</span>
|
||
<span class="token keyword">cmake_minimum_required</span><span class="token punctuation">(</span><span class="token property">VERSION</span> <span class="token number">3.10</span><span class="token punctuation">)</span>
|
||
|
||
<span class="token comment"># TODO 2: 创建一个名为Tutorial的项目</span>
|
||
<span class="token keyword">project</span><span class="token punctuation">(</span>Tutorial<span class="token punctuation">)</span>
|
||
|
||
<span class="token comment"># TODO 7: 用上面project命令将项目版本设为 1.0</span>
|
||
|
||
<span class="token comment"># TODO 6: 设置变量 CMAKE_CXX_STANDARD 为 11</span>
|
||
<span class="token comment"># CMAKE_CXX_STANDARD_REQUIRED 为 True</span>
|
||
<span class="token keyword">set</span><span class="token punctuation">(</span><span class="token variable">CMAKE_CXX_STANDARD</span> <span class="token number">26</span><span class="token punctuation">)</span>
|
||
<span class="token keyword">set</span><span class="token punctuation">(</span><span class="token variable">CMAKE_CXX_STANDARD_REQUIRED</span> True<span class="token punctuation">)</span>
|
||
|
||
<span class="token comment"># TODO 8: 用 configure_file 复制 TutorialConfig.h.in 生成</span>
|
||
<span class="token comment"># TutorialConfig.h</span>
|
||
|
||
<span class="token comment"># TODO 3: 为项目添加一个叫做 Tutorial 的可执行文件</span>
|
||
<span class="token comment"># Hint: 一定要指定源文件 tutorial.cxx</span>
|
||
<span class="token keyword">add_executable</span><span class="token punctuation">(</span>Tutorial tutorial.cxx<span class="token punctuation">)</span></code></pre>
|
||
<p><strong>要点</strong></p>
|
||
<p>①<mark>set</mark></p>
|
||
<p>用于给变量设置值</p>
|
||
<p>用法与示例:</p>
|
||
<pre><code class="fenced-code-block language-cmake"><span class="token comment"># 用法</span>
|
||
<span class="token keyword">set</span><span class="token punctuation">(</span><变量名<span class="token punctuation">></span> <变量值<span class="token punctuation">></span><span class="token punctuation">)</span>
|
||
<span class="token comment"># 示例</span>
|
||
<span class="token keyword">set</span><span class="token punctuation">(</span><span class="token variable">CMAKE_CXX_STANDARD</span> <span class="token number">26</span><span class="token punctuation">)</span>
|
||
<span class="token keyword">set</span><span class="token punctuation">(</span>SRC_DIR /home/src<span class="token punctuation">)</span></code></pre>
|
||
<p>②<mark>CMAKE_CXX_STANDARD</mark></p>
|
||
<p>变量,用于指定C++标准</p>
|
||
<p>用法与示例:</p>
|
||
<pre><code class="fenced-code-block language-cmake"><span class="token comment"># 用法 截止2023/6 std_num∈{98,11,14,17,20,23,26}</span>
|
||
<span class="token keyword">set</span><span class="token punctuation">(</span><span class="token variable">CMAKE_CXX_STANDARD</span> <std_num<span class="token punctuation">></span><span class="token punctuation">)</span>
|
||
<span class="token comment"># 示例</span>
|
||
<span class="token keyword">set</span><span class="token punctuation">(</span><span class="token variable">CMAKE_CXX_STANDARD</span> <span class="token number">11</span><span class="token punctuation">)</span>
|
||
<span class="token keyword">set</span><span class="token punctuation">(</span><span class="token variable">CMAKE_CXX_STANDARD</span> <span class="token number">17</span><span class="token punctuation">)</span></code></pre>
|
||
<blockquote>
|
||
<p>在C++中可以通过输出__cplusplus查看当前编译器所用的标准</p>
|
||
<table>
|
||
<thead>
|
||
<tr>
|
||
<th align="center">__cplusplus的值</th>
|
||
<th align="center">对应的C++标准</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody><tr>
|
||
<td align="center">199711</td>
|
||
<td align="center">C++98</td>
|
||
</tr>
|
||
<tr>
|
||
<td align="center">201103</td>
|
||
<td align="center">C++11</td>
|
||
</tr>
|
||
<tr>
|
||
<td align="center">201402</td>
|
||
<td align="center">C++14</td>
|
||
</tr>
|
||
<tr>
|
||
<td align="center">201703</td>
|
||
<td align="center">C++17</td>
|
||
</tr>
|
||
<tr>
|
||
<td align="center">202002</td>
|
||
<td align="center">C++20</td>
|
||
</tr>
|
||
<tr>
|
||
<td align="center">202100</td>
|
||
<td align="center">C++23</td>
|
||
</tr>
|
||
</tbody></table>
|
||
</blockquote>
|
||
<p>③<mark>CMAKE_CXX_STANDARD_REQUIRED</mark></p>
|
||
<p>变量,如果设置为True,则通过CMAKE_CXX_STANDARD设置的C++标准是必需的,如果编译器不支持该标准则会输出错误提示信息。如果不设置或者设置为False,则CMAKE_CXX_STANDARD设置的C++标准不是必需的,如果编译器不支持对应的标准,则会使用上一个版本的标准进行编译。</p>
|
||
<p>用法与示例:</p>
|
||
<pre><code class="fenced-code-block language-cmake"><span class="token keyword">set</span><span class="token punctuation">(</span><span class="token variable">CMAKE_CXX_STANDARD_REQUIRED</span> True<span class="token punctuation">)</span></code></pre>
|
||
<p> </p>
|
||
<p> </p>
|
||
<p><strong>课后练习</strong></p>
|
||
<ol>
|
||
<li>在std_num∈{98,11,14,17,20,23,26}的范围内设置C++标准,输出__cplusplus的值并观察规律。</li>
|
||
<li>设置std_num∉{98,11,14,17,20,23,26}的C++标准值,观察cmake提示信息并输出__cplusplus的值,总结其规律。</li>
|
||
<li>类比C++标准的指定,查询文档或其他资料,补充C语言标准指定方式,并准备几个C语言源文件进行实验。</li>
|
||
</ol>
|
||
<p> </p>
|
||
<p> </p>
|
||
<p> </p>
|
||
<h3 class="atx" id="练习3-添加版本号和配置头文件">练习3 添加版本号和配置头文件</h3>
|
||
<p>有些时候需要让源代码能访问CMakeLIsts.txt当中的数据,比如说在CMakeLists.txt中定义版本号之后,希望能在源程序中对版本号进行输出。本节内容为如何让源代码中能访问CMakeLists.txt中的变量数据。</p>
|
||
<p><code>CMakeLists.txt</code></p>
|
||
<pre><code class="fenced-code-block language-cmake"><span class="token comment"># TODO 1: 设置CMake最低版本要求为 3.10</span>
|
||
<span class="token keyword">cmake_minimum_required</span><span class="token punctuation">(</span><span class="token property">VERSION</span> <span class="token number">3.10</span><span class="token punctuation">)</span>
|
||
|
||
<span class="token comment"># TODO 2: 创建一个名为Tutorial的项目</span>
|
||
<span class="token keyword">project</span><span class="token punctuation">(</span>Tutorial <span class="token property">VERSION</span> <span class="token number">11.25</span><span class="token punctuation">)</span>
|
||
|
||
<span class="token comment"># TODO 7: 用上面project命令将项目版本设为 1.0</span>
|
||
|
||
<span class="token comment"># TODO 6: 设置变量 CMAKE_CXX_STANDARD 为 11</span>
|
||
<span class="token comment"># CMAKE_CXX_STANDARD_REQUIRED 为 True</span>
|
||
<span class="token keyword">set</span><span class="token punctuation">(</span><span class="token variable">CMAKE_CXX_STANDARD</span> <span class="token number">11</span><span class="token punctuation">)</span>
|
||
<span class="token keyword">set</span><span class="token punctuation">(</span><span class="token variable">CMAKE_CXX_STANDARD_REQUIRED</span> True<span class="token punctuation">)</span>
|
||
|
||
<span class="token comment"># set(STR_TEST "Hello World")</span>
|
||
|
||
<span class="token comment"># TODO 8: 用 configure_file 复制 TutorialConfig.h.in 生成</span>
|
||
<span class="token comment"># TutorialConfig.h</span>
|
||
<span class="token keyword">configure_file</span><span class="token punctuation">(</span>TutorialConfig.h.in TutorialConfig.h<span class="token punctuation">)</span>
|
||
|
||
<span class="token comment"># TODO 3: 为项目添加一个叫做 Tutorial 的可执行文件</span>
|
||
<span class="token comment"># Hint: 一定要指定源文件 tutorial.cxx</span>
|
||
<span class="token keyword">add_executable</span><span class="token punctuation">(</span>Tutorial tutorial.cxx<span class="token punctuation">)</span>
|
||
|
||
<span class="token comment"># TODO 9: 用 target_include_directories 添加头文件搜索目录 ${PROJECT_BINARY_DIR}</span>
|
||
<span class="token comment"># PUBLIC PRIVATE INTERFACE</span>
|
||
<span class="token keyword">target_include_directories</span><span class="token punctuation">(</span>Tutorial <span class="token namespace">PUBLIC</span> <span class="token punctuation">${</span><span class="token variable">PROJECT_BINARY_DIR</span><span class="token punctuation">}</span><span class="token punctuation">)</span></code></pre>
|
||
<p><code>TutorialConfig.h.in</code></p>
|
||
<pre><code class="fenced-code-block language-c"><span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">define</span> <span class="token macro-name">Tutorial_VERSION_MAJOR</span> <span class="token expression">@Tutorial_VERSION_MAJOR@</span></span>
|
||
<span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">define</span> <span class="token macro-name">Tutorial_VERSION_MINOR</span> <span class="token expression">@Tutorial_VERSION_MINOR@</span></span></code></pre>
|
||
<p><strong>要点</strong></p>
|
||
<p>〇<mark>project第二种用法</mark></p>
|
||
<p>定义项目名和版本号</p>
|
||
<pre><code class="fenced-code-block language-cmake"><span class="token keyword">project</span><span class="token punctuation">(</span>Tutorial <span class="token property">VERSION</span> <span class="token number">2.15</span><span class="token punctuation">)</span></code></pre>
|
||
<p>①<mark>configure_file</mark></p>
|
||
<p>将输入文件复制为输出文件,并把其中的变量引用替换为CMakeLists.txt中定义的变量,如果变量未定义,则替换为空串。输入文件中的变量引用方式为**@@变量名@@<strong>或者</strong>${变量名}**。</p>
|
||
<p>输入文件默认路径为CMakeLists.txt所在的路径,输出文件的路径默认为cmake生成文件所在的路径。</p>
|
||
<p>用法与示例:</p>
|
||
<pre><code class="fenced-code-block language-cmake"><span class="token comment"># 用法</span>
|
||
<span class="token keyword">configure_file</span><span class="token punctuation">(</span><inputfile<span class="token punctuation">></span> <outputfile<span class="token punctuation">></span><span class="token punctuation">)</span>
|
||
<span class="token comment"># 示例</span>
|
||
<span class="token keyword">configure_file</span><span class="token punctuation">(</span>TutorialConfig.h.in TutorialConfig.h<span class="token punctuation">)</span></code></pre>
|
||
<p>在输入文件中,用宏定义的方式对变量进行定义</p>
|
||
<pre><code class="fenced-code-block language-c"><span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">define</span> <span class="token macro-name">Tutorial_VERSION_MAJOR</span> <span class="token expression">@Tutorial_VERSION_MAJOR@</span></span>
|
||
<span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">define</span> <span class="token macro-name">Tutorial_VERSION_MINOR</span> <span class="token expression">$<span class="token punctuation">{</span>Tutorial_VERSION_MINOR<span class="token punctuation">}</span></span></span>
|
||
|
||
<span class="token comment">// 因为CMakeLists.txt中定义的字符串都是裸的,所以如果一个变量的值为字符串,需要用双引号包起来</span>
|
||
<span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">define</span> <span class="token macro-name">STR_VAR</span> <span class="token string">"@STR_VAR@"</span></span></code></pre>
|
||
<p>上述定义中@Tutorial_VERSION_MAJOR@、${Tutorial_VERSION_MINOR}、@STR_VAR@在输出文件中会被替换为CMakeLists.txt中定义的对应变量值。</p>
|
||
<p> </p>
|
||
<p>②<mark>target_include_directories</mark></p>
|
||
<p>给指定的目标添加头文件搜索路径。</p>
|
||
<p>用法与示例:</p>
|
||
<pre><code class="fenced-code-block language-cmake"><span class="token comment"># 用法</span>
|
||
<span class="token keyword">target_include_directories</span><span class="token punctuation">(</span><target<span class="token punctuation">></span> <<span class="token namespace">INTERFACE</span>|<span class="token namespace">PUBLIC</span>|<span class="token namespace">PRIVATE</span><span class="token punctuation">></span> <dir1 dir2 ...<span class="token punctuation">></span><span class="token punctuation">)</span>
|
||
|
||
<span class="token comment"># 示例</span>
|
||
<span class="token keyword">target_include_directories</span><span class="token punctuation">(</span>Tutorial <span class="token namespace">PUBLIC</span> <span class="token punctuation">${</span><span class="token variable">PROJECT_BINARY_DIR</span><span class="token punctuation">}</span><span class="token punctuation">)</span></code></pre>
|
||
<p> </p>
|
||
<p>③<mark>_VERSION_MAJOR</mark> </p>
|
||
<p>版本号第一个组成部分。该变量为cmake自动定义的一个变量,不需要手动定义,值来自于project的定义。其中为用<strong>project</strong>定义的项目名。</p>
|
||
<p> </p>
|
||
<p>④<mark>_VERSION_MINOR</mark></p>
|
||
<p>版本号第二个组成部分。该变量为cmake自动定义的一个变量,不需要手动定义,值来自于project的定义。其中为用<strong>project</strong>定义的项目名。</p>
|
||
<p> </p>
|
||
<p> </p>
|
||
<p><strong>课后练习</strong></p>
|
||
<p>①通过本节学习的内容访问更多CMakeLists.txt中的变量。</p>
|
||
<p>②自行探究一下<code>include_directories</code>的用法,比较与target_include_directories的异同。</p>
|
||
<p> </p>
|
||
<p> </p>
|
||
<p> </p>
|
||
<h2 class="atx" id="第二步-加个库">第二步 加个库</h2>
|
||
<h3 class="atx" id="练习1-创建库文件">练习1 创建库文件</h3>
|
||
<p>前面的练习当中创建了可执行文件。本节将学习如何创建库文件以及库文件的使用 。同时也将练习将一个项目划分为多个子目录的方法。</p>
|
||
<p><code>CMakeLists.txt</code></p>
|
||
<pre><code class="fenced-code-block language-cmake"><span class="token keyword">cmake_minimum_required</span><span class="token punctuation">(</span><span class="token property">VERSION</span> <span class="token number">3.10</span><span class="token punctuation">)</span>
|
||
|
||
<span class="token comment"># set the project name and version</span>
|
||
<span class="token keyword">project</span><span class="token punctuation">(</span>Tutorial <span class="token property">VERSION</span> <span class="token number">1.0</span><span class="token punctuation">)</span>
|
||
|
||
<span class="token comment"># specify the C++ standard</span>
|
||
<span class="token keyword">set</span><span class="token punctuation">(</span><span class="token variable">CMAKE_CXX_STANDARD</span> <span class="token number">11</span><span class="token punctuation">)</span>
|
||
<span class="token keyword">set</span><span class="token punctuation">(</span><span class="token variable">CMAKE_CXX_STANDARD_REQUIRED</span> True<span class="token punctuation">)</span>
|
||
|
||
<span class="token comment"># TODO 7: Create a variable USE_MYMATH using option and set default to ON</span>
|
||
|
||
|
||
<span class="token comment"># configure a header file to pass some of the CMake settings</span>
|
||
<span class="token comment"># to the source code</span>
|
||
<span class="token keyword">configure_file</span><span class="token punctuation">(</span>TutorialConfig.h.in TutorialConfig.h<span class="token punctuation">)</span>
|
||
|
||
<span class="token comment"># TODO 8: Use list() and APPEND to create a list of optional libraries</span>
|
||
<span class="token comment"># called EXTRA_LIBS and a list of optional include directories called</span>
|
||
<span class="token comment"># EXTRA_INCLUDES. Add the MathFunctions library and source directory to</span>
|
||
<span class="token comment"># the appropriate lists.</span>
|
||
<span class="token comment">#</span>
|
||
<span class="token comment"># Only call add_subdirectory and only add MathFunctions specific values</span>
|
||
<span class="token comment"># to EXTRA_LIBS and EXTRA_INCLUDES if USE_MYMATH is true.</span>
|
||
|
||
<span class="token comment"># TODO 2: Use add_subdirectory() to add MathFunctions to this project</span>
|
||
|
||
<span class="token keyword">add_subdirectory</span><span class="token punctuation">(</span>MathFunctions<span class="token punctuation">)</span>
|
||
|
||
|
||
|
||
|
||
<span class="token comment"># add the executable</span>
|
||
<span class="token keyword">add_executable</span><span class="token punctuation">(</span>Tutorial tutorial.cxx<span class="token punctuation">)</span>
|
||
|
||
<span class="token comment"># TODO 9: Use EXTRA_LIBS instead of the MathFunctions specific values</span>
|
||
<span class="token comment"># in target_link_libraries.</span>
|
||
|
||
<span class="token comment"># TODO 3: Use target_link_libraries to link the library to our executable</span>
|
||
<span class="token keyword">target_link_libraries</span><span class="token punctuation">(</span>Tutorial <span class="token namespace">PUBLIC</span> MathFunctions<span class="token punctuation">)</span>
|
||
|
||
<span class="token comment"># TODO 4: Add MathFunctions to Tutorial's target_include_directories()</span>
|
||
<span class="token comment"># Hint: ${PROJECT_SOURCE_DIR} is a path to the project source. AKA This folder!</span>
|
||
|
||
<span class="token comment"># TODO 10: Use EXTRA_INCLUDES instead of the MathFunctions specific values</span>
|
||
<span class="token comment"># in target_include_directories.</span>
|
||
|
||
<span class="token comment"># add the binary tree to the search path for include files</span>
|
||
<span class="token comment"># so that we will find TutorialConfig.h</span>
|
||
<span class="token keyword">target_include_directories</span><span class="token punctuation">(</span>Tutorial <span class="token namespace">PUBLIC</span>
|
||
<span class="token string">"<span class="token interpolation"><span class="token punctuation">${</span><span class="token variable">PROJECT_BINARY_DIR</span><span class="token punctuation">}</span></span>"</span>
|
||
<span class="token string">"<span class="token interpolation"><span class="token punctuation">${</span><span class="token variable">PROJECT_SOURCE_DIR</span><span class="token punctuation">}</span></span>/MathFunctions"</span>
|
||
<span class="token punctuation">)</span></code></pre>
|
||
<p><code>MathFunctions/CMakeLists.txt</code></p>
|
||
<pre><code class="fenced-code-block language-cmake"><span class="token comment"># TODO 1: Add a library called MathFunctions</span>
|
||
<span class="token comment"># Hint: You will need the add_library command</span>
|
||
<span class="token keyword">add_library</span><span class="token punctuation">(</span>MathFunctions mysqrt.cxx<span class="token punctuation">)</span></code></pre>
|
||
<p><strong>要点</strong></p>
|
||
<p>①<mark>add_subdirectory</mark></p>
|
||
<p>为当前项目添加子目录。子目录当中必须包含一个CMakeLists.txt文件,其中可以不写cmake_minimum_required与project。</p>
|
||
<p>用法与示例:</p>
|
||
<pre><code class="fenced-code-block language-cmake"><span class="token comment"># 用法</span>
|
||
<span class="token keyword">add_subdirectory</span><span class="token punctuation">(</span><source_dir<span class="token punctuation">></span><span class="token punctuation">)</span>
|
||
<span class="token comment"># 示例</span>
|
||
<span class="token keyword">add_subdirectory</span><span class="token punctuation">(</span>MathFunctions<span class="token punctuation">)</span></code></pre>
|
||
<p>②<mark>target_link_libraries</mark></p>
|
||
<p>为指定目录指定链接库。</p>
|
||
<p>用法与示例:</p>
|
||
<pre><code class="fenced-code-block language-cmake"><span class="token comment"># 用法</span>
|
||
<span class="token keyword">target_link_libraries</span><span class="token punctuation">(</span><target<span class="token punctuation">></span> ... <item<span class="token punctuation">></span>... ...<span class="token punctuation">)</span>
|
||
<span class="token comment"># 示例</span>
|
||
<span class="token keyword">target_link_libraries</span><span class="token punctuation">(</span>Tutorial <span class="token namespace">PUBLIC</span> MathFunctions<span class="token punctuation">)</span></code></pre>
|
||
<p>③<mark>PROJECT_SOURCE_DIR</mark></p>
|
||
<p>最后一次调用project的CMakeLists.txt文件所在的目录。</p>
|
||
<p>④<mark>add_library</mark></p>
|
||
<p>用指定的源文件生成库文件。</p>
|
||
<p>用法与示例:</p>
|
||
<pre><code class="fenced-code-block language-cmake"><span class="token comment"># 用法</span>
|
||
<span class="token keyword">add_library</span><span class="token punctuation">(</span><name<span class="token punctuation">></span> [<source<span class="token punctuation">></span>...]<span class="token punctuation">)</span>
|
||
<span class="token comment"># 示例</span>
|
||
<span class="token keyword">add_library</span><span class="token punctuation">(</span>MathFunctions mysqrt.cxx MathFunctions.h<span class="token punctuation">)</span></code></pre>
|
||
<p> </p>
|
||
<p> </p>
|
||
<h3 class="atx" id="练习2-库文件可选编译">练习2 库文件可选编译</h3>
|
||
<p>本节内容为设置库文件(子目录)可选编译。</p>
|
||
<pre><code class="fenced-code-block language-cmake"><span class="token keyword">cmake_minimum_required</span><span class="token punctuation">(</span><span class="token property">VERSION</span> <span class="token number">3.10</span><span class="token punctuation">)</span>
|
||
|
||
<span class="token comment"># set the project name and version</span>
|
||
<span class="token keyword">project</span><span class="token punctuation">(</span>Tutorial <span class="token property">VERSION</span> <span class="token number">1.0</span><span class="token punctuation">)</span>
|
||
|
||
<span class="token comment"># specify the C++ standard</span>
|
||
<span class="token keyword">set</span><span class="token punctuation">(</span><span class="token variable">CMAKE_CXX_STANDARD</span> <span class="token number">11</span><span class="token punctuation">)</span>
|
||
<span class="token keyword">set</span><span class="token punctuation">(</span><span class="token variable">CMAKE_CXX_STANDARD_REQUIRED</span> True<span class="token punctuation">)</span>
|
||
|
||
<span class="token comment"># TODO 7: Create a variable USE_MYMATH using option and set default to ON</span>
|
||
<span class="token keyword">option</span><span class="token punctuation">(</span>USE_MYMATH <span class="token string">"Use My Math?"</span> <span class="token boolean">OFF</span><span class="token punctuation">)</span>
|
||
|
||
<span class="token comment"># configure a header file to pass some of the CMake settings</span>
|
||
<span class="token comment"># to the source code</span>
|
||
<span class="token keyword">configure_file</span><span class="token punctuation">(</span>TutorialConfig.h.in TutorialConfig.h<span class="token punctuation">)</span>
|
||
|
||
<span class="token comment"># TODO 8: Use list() and APPEND to create a list of optional libraries</span>
|
||
<span class="token comment"># called EXTRA_LIBS and a list of optional include directories called</span>
|
||
<span class="token comment"># EXTRA_INCLUDES. Add the MathFunctions library and source directory to</span>
|
||
<span class="token comment"># the appropriate lists.</span>
|
||
<span class="token comment">#</span>
|
||
<span class="token comment"># Only call add_subdirectory and only add MathFunctions specific values</span>
|
||
<span class="token comment"># to EXTRA_LIBS and EXTRA_INCLUDES if USE_MYMATH is true.</span>
|
||
|
||
<span class="token comment"># TODO 2: Use add_subdirectory() to add MathFunctions to this project</span>
|
||
<span class="token keyword">if</span><span class="token punctuation">(</span>USE_MYMATH<span class="token punctuation">)</span>
|
||
<span class="token keyword">add_subdirectory</span><span class="token punctuation">(</span>MathFunctions<span class="token punctuation">)</span>
|
||
<span class="token keyword">list</span><span class="token punctuation">(</span>APPEND EXTRA_LIBS MathFunctions<span class="token punctuation">)</span>
|
||
<span class="token keyword">list</span><span class="token punctuation">(</span>APPEND EXTRA_INCLUDES <span class="token string">"<span class="token interpolation"><span class="token punctuation">${</span><span class="token variable">PROJECT_SOURCE_DIR</span><span class="token punctuation">}</span></span>/MathFunctions"</span><span class="token punctuation">)</span>
|
||
<span class="token keyword">endif</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
|
||
|
||
|
||
|
||
<span class="token comment"># add the executable</span>
|
||
<span class="token keyword">add_executable</span><span class="token punctuation">(</span>Tutorial tutorial.cxx<span class="token punctuation">)</span>
|
||
|
||
<span class="token comment"># TODO 9: Use EXTRA_LIBS instead of the MathFunctions specific values</span>
|
||
<span class="token comment"># in target_link_libraries.</span>
|
||
|
||
<span class="token comment"># TODO 3: Use target_link_libraries to link the library to our executable</span>
|
||
<span class="token keyword">target_link_libraries</span><span class="token punctuation">(</span>Tutorial <span class="token namespace">PUBLIC</span> <span class="token punctuation">${</span>EXTRA_LIBS<span class="token punctuation">}</span><span class="token punctuation">)</span>
|
||
|
||
<span class="token comment"># TODO 4: Add MathFunctions to Tutorial's target_include_directories()</span>
|
||
<span class="token comment"># Hint: ${PROJECT_SOURCE_DIR} is a path to the project source. AKA This folder!</span>
|
||
|
||
<span class="token comment"># TODO 10: Use EXTRA_INCLUDES instead of the MathFunctions specific values</span>
|
||
<span class="token comment"># in target_include_directories.</span>
|
||
|
||
<span class="token comment"># add the binary tree to the search path for include files</span>
|
||
<span class="token comment"># so that we will find TutorialConfig.h</span>
|
||
<span class="token keyword">target_include_directories</span><span class="token punctuation">(</span>Tutorial <span class="token namespace">PUBLIC</span>
|
||
<span class="token string">"<span class="token interpolation"><span class="token punctuation">${</span><span class="token variable">PROJECT_BINARY_DIR</span><span class="token punctuation">}</span></span>"</span>
|
||
<span class="token string">"<span class="token interpolation"><span class="token punctuation">${</span><span class="token variable">EXTRA_INCLUDES</span><span class="token punctuation">}</span></span>"</span>
|
||
<span class="token punctuation">)</span></code></pre>
|
||
<p><strong>要点</strong></p>
|
||
<p>①<mark>option</mark></p>
|
||
<p>提供一个布尔变量,可以让用户自行选择。</p>
|
||
<p>用法与示例:</p>
|
||
<pre><code class="fenced-code-block language-cmake"><span class="token comment"># 用法</span>
|
||
<span class="token keyword">option</span><span class="token punctuation">(</span><variable<span class="token punctuation">></span> <span class="token string">"<help_text>"</span> [value]<span class="token punctuation">)</span>
|
||
<span class="token comment"># 示例</span>
|
||
<span class="token keyword">option</span><span class="token punctuation">(</span>USE_MYMATH <span class="token string">"Use MyMath"</span> <span class="token boolean">ON</span><span class="token punctuation">)</span></code></pre>
|
||
<p><code>value</code>值为<code>ON</code>或<code>OFF</code>,默认值为<code>OFF</code>。</p>
|
||
<p>在执行配置时,可以用<code>-D</code>来指定值,例如</p>
|
||
<pre><code class="fenced-code-block language-shell">cmake <span class="token builtin class-name">.</span> -DUSE_MYMATH<span class="token operator">=</span>OFF</code></pre>
|
||
<p>②<mark>if()</mark> & <mark>endif()</mark></p>
|
||
<p>条件判断开始与结束。</p>
|
||
<p>语法:</p>
|
||
<pre><code class="fenced-code-block language-cmake"><span class="token keyword">if</span><span class="token punctuation">(</span><condition<span class="token punctuation">></span><span class="token punctuation">)</span>
|
||
<commands<span class="token punctuation">></span>
|
||
<span class="token keyword">elseif</span><span class="token punctuation">(</span><condition<span class="token punctuation">></span><span class="token punctuation">)</span>
|
||
<commands<span class="token punctuation">></span>
|
||
<span class="token keyword">else</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
|
||
<commands<span class="token punctuation">></span>
|
||
<span class="token keyword">endif</span><span class="token punctuation">(</span><span class="token punctuation">)</span></code></pre>
|
||
<table>
|
||
<thead>
|
||
<tr>
|
||
<th align="center"><condition>判断为真的值</th>
|
||
<th align="center"><condition>判断为假的值</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody><tr>
|
||
<td align="center">1</td>
|
||
<td align="center">0</td>
|
||
</tr>
|
||
<tr>
|
||
<td align="center">ON</td>
|
||
<td align="center">OFF</td>
|
||
</tr>
|
||
<tr>
|
||
<td align="center">TRUE</td>
|
||
<td align="center">FALSE</td>
|
||
</tr>
|
||
<tr>
|
||
<td align="center">YES</td>
|
||
<td align="center">NO</td>
|
||
</tr>
|
||
<tr>
|
||
<td align="center">Y</td>
|
||
<td align="center">N</td>
|
||
</tr>
|
||
<tr>
|
||
<td align="center">其他非0数</td>
|
||
<td align="center">IGNORE</td>
|
||
</tr>
|
||
<tr>
|
||
<td align="center"></td>
|
||
<td align="center">NOTFOUND或以-NOTFOUND结尾的</td>
|
||
</tr>
|
||
<tr>
|
||
<td align="center"></td>
|
||
<td align="center">值不是判断为真的字符串</td>
|
||
</tr>
|
||
</tbody></table>
|
||
<p>③<mark>list</mark></p>
|
||
<p>列表操作。详细操作见<a href="#">list</a>,这里只讲用到的APPEND操作。将一些元素追加到已有的列表当中。如果列表变量还未定义,则会当做空列表处理。</p>
|
||
<p>语法与示例:</p>
|
||
<pre><code class="fenced-code-block language-cmake"><span class="token comment"># 语法</span>
|
||
<span class="token keyword">list</span><span class="token punctuation">(</span>APPEND <list<span class="token punctuation">></span> [<element<span class="token punctuation">></span> ...]<span class="token punctuation">)</span>
|
||
<span class="token comment"># 示例 将MathFunctions追加到EXTRA_LIBS当中</span>
|
||
<span class="token keyword">list</span><span class="token punctuation">(</span>APPEND EXTRA_LIBS MathFunctions<span class="token punctuation">)</span></code></pre>
|
||
<p>④<mark>cmakedefine</mark></p>
|
||
<p>用法与#define相同,用在configure_file的输入文件当中进行宏定义。</p>
|
||
<p>不同点在于,#define本身就是C/C++当中的宏定义,所以不论对应的变量是否在CMakeLists.txt中有定义,都会在输出文件中定义一个宏。而#cmakedfine则会根据变量在CMakeLists.txt中的定义情况来确定是否会在输出文件中定义宏。如果变量在CMakeLists.txt中没有定义或都已定义但是一个判断为假的布尔值,则不会在输出文件中定义对应的宏,如果变量在CMakeLists.txt中有定义且不为布尔值、或者为布尔值但判断为真,则会在输出文件中定义对应的宏。</p>
|
||
<p>用法示例:</p>
|
||
<pre><code class="fenced-code-block language-c"><span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">cmakedefine</span> <span class="token expression">USE_MYMATH</span></span></code></pre>
|
||
<p> </p>
|
||
<p> </p>
|
||
<h2 class="atx" id="第三步-添加使用依赖">第三步 添加使用依赖</h2>
|
||
<h3 class="atx" id="练习1-为库添加使用依赖">练习1 为库添加使用依赖</h3>
|
||
<p><code>CMakeLists.txt</code></p>
|
||
<pre><code class="fenced-code-block language-cmake"><span class="token keyword">cmake_minimum_required</span><span class="token punctuation">(</span><span class="token property">VERSION</span> <span class="token number">3.10</span><span class="token punctuation">)</span>
|
||
|
||
<span class="token comment"># set the project name and version</span>
|
||
<span class="token keyword">project</span><span class="token punctuation">(</span>Tutorial <span class="token property">VERSION</span> <span class="token number">1.0</span><span class="token punctuation">)</span>
|
||
|
||
<span class="token comment"># specify the C++ standard</span>
|
||
<span class="token keyword">set</span><span class="token punctuation">(</span><span class="token variable">CMAKE_CXX_STANDARD</span> <span class="token number">11</span><span class="token punctuation">)</span>
|
||
<span class="token keyword">set</span><span class="token punctuation">(</span><span class="token variable">CMAKE_CXX_STANDARD_REQUIRED</span> True<span class="token punctuation">)</span>
|
||
|
||
<span class="token comment"># should we use our own math functions</span>
|
||
<span class="token keyword">option</span><span class="token punctuation">(</span>USE_MYMATH <span class="token string">"Use tutorial provided math implementation"</span> <span class="token boolean">ON</span><span class="token punctuation">)</span>
|
||
<span class="token keyword">message</span><span class="token punctuation">(</span>STATUS <span class="token string">"OUT --- <span class="token interpolation"><span class="token punctuation">${</span><span class="token variable">CMAKE_CURRENT_SOURCE_DIR</span><span class="token punctuation">}</span></span>"</span><span class="token punctuation">)</span>
|
||
|
||
<span class="token comment"># configure a header file to pass some of the CMake settings</span>
|
||
<span class="token comment"># to the source code</span>
|
||
<span class="token keyword">configure_file</span><span class="token punctuation">(</span>TutorialConfig.h.in TutorialConfig.h<span class="token punctuation">)</span>
|
||
|
||
<span class="token comment"># TODO 2: 删除EXTRA_INCLUDES</span>
|
||
|
||
<span class="token comment"># add the MathFunctions library</span>
|
||
<span class="token keyword">if</span><span class="token punctuation">(</span>USE_MYMATH<span class="token punctuation">)</span>
|
||
<span class="token keyword">add_subdirectory</span><span class="token punctuation">(</span>MathFunctions<span class="token punctuation">)</span>
|
||
<span class="token keyword">list</span><span class="token punctuation">(</span>APPEND EXTRA_LIBS MathFunctions<span class="token punctuation">)</span>
|
||
<span class="token keyword">endif</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
|
||
|
||
<span class="token comment"># add the executable</span>
|
||
<span class="token keyword">add_executable</span><span class="token punctuation">(</span>Tutorial tutorial.cxx<span class="token punctuation">)</span>
|
||
|
||
<span class="token keyword">target_link_libraries</span><span class="token punctuation">(</span>Tutorial <span class="token namespace">PUBLIC</span> <span class="token punctuation">${</span>EXTRA_LIBS<span class="token punctuation">}</span><span class="token punctuation">)</span>
|
||
|
||
<span class="token comment"># TODO 3: 删除EXTRA_INCLUDES</span>
|
||
|
||
<span class="token comment"># add the binary tree to the search path for include files</span>
|
||
<span class="token comment"># so that we will find TutorialConfig.h</span>
|
||
<span class="token keyword">target_include_directories</span><span class="token punctuation">(</span>Tutorial <span class="token namespace">PUBLIC</span>
|
||
<span class="token string">"<span class="token interpolation"><span class="token punctuation">${</span><span class="token variable">PROJECT_BINARY_DIR</span><span class="token punctuation">}</span></span>"</span>
|
||
<span class="token punctuation">)</span></code></pre>
|
||
<p><code>MathFunctions/CMakeLists.txt</code></p>
|
||
<pre><code class="fenced-code-block language-cmake"><span class="token keyword">add_library</span><span class="token punctuation">(</span>MathFunctions mysqrt.cxx<span class="token punctuation">)</span>
|
||
|
||
<span class="token comment"># TODO 1: 声明所有需要链接MathFunctions库的都要在头文件搜索中加入当前当前目录,但是MathFunctions本身不需要</span>
|
||
<span class="token comment"># Hint: 用target_include_directories和INTERFACE </span>
|
||
<span class="token comment"># PUBLIC 本目标需要用,依赖这个目标的其他目标也需要用</span>
|
||
<span class="token comment"># INTERFACE 本目标不需要,依赖本目标的其他目标需要</span>
|
||
<span class="token comment"># PRIVATE 本目标需要,依赖这个目标的其他目标不需要</span>
|
||
<span class="token keyword">target_include_directories</span><span class="token punctuation">(</span>MathFunctions <span class="token namespace">INTERFACE</span> <span class="token string">"<span class="token interpolation"><span class="token punctuation">${</span><span class="token variable">CMAKE_CURRENT_SOURCE_DIR</span><span class="token punctuation">}</span></span>"</span><span class="token punctuation">)</span>
|
||
<span class="token keyword">message</span><span class="token punctuation">(</span>STATUS <span class="token string">"MathFunction --- <span class="token interpolation"><span class="token punctuation">${</span><span class="token variable">CMAKE_CURRENT_SOURCE_DIR</span><span class="token punctuation">}</span></span>"</span><span class="token punctuation">)</span></code></pre>
|
||
<p><strong>要点</strong></p>
|
||
<p>①<mark>PUBLIC | INTERFACE | PRIVATE</mark></p>
|
||
<p>在使用<code>target_include_directories</code>和<code>target_link_libraries</code>添加搜索目录时,有三个修饰符<code>PUBLIC | INTERFACE | PRIVATE</code>,其含义如下:</p>
|
||
<p><strong>PUBLIC</strong>:当前目标和以当前目标为依赖的目标都能能使用添加的目录,都能在对应的目录中进行搜索</p>
|
||
<p><strong>PRIVATE</strong>:只有当前目标能使用添加的目录,以当前目标为依赖的目标不能使用</p>
|
||
<p><strong>INTERFACE</strong>:以当前目标为依赖的目标需要使用添加的目录,但当前目标不需要用这种方式添加对应搜索目录时用INTERFACE。</p>
|
||
<p> </p>
|
||
<p>②<mark>CMAKE_CURRENT_SOURCE_DIR</mark></p>
|
||
<p>变量。当前CMakeLists.txt所在的目录。</p>
|
||
<p> </p>
|
||
<p><strong>课后练习</strong></p>
|
||
<p>①找一个外部的头文件目录,分别在两个cxx文件里引用,并用本节内容方法在MathFunctions/CMakeLists.txt里添加使用依赖,分别使用PUBLIC | INTERFACE | PRIVATE修饰符,查看编译报错信息,验证本节所讲知识点。</p>
|
||
<p> </p>
|
||
<p> </p>
|
||
<h2 class="atx" id="第四步-生成器表达式">第四步 生成器表达式</h2>
|
||
<h3 class="atx" id="练习1-用接口库设置c标准">练习1 用接口库设置C++标准</h3>
|
||
<p><code>CMakeLists.txt</code></p>
|
||
<pre><code class="fenced-code-block language-cmake"><span class="token comment"># TODO 4: Update the minimum required version to 3.15</span>
|
||
|
||
<span class="token keyword">cmake_minimum_required</span><span class="token punctuation">(</span><span class="token property">VERSION</span> <span class="token number">3.10</span><span class="token punctuation">)</span>
|
||
|
||
<span class="token comment"># set the project name and version</span>
|
||
<span class="token keyword">project</span><span class="token punctuation">(</span>Tutorial <span class="token property">VERSION</span> <span class="token number">1.0</span><span class="token punctuation">)</span>
|
||
|
||
<span class="token comment"># TODO 1: 将下面的代码替换为:</span>
|
||
<span class="token comment"># * 创建一个interface库tutorial_compiler_flags</span>
|
||
<span class="token comment"># Hint: use add_library() with the INTERFACE signature</span>
|
||
<span class="token comment"># * 添加编译特性cxx_std_11到tutorial_compiler_flags</span>
|
||
<span class="token comment"># Hint: Use target_compile_features()</span>
|
||
<span class="token keyword">add_library</span><span class="token punctuation">(</span>tutorial_compiler_flags <span class="token namespace">INTERFACE</span><span class="token punctuation">)</span>
|
||
<span class="token keyword">target_compile_features</span><span class="token punctuation">(</span>tutorial_compiler_flags <span class="token namespace">INTERFACE</span> <span class="token property">cxx_std_14</span><span class="token punctuation">)</span>
|
||
|
||
|
||
|
||
<span class="token comment"># TODO 5: 创建一些辅助变量用来确定用的是哪个编译器:</span>
|
||
<span class="token comment"># * 创建一个变量gcc_like_cxx如果用的是CXX并且用的是下列任意一个编译器那么值为true</span>
|
||
<span class="token comment"># ARMClang, AppleClang, Clang, GNU, LCC</span>
|
||
<span class="token comment"># * 创建一个变量msvc_cxx如果用的是CXX和MSVC那么值为true</span>
|
||
<span class="token comment"># Hint: Use set() and COMPILE_LANG_AND_ID</span>
|
||
|
||
<span class="token comment"># TODO 6: 向interface库tutorial_compiler_flags中添加警告选项:</span>
|
||
<span class="token comment"># </span>
|
||
<span class="token comment"># * 如果是gcc_like_cxx, 添加 -Wall;-Wextra;-Wshadow;-Wformat=2;-Wunused</span>
|
||
<span class="token comment"># * 如果是msvc_cxx, 添加 -W3</span>
|
||
<span class="token comment"># Hint: Use target_compile_options()</span>
|
||
|
||
<span class="token comment"># TODO 7: 用嵌套生成器表达式, 只在构建的时警告</span>
|
||
<span class="token comment"># </span>
|
||
<span class="token comment"># Hint: Use BUILD_INTERFACE</span>
|
||
|
||
<span class="token comment"># should we use our own math functions</span>
|
||
<span class="token keyword">option</span><span class="token punctuation">(</span>USE_MYMATH <span class="token string">"Use tutorial provided math implementation"</span> <span class="token boolean">ON</span><span class="token punctuation">)</span>
|
||
|
||
<span class="token comment"># configure a header file to pass some of the CMake settings</span>
|
||
<span class="token comment"># to the source code</span>
|
||
<span class="token keyword">configure_file</span><span class="token punctuation">(</span>TutorialConfig.h.in TutorialConfig.h<span class="token punctuation">)</span>
|
||
|
||
<span class="token comment"># add the MathFunctions library</span>
|
||
<span class="token keyword">if</span><span class="token punctuation">(</span>USE_MYMATH<span class="token punctuation">)</span>
|
||
<span class="token keyword">add_subdirectory</span><span class="token punctuation">(</span>MathFunctions<span class="token punctuation">)</span>
|
||
<span class="token keyword">list</span><span class="token punctuation">(</span>APPEND EXTRA_LIBS MathFunctions<span class="token punctuation">)</span>
|
||
<span class="token keyword">endif</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
|
||
|
||
<span class="token comment"># add the executable</span>
|
||
<span class="token keyword">add_executable</span><span class="token punctuation">(</span>Tutorial tutorial.cxx<span class="token punctuation">)</span>
|
||
|
||
<span class="token comment"># TODO 2: 链接tutorial_compiler_flags</span>
|
||
|
||
<span class="token keyword">target_link_libraries</span><span class="token punctuation">(</span>Tutorial <span class="token namespace">PUBLIC</span> <span class="token punctuation">${</span>EXTRA_LIBS<span class="token punctuation">}</span> tutorial_compiler_flags<span class="token punctuation">)</span>
|
||
|
||
<span class="token comment"># add the binary tree to the search path for include files</span>
|
||
<span class="token comment"># so that we will find TutorialConfig.h</span>
|
||
<span class="token keyword">target_include_directories</span><span class="token punctuation">(</span>Tutorial <span class="token namespace">PUBLIC</span>
|
||
<span class="token string">"<span class="token interpolation"><span class="token punctuation">${</span><span class="token variable">PROJECT_BINARY_DIR</span><span class="token punctuation">}</span></span>"</span>
|
||
<span class="token punctuation">)</span></code></pre>
|
||
<p><code>MathFunctions/CMakeLists.txt</code></p>
|
||
<pre><code class="fenced-code-block language-cmake"><span class="token keyword">add_library</span><span class="token punctuation">(</span>MathFunctions mysqrt.cxx<span class="token punctuation">)</span>
|
||
|
||
<span class="token comment"># state that anybody linking to us needs to include the current source dir</span>
|
||
<span class="token comment"># to find MathFunctions.h, while we don't.</span>
|
||
<span class="token keyword">target_include_directories</span><span class="token punctuation">(</span>MathFunctions
|
||
<span class="token namespace">INTERFACE</span> <span class="token punctuation">${</span><span class="token variable">CMAKE_CURRENT_SOURCE_DIR</span><span class="token punctuation">}</span>
|
||
<span class="token punctuation">)</span>
|
||
|
||
<span class="token comment"># TODO 3: 链接tutorial_compiler_flags</span>
|
||
<span class="token keyword">target_link_libraries</span><span class="token punctuation">(</span>MathFunctions <span class="token namespace">PUBLIC</span> tutorial_compiler_flags<span class="token punctuation">)</span></code></pre>
|
||
<p><strong>要点</strong></p>
|
||
<p>①<mark>INTERFACE库</mark></p>
|
||
<p>使用<code>add_library(<libname> INTERFACE)</code>可以创建个Interface库,这样的库并不是真实存在的,是一个虚拟的库,通常用来传递一些选项。用法和正常的库一样,可通过<code>target_link_libraries</code>链接到目标,可以向指定的目标传递一些指定的参数选项。</p>
|
||
<p> </p>
|
||
<p>②<mark>target_compile_features</mark></p>
|
||
<p><code>target_compile_features</code> 是 CMake 用来指定编译器特性的命令。它可以用来指定编译器需要支持的 C++ 标准或者其他编译器特性。具体支持的特性取决于编译器版本和 CMake 版本。</p>
|
||
<p>语法与示例</p>
|
||
<pre><code class="fenced-code-block language-cmake"><span class="token keyword">target_compile_features</span><span class="token punctuation">(</span><target<span class="token punctuation">></span> <<span class="token namespace">PRIVATE</span>|<span class="token namespace">PUBLIC</span>|<span class="token namespace">INTERFACE</span><span class="token punctuation">></span> <feature<span class="token punctuation">></span> [...]<span class="token punctuation">)</span>
|
||
|
||
<span class="token comment"># 示例</span>
|
||
<span class="token keyword">target_compile_features</span><span class="token punctuation">(</span>tutorial_compiler_flags <span class="token namespace">INTERFACE</span> <span class="token property">cxx_std_11</span><span class="token punctuation">)</span></code></pre>
|
||
<p>以下是一些常见的特性:</p>
|
||
<ul>
|
||
<li><code>cxx_std_11</code>:指定 C++11 标准。</li>
|
||
<li><code>cxx_std_14</code>:指定 C++14 标准。</li>
|
||
<li><code>cxx_std_17</code>:指定 C++17 标准。</li>
|
||
<li><code>cxx_std_20</code>:指定 C++20 标准。</li>
|
||
<li><code>cxx_constexpr</code>:启用 C++11 constexpr 函数。</li>
|
||
<li><code>cxx_nullptr</code>:启用 C++11 nullptr 关键字。</li>
|
||
<li><code>cxx_auto_type</code>:启用 C++11 auto 关键字。</li>
|
||
<li><code>cxx_lambdas</code>:启用 C++11 lambda 表达式。</li>
|
||
<li><code>cxx_range_for</code>:启用 C++11 range-based for 循环。</li>
|
||
<li><code>cxx_override</code>:启用 C++11 override 关键字。</li>
|
||
<li><code>cxx_final</code>:启用 C++11 final 关键字。</li>
|
||
</ul>
|
||
<p> </p>
|
||
<h3 class="atx" id="练习2-添加编译警告选项">练习2 添加编译警告选项</h3>
|
||
<p><strong>CMakeLists.txt解析过程</strong></p>
|
||
<p>CMake构建过程分为两个阶段</p>
|
||
<ol>
|
||
<li>配置阶段,CMake 会读取项目的 CMakeLists.txt 文件,并根据其中的指令和参数来生成 Makefile 或者 IDE 的项目文件<ul>
|
||
<li>检查编译器和工具链是否可用,并设置编译器选项和链接选项</li>
|
||
<li>检查系统库和第三方库是否可用,并设置库的路径和链接选项</li>
|
||
<li>检查项目的源代码文件,并设置编译选项和链接选项</li>
|
||
<li>生成 Makefile 或者 IDE 的项目文件</li>
|
||
<li>根据不同的平台和编译器生成不同的 Makefile 或者项目文件,以保证项目可以在不同的平台和编译器上构建</li>
|
||
</ul>
|
||
</li>
|
||
<li>生成阶段,CMake 会根据配置阶段生成的 Makefile 或者项目文件来执行实际的构建操作<ul>
|
||
<li>根据 Makefile 或者项目文件中的指令和参数来编译源代码文件,并生成目标文件</li>
|
||
<li>根据 Makefile 或者项目文件中的指令和参数来链接目标文件,并生成可执行文件或者库文件</li>
|
||
</ul>
|
||
</li>
|
||
</ol>
|
||
<p> </p>
|
||
<p><strong>生成器表达式</strong></p>
|
||
<p>CMake生成器表达式是一种特殊的语法,用于在CMake构建系统中动态地生成构建规则。它们可以用于指定编译器选项、链接选项等。</p>
|
||
<p>本节先学习其中两种表达式:</p>
|
||
<p><strong>$<condition:true_string></strong></p>
|
||
<ul>
|
||
<li>如果<code>condition</code>为1,则此表达式结果为<code>true_string</code></li>
|
||
<li>如果<code>condition</code>为0,则此表达式结果为空</li>
|
||
</ul>
|
||
<p><strong>$<COMPILE_LANG_AND_ID:language,compiler_ids></strong></p>
|
||
<ul>
|
||
<li>如果当前所用的语言与<code>language</code>一致且编译器ID在<code>compiler_ids</code>的列表中,则表达式值为1,否则为0</li>
|
||
<li><code>language</code>值主要为<code>CXX</code>和<code>C</code></li>
|
||
<li><code>compiler_ids</code>主要有GNU、Clang、MSVC等,有多个时用逗号隔开</li>
|
||
</ul>
|
||
<p>生成器表达式因为是在生成阶段可用,所以不能在配置阶段进行输出 ,可用下面方式调式</p>
|
||
<pre><code class="fenced-code-block language-cmake"><span class="token keyword">add_custom_target</span><span class="token punctuation">(</span>ged COMMAND <span class="token punctuation">${</span><span class="token variable">CMAKE_COMMAND</span><span class="token punctuation">}</span> -E echo <span class="token string">"$<1:hello>"</span><span class="token punctuation">)</span></code></pre>
|
||
<p>配置完成之后,用以下命令进行输出</p>
|
||
<pre><code class="fenced-code-block language-shell">cmake --build <span class="token builtin class-name">.</span> --target ged
|
||
<span class="token comment"># 用make可简写</span>
|
||
<span class="token function">make</span> ged</code></pre>
|
||
<p>但不是所有的表达式都能这样输出,有的表达式无法输出,比如<code>$<COMPILE_LANG_AND_ID:CXX,ARMClang,AppleClang,Clang,GNU,LCC></code></p>
|
||
<p> </p>
|
||
<pre><code class="fenced-code-block language-cmake"><span class="token comment"># TODO 4: Update the minimum required version to 3.15</span>
|
||
|
||
<span class="token keyword">cmake_minimum_required</span><span class="token punctuation">(</span><span class="token property">VERSION</span> <span class="token number">3.15</span><span class="token punctuation">)</span>
|
||
|
||
<span class="token comment"># set the project name and version</span>
|
||
<span class="token keyword">project</span><span class="token punctuation">(</span>Tutorial <span class="token property">VERSION</span> <span class="token number">1.0</span><span class="token punctuation">)</span>
|
||
|
||
<span class="token comment"># TODO 1: 将下面的代码替换为:</span>
|
||
<span class="token comment"># * 创建一个interface库tutorial_compiler_flags</span>
|
||
<span class="token comment"># Hint: use add_library() with the INTERFACE signature</span>
|
||
<span class="token comment"># * 添加编译特性cxx_std_11到tutorial_compiler_flags</span>
|
||
<span class="token comment"># Hint: Use target_compile_features()</span>
|
||
<span class="token keyword">add_library</span><span class="token punctuation">(</span>tutorial_compiler_flags <span class="token namespace">INTERFACE</span><span class="token punctuation">)</span>
|
||
<span class="token keyword">target_compile_features</span><span class="token punctuation">(</span>tutorial_compiler_flags <span class="token namespace">INTERFACE</span> <span class="token property">cxx_std_14</span><span class="token punctuation">)</span>
|
||
|
||
<span class="token comment"># add_custom_target(ged COMMAND ${CMAKE_COMMAND} -E echo "$<COMPILE_LANG_AND_ID:CXX,GNU>")</span>
|
||
|
||
<span class="token comment"># TODO 5: 创建一些辅助变量用来确定用的是哪个编译器:</span>
|
||
<span class="token comment"># * 创建一个变量gcc_like_cxx如果用的是CXX并且用的是下列任意一个编译器那么值为true</span>
|
||
<span class="token comment"># ARMClang, AppleClang, Clang, GNU, LCC</span>
|
||
<span class="token comment"># * 创建一个变量msvc_cxx如果用的是CXX和MSVC那么值为true</span>
|
||
<span class="token comment"># Hint: Use set() and COMPILE_LANG_AND_ID</span>
|
||
<span class="token keyword">set</span><span class="token punctuation">(</span>gcc_like_cxx <span class="token string">"$<COMPILE_LANG_AND_ID:CXX,ARMClang,AppleClang,Clang,GNU,LCC>"</span><span class="token punctuation">)</span>
|
||
<span class="token keyword">set</span><span class="token punctuation">(</span>msvc_cxx <span class="token string">"$<COMPILE_LANG_AND_ID:CXX,MSVC>"</span><span class="token punctuation">)</span>
|
||
|
||
|
||
<span class="token comment"># TODO 6: 向interface库tutorial_compiler_flags中添加警告选项:</span>
|
||
<span class="token comment"># </span>
|
||
<span class="token comment"># * 如果是gcc_like_cxx, 添加 -Wall;-Wextra;-Wshadow;-Wformat=2;-Wunused</span>
|
||
<span class="token comment"># * 如果是msvc_cxx, 添加 -W3</span>
|
||
<span class="token comment"># Hint: Use target_compile_options()</span>
|
||
<span class="token keyword">target_compile_options</span><span class="token punctuation">(</span>tutorial_compiler_flags <span class="token namespace">INTERFACE</span>
|
||
<span class="token string">"$<<span class="token interpolation"><span class="token punctuation">${</span><span class="token variable">gcc_like_cxx</span><span class="token punctuation">}</span></span>:-Wall;-Wextra;-Wshadow;-Wformat=2;-Wunused>"</span>
|
||
<span class="token string">"$<<span class="token interpolation"><span class="token punctuation">${</span><span class="token variable">msvc_cxx</span><span class="token punctuation">}</span></span>:-W3>"</span>
|
||
<span class="token punctuation">)</span>
|
||
|
||
<span class="token comment"># TODO 7: 用嵌套生成器表达式, 只在构建的时警告</span>
|
||
<span class="token comment"># </span>
|
||
<span class="token comment"># Hint: Use BUILD_INTERFACE</span>
|
||
|
||
<span class="token comment"># should we use our own math functions</span>
|
||
<span class="token keyword">option</span><span class="token punctuation">(</span>USE_MYMATH <span class="token string">"Use tutorial provided math implementation"</span> <span class="token boolean">ON</span><span class="token punctuation">)</span>
|
||
|
||
<span class="token comment"># configure a header file to pass some of the CMake settings</span>
|
||
<span class="token comment"># to the source code</span>
|
||
<span class="token keyword">configure_file</span><span class="token punctuation">(</span>TutorialConfig.h.in TutorialConfig.h<span class="token punctuation">)</span>
|
||
|
||
<span class="token comment"># add the MathFunctions library</span>
|
||
<span class="token keyword">if</span><span class="token punctuation">(</span>USE_MYMATH<span class="token punctuation">)</span>
|
||
<span class="token keyword">add_subdirectory</span><span class="token punctuation">(</span>MathFunctions<span class="token punctuation">)</span>
|
||
<span class="token keyword">list</span><span class="token punctuation">(</span>APPEND EXTRA_LIBS MathFunctions<span class="token punctuation">)</span>
|
||
<span class="token keyword">endif</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
|
||
|
||
<span class="token comment"># add the executable</span>
|
||
<span class="token keyword">add_executable</span><span class="token punctuation">(</span>Tutorial tutorial.cxx<span class="token punctuation">)</span>
|
||
|
||
<span class="token comment"># TODO 2: 链接tutorial_compiler_flags</span>
|
||
|
||
<span class="token keyword">target_link_libraries</span><span class="token punctuation">(</span>Tutorial <span class="token namespace">PUBLIC</span> <span class="token punctuation">${</span>EXTRA_LIBS<span class="token punctuation">}</span> tutorial_compiler_flags<span class="token punctuation">)</span>
|
||
|
||
<span class="token comment"># add the binary tree to the search path for include files</span>
|
||
<span class="token comment"># so that we will find TutorialConfig.h</span>
|
||
<span class="token keyword">target_include_directories</span><span class="token punctuation">(</span>Tutorial <span class="token namespace">PUBLIC</span>
|
||
<span class="token string">"<span class="token interpolation"><span class="token punctuation">${</span><span class="token variable">PROJECT_BINARY_DIR</span><span class="token punctuation">}</span></span>"</span>
|
||
<span class="token punctuation">)</span></code></pre>
|
||
<p><strong>要点</strong></p>
|
||
<p>①<mark>target_compile_options</mark></p>
|
||
<p>给指定的目标添加编译选项。</p>
|
||
<p>语法及示例:</p>
|
||
<pre><code class="fenced-code-block language-cmake"><span class="token keyword">target_compile_options</span><span class="token punctuation">(</span><target<span class="token punctuation">></span> [BEFORE]
|
||
<<span class="token namespace">INTERFACE</span>|<span class="token namespace">PUBLIC</span>|<span class="token namespace">PRIVATE</span><span class="token punctuation">></span> [items1...]
|
||
[<<span class="token namespace">INTERFACE</span>|<span class="token namespace">PUBLIC</span>|<span class="token namespace">PRIVATE</span><span class="token punctuation">></span> [items2...] ...]<span class="token punctuation">)</span>
|
||
|
||
<span class="token comment"># 示例</span>
|
||
<span class="token keyword">target_compile_options</span><span class="token punctuation">(</span>Tutorial <span class="token namespace">PUBLIC</span> -std=c++<span class="token number">11</span> -Wunused<span class="token punctuation">)</span></code></pre>
|
||
<p> </p>
|
||
<p><strong>课后练习</strong></p>
|
||
<p>①有余力的同学自行探究一下生成器表达式的其他内容。</p>
|
||
<p> </p>
|
||
<p> </p>
|
||
<h2 class="atx" id="第五步-安装与测试">第五步 安装与测试</h2>
|
||
<h3 class="atx" id="练习1-安装规则">练习1 安装规则</h3>
|
||
<p><code>CMakeLists.txt</code></p>
|
||
<pre><code class="fenced-code-block language-cmake"><span class="token keyword">cmake_minimum_required</span><span class="token punctuation">(</span><span class="token property">VERSION</span> <span class="token number">3.15</span><span class="token punctuation">)</span>
|
||
|
||
<span class="token comment"># set the project name and version</span>
|
||
<span class="token keyword">project</span><span class="token punctuation">(</span>Tutorial <span class="token property">VERSION</span> <span class="token number">1.0</span><span class="token punctuation">)</span>
|
||
|
||
<span class="token comment"># specify the C++ standard</span>
|
||
<span class="token keyword">add_library</span><span class="token punctuation">(</span>tutorial_compiler_flags <span class="token namespace">INTERFACE</span><span class="token punctuation">)</span>
|
||
<span class="token keyword">target_compile_features</span><span class="token punctuation">(</span>tutorial_compiler_flags <span class="token namespace">INTERFACE</span> <span class="token property">cxx_std_11</span><span class="token punctuation">)</span>
|
||
|
||
<span class="token comment"># add compiler warning flags just when building this project via</span>
|
||
<span class="token comment"># the BUILD_INTERFACE genex</span>
|
||
<span class="token keyword">set</span><span class="token punctuation">(</span>gcc_like_cxx <span class="token string">"$<COMPILE_LANG_AND_ID:CXX,ARMClang,AppleClang,Clang,GNU,LCC>"</span><span class="token punctuation">)</span>
|
||
<span class="token keyword">set</span><span class="token punctuation">(</span>msvc_cxx <span class="token string">"$<COMPILE_LANG_AND_ID:CXX,MSVC>"</span><span class="token punctuation">)</span>
|
||
<span class="token keyword">target_compile_options</span><span class="token punctuation">(</span>tutorial_compiler_flags <span class="token namespace">INTERFACE</span>
|
||
<span class="token string">"$<<span class="token interpolation"><span class="token punctuation">${</span><span class="token variable">gcc_like_cxx</span><span class="token punctuation">}</span></span>:$<BUILD_INTERFACE:-Wall;-Wextra;-Wshadow;-Wformat=2;-Wunused>>"</span>
|
||
<span class="token string">"$<<span class="token interpolation"><span class="token punctuation">${</span><span class="token variable">msvc_cxx</span><span class="token punctuation">}</span></span>:$<BUILD_INTERFACE:-W3>>"</span>
|
||
<span class="token punctuation">)</span>
|
||
|
||
<span class="token comment"># should we use our own math functions</span>
|
||
<span class="token keyword">option</span><span class="token punctuation">(</span>USE_MYMATH <span class="token string">"Use tutorial provided math implementation"</span> <span class="token boolean">ON</span><span class="token punctuation">)</span>
|
||
|
||
<span class="token comment"># configure a header file to pass some of the CMake settings</span>
|
||
<span class="token comment"># to the source code</span>
|
||
<span class="token keyword">configure_file</span><span class="token punctuation">(</span>TutorialConfig.h.in TutorialConfig.h<span class="token punctuation">)</span>
|
||
|
||
<span class="token comment"># add the MathFunctions library</span>
|
||
<span class="token keyword">if</span><span class="token punctuation">(</span>USE_MYMATH<span class="token punctuation">)</span>
|
||
<span class="token keyword">add_subdirectory</span><span class="token punctuation">(</span>MathFunctions<span class="token punctuation">)</span>
|
||
<span class="token keyword">list</span><span class="token punctuation">(</span>APPEND EXTRA_LIBS MathFunctions<span class="token punctuation">)</span>
|
||
<span class="token keyword">endif</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
|
||
|
||
<span class="token comment"># add the executable</span>
|
||
<span class="token keyword">add_executable</span><span class="token punctuation">(</span>Tutorial tutorial.cxx<span class="token punctuation">)</span>
|
||
<span class="token keyword">target_link_libraries</span><span class="token punctuation">(</span>Tutorial <span class="token namespace">PUBLIC</span> <span class="token punctuation">${</span>EXTRA_LIBS<span class="token punctuation">}</span> tutorial_compiler_flags<span class="token punctuation">)</span>
|
||
|
||
<span class="token comment"># add the binary tree to the search path for include files</span>
|
||
<span class="token comment"># so that we will find TutorialConfig.h</span>
|
||
<span class="token keyword">target_include_directories</span><span class="token punctuation">(</span>Tutorial <span class="token namespace">PUBLIC</span>
|
||
<span class="token string">"<span class="token interpolation"><span class="token punctuation">${</span><span class="token variable">PROJECT_BINARY_DIR</span><span class="token punctuation">}</span></span>"</span>
|
||
<span class="token punctuation">)</span>
|
||
|
||
<span class="token comment"># TODO 3: 安装 Tutorial 到 bin 目录 ${CMAKE_INSTALL_PREFIX}</span>
|
||
<span class="token comment"># Hint: Use the TARGETS and DESTINATION parameters</span>
|
||
<span class="token comment"># install(TARGETS targets... [DESTINATION <dir>])</span>
|
||
<span class="token keyword">install</span><span class="token punctuation">(</span>TARGETS Tutorial DESTINATION bin<span class="token punctuation">)</span>
|
||
<span class="token keyword">message</span><span class="token punctuation">(</span>STATUS <span class="token string">"<span class="token interpolation"><span class="token punctuation">${</span><span class="token variable">CMAKE_INSTALL_PREFIX</span><span class="token punctuation">}</span></span>"</span><span class="token punctuation">)</span>
|
||
|
||
<span class="token comment"># TODO 4: 安装TutorialConfig.h到include目录</span>
|
||
<span class="token comment"># Hint: Use the FILES and DESTINATION parameters</span>
|
||
<span class="token keyword">install</span><span class="token punctuation">(</span>FILES <span class="token string">"<span class="token interpolation"><span class="token punctuation">${</span><span class="token variable">PROJECT_BINARY_DIR</span><span class="token punctuation">}</span></span>/TutorialConfig.h"</span> DESTINATION include<span class="token punctuation">)</span></code></pre>
|
||
<p><code>MathFunctions/CMakeLists.txt</code></p>
|
||
<pre><code class="fenced-code-block language-cmake"><span class="token keyword">add_library</span><span class="token punctuation">(</span>MathFunctions mysqrt.cxx<span class="token punctuation">)</span>
|
||
|
||
<span class="token keyword">target_include_directories</span><span class="token punctuation">(</span>MathFunctions
|
||
<span class="token namespace">INTERFACE</span> <span class="token punctuation">${</span><span class="token variable">CMAKE_CURRENT_SOURCE_DIR</span><span class="token punctuation">}</span>
|
||
<span class="token punctuation">)</span>
|
||
|
||
<span class="token keyword">target_link_libraries</span><span class="token punctuation">(</span>MathFunctions tutorial_compiler_flags<span class="token punctuation">)</span>
|
||
|
||
<span class="token keyword">set</span><span class="token punctuation">(</span>installable_libs MathFunctions tutorial_compiler_flags<span class="token punctuation">)</span>
|
||
<span class="token keyword">if</span><span class="token punctuation">(</span>TARGET SqrtLibrary<span class="token punctuation">)</span>
|
||
<span class="token keyword">list</span><span class="token punctuation">(</span>APPEND installable_libs SqrtLibrary<span class="token punctuation">)</span>
|
||
<span class="token keyword">endif</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
|
||
<span class="token keyword">install</span><span class="token punctuation">(</span>TARGETS <span class="token punctuation">${</span>installable_libs<span class="token punctuation">}</span> DESTINATION lib<span class="token punctuation">)</span>
|
||
|
||
<span class="token keyword">install</span><span class="token punctuation">(</span>FILES MathFunctions.h DESTINATION include<span class="token punctuation">)</span></code></pre>
|
||
<p><strong>要点</strong></p>
|
||
<p>①<mark>if(TARGET target-name)</mark></p>
|
||
<ul>
|
||
<li>如果<code>target-name</code>是一个已经调用<code>add_executable</code>、<code>add_library</code>、<code>add_custom_target</code>创建的目标,则返回True</li>
|
||
</ul>
|
||
<pre><code class="fenced-code-block language-cmake"></code></pre>
|
||
<p>②<mark>install</mark></p>
|
||
<p>用于定义安装规则。</p>
|
||
<p>语法与示例(简洁版)</p>
|
||
<pre><code class="fenced-code-block language-cmake"><span class="token comment"># 安装生成的目标文件</span>
|
||
<span class="token keyword">install</span><span class="token punctuation">(</span>TARGETS <目标名列表<span class="token punctuation">></span> DESTINATION <安装位置<span class="token punctuation">></span><span class="token punctuation">)</span>
|
||
<span class="token comment"># 安装其他文件</span>
|
||
<span class="token keyword">install</span><span class="token punctuation">(</span>FILES <文件列表<span class="token punctuation">></span> DESTINATION <安装位置<span class="token punctuation">></span><span class="token punctuation">)</span></code></pre>
|
||
<p>安装多个文件时,用空格隔开。安装位置是相对于<code>CMAKE_INSTALL_PREFIX</code>的,<code>CMAKE_INSTALL_PREFIX</code>是安装时的默认路径,可以自行用<code>set</code>设置。</p>
|
||
<p>运行安装:</p>
|
||
<p>安装到默认路径下</p>
|
||
<pre><code class="fenced-code-block language-shell">cmake --install <span class="token builtin class-name">.</span></code></pre>
|
||
<p>如果有多个生成版本,指定安装版本</p>
|
||
<pre><code class="fenced-code-block language-shell">cmake --install <span class="token builtin class-name">.</span> --config Release</code></pre>
|
||
<p>如果用的是IDE,用下列命令</p>
|
||
<pre><code class="fenced-code-block language-shell">cmake --build <span class="token builtin class-name">.</span> --target <span class="token function">install</span> --config Debug</code></pre>
|
||
<p>自行指定安装路径</p>
|
||
<pre><code class="fenced-code-block language-shell">cmake --install <span class="token builtin class-name">.</span> --prefix <span class="token string">"/path/to/your/installdir"</span></code></pre>
|
||
<p> </p>
|
||
<h3 class="atx" id="练习2-测试支持">练习2 测试支持</h3>
|
||
<p><code>CTest</code>提供了一些测试管理。本节内容为给可执行文件创建单元测试。</p>
|
||
<pre><code class="fenced-code-block language-cmake"><span class="token keyword">cmake_minimum_required</span><span class="token punctuation">(</span><span class="token property">VERSION</span> <span class="token number">3.15</span><span class="token punctuation">)</span>
|
||
|
||
<span class="token comment"># set the project name and version</span>
|
||
<span class="token keyword">project</span><span class="token punctuation">(</span>Tutorial <span class="token property">VERSION</span> <span class="token number">1.0</span><span class="token punctuation">)</span>
|
||
|
||
<span class="token comment"># specify the C++ standard</span>
|
||
<span class="token keyword">add_library</span><span class="token punctuation">(</span>tutorial_compiler_flags <span class="token namespace">INTERFACE</span><span class="token punctuation">)</span>
|
||
<span class="token keyword">target_compile_features</span><span class="token punctuation">(</span>tutorial_compiler_flags <span class="token namespace">INTERFACE</span> <span class="token property">cxx_std_11</span><span class="token punctuation">)</span>
|
||
|
||
<span class="token comment"># add compiler warning flags just when building this project via</span>
|
||
<span class="token comment"># the BUILD_INTERFACE genex</span>
|
||
<span class="token keyword">set</span><span class="token punctuation">(</span>gcc_like_cxx <span class="token string">"$<COMPILE_LANG_AND_ID:CXX,ARMClang,AppleClang,Clang,GNU,LCC>"</span><span class="token punctuation">)</span>
|
||
<span class="token keyword">set</span><span class="token punctuation">(</span>msvc_cxx <span class="token string">"$<COMPILE_LANG_AND_ID:CXX,MSVC>"</span><span class="token punctuation">)</span>
|
||
<span class="token keyword">target_compile_options</span><span class="token punctuation">(</span>tutorial_compiler_flags <span class="token namespace">INTERFACE</span>
|
||
<span class="token string">"$<<span class="token interpolation"><span class="token punctuation">${</span><span class="token variable">gcc_like_cxx</span><span class="token punctuation">}</span></span>:$<BUILD_INTERFACE:-Wall;-Wextra;-Wshadow;-Wformat=2;-Wunused>>"</span>
|
||
<span class="token string">"$<<span class="token interpolation"><span class="token punctuation">${</span><span class="token variable">msvc_cxx</span><span class="token punctuation">}</span></span>:$<BUILD_INTERFACE:-W3>>"</span>
|
||
<span class="token punctuation">)</span>
|
||
|
||
<span class="token comment"># should we use our own math functions</span>
|
||
<span class="token keyword">option</span><span class="token punctuation">(</span>USE_MYMATH <span class="token string">"Use tutorial provided math implementation"</span> <span class="token boolean">ON</span><span class="token punctuation">)</span>
|
||
|
||
<span class="token comment"># configure a header file to pass some of the CMake settings</span>
|
||
<span class="token comment"># to the source code</span>
|
||
<span class="token keyword">configure_file</span><span class="token punctuation">(</span>TutorialConfig.h.in TutorialConfig.h<span class="token punctuation">)</span>
|
||
|
||
<span class="token comment"># add the MathFunctions library</span>
|
||
<span class="token keyword">if</span><span class="token punctuation">(</span>USE_MYMATH<span class="token punctuation">)</span>
|
||
<span class="token keyword">add_subdirectory</span><span class="token punctuation">(</span>MathFunctions<span class="token punctuation">)</span>
|
||
<span class="token keyword">list</span><span class="token punctuation">(</span>APPEND EXTRA_LIBS MathFunctions<span class="token punctuation">)</span>
|
||
<span class="token keyword">endif</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
|
||
|
||
<span class="token comment"># add the executable</span>
|
||
<span class="token keyword">add_executable</span><span class="token punctuation">(</span>Tutorial tutorial.cxx<span class="token punctuation">)</span>
|
||
<span class="token keyword">target_link_libraries</span><span class="token punctuation">(</span>Tutorial <span class="token namespace">PUBLIC</span> <span class="token punctuation">${</span>EXTRA_LIBS<span class="token punctuation">}</span> tutorial_compiler_flags<span class="token punctuation">)</span>
|
||
|
||
<span class="token comment"># add the binary tree to the search path for include files</span>
|
||
<span class="token comment"># so that we will find TutorialConfig.h</span>
|
||
<span class="token keyword">target_include_directories</span><span class="token punctuation">(</span>Tutorial <span class="token namespace">PUBLIC</span>
|
||
<span class="token string">"<span class="token interpolation"><span class="token punctuation">${</span><span class="token variable">PROJECT_BINARY_DIR</span><span class="token punctuation">}</span></span>"</span>
|
||
<span class="token punctuation">)</span>
|
||
|
||
<span class="token comment"># TODO 3: 安装 Tutorial 到 bin 目录 ${CMAKE_INSTALL_PREFIX}</span>
|
||
<span class="token comment"># Hint: Use the TARGETS and DESTINATION parameters</span>
|
||
<span class="token comment"># install(TARGETS targets... [DESTINATION <dir>])</span>
|
||
<span class="token comment"># target: add_excutable add_library</span>
|
||
<span class="token keyword">install</span><span class="token punctuation">(</span>TARGETS Tutorial DESTINATION bin<span class="token punctuation">)</span>
|
||
<span class="token keyword">message</span><span class="token punctuation">(</span>STATUS <span class="token string">"<span class="token interpolation"><span class="token punctuation">${</span><span class="token variable">CMAKE_INSTALL_PREFIX</span><span class="token punctuation">}</span></span>"</span><span class="token punctuation">)</span>
|
||
|
||
<span class="token comment"># TODO 4: 安装TutorialConfig.h到include目录</span>
|
||
<span class="token comment"># Hint: Use the FILES and DESTINATION parameters</span>
|
||
<span class="token keyword">install</span><span class="token punctuation">(</span>FILES <span class="token string">"<span class="token interpolation"><span class="token punctuation">${</span><span class="token variable">PROJECT_BINARY_DIR</span><span class="token punctuation">}</span></span>/TutorialConfig.h"</span> DESTINATION include<span class="token punctuation">)</span>
|
||
|
||
<span class="token comment"># TODO 5: Enable testing</span>
|
||
<span class="token keyword">enable_testing</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
|
||
|
||
<span class="token comment"># TODO 6: 添加一个Runs测试,运行下面的命令:</span>
|
||
<span class="token comment"># $ Tutorial 25</span>
|
||
<span class="token keyword">add_test</span><span class="token punctuation">(</span><span class="token property">NAME</span> Runs COMMAND Tutorial <span class="token number">25</span><span class="token punctuation">)</span>
|
||
|
||
<span class="token comment"># TODO 7: 添加一个叫Usage的测试,执行下面的命令:</span>
|
||
<span class="token comment"># $ Tutorial</span>
|
||
<span class="token comment"># 要保证输出期望的内容.</span>
|
||
<span class="token comment"># Hint: 用PASS_REGULAR_EXPRESSION属性匹配"Usage.*number"</span>
|
||
<span class="token keyword">add_test</span><span class="token punctuation">(</span><span class="token property">NAME</span> Usage COMMAND Tutorial<span class="token punctuation">)</span>
|
||
<span class="token keyword">set_tests_properties</span><span class="token punctuation">(</span>Usage <span class="token namespace">PROPERTIES</span> <span class="token property">PASS_REGULAR_EXPRESSION</span> <span class="token string">"Usage.*number"</span><span class="token punctuation">)</span>
|
||
|
||
<span class="token comment"># TODO 8: 再添加一个运行下面命令的测试:</span>
|
||
<span class="token comment"># $ Tutorial 4</span>
|
||
<span class="token comment"># 保证输出结果是正确的.</span>
|
||
<span class="token comment"># Hint: 用PASS_REGULAR_EXPRESSION属性匹配"4 is 2"</span>
|
||
<span class="token keyword">add_test</span><span class="token punctuation">(</span><span class="token property">NAME</span> Com4 COMMAND Tutorial <span class="token number">4</span><span class="token punctuation">)</span>
|
||
<span class="token keyword">set_tests_properties</span><span class="token punctuation">(</span>Com4 <span class="token namespace">PROPERTIES</span> <span class="token property">PASS_REGULAR_EXPRESSION</span> <span class="token string">"4 is 2"</span><span class="token punctuation">)</span>
|
||
|
||
|
||
<span class="token comment"># TODO 9: 添加更多测试. 创建一个函数do_test完成重复内容</span>
|
||
<span class="token comment"># 测试以下数值: 4, 9, 5, 7, 25, -25 and 0.0001.</span>
|
||
<span class="token keyword">function</span><span class="token punctuation">(</span>do_test num result<span class="token punctuation">)</span>
|
||
<span class="token keyword">add_test</span><span class="token punctuation">(</span><span class="token property">NAME</span> Com<span class="token punctuation">${</span>num<span class="token punctuation">}</span> COMMAND Tutorial <span class="token punctuation">${</span>num<span class="token punctuation">}</span><span class="token punctuation">)</span>
|
||
<span class="token keyword">set_tests_properties</span><span class="token punctuation">(</span>Com<span class="token punctuation">${</span>num<span class="token punctuation">}</span> <span class="token namespace">PROPERTIES</span> <span class="token property">PASS_REGULAR_EXPRESSION</span> <span class="token string">"<span class="token interpolation"><span class="token punctuation">${</span><span class="token variable">num</span><span class="token punctuation">}</span></span> is <span class="token interpolation"><span class="token punctuation">${</span><span class="token variable">result</span><span class="token punctuation">}</span></span>"</span><span class="token punctuation">)</span>
|
||
<span class="token keyword">endfunction</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
|
||
|
||
<span class="token function">do_test</span><span class="token punctuation">(</span><span class="token number">9</span> <span class="token number">3</span><span class="token punctuation">)</span>
|
||
<span class="token function">do_test</span><span class="token punctuation">(</span><span class="token number">5</span> <span class="token number">2.236</span><span class="token punctuation">)</span>
|
||
<span class="token function">do_test</span><span class="token punctuation">(</span><span class="token number">7</span> <span class="token number">2.645</span><span class="token punctuation">)</span>
|
||
<span class="token function">do_test</span><span class="token punctuation">(</span>-<span class="token number">25</span> <span class="token string">"(-nan|nan|0)"</span><span class="token punctuation">)</span> <span class="token comment"># not a number</span>
|
||
<span class="token function">do_test</span><span class="token punctuation">(</span><span class="token number">0.0001</span> <span class="token number">0.001</span><span class="token punctuation">)</span>
|
||
|
||
|
||
<span class="token comment"># 5 2.236</span>
|
||
<span class="token comment"># 7 2.645</span>
|
||
<span class="token comment"># -25 "(-nan|nan|0)"</span>
|
||
<span class="token comment"># 0.0001 0.001</span>
|
||
<span class="token comment"># do_test(4 2)</span></code></pre>
|
||
<p><strong>要点</strong></p>
|
||
<p>①<mark>enable_testing()</mark></p>
|
||
<p>开启当前目录及子目录的测试支持。</p>
|
||
<p>②<mark>add_test</mark></p>
|
||
<p>添加一条测试</p>
|
||
<p>简版用法:</p>
|
||
<pre><code class="fenced-code-block language-cmake"><span class="token keyword">add_test</span><span class="token punctuation">(</span><span class="token property">NAME</span> <name<span class="token punctuation">></span> COMMAND <command<span class="token punctuation">></span> [<arg<span class="token punctuation">></span>...]<span class="token punctuation">)</span></code></pre>
|
||
<ul>
|
||
<li><code>name</code>为本条测试名称</li>
|
||
<li><code>command</code>测试用的命令</li>
|
||
<li><code>arg</code>传递测试命令的参数</li>
|
||
</ul>
|
||
<p>③<mark>set_tests_properties</mark></p>
|
||
<p>设置测试的属性。</p>
|
||
<p>语法</p>
|
||
<pre><code class="fenced-code-block language-cmake"><span class="token keyword">set_tests_properties</span><span class="token punctuation">(</span>test1 [test2...] <span class="token namespace">PROPERTIES</span> prop1 value1 prop2 value2<span class="token punctuation">)</span></code></pre>
|
||
<ul>
|
||
<li><code>test1...</code>为用add_test添加的测试名</li>
|
||
<li><code>prop1</code>为需要设置的属性名,本节中只学<code>PASS_REGULAR_EXPRESSION</code>,表示测试程序的输出结果需要能匹配<code>value</code>所表示的正则表达式才能通过,如果匹配不了则不通过。</li>
|
||
<li><code>value</code>要设置的属性值</li>
|
||
</ul>
|
||
<p>示例</p>
|
||
<pre><code class="fenced-code-block language-cmake"><span class="token keyword">set_tests_properties</span><span class="token punctuation">(</span>Usage
|
||
<span class="token namespace">PROPERTIES</span> <span class="token property">PASS_REGULAR_EXPRESSION</span> <span class="token string">"Usage:.*number"</span>
|
||
<span class="token punctuation">)</span></code></pre>
|
||
<p>表示运行<code>Usage</code>这个测试时测试程序的输出结果要能正则匹配到"Usage:.*number"。</p>
|
||
<p>④<mark>function()与endfunction()</mark></p>
|
||
<p>用于在定义函数,分别表示函数开始与函数结束</p>
|
||
<p>语法</p>
|
||
<pre><code class="fenced-code-block language-cmake"><span class="token keyword">function</span><span class="token punctuation">(</span><name<span class="token punctuation">></span> [<arg1<span class="token punctuation">></span> ...]<span class="token punctuation">)</span>
|
||
<commands<span class="token punctuation">></span>
|
||
<span class="token keyword">endfunction</span><span class="token punctuation">(</span><span class="token punctuation">)</span></code></pre>
|
||
<ul>
|
||
<li>括号里第一个参数为函数名,后面是参数列表,可以有多个,多个参数用空格隔开</li>
|
||
</ul>
|
||
<p>示例:</p>
|
||
<pre><code class="fenced-code-block language-cmake"><span class="token comment"># 定义</span>
|
||
<span class="token keyword">function</span><span class="token punctuation">(</span>do_test target arg result<span class="token punctuation">)</span>
|
||
<span class="token keyword">add_test</span><span class="token punctuation">(</span><span class="token property">NAME</span> Comp<span class="token punctuation">${</span>arg<span class="token punctuation">}</span> COMMAND <span class="token punctuation">${</span>target<span class="token punctuation">}</span> <span class="token punctuation">${</span>arg<span class="token punctuation">}</span><span class="token punctuation">)</span>
|
||
<span class="token keyword">set_tests_properties</span><span class="token punctuation">(</span>Comp<span class="token punctuation">${</span>arg<span class="token punctuation">}</span>
|
||
<span class="token namespace">PROPERTIES</span> <span class="token property">PASS_REGULAR_EXPRESSION</span> <span class="token punctuation">${</span>result<span class="token punctuation">}</span>
|
||
<span class="token punctuation">)</span>
|
||
<span class="token keyword">endfunction</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
|
||
|
||
<span class="token comment"># 调用</span>
|
||
<span class="token function">do_test</span><span class="token punctuation">(</span>Tutorial <span class="token number">4</span> <span class="token string">"4 is 1"</span><span class="token punctuation">)</span></code></pre>
|
||
<p> </p>
|
||
<p> </p>
|
||
<h2 class="atx" id="第六步-添加测试面板支持">第六步 添加测试面板支持</h2>
|
||
<h3 class="atx" id="练习1-发送测试结果到测试面板">练习1 发送测试结果到测试面板</h3>
|
||
<p><code>CMakeLists.txt</code></p>
|
||
<pre><code class="fenced-code-block language-cmake"><span class="token comment"># 将enable_testing()替换为下面这行</span>
|
||
<span class="token keyword">include</span><span class="token punctuation">(</span>CTest<span class="token punctuation">)</span></code></pre>
|
||
<p>在build目录执行</p>
|
||
<pre><code class="fenced-code-block language-shell">cmake -G <span class="token string">"MinGW Makefiles"</span> <span class="token punctuation">..</span></code></pre>
|
||
<p>之后执行</p>
|
||
<pre><code class="fenced-code-block language-shell">ctest -VV -D Experimental</code></pre>
|
||
<p>即可。</p>
|
||
<p>完成之后可在<a href="https://my.cdash.org/index.php?project=CMakeTutorial%E6%9F%A5%E7%9C%8B%E6%8F%90%E4%BA%A4%E7%9A%84%E6%B5%8B%E8%AF%95%E7%BB%93%E6%9E%9C%E3%80%82">https://my.cdash.org/index.php?project=CMakeTutorial查看提交的测试结果。</a></p>
|
||
<p> </p>
|
||
<p> </p>
|
||
<h2 class="atx" id="第七步-添加系统特性检查">第七步 添加系统特性检查</h2>
|
||
<h3 class="atx" id="练习1-评估依赖可用性">练习1 评估依赖可用性</h3>
|
||
<p><code>MathFunctions/CMakeLists.txt</code></p>
|
||
<pre><code class="fenced-code-block language-cmake"><span class="token keyword">add_library</span><span class="token punctuation">(</span>MathFunctions mysqrt.cxx<span class="token punctuation">)</span>
|
||
|
||
<span class="token comment"># state that anybody linking to us needs to include the current source dir</span>
|
||
<span class="token comment"># to find MathFunctions.h, while we don't.</span>
|
||
<span class="token keyword">target_include_directories</span><span class="token punctuation">(</span>MathFunctions
|
||
<span class="token namespace">INTERFACE</span> <span class="token punctuation">${</span><span class="token variable">CMAKE_CURRENT_SOURCE_DIR</span><span class="token punctuation">}</span>
|
||
<span class="token punctuation">)</span>
|
||
|
||
<span class="token comment"># link our compiler flags interface library</span>
|
||
<span class="token keyword">target_link_libraries</span><span class="token punctuation">(</span>MathFunctions tutorial_compiler_flags<span class="token punctuation">)</span>
|
||
|
||
<span class="token comment"># TODO 1: Include CheckCXXSourceCompiles</span>
|
||
<span class="token keyword">include</span><span class="token punctuation">(</span>CheckCXXSourceCompiles<span class="token punctuation">)</span>
|
||
|
||
<span class="token comment"># TODO 2:用check_cxx_source_compiles和简单C++代码检测</span>
|
||
<span class="token comment"># 以下两个函数是否可用:</span>
|
||
<span class="token comment"># * std::log ln</span>
|
||
<span class="token comment"># * std::exp e^2</span>
|
||
<span class="token comment"># 把结果存在HAVE_LOG 和 HAVE_EXP 中.</span>
|
||
|
||
<span class="token comment"># Hint: Sample C++ code which uses log:</span>
|
||
<span class="token comment"># #include <cmath></span>
|
||
<span class="token comment"># int main() {</span>
|
||
<span class="token comment"># std::log(1.0);</span>
|
||
<span class="token comment"># return 0;</span>
|
||
<span class="token comment"># }</span>
|
||
|
||
|
||
|
||
<span class="token function">check_cxx_source_compiles</span><span class="token punctuation">(</span><span class="token string">"
|
||
#include <cmath>
|
||
int main() {
|
||
std::log(1.0);
|
||
return 0;
|
||
}
|
||
"</span> HAVE_LOG<span class="token punctuation">)</span>
|
||
|
||
<span class="token function">check_cxx_source_compiles</span><span class="token punctuation">(</span><span class="token string">"
|
||
#include <cmath>
|
||
int main() {
|
||
std::exp(1.0);
|
||
return 0;
|
||
}
|
||
"</span> HAVE_EXP<span class="token punctuation">)</span>
|
||
|
||
<span class="token comment"># TODO 3: 如果HAVE_LOG和HAVE_EXP为真, 添加预编译定义</span>
|
||
<span class="token comment"># "HAVE_LOG"和"HAVE_EXP"到目标MathFunctions上.</span>
|
||
<span class="token comment">#Hint: Use target_compile_definitions()</span>
|
||
<span class="token keyword">if</span><span class="token punctuation">(</span>HAVE_LOG <span class="token operator">AND</span> HAVE_EXP<span class="token punctuation">)</span>
|
||
<span class="token keyword">target_compile_definitions</span><span class="token punctuation">(</span>MathFunctions <span class="token namespace">PRIVATE</span> <span class="token string">"HAVE_LOG"</span> <span class="token string">"HAVE_EXP"</span><span class="token punctuation">)</span>
|
||
<span class="token keyword">endif</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
|
||
|
||
|
||
|
||
<span class="token comment"># install libs</span>
|
||
<span class="token keyword">set</span><span class="token punctuation">(</span>installable_libs MathFunctions tutorial_compiler_flags<span class="token punctuation">)</span>
|
||
<span class="token keyword">install</span><span class="token punctuation">(</span>TARGETS <span class="token punctuation">${</span>installable_libs<span class="token punctuation">}</span> DESTINATION lib<span class="token punctuation">)</span>
|
||
<span class="token comment"># install include headers</span>
|
||
<span class="token keyword">install</span><span class="token punctuation">(</span>FILES MathFunctions.h DESTINATION include<span class="token punctuation">)</span></code></pre>
|
||
<p><strong>要点</strong></p>
|
||
<p>①<mark>include</mark></p>
|
||
<p>用于导入其他CMake文件或模块。</p>
|
||
<pre><code class="fenced-code-block language-cmake"><span class="token keyword">include</span><span class="token punctuation">(</span><file|module<span class="token punctuation">></span> [OPTIONAL] [RESULT_VARIABLE <var<span class="token punctuation">></span>]
|
||
[NO_POLICY_SCOPE]<span class="token punctuation">)</span></code></pre>
|
||
<p>②<mark>check_cxx_source_compiles</mark></p>
|
||
<p>检查给定的C++代码能不能编译及链接成可执行文件。通常用来检查当前环境中是否具有某些特性。</p>
|
||
<p>用法</p>
|
||
<pre><code class="fenced-code-block language-cmake"><span class="token function">check_cxx_source_compiles</span><span class="token punctuation">(</span><code<span class="token punctuation">></span> <resultVar<span class="token punctuation">></span> [FAIL_REGEX <regex1<span class="token punctuation">></span> [<regex2<span class="token punctuation">></span>...]]<span class="token punctuation">)</span></code></pre>
|
||
<ul>
|
||
<li><code>code</code>为需要检查的代码,需要包含<code>main</code>函数</li>
|
||
<li><code>resultVar</code>为检查结果,如果成功返回布尔真,否则返回布尔假</li>
|
||
<li><code>FAIL_REGEX</code>如果提供,则返回为假的结果需要能匹配上对应的正则表达式</li>
|
||
</ul>
|
||
<p>③<mark>target_compile_definitions</mark></p>
|
||
<p>为指定可执行文件及库文件这类目标添加编译器定义,用来控制代码中的条件编译。有点类似于<code>#cmakedefine</code>与<code>configure_file</code>的作用,但这两个操作的结果会生成一个文件再进行引用,而<code>target_compile_definitions</code>不会生成文件。</p>
|
||
<p>用法</p>
|
||
<pre><code class="fenced-code-block language-cmake"><span class="token keyword">target_compile_definitions</span><span class="token punctuation">(</span><target<span class="token punctuation">></span>
|
||
<<span class="token namespace">INTERFACE</span>|<span class="token namespace">PUBLIC</span>|<span class="token namespace">PRIVATE</span><span class="token punctuation">></span> [items1...]
|
||
[<<span class="token namespace">INTERFACE</span>|<span class="token namespace">PUBLIC</span>|<span class="token namespace">PRIVATE</span><span class="token punctuation">></span> [items2...] ...]<span class="token punctuation">)</span></code></pre>
|
||
<p>示例</p>
|
||
<pre><code class="fenced-code-block language-cmake"><span class="token keyword">target_compile_definitions</span><span class="token punctuation">(</span>MathFunctions <span class="token namespace">PRIVATE</span> <span class="token string">"HAVE_LOG"</span> <span class="token string">"HAVE_EXP"</span><span class="token punctuation">)</span></code></pre>
|
||
<p> </p>
|
||
<p> </p>
|
||
<h2 class="atx" id="第八步-添加自定义命令及用自定义命令生成文件">第八步 添加自定义命令及用自定义命令生成文件</h2>
|
||
<p>在Linux中,有许多的工具命令,例如<code>ls</code>、<code>mv</code>、<code>mkdir</code>等。在CMake项目中,可以用源代码写一些自定义小工具,然后在CMake中进行调用,来完成一些工作。</p>
|
||
<p>本节的内容为自定义一个<code>MakeTable</code>命令用来生成指定范围整数的平方根并保存到文件中,在计算的时候可以用这些已经计算好的值来辅助计算。</p>
|
||
<p><code>MathFunctions/CMakeLists.txt</code></p>
|
||
<pre><code class="fenced-code-block language-cmake"><span class="token keyword">add_library</span><span class="token punctuation">(</span>MathFunctions mysqrt.cxx Table.h<span class="token punctuation">)</span>
|
||
|
||
<span class="token keyword">add_executable</span><span class="token punctuation">(</span>MakeTable MakeTable.cxx<span class="token punctuation">)</span>
|
||
<span class="token keyword">add_custom_command</span><span class="token punctuation">(</span>
|
||
OUTPUT <span class="token punctuation">${</span><span class="token variable">CMAKE_CURRENT_BINARY_DIR</span><span class="token punctuation">}</span>/Table.h
|
||
COMMAND MakeTable <span class="token punctuation">${</span><span class="token variable">CMAKE_CURRENT_BINARY_DIR</span><span class="token punctuation">}</span>/Table.h
|
||
<span class="token property">DEPENDS</span> MakeTable
|
||
<span class="token punctuation">)</span>
|
||
|
||
|
||
<span class="token comment"># state that anybody linking to us needs to include the current source dir</span>
|
||
<span class="token comment"># to find MathFunctions.h, while we don't.</span>
|
||
<span class="token keyword">target_include_directories</span><span class="token punctuation">(</span>MathFunctions
|
||
<span class="token namespace">INTERFACE</span> <span class="token punctuation">${</span><span class="token variable">CMAKE_CURRENT_SOURCE_DIR</span><span class="token punctuation">}</span>
|
||
<span class="token namespace">PRIVATE</span> <span class="token punctuation">${</span><span class="token variable">CMAKE_CURRENT_BINARY_DIR</span><span class="token punctuation">}</span>
|
||
<span class="token punctuation">)</span>
|
||
|
||
<span class="token comment"># link our compiler flags interface library</span>
|
||
<span class="token keyword">target_link_libraries</span><span class="token punctuation">(</span>MathFunctions tutorial_compiler_flags<span class="token punctuation">)</span>
|
||
|
||
<span class="token comment"># does this system provide the log and exp functions?</span>
|
||
<span class="token keyword">include</span><span class="token punctuation">(</span>CheckCXXSourceCompiles<span class="token punctuation">)</span>
|
||
<span class="token function">check_cxx_source_compiles</span><span class="token punctuation">(</span><span class="token string">"
|
||
#include <cmath>
|
||
int main() {
|
||
std::log(1.0);
|
||
return 0;
|
||
}
|
||
"</span> HAVE_LOG<span class="token punctuation">)</span>
|
||
<span class="token function">check_cxx_source_compiles</span><span class="token punctuation">(</span><span class="token string">"
|
||
#include <cmath>
|
||
int main() {
|
||
std::exp(1.0);
|
||
return 0;
|
||
}
|
||
"</span> HAVE_EXP<span class="token punctuation">)</span>
|
||
|
||
<span class="token comment"># add compile definitions</span>
|
||
<span class="token keyword">if</span><span class="token punctuation">(</span>HAVE_LOG <span class="token operator">AND</span> HAVE_EXP<span class="token punctuation">)</span>
|
||
<span class="token keyword">target_compile_definitions</span><span class="token punctuation">(</span>MathFunctions
|
||
<span class="token namespace">PRIVATE</span> <span class="token string">"HAVE_LOG"</span> <span class="token string">"HAVE_EXP"</span><span class="token punctuation">)</span>
|
||
<span class="token keyword">endif</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
|
||
|
||
<span class="token comment"># install libs</span>
|
||
<span class="token keyword">set</span><span class="token punctuation">(</span>installable_libs MathFunctions tutorial_compiler_flags<span class="token punctuation">)</span>
|
||
<span class="token keyword">install</span><span class="token punctuation">(</span>TARGETS <span class="token punctuation">${</span>installable_libs<span class="token punctuation">}</span> DESTINATION lib<span class="token punctuation">)</span>
|
||
<span class="token comment"># install include headers</span>
|
||
<span class="token keyword">install</span><span class="token punctuation">(</span>FILES MathFunctions.h DESTINATION include<span class="token punctuation">)</span></code></pre>
|
||
<p><strong>要点</strong></p>
|
||
<p>①<mark>add_custom_command</mark></p>
|
||
<p>执行自定义指令。</p>
|
||
<p>简版用法</p>
|
||
<pre><code class="fenced-code-block language-cmake"><span class="token keyword">add_custom_command</span><span class="token punctuation">(</span>OUTPUT output1
|
||
COMMAND command1
|
||
<span class="token property">DEPENDS</span> depends<span class="token punctuation">)</span></code></pre>
|
||
<ul>
|
||
<li><code>OUTPUT</code>指定输出文件名</li>
|
||
<li><code>COMMAND</code>指定要执行的指令</li>
|
||
<li><code>DEPENDS</code>执行指令需要依赖的内容。如果是由<code>add_executable</code>或<code>add_library</code>添加的目标名,写这一条可以保证对应目标的生成。</li>
|
||
</ul>
|
||
<p> </p>
|
||
<p> </p>
|
||
<h2 class="atx" id="第九步-打包安装程序">第九步 打包安装程序</h2>
|
||
<p>发布程序可以有多种形式,比如安装包、压缩包、源文件等。CMake也提供了打包程序<code>cpack</code>可将程序打包成多种形式。</p>
|
||
<p>只需要在顶层CMakelists.txt中添加以下代码</p>
|
||
<pre><code class="fenced-code-block language-cmake"><span class="token keyword">include</span><span class="token punctuation">(</span>InstallRequiredSystemLibraries<span class="token punctuation">)</span>
|
||
<span class="token keyword">set</span><span class="token punctuation">(</span>CPACK_RESOURCE_FILE_LICENSE <span class="token string">"<span class="token interpolation"><span class="token punctuation">${</span><span class="token variable">CMAKE_CURRENT_SOURCE_DIR</span><span class="token punctuation">}</span></span>/License.txt"</span><span class="token punctuation">)</span>
|
||
<span class="token keyword">set</span><span class="token punctuation">(</span><span class="token variable">CPACK_PACKAGE_VERSION_MAJOR</span> <span class="token string">"<span class="token interpolation"><span class="token punctuation">${</span><span class="token variable">Tutorial_VERSION_MAJOR</span><span class="token punctuation">}</span></span>"</span><span class="token punctuation">)</span>
|
||
<span class="token keyword">set</span><span class="token punctuation">(</span><span class="token variable">CPACK_PACKAGE_VERSION_MINOR</span> <span class="token string">"<span class="token interpolation"><span class="token punctuation">${</span><span class="token variable">Tutorial_VERSION_MINOR</span><span class="token punctuation">}</span></span>"</span><span class="token punctuation">)</span>
|
||
<span class="token keyword">set</span><span class="token punctuation">(</span>CPACK_SOURCE_GENERATOR <span class="token string">"TGZ"</span><span class="token punctuation">)</span>
|
||
<span class="token keyword">include</span><span class="token punctuation">(</span>CPack<span class="token punctuation">)</span></code></pre>
|
||
<p>在项目构建完成之后,可以直接执行</p>
|
||
<pre><code class="fenced-code-block language-shell">cpack</code></pre>
|
||
<p>在Windows上默认情况会打包成.exe文件,所以需要先安装一个exe打包程序NSIS(Null Soft Installer)</p>
|
||
<p>NSIS下载地址:<a href="https://sourceforge.net/projects/nsis/">https://sourceforge.net/projects/nsis/</a></p>
|
||
<p>也可以指定生成器打包成对应的格式</p>
|
||
<pre><code class="fenced-code-block language-shell">cpack -G ZIP <span class="token comment"># 打包成ZIP</span></code></pre>
|
||
<p>具体生成器各类可以通过<code>cpack --help</code>查看</p>
|
||
<p>对于多配置项目,可以指定打包配置</p>
|
||
<pre><code class="fenced-code-block language-shell">cpack -C Debug <span class="token comment"># 打包Debug版本</span></code></pre>
|
||
<p>也可以打包源代码</p>
|
||
<pre><code class="fenced-code-block language-shell">cpack --config CPackSourceConfig.cmake</code></pre>
|
||
<p> </p>
|
||
<p> </p>
|
||
<h2 class="atx" id="第十步-选择静态链接库或动态链接库">第十步 选择静态链接库或动态链接库</h2>
|
||
<p><code>CMakeLists.txt</code></p>
|
||
<pre><code class="fenced-code-block language-cmake"><span class="token keyword">cmake_minimum_required</span><span class="token punctuation">(</span><span class="token property">VERSION</span> <span class="token number">3.15</span><span class="token punctuation">)</span>
|
||
|
||
<span class="token comment"># set the project name and version</span>
|
||
<span class="token keyword">project</span><span class="token punctuation">(</span>Tutorial <span class="token property">VERSION</span> <span class="token number">1.0</span><span class="token punctuation">)</span>
|
||
|
||
<span class="token comment"># specify the C++ standard</span>
|
||
<span class="token keyword">add_library</span><span class="token punctuation">(</span>tutorial_compiler_flags <span class="token namespace">INTERFACE</span><span class="token punctuation">)</span>
|
||
<span class="token keyword">target_compile_features</span><span class="token punctuation">(</span>tutorial_compiler_flags <span class="token namespace">INTERFACE</span> <span class="token property">cxx_std_11</span><span class="token punctuation">)</span>
|
||
|
||
<span class="token comment"># add compiler warning flags just when building this project via</span>
|
||
<span class="token comment"># the BUILD_INTERFACE genex</span>
|
||
<span class="token keyword">set</span><span class="token punctuation">(</span>gcc_like_cxx <span class="token string">"$<COMPILE_LANG_AND_ID:CXX,ARMClang,AppleClang,Clang,GNU,LCC>"</span><span class="token punctuation">)</span>
|
||
<span class="token keyword">set</span><span class="token punctuation">(</span>msvc_cxx <span class="token string">"$<COMPILE_LANG_AND_ID:CXX,MSVC>"</span><span class="token punctuation">)</span>
|
||
<span class="token keyword">target_compile_options</span><span class="token punctuation">(</span>tutorial_compiler_flags <span class="token namespace">INTERFACE</span>
|
||
<span class="token string">"$<<span class="token interpolation"><span class="token punctuation">${</span><span class="token variable">gcc_like_cxx</span><span class="token punctuation">}</span></span>:$<BUILD_INTERFACE:-Wall;-Wextra;-Wshadow;-Wformat=2;-Wunused>>"</span>
|
||
<span class="token string">"$<<span class="token interpolation"><span class="token punctuation">${</span><span class="token variable">msvc_cxx</span><span class="token punctuation">}</span></span>:$<BUILD_INTERFACE:-W3>>"</span>
|
||
<span class="token punctuation">)</span>
|
||
|
||
<span class="token comment"># should we use our own math functions</span>
|
||
<span class="token keyword">option</span><span class="token punctuation">(</span>USE_MYMATH <span class="token string">"Use tutorial provided math implementation"</span> <span class="token boolean">ON</span><span class="token punctuation">)</span>
|
||
<span class="token keyword">option</span><span class="token punctuation">(</span><span class="token variable">BUILD_SHARED_LIBS</span> <span class="token string">"Use Dynamic? "</span> <span class="token boolean">ON</span><span class="token punctuation">)</span>
|
||
|
||
<span class="token comment"># configure a header file to pass some of the CMake settings</span>
|
||
<span class="token comment"># to the source code</span>
|
||
<span class="token keyword">configure_file</span><span class="token punctuation">(</span>TutorialConfig.h.in TutorialConfig.h<span class="token punctuation">)</span>
|
||
|
||
<span class="token keyword">set</span><span class="token punctuation">(</span><span class="token variable">CMAKE_ARCHIVE_OUTPUT_DIRECTORY</span> <span class="token string">"<span class="token interpolation"><span class="token punctuation">${</span><span class="token variable">PROJECT_BINARY_DIR</span><span class="token punctuation">}</span></span>"</span><span class="token punctuation">)</span> <span class="token comment"># .a .lib</span>
|
||
<span class="token keyword">set</span><span class="token punctuation">(</span><span class="token variable">CMAKE_RUNTIME_OUTPUT_DIRECTORY</span> <span class="token string">"<span class="token interpolation"><span class="token punctuation">${</span><span class="token variable">PROJECT_BINARY_DIR</span><span class="token punctuation">}</span></span>"</span><span class="token punctuation">)</span> <span class="token comment"># .dll .exe</span>
|
||
<span class="token keyword">set</span><span class="token punctuation">(</span><span class="token variable">CMAKE_LIBRARY_OUTPUT_DIRECTORY</span> <span class="token string">"<span class="token interpolation"><span class="token punctuation">${</span><span class="token variable">PROJECT_BINARY_DIR</span><span class="token punctuation">}</span></span>"</span><span class="token punctuation">)</span> <span class="token comment"># .so</span>
|
||
|
||
<span class="token comment"># add the MathFunctions library</span>
|
||
<span class="token keyword">if</span><span class="token punctuation">(</span>USE_MYMATH<span class="token punctuation">)</span>
|
||
<span class="token keyword">add_subdirectory</span><span class="token punctuation">(</span>MathFunctions<span class="token punctuation">)</span>
|
||
<span class="token keyword">list</span><span class="token punctuation">(</span>APPEND EXTRA_LIBS MathFunctions<span class="token punctuation">)</span>
|
||
<span class="token keyword">endif</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
|
||
|
||
<span class="token comment"># add the executable</span>
|
||
<span class="token keyword">add_executable</span><span class="token punctuation">(</span>Tutorial tutorial.cxx<span class="token punctuation">)</span>
|
||
<span class="token keyword">target_link_libraries</span><span class="token punctuation">(</span>Tutorial <span class="token namespace">PUBLIC</span> <span class="token punctuation">${</span>EXTRA_LIBS<span class="token punctuation">}</span> tutorial_compiler_flags<span class="token punctuation">)</span>
|
||
|
||
<span class="token comment"># add the binary tree to the search path for include files</span>
|
||
<span class="token comment"># so that we will find TutorialConfig.h</span>
|
||
<span class="token keyword">target_include_directories</span><span class="token punctuation">(</span>Tutorial <span class="token namespace">PUBLIC</span>
|
||
<span class="token string">"<span class="token interpolation"><span class="token punctuation">${</span><span class="token variable">PROJECT_BINARY_DIR</span><span class="token punctuation">}</span></span>"</span>
|
||
<span class="token punctuation">)</span>
|
||
|
||
<span class="token comment"># add the install targets</span>
|
||
<span class="token keyword">install</span><span class="token punctuation">(</span>TARGETS Tutorial DESTINATION bin<span class="token punctuation">)</span>
|
||
<span class="token keyword">install</span><span class="token punctuation">(</span>FILES <span class="token string">"<span class="token interpolation"><span class="token punctuation">${</span><span class="token variable">PROJECT_BINARY_DIR</span><span class="token punctuation">}</span></span>/TutorialConfig.h"</span>
|
||
DESTINATION include
|
||
<span class="token punctuation">)</span>
|
||
|
||
<span class="token comment"># enable testing</span>
|
||
<span class="token keyword">include</span><span class="token punctuation">(</span>CTest<span class="token punctuation">)</span>
|
||
|
||
<span class="token comment"># does the application run</span>
|
||
<span class="token keyword">add_test</span><span class="token punctuation">(</span><span class="token property">NAME</span> Runs COMMAND Tutorial <span class="token number">25</span><span class="token punctuation">)</span>
|
||
|
||
<span class="token comment"># does the usage message work?</span>
|
||
<span class="token keyword">add_test</span><span class="token punctuation">(</span><span class="token property">NAME</span> Usage COMMAND Tutorial<span class="token punctuation">)</span>
|
||
<span class="token keyword">set_tests_properties</span><span class="token punctuation">(</span>Usage
|
||
<span class="token namespace">PROPERTIES</span> <span class="token property">PASS_REGULAR_EXPRESSION</span> <span class="token string">"Usage:.*number"</span>
|
||
<span class="token punctuation">)</span>
|
||
|
||
<span class="token comment"># define a function to simplify adding tests</span>
|
||
<span class="token keyword">function</span><span class="token punctuation">(</span>do_test target arg result<span class="token punctuation">)</span>
|
||
<span class="token keyword">add_test</span><span class="token punctuation">(</span><span class="token property">NAME</span> Comp<span class="token punctuation">${</span>arg<span class="token punctuation">}</span> COMMAND <span class="token punctuation">${</span>target<span class="token punctuation">}</span> <span class="token punctuation">${</span>arg<span class="token punctuation">}</span><span class="token punctuation">)</span>
|
||
<span class="token keyword">set_tests_properties</span><span class="token punctuation">(</span>Comp<span class="token punctuation">${</span>arg<span class="token punctuation">}</span>
|
||
<span class="token namespace">PROPERTIES</span> <span class="token property">PASS_REGULAR_EXPRESSION</span> <span class="token punctuation">${</span>result<span class="token punctuation">}</span>
|
||
<span class="token punctuation">)</span>
|
||
<span class="token keyword">endfunction</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
|
||
|
||
<span class="token comment"># do a bunch of result based tests</span>
|
||
<span class="token function">do_test</span><span class="token punctuation">(</span>Tutorial <span class="token number">4</span> <span class="token string">"4 is 2"</span><span class="token punctuation">)</span>
|
||
<span class="token function">do_test</span><span class="token punctuation">(</span>Tutorial <span class="token number">9</span> <span class="token string">"9 is 3"</span><span class="token punctuation">)</span>
|
||
<span class="token function">do_test</span><span class="token punctuation">(</span>Tutorial <span class="token number">5</span> <span class="token string">"5 is 2.236"</span><span class="token punctuation">)</span>
|
||
<span class="token function">do_test</span><span class="token punctuation">(</span>Tutorial <span class="token number">7</span> <span class="token string">"7 is 2.645"</span><span class="token punctuation">)</span>
|
||
<span class="token function">do_test</span><span class="token punctuation">(</span>Tutorial <span class="token number">25</span> <span class="token string">"25 is 5"</span><span class="token punctuation">)</span>
|
||
<span class="token function">do_test</span><span class="token punctuation">(</span>Tutorial -<span class="token number">25</span> <span class="token string">"-25 is (-nan|nan|0)"</span><span class="token punctuation">)</span>
|
||
<span class="token function">do_test</span><span class="token punctuation">(</span>Tutorial <span class="token number">0.0001</span> <span class="token string">"0.0001 is 0.01"</span><span class="token punctuation">)</span>
|
||
|
||
<span class="token comment"># setup installer</span>
|
||
<span class="token keyword">include</span><span class="token punctuation">(</span>InstallRequiredSystemLibraries<span class="token punctuation">)</span>
|
||
<span class="token keyword">set</span><span class="token punctuation">(</span>CPACK_RESOURCE_FILE_LICENSE <span class="token string">"<span class="token interpolation"><span class="token punctuation">${</span><span class="token variable">CMAKE_CURRENT_SOURCE_DIR</span><span class="token punctuation">}</span></span>/License.txt"</span><span class="token punctuation">)</span>
|
||
<span class="token keyword">set</span><span class="token punctuation">(</span><span class="token variable">CPACK_PACKAGE_VERSION_MAJOR</span> <span class="token string">"<span class="token interpolation"><span class="token punctuation">${</span><span class="token variable">Tutorial_VERSION_MAJOR</span><span class="token punctuation">}</span></span>"</span><span class="token punctuation">)</span>
|
||
<span class="token keyword">set</span><span class="token punctuation">(</span><span class="token variable">CPACK_PACKAGE_VERSION_MINOR</span> <span class="token string">"<span class="token interpolation"><span class="token punctuation">${</span><span class="token variable">Tutorial_VERSION_MINOR</span><span class="token punctuation">}</span></span>"</span><span class="token punctuation">)</span>
|
||
<span class="token keyword">set</span><span class="token punctuation">(</span>CPACK_SOURCE_GENERATOR <span class="token string">"TGZ"</span><span class="token punctuation">)</span>
|
||
<span class="token keyword">include</span><span class="token punctuation">(</span>CPack<span class="token punctuation">)</span></code></pre>
|
||
<p><strong>要点</strong></p>
|
||
<p>①<mark>BUILD_SHARED_LIBS</mark></p>
|
||
<p>全局为<code>add_library</code>设置库的生成类型。<code>ON</code>则生成动态链接库,<code>OFF</code>则生成静态链接库。</p>
|
||
<p>②<mark>CMAKE_ARCHIVE_OUTPUT_DIRECTORY</mark></p>
|
||
<p>指定静态库文件的生成位置。</p>
|
||
<p>③<mark>CMAKE_RUNTIME_OUTPUT_DIRECTORY</mark></p>
|
||
<p>指定执行文件的生成位置,包括可执行程序和Windows上动态库文件(.dll)</p>
|
||
<p>④<mark>CMAKE_LIBRARY_OUTPUT_DIRECTORY</mark></p>
|
||
<p>非Windows平台上的生成的.so库文件</p>
|
||
<p> </p>
|
||
<p> </p>
|
||
<h2 class="atx" id="第十一步-添加导出配置">第十一步 添加导出配置</h2>
|
||
<p>先来复习一下在CMake中使用其他库的方法。本节把<code>MathFunctions</code>生成的库文件、头文件放到其他路径当中,这时库的引入方式如下:</p>
|
||
<p><code>CMakeLists.txt</code></p>
|
||
<pre><code class="fenced-code-block language-cmake"><span class="token keyword">cmake_minimum_required</span><span class="token punctuation">(</span><span class="token property">VERSION</span> <span class="token number">3.10</span><span class="token punctuation">)</span>
|
||
<span class="token keyword">project</span><span class="token punctuation">(</span>Tutorial<span class="token punctuation">)</span>
|
||
|
||
<span class="token keyword">add_executable</span><span class="token punctuation">(</span>Tutorial tutorial.cxx<span class="token punctuation">)</span>
|
||
|
||
<span class="token keyword">set</span><span class="token punctuation">(</span>mathlib_DIR C:/Users/YAN/Desktop/cmake/mathlib<span class="token punctuation">)</span>
|
||
|
||
<span class="token comment"># cmake中使用第三方库的一般步骤</span>
|
||
<span class="token comment"># 1. 设置头文件位置</span>
|
||
<span class="token keyword">target_include_directories</span><span class="token punctuation">(</span>Tutorial <span class="token namespace">PRIVATE</span> <span class="token string">"<span class="token interpolation"><span class="token punctuation">${</span><span class="token variable">mathlib_DIR</span><span class="token punctuation">}</span></span>/include"</span><span class="token punctuation">)</span>
|
||
|
||
<span class="token comment"># 2. 设置库文件搜索位置</span>
|
||
<span class="token keyword">target_link_directories</span><span class="token punctuation">(</span>Tutorial <span class="token namespace">PRIVATE</span> <span class="token string">"<span class="token interpolation"><span class="token punctuation">${</span><span class="token variable">mathlib_DIR</span><span class="token punctuation">}</span></span>/lib"</span><span class="token punctuation">)</span>
|
||
|
||
<span class="token comment"># 3. 指定需要链接的库(libXXX.a libXXX.dll直接写成XXX的形式即可)</span>
|
||
<span class="token keyword">target_link_libraries</span><span class="token punctuation">(</span>Tutorial <span class="token namespace">PRIVATE</span> MathFunctions<span class="token punctuation">)</span></code></pre>
|
||
<p>现在的问题是,如果一个库不用CMake管理,那就是用如上方法来引用,可是这个库也是由CMake构建来的,还用同样的方法来引入,那CMake不是白用了吗?</p>
|
||
<p>用CMake管理简化后的版本为</p>
|
||
<pre><code class="fenced-code-block language-cmake"><span class="token keyword">cmake_minimum_required</span><span class="token punctuation">(</span><span class="token property">VERSION</span> <span class="token number">3.10</span><span class="token punctuation">)</span>
|
||
<span class="token keyword">project</span><span class="token punctuation">(</span>Tutorial<span class="token punctuation">)</span>
|
||
|
||
<span class="token keyword">add_executable</span><span class="token punctuation">(</span>Tutorial tutorial.cxx<span class="token punctuation">)</span>
|
||
|
||
<span class="token comment"># 如果库是安装在环境变量里有的位置,这行可以不用写</span>
|
||
<span class="token comment"># set(MathFunctions_DIR C:/Users/YAN/Desktop/cmake/mathlib/lib/cmake/MathFunctions)</span>
|
||
<span class="token keyword">find_package</span><span class="token punctuation">(</span>MathFunctions REQUIRED<span class="token punctuation">)</span>
|
||
|
||
|
||
<span class="token keyword">target_link_libraries</span><span class="token punctuation">(</span>Tutorial <span class="token namespace">PRIVATE</span> MathFunctions<span class="token punctuation">)</span></code></pre>
|
||
<p>所以本节内容为如何导出一个用CMake管理的库。</p>
|
||
<p><strong>第一步</strong> 将目标安装添加导出</p>
|
||
<p><code>MathFunctions/CMakeLists.txt</code></p>
|
||
<pre><code class="fenced-code-block language-cmake"><span class="token keyword">install</span><span class="token punctuation">(</span>TARGETS <span class="token punctuation">${</span>installable_libs<span class="token punctuation">}</span>
|
||
EXPORT MathFunctionsTargets
|
||
DESTINATION lib<span class="token punctuation">)</span></code></pre>
|
||
<p><code>EXPORT</code>可以生成一个<code>MathFunctionsTargets.cmake</code>的文件,里面描述了此处安装的这些目标的一些导出配置。</p>
|
||
<p><strong>第二步</strong> 要让导出文件配置的路径对其他项目也可用,而不是绑定当前项目路径,需要修改头文件搜索路径,构建时和安装后为不同值</p>
|
||
<p><code>MathFunctions/CMakeLists.txt</code></p>
|
||
<pre><code class="fenced-code-block language-cmake"><span class="token keyword">target_include_directories</span><span class="token punctuation">(</span>MathFunctions
|
||
<span class="token namespace">INTERFACE</span>
|
||
<span class="token punctuation">$<</span>BUILD_INTERFACE:<span class="token punctuation">${</span><span class="token variable">CMAKE_CURRENT_SOURCE_DIR</span><span class="token punctuation">}</span><span class="token punctuation">></span>
|
||
<span class="token punctuation">$<</span>INSTALL_INTERFACE:include<span class="token punctuation">></span>
|
||
<span class="token punctuation">)</span></code></pre>
|
||
<p><strong>第三步</strong> 安装生成的<code>MathFunctionsTargets.cmake</code></p>
|
||
<p><code>MathFunctions/CMakeLists.txt</code></p>
|
||
<pre><code class="fenced-code-block language-cmake"><span class="token keyword">install</span><span class="token punctuation">(</span>EXPORT MathFunctionsTargets
|
||
FILE MathFunctionsTargets.cmake
|
||
DESTINATION lib/cmake/MathFunctions
|
||
<span class="token punctuation">)</span></code></pre>
|
||
<p><strong>第四步</strong> 准备<code>MathFunctionsConfig.cmake</code>文件模板与生成</p>
|
||
<p>用CMake管理的库需要用<code>find_package</code>进行导入,为了让<code>find_package</code>能正确找到对应的库,需要再准备一个<code>MathFunctionsConfig.cmake</code>文件,通常由模板生成,模板格式固定,内容如下</p>
|
||
<p><code>MathFunctions/Config.cmake.in</code></p>
|
||
<pre><code class="fenced-code-block language-cmake">@PACKAGE_INIT@
|
||
|
||
<span class="token keyword">include</span><span class="token punctuation">(</span><span class="token string">"<span class="token interpolation"><span class="token punctuation">${</span><span class="token variable">CMAKE_CURRENT_LIST_DIR</span><span class="token punctuation">}</span></span>/MathFunctionsTargets.cmake"</span> <span class="token punctuation">)</span></code></pre>
|
||
<p>由<code>configure_package_config_file</code>根据模板生成<code>MathFunctionsConfig.cmake</code>文件。</p>
|
||
<p><code>MathFunctions/CMakeLists.txt</code></p>
|
||
<pre><code class="fenced-code-block language-cmake"><span class="token keyword">include</span><span class="token punctuation">(</span>CMakePackageConfigHelpers<span class="token punctuation">)</span>
|
||
|
||
<span class="token function">configure_package_config_file</span><span class="token punctuation">(</span><span class="token punctuation">${</span><span class="token variable">CMAKE_CURRENT_SOURCE_DIR</span><span class="token punctuation">}</span>/Config.cmake.in
|
||
<span class="token string">"<span class="token interpolation"><span class="token punctuation">${</span><span class="token variable">CMAKE_CURRENT_BINARY_DIR</span><span class="token punctuation">}</span></span>/MathFunctionsConfig.cmake"</span>
|
||
INSTALL_DESTINATION <span class="token string">"lib/cmake/example"</span>
|
||
NO_SET_AND_CHECK_MACRO
|
||
NO_CHECK_REQUIRED_COMPONENTS_MACRO
|
||
<span class="token punctuation">)</span></code></pre>
|
||
<p><strong>第五步</strong> 生成版本文件(非必需)</p>
|
||
<p><code>MathFunctions/CMakeLists.txt</code></p>
|
||
<pre><code class="fenced-code-block language-cmake"><span class="token function">write_basic_package_version_file</span><span class="token punctuation">(</span>
|
||
<span class="token string">"<span class="token interpolation"><span class="token punctuation">${</span><span class="token variable">CMAKE_CURRENT_BINARY_DIR</span><span class="token punctuation">}</span></span>/MathFunctionsConfigVersion.cmake"</span>
|
||
<span class="token property">VERSION</span> <span class="token string">"<span class="token interpolation"><span class="token punctuation">${</span><span class="token variable">Tutorial_VERSION_MAJOR</span><span class="token punctuation">}</span></span>.<span class="token interpolation"><span class="token punctuation">${</span><span class="token variable">Tutorial_VERSION_MINOR</span><span class="token punctuation">}</span></span>"</span>
|
||
COMPATIBILITY AnyNewerVersion
|
||
<span class="token punctuation">)</span></code></pre>
|
||
<p><strong>第六步</strong> 安装生成文件</p>
|
||
<p><code>MathFunctions/CMakeLists.txt</code></p>
|
||
<pre><code class="fenced-code-block language-cmake"><span class="token keyword">install</span><span class="token punctuation">(</span>FILES
|
||
<span class="token punctuation">${</span><span class="token variable">CMAKE_CURRENT_BINARY_DIR</span><span class="token punctuation">}</span>/MathFunctionsConfig.cmake
|
||
<span class="token punctuation">${</span><span class="token variable">CMAKE_CURRENT_BINARY_DIR</span><span class="token punctuation">}</span>/MathFunctionsConfigVersion.cmake
|
||
DESTINATION lib/cmake/MathFunctions
|
||
<span class="token punctuation">)</span></code></pre>
|
||
<p> </p>
|
||
<p> </p>
|
||
<h2 class="atx" id="第十二步-打包调试版和发行版">第十二步 打包调试版和发行版</h2>
|
||
<p>本节示例只针对单配置生成器。对多配置生成器(如Visual Studio)不生效。</p>
|
||
<p>CMake一个构建目录只能有一种配置,分别为<code>Debug</code>,<code>Release</code>,<code>MinSizeRel</code>,<code>RelWithDebInfo</code>。</p>
|
||
<p>对于需要指定的不同版本,只需要在配置时指明即可</p>
|
||
<pre><code class="fenced-code-block language-shell"><span class="token comment"># 指定生成器、配置为Release版本</span>
|
||
cmake -G <span class="token string">"MinGW Makefiles"</span> -DCMAKE_BUILD_TYPE<span class="token operator">=</span>Release <span class="token punctuation">..</span>
|
||
<span class="token comment"># 使用默认生成器,配置为Debug版</span>
|
||
cmake -DCMAKE_BUILD_TYPE<span class="token operator">=</span>Debug <span class="token punctuation">..</span></code></pre>
|
||
<p>如果需要让Debug版本生成的目标名称与Release版本不同,可以使用<code>CMAKE_DEBUG_POSTFIX</code>为Debug版设置后缀。</p>
|
||
<pre><code class="fenced-code-block language-cmake"><span class="token keyword">set</span><span class="token punctuation">(</span><span class="token variable">CMAKE_DEBUG_POSTFIX</span> d<span class="token punctuation">)</span>
|
||
<span class="token keyword">add_executable</span><span class="token punctuation">(</span>Tutorial tutorial.cxx<span class="token punctuation">)</span>
|
||
<span class="token keyword">set_target_properties</span><span class="token punctuation">(</span>Tutorial <span class="token namespace">PROPERTIES</span> <span class="token property">DEBUG_POSTFIX</span> <span class="token punctuation">${</span><span class="token variable">CMAKE_DEBUG_POSTFIX</span><span class="token punctuation">}</span><span class="token punctuation">)</span></code></pre>
|
||
<p>这样一来该目标及其依赖的目标生成的文件都会带有后缀<code>d</code>。</p>
|
||
<p> 通常来说会把Debug版与Release版分别放入两个<code>debug</code>和<code>release</code>目录中。如果只需要打包一版本,到对应目录中直接运行<code>cpack</code>即可。如果需要同时打包两个版本的内容,则在<code>debug</code>和<code>release</code>同级目录下新建一个<code>MultiCPackConfig.cmake</code>文件,内容如下</p>
|
||
<pre><code class="fenced-code-block language-cmake"><span class="token keyword">include</span><span class="token punctuation">(</span><span class="token string">"release/CPackConfig.cmake"</span><span class="token punctuation">)</span>
|
||
|
||
<span class="token keyword">set</span><span class="token punctuation">(</span>CPACK_INSTALL_CMAKE_PROJECTS
|
||
<span class="token string">"debug;Tutorial;libSqrtLibraryd.a;/"</span>
|
||
<span class="token string">"release;Tutorial;ALL;/"</span>
|
||
<span class="token punctuation">)</span></code></pre>
|
||
<p><code>CPACK_INSTALL_CMAKE_PROJECTS</code>用来指定要打包的内容,可以有多项,每一项里有4部分内容,分别为</p>
|
||
<ul>
|
||
<li>项目路径:指定要打包的项目所在的路径</li>
|
||
<li>项目名称:指定要打包的项目的名称</li>
|
||
<li>安装组件:指定要打包的项目的安装组件。可以是ALL(所有组件)、DEFAULT(默认组件)或者是一个具体的组件名称</li>
|
||
<li>安装路径:指定要打包的项目的安装路径(相对整打包好的整个目录来说的)</li>
|
||
</ul>
|
||
<p>完成之后在本目录下执行</p>
|
||
<pre><code class="fenced-code-block language-shell">cpack --config MultiCPackConfig.cmake</code></pre>
|
||
<p>即可打包配置好的内容。</p>
|
||
<p> </p>
|
||
<h2 class="atx" id="练习-cmake-gui的使用">练习 cmake-gui的使用</h2>
|
||
<p>前面的配置与构建过程都是用命令,CMake还提供了界面工具<code>cmake-gui</code>可以完成类似的工作。</p>
|
||
<p> </p>
|
||
<p> </p>
|
||
<h1 class="atx" id="cmake基础知识补充">CMake基础知识补充</h1>
|
||
<p>前面Tutorial中,只是简单过了一下涉及到的知识,并没有对相关知识进行扩展。部分的内容主要为补充一些基础知识。由于CMake文档当中内容繁多,本部分内容也不会全部涉及,只挑选其中一部分进行讲解。有需要更深入了解的请自行查阅<a href="https://cmake.org/cmake/help/latest/index.html">官方文档</a>。</p>
|
||
<p> </p>
|
||
<h2 class="atx" id="cmake命令使用">CMake命令使用</h2>
|
||
<h3 class="atx" id="创建项目构建系统">创建项目构建系统</h3>
|
||
<p><strong>用法</strong></p>
|
||
<pre><code class="fenced-code-block language-cmake">cmake [<options<span class="token punctuation">></span>] <path-to-source | path-to-existing-build<span class="token punctuation">></span>
|
||
cmake [<options<span class="token punctuation">></span>] -S <path-to-source<span class="token punctuation">></span> -B <path-to-build<span class="token punctuation">></span></code></pre>
|
||
<p><code>cmake [<options>] <path-to-source></code></p>
|
||
<p>指定源文件(含有<code>CMakeLists.txt</code>文件的)目录,在当前目录下生成构建文件。指定目录可以是相对路径,也可以是绝对路径。</p>
|
||
<p><code>cmake [<options>] <path-to-existing-build></code></p>
|
||
<p>指定已经生成构建文件(已经生成有<code>CMakeCache.txt</code>)的目录,重新加载(生成)。</p>
|
||
<p><code>cmake [<options>] -S <path-to-source> -B <path-to-build></code></p>
|
||
<p>明确指定源文件目录与构建目录。</p>
|
||
<p> </p>
|
||
<p><strong>常用选项</strong></p>
|
||
<ul>
|
||
<li><p><strong>-S <path-to-source></strong>:指定源文件根目录</p>
|
||
</li>
|
||
<li><p><strong>-B <path-to-build></strong>:指定构建文件目录</p>
|
||
</li>
|
||
<li><p><strong>-G <generator-name></strong>:指定生成器。具体支持哪些生成器可用</p>
|
||
<pre><code class="fenced-code-block language-shell">cmake --help</code></pre>
|
||
<p>查看。</p>
|
||
</li>
|
||
</ul>
|
||
<p>具体示例:</p>
|
||
<pre><code class="fenced-code-block language-shell"><span class="token comment"># 指定生成器为MinGW Makefiles,生成mingw32-make的Makefile文件</span>
|
||
<span class="token comment"># 指定源文件根目录为src,构建目录为build</span>
|
||
cmake -G <span class="token string">"MinGW Makefiles"</span> -S src -B build</code></pre>
|
||
<p> </p>
|
||
<h3 class="atx" id="构建项目">构建项目</h3>
|
||
<p><strong>用法</strong></p>
|
||
<pre><code class="fenced-code-block language-cmake">cmake --build <dir<span class="token punctuation">></span> [<options<span class="token punctuation">></span>] [-- <build-tool-options<span class="token punctuation">></span>]</code></pre>
|
||
<p><code>cmake --build <dir></code></p>
|
||
<p><dir>为上述生成了构建文件的目录。生成器对应的构建工具来构建项目。</p>
|
||
<pre><code class="fenced-code-block language-cmake">cmake --build .</code></pre>
|
||
<p> </p>
|
||
<p><strong>常用选项</strong></p>
|
||
<ul>
|
||
<li><p><strong>-j [<jobs>], --parallel [<jobs>]</strong>:指定构建时的线程数,可以开启多线程构建提升速度</p>
|
||
<pre><code class="fenced-code-block language-shell">cmake --build <span class="token builtin class-name">.</span> -j <span class="token number">4</span>
|
||
cmake --build <span class="token builtin class-name">.</span> --parallel <span class="token number">4</span></code></pre>
|
||
</li>
|
||
<li><p><strong>-t <tgt>..., --target <tgt>...</strong>:指定构建目标。</p>
|
||
<pre><code class="fenced-code-block language-shell"><span class="token comment"># 指定目标为clean</span>
|
||
cmake --build <span class="token builtin class-name">.</span> -t clean
|
||
<span class="token comment"># 指定构建目标为install</span>
|
||
cmake --build <span class="token builtin class-name">.</span> --target <span class="token function">install</span></code></pre>
|
||
</li>
|
||
<li><p><strong>--clean-first</strong>:构建前先clean</p>
|
||
</li>
|
||
</ul>
|
||
<p>使用<code>cmake --build</code>可以查看相关帮助信息。</p>
|
||
<p> </p>
|
||
<h3 class="atx" id="安装">安装</h3>
|
||
<p>安装已构建好的项目</p>
|
||
<p><strong>用法</strong></p>
|
||
<pre><code class="fenced-code-block language-shell">cmake --install <span class="token operator"><</span>dir<span class="token operator">></span> <span class="token punctuation">[</span><span class="token operator"><</span>options<span class="token operator">></span><span class="token punctuation">]</span></code></pre>
|
||
<ul>
|
||
<li><code>dir</code>为项目构建目录</li>
|
||
<li><code>options</code>安装选项</li>
|
||
</ul>
|
||
<p>常用选项</p>
|
||
<ul>
|
||
<li>*<em>--config <cfg> *</em> 对于多配置的项目,用于指定需要安装的配置</li>
|
||
<li><strong>--prefix <prefix></strong> 指定安装目录</li>
|
||
</ul>
|
||
<p> </p>
|
||
<p> </p>
|
||
<h3 class="atx" id="运行脚本">运行脚本</h3>
|
||
<p>CMake在一定程度上也可以算是一种编程语言。但是前面执行对应的代码都需要建立一个项目,提供CMakeLists.txt文件,再生成构建文件,步骤比较多。</p>
|
||
<p>尤其是在学习阶段,有时候可能只是想看一下里面一些内容运行是什么效果,这样做就有点麻烦了。CMake提供了一种直接执行脚本的方式,即先建立一个<code><filename>.cmake</code>的脚本,再通过以下命令来执行。</p>
|
||
<p><strong>用法</strong></p>
|
||
<pre><code class="fenced-code-block language-shell">cmake <span class="token punctuation">[</span>-D <span class="token operator"><</span>var<span class="token operator">>=</span><span class="token operator"><</span>value<span class="token operator">></span><span class="token punctuation">]</span><span class="token punctuation">..</span>. -P <span class="token operator"><</span>cmake-script-file<span class="token operator">></span> <span class="token punctuation">[</span>-- <span class="token operator"><</span>unparsed-options<span class="token operator">></span><span class="token punctuation">..</span>.<span class="token punctuation">]</span>
|
||
<span class="token comment"># 简写</span>
|
||
cmake -P <span class="token operator"><</span>cmake-script-file<span class="token operator">></span></code></pre>
|
||
<p>示例</p>
|
||
<pre><code class="fenced-code-block language-shell">cmake -P learn.cmake</code></pre>
|
||
<p> </p>
|
||
<h3 class="atx" id="运行命令行工具">运行命令行工具</h3>
|
||
<p>CMake提供了一系列命令行工具如文件复制删除、哈希值计算等,用<code>cmake -E</code>可查看相关帮助。</p>
|
||
<p><strong>用法</strong></p>
|
||
<pre><code class="fenced-code-block language-shell">cmake -E <span class="token operator"><</span>command<span class="token operator">></span> <span class="token punctuation">[</span><span class="token operator"><</span>options<span class="token operator">></span><span class="token punctuation">]</span></code></pre>
|
||
<p>示例</p>
|
||
<pre><code class="fenced-code-block language-shell"><span class="token comment"># 以JSON格式输出CMake功能</span>
|
||
cmake -E capabilities
|
||
<span class="token comment"># 计算文件MD5值</span>
|
||
cmake -E md5sum tutorial.cxx
|
||
<span class="token comment"># 如果文件有改动则复制</span>
|
||
cmake -E copy_if_different file1.txt build/file2.txt</code></pre>
|
||
<p>更多命令详见<a href="https://cmake.org/cmake/help/latest/manual/cmake.1.html#run-a-command-line-tool">官方文档</a></p>
|
||
<p> </p>
|
||
<p> </p>
|
||
<p> </p>
|
||
<h2 class="atx" id="cmake指令">CMake指令</h2>
|
||
<h3 class="atx" id="脚本指令">脚本指令</h3>
|
||
<h4 class="atx" id="message">message</h4>
|
||
<p>用于输出信息。</p>
|
||
<p><strong>用法</strong></p>
|
||
<pre><code class="fenced-code-block language-cmake"><span class="token comment"># 普通消息 <mode> 部分可以省略</span>
|
||
<span class="token keyword">message</span><span class="token punctuation">(</span>[<mode<span class="token punctuation">></span>] <span class="token string">"message text"</span> ...<span class="token punctuation">)</span>
|
||
<span class="token comment"># 状态消息</span>
|
||
<span class="token keyword">message</span><span class="token punctuation">(</span><checkState<span class="token punctuation">></span> <span class="token string">"message text"</span> ...<span class="token punctuation">)</span>
|
||
<span class="token comment"># 配置日志</span>
|
||
<span class="token keyword">message</span><span class="token punctuation">(</span>CONFIGURE_LOG <text<span class="token punctuation">></span>...<span class="token punctuation">)</span></code></pre>
|
||
<p><code><mode></code>常用选项有如下几种</p>
|
||
<ul>
|
||
<li><code>FATAL_ERROR</code>:CMake错误,会终止往下执行</li>
|
||
<li><code>SEND_ERROR</code>:CMake错误,会继续执行,但会跳过一些文件的生成</li>
|
||
<li><code>WARNING</code>:输出警告信息,不会终止执行</li>
|
||
<li><code>NOTICE</code>:一些需要注意的提示信息</li>
|
||
<li><code>DEBUG</code>:输出调试信息</li>
|
||
<li><code>STATUS</code>:输出当前状态信息</li>
|
||
</ul>
|
||
<p>更多选项与例子见<a href="https://cmake.org/cmake/help/latest/command/message.html">官方文档</a></p>
|
||
<p><code><checkState></code>选项有以下三种</p>
|
||
<ul>
|
||
<li><code>CHECK_START</code>:开始检测</li>
|
||
<li><code>CHECK_PASS</code>:检测通过</li>
|
||
<li><code>CHECK_FAIL</code>:检测不通过</li>
|
||
</ul>
|
||
<p> </p>
|
||
<h4 class="atx" id="变量定义与取消">变量定义与取消</h4>
|
||
<p><strong>定义普通变量</strong></p>
|
||
<pre><code class="fenced-code-block language-cmake"><span class="token keyword">set</span><span class="token punctuation">(</span><variable<span class="token punctuation">></span> <value<span class="token punctuation">></span>... [PARENT_SCOPE]<span class="token punctuation">)</span></code></pre>
|
||
<ul>
|
||
<li><code>PARENT_SCOPE</code>会将该变量定义到父作用域。并且变量值在当前作用域不可用。</li>
|
||
</ul>
|
||
<p><strong>修改环境变量</strong></p>
|
||
<pre><code class="fenced-code-block language-cmake"><span class="token keyword">set</span><span class="token punctuation">(</span><span class="token variable">ENV</span>{<variable<span class="token punctuation">></span><span class="token punctuation">}</span> [<value<span class="token punctuation">></span>]<span class="token punctuation">)</span></code></pre>
|
||
<p><strong>定义Cache Entry</strong></p>
|
||
<pre><code class="fenced-code-block language-cmake"><span class="token keyword">set</span><span class="token punctuation">(</span><variable<span class="token punctuation">></span> <value<span class="token punctuation">></span>... <span class="token variable">CACHE</span> <type<span class="token punctuation">></span> <docstring<span class="token punctuation">></span> [FORCE]<span class="token punctuation">)</span></code></pre>
|
||
<ul>
|
||
<li><p><code>type</code>为类型,有以下几种</p>
|
||
<ul>
|
||
<li><p><code>BOOL</code>布尔<code>ON/OFF</code>值。<code>cmake-gui</code>中为复选框</p>
|
||
</li>
|
||
<li><p><code>FILEPATH</code>文件路径。<code>cmake-gui</code>中为文件选择窗口</p>
|
||
</li>
|
||
<li><p><code>PATH</code>目录路径,<code>cmake-gui</code>中为文件选择窗口</p>
|
||
</li>
|
||
<li><p><code>STRING</code>一行文字,<code>cmake-gui</code>中为文本输入框或下拉框</p>
|
||
<p>下拉框需要设置STRINGS属性,多项可用空格或分号隔开</p>
|
||
<pre><code class="fenced-code-block language-cmake"><span class="token keyword">set</span><span class="token punctuation">(</span>STRINT_TEST <span class="token string">""</span> <span class="token variable">CACHE</span> STRING <span class="token string">"Input text ..."</span><span class="token punctuation">)</span>
|
||
<span class="token keyword">set_property</span><span class="token punctuation">(</span><span class="token variable">CACHE</span> STRINT_TEST PROPERTY <span class="token property">STRINGS</span> hello world and you<span class="token punctuation">)</span></code></pre>
|
||
</li>
|
||
</ul>
|
||
</li>
|
||
<li><p><code>INTERNAL</code>一行文本,<code>cmake-gui</code>中不显示此类变量。用来存储处理过程中不变的内容。</p>
|
||
</li>
|
||
</ul>
|
||
<p><strong>变量取消定义</strong></p>
|
||
<pre><code class="fenced-code-block language-cmake"><span class="token keyword">unset</span><span class="token punctuation">(</span><variable<span class="token punctuation">></span> [<span class="token variable">CACHE</span> | PARENT_SCOPE]<span class="token punctuation">)</span>
|
||
<span class="token keyword">unset</span><span class="token punctuation">(</span><span class="token variable">ENV</span>{<variable<span class="token punctuation">></span><span class="token punctuation">}</span><span class="token punctuation">)</span></code></pre>
|
||
<pre><code class="fenced-code-block language-cmake"><span class="token comment"># 取消环境变量</span>
|
||
<span class="token keyword">unset</span><span class="token punctuation">(</span><span class="token variable">ENV</span>{JAVA_HOME<span class="token punctuation">}</span><span class="token punctuation">)</span>
|
||
<span class="token comment"># 取消Cache Entry变量</span>
|
||
<span class="token keyword">unset</span><span class="token punctuation">(</span>FILE_PATH <span class="token variable">CACHE</span><span class="token punctuation">)</span>
|
||
<span class="token comment"># 取消上一级作用域的变量</span>
|
||
<span class="token keyword">unset</span><span class="token punctuation">(</span>VAR_OUT PARENT_SCOPE<span class="token punctuation">)</span></code></pre>
|
||
<p> </p>
|
||
<h4 class="atx" id="条件判断">条件判断</h4>
|
||
<p><strong>语法</strong></p>
|
||
<pre><code class="fenced-code-block language-cmake"><span class="token keyword">if</span><span class="token punctuation">(</span><condition<span class="token punctuation">></span><span class="token punctuation">)</span>
|
||
<commands<span class="token punctuation">></span>
|
||
<span class="token keyword">elseif</span><span class="token punctuation">(</span><condition<span class="token punctuation">></span><span class="token punctuation">)</span> <span class="token comment"># 可选、可重复</span>
|
||
<commands<span class="token punctuation">></span>
|
||
<span class="token keyword">else</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token comment"># 可选</span>
|
||
<commands<span class="token punctuation">></span>
|
||
<span class="token keyword">endif</span><span class="token punctuation">(</span><span class="token punctuation">)</span></code></pre>
|
||
<p><strong>基础用法</strong></p>
|
||
<p><em>此部分测试不能用脚本运行的方式进行,会有一些其他问题</em></p>
|
||
<ul>
|
||
<li><p>常量判断</p>
|
||
<p><code>1</code>, <code>ON</code>, <code>YES</code>, <code>TRUE</code>, <code>Y</code>为真, <code>0</code>, <code>OFF</code>, <code>NO</code>, <code>FALSE</code>, <code>N</code>, <code>IGNORE</code>, <code>NOTFOUND</code>假,不区分大小写。如果不是这些常量,则会被当作变量或字符串对待。</p>
|
||
<pre><code class="fenced-code-block language-cmake"><span class="token keyword">if</span><span class="token punctuation">(</span>YES<span class="token punctuation">)</span> <span class="token comment"># 把以上值填入括号测试</span>
|
||
<span class="token keyword">message</span><span class="token punctuation">(</span>STATUS 真<span class="token punctuation">)</span>
|
||
<span class="token keyword">else</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
|
||
<span class="token keyword">message</span><span class="token punctuation">(</span>STATUS 假<span class="token punctuation">)</span>
|
||
<span class="token keyword">endif</span><span class="token punctuation">(</span><span class="token punctuation">)</span></code></pre>
|
||
</li>
|
||
<li><p>变量判断</p>
|
||
<p>普通变量和环境变量都用这种方式。如果变量值不是为假的常量则为真。值为上述为假的或未定义则为假</p>
|
||
<pre><code class="fenced-code-block language-cmake"><span class="token keyword">set</span><span class="token punctuation">(</span>VAR_1 hello world<span class="token punctuation">)</span>
|
||
|
||
<span class="token keyword">if</span><span class="token punctuation">(</span>VAR_1<span class="token punctuation">)</span> <span class="token comment"># 变量用做判断时不用加${}</span>
|
||
<span class="token keyword">message</span><span class="token punctuation">(</span>STATUS 真<span class="token punctuation">)</span>
|
||
<span class="token keyword">else</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
|
||
<span class="token keyword">message</span><span class="token punctuation">(</span>STATUS 假<span class="token punctuation">)</span>
|
||
<span class="token keyword">endif</span><span class="token punctuation">(</span><span class="token punctuation">)</span></code></pre>
|
||
</li>
|
||
<li><p>引号内字符串</p>
|
||
<p>除了引号内为上述为真的值,其他都为假</p>
|
||
<pre><code class="fenced-code-block language-cmake"><span class="token keyword">if</span><span class="token punctuation">(</span><span class="token string">"HELLO"</span><span class="token punctuation">)</span>
|
||
<span class="token keyword">message</span><span class="token punctuation">(</span>STATUS 真<span class="token punctuation">)</span>
|
||
<span class="token keyword">else</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
|
||
<span class="token keyword">message</span><span class="token punctuation">(</span>STATUS 假<span class="token punctuation">)</span>
|
||
<span class="token keyword">endif</span><span class="token punctuation">(</span><span class="token punctuation">)</span></code></pre>
|
||
</li>
|
||
</ul>
|
||
<p><strong>逻辑运算</strong></p>
|
||
<p>与</p>
|
||
<pre><code class="fenced-code-block language-cmake"><span class="token keyword">if</span><span class="token punctuation">(</span><cond1<span class="token punctuation">></span> <span class="token operator">AND</span> <cond2<span class="token punctuation">></span><span class="token punctuation">)</span></code></pre>
|
||
<p>或</p>
|
||
<pre><code class="fenced-code-block language-cmake"><span class="token keyword">if</span><span class="token punctuation">(</span><cond1<span class="token punctuation">></span> <span class="token operator">OR</span> <cond2<span class="token punctuation">></span><span class="token punctuation">)</span></code></pre>
|
||
<p>非</p>
|
||
<pre><code class="fenced-code-block language-cmake"><span class="token keyword">if</span><span class="token punctuation">(</span><span class="token operator">NOT</span> <condition<span class="token punctuation">></span><span class="token punctuation">)</span></code></pre>
|
||
<p> </p>
|
||
<p><strong>其他常用判断</strong></p>
|
||
<ul>
|
||
<li><p><code>if(TARGET target-name)</code> 判断一个目标是否存在(由<code>add_executable()</code>, <code>add_library()</code>, <code>add_custom_target()</code>创建)</p>
|
||
</li>
|
||
<li><p><code>if(DEFINED <name>|CACHE{<name>}|ENV{<name>})</code>判断一个变量是否已定义</p>
|
||
</li>
|
||
<li><p><code>if(<variable|string> IN_LIST <variable>)</code>判断给定元素是否在列表中。列表中各项可用空格或分号隔开</p>
|
||
<pre><code class="fenced-code-block language-cmake"><span class="token keyword">set</span><span class="token punctuation">(</span>M_LIST hello;world;and;not<span class="token punctuation">)</span>
|
||
|
||
<span class="token keyword">if</span><span class="token punctuation">(</span><span class="token string">"hello"</span> IN_LIST M_LIST<span class="token punctuation">)</span>
|
||
<span class="token keyword">message</span><span class="token punctuation">(</span>STATUS 真<span class="token punctuation">)</span>
|
||
<span class="token keyword">else</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
|
||
<span class="token keyword">message</span><span class="token punctuation">(</span>STATUS 假<span class="token punctuation">)</span>
|
||
<span class="token keyword">endif</span><span class="token punctuation">(</span><span class="token punctuation">)</span></code></pre>
|
||
</li>
|
||
<li><p><code>if(EXISTS path-to-file-or-directory)</code>判断文件或路径是否存在</p>
|
||
</li>
|
||
<li><p><code>if(<variable|string> MATCHES regex)</code>判断能否匹配上正则</p>
|
||
</li>
|
||
</ul>
|
||
<p>更多比较操作见<a href="https://cmake.org/cmake/help/v3.26/command/if.html">官方文档</a>。</p>
|
||
<p> </p>
|
||
<h4 class="atx" id="循环">循环</h4>
|
||
<p><strong>foreach</strong></p>
|
||
<p>用法一:</p>
|
||
<pre><code class="fenced-code-block language-cmake"><span class="token keyword">foreach</span><span class="token punctuation">(</span><loop_var<span class="token punctuation">></span> <item_list<span class="token punctuation">></span><span class="token punctuation">)</span>
|
||
<commands<span class="token punctuation">></span>
|
||
<span class="token keyword">endforeach</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
|
||
|
||
<span class="token comment"># 示例</span>
|
||
<span class="token keyword">set</span><span class="token punctuation">(</span>M_LIST hello world and not<span class="token punctuation">)</span>
|
||
|
||
<span class="token keyword">foreach</span><span class="token punctuation">(</span>WORD <span class="token punctuation">${</span>M_LIST<span class="token punctuation">}</span><span class="token punctuation">)</span>
|
||
<span class="token keyword">message</span><span class="token punctuation">(</span>STATUS <span class="token punctuation">${</span>WORD<span class="token punctuation">}</span><span class="token punctuation">)</span>
|
||
<span class="token keyword">endforeach</span><span class="token punctuation">(</span><span class="token punctuation">)</span></code></pre>
|
||
<ul>
|
||
<li><code>loop_var</code> 用来接收列表中每一项的变量</li>
|
||
<li><code>item_list</code>需要循环的列表,里面每一项用空格或者分号隔开</li>
|
||
</ul>
|
||
<p>可以用<code>continue()</code>结束本次循环,用<code>break()</code>终止循环</p>
|
||
<pre><code class="fenced-code-block language-cmake"><span class="token keyword">set</span><span class="token punctuation">(</span>M_LIST hello world and how not <span class="token number">1</span> <span class="token number">2</span> <span class="token number">3</span><span class="token punctuation">)</span>
|
||
|
||
<span class="token keyword">foreach</span><span class="token punctuation">(</span>WORD <span class="token punctuation">${</span>M_LIST<span class="token punctuation">}</span><span class="token punctuation">)</span>
|
||
<span class="token keyword">if</span><span class="token punctuation">(</span><span class="token punctuation">${</span>WORD<span class="token punctuation">}</span> <span class="token operator">STREQUAL</span> <span class="token string">"and"</span><span class="token punctuation">)</span>
|
||
<span class="token keyword">continue</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
|
||
<span class="token keyword">endif</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
|
||
<span class="token keyword">if</span><span class="token punctuation">(</span><span class="token punctuation">${</span>WORD<span class="token punctuation">}</span> <span class="token operator">STREQUAL</span> <span class="token string">"not"</span><span class="token punctuation">)</span>
|
||
<span class="token keyword">break</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
|
||
<span class="token keyword">endif</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
|
||
<span class="token keyword">message</span><span class="token punctuation">(</span>STATUS <span class="token punctuation">${</span>WORD<span class="token punctuation">}</span><span class="token punctuation">)</span>
|
||
<span class="token keyword">endforeach</span><span class="token punctuation">(</span><span class="token punctuation">)</span></code></pre>
|
||
<p>用法二:</p>
|
||
<pre><code class="fenced-code-block language-cmake"><span class="token keyword">foreach</span><span class="token punctuation">(</span><loop_var<span class="token punctuation">></span> RANGE <stop<span class="token punctuation">></span><span class="token punctuation">)</span></code></pre>
|
||
<p>从0循环到<code>stop</code>指定的数,可以为负数</p>
|
||
<pre><code class="fenced-code-block language-cmake"><span class="token keyword">foreach</span><span class="token punctuation">(</span>NUM RANGE -<span class="token number">11</span><span class="token punctuation">)</span>
|
||
<span class="token keyword">message</span><span class="token punctuation">(</span>STATUS <span class="token punctuation">${</span>NUM<span class="token punctuation">}</span><span class="token punctuation">)</span>
|
||
<span class="token keyword">endforeach</span><span class="token punctuation">(</span><span class="token punctuation">)</span></code></pre>
|
||
<pre><code class="fenced-code-block language-cmake"><span class="token keyword">foreach</span><span class="token punctuation">(</span><loop_var<span class="token punctuation">></span> RANGE <start<span class="token punctuation">></span> <stop<span class="token punctuation">></span> [<step<span class="token punctuation">></span>]<span class="token punctuation">)</span></code></pre>
|
||
<p>从<code>start</code>指定的数循环到<code>stop</code>指定的数,默认步长为1,也可以指定步长。</p>
|
||
<pre><code class="fenced-code-block language-cmake"><span class="token keyword">foreach</span><span class="token punctuation">(</span>NUM RANGE <span class="token number">10</span> <span class="token number">20</span> <span class="token number">2</span><span class="token punctuation">)</span>
|
||
<span class="token keyword">message</span><span class="token punctuation">(</span>STATUS <span class="token punctuation">${</span>NUM<span class="token punctuation">}</span><span class="token punctuation">)</span>
|
||
<span class="token keyword">endforeach</span><span class="token punctuation">(</span><span class="token punctuation">)</span></code></pre>
|
||
<p>用法三:</p>
|
||
<pre><code class="fenced-code-block language-cmake"><span class="token keyword">foreach</span><span class="token punctuation">(</span><loop_var<span class="token punctuation">></span> IN [LISTS [<lists<span class="token punctuation">></span>]] [ITEMS [<items<span class="token punctuation">></span>]]<span class="token punctuation">)</span></code></pre>
|
||
<ul>
|
||
<li><code>LISTS</code>后面可以跟一个或多个用分号或空格隔开的列表,会分别循环取出每个列表中的每一项</li>
|
||
<li><code>ITEMS</code>后面可以放上多项内容,循环也会取出每一项</li>
|
||
</ul>
|
||
<pre><code class="fenced-code-block language-cmake"><span class="token keyword">set</span><span class="token punctuation">(</span>A <span class="token number">0</span>;<span class="token number">1</span>;<span class="token number">3</span><span class="token punctuation">)</span>
|
||
<span class="token keyword">set</span><span class="token punctuation">(</span>B <span class="token number">2</span> <span class="token number">3</span><span class="token punctuation">)</span>
|
||
<span class="token keyword">set</span><span class="token punctuation">(</span>C <span class="token string">"4 5"</span><span class="token punctuation">)</span>
|
||
<span class="token keyword">set</span><span class="token punctuation">(</span>D <span class="token number">6</span>;<span class="token number">7</span> <span class="token number">8</span><span class="token punctuation">)</span>
|
||
<span class="token keyword">set</span><span class="token punctuation">(</span>E <span class="token string">""</span><span class="token punctuation">)</span>
|
||
<span class="token keyword">foreach</span><span class="token punctuation">(</span>X IN LISTS A B C D E ITEMS <span class="token punctuation">${</span>A<span class="token punctuation">}</span><span class="token punctuation">)</span>
|
||
<span class="token keyword">message</span><span class="token punctuation">(</span>STATUS <span class="token string">"X=<span class="token interpolation"><span class="token punctuation">${</span><span class="token variable">X</span><span class="token punctuation">}</span></span>"</span><span class="token punctuation">)</span>
|
||
<span class="token keyword">endforeach</span><span class="token punctuation">(</span><span class="token punctuation">)</span></code></pre>
|
||
<p>用法四:</p>
|
||
<pre><code class="fenced-code-block language-cmake"><span class="token keyword">foreach</span><span class="token punctuation">(</span><loop_var<span class="token punctuation">></span>... IN ZIP_LISTS <lists<span class="token punctuation">></span><span class="token punctuation">)</span></code></pre>
|
||
<p>用指定变量循环多个列表</p>
|
||
<pre><code class="fenced-code-block language-cmake"><span class="token keyword">list</span><span class="token punctuation">(</span>APPEND English one two three four<span class="token punctuation">)</span>
|
||
<span class="token keyword">list</span><span class="token punctuation">(</span>APPEND Bahasa satu dua tiga<span class="token punctuation">)</span>
|
||
<span class="token keyword">list</span><span class="token punctuation">(</span>APPEND Chinese 一 二 三 四 五 六<span class="token punctuation">)</span>
|
||
|
||
<span class="token keyword">foreach</span><span class="token punctuation">(</span>num IN ZIP_LISTS English Bahasa Chinese<span class="token punctuation">)</span>
|
||
<span class="token keyword">message</span><span class="token punctuation">(</span>STATUS <span class="token string">"num_0=<span class="token interpolation"><span class="token punctuation">${</span><span class="token variable">num_0</span><span class="token punctuation">}</span></span>, num_1=<span class="token interpolation"><span class="token punctuation">${</span><span class="token variable">num_1</span><span class="token punctuation">}</span></span>, num_2=<span class="token interpolation"><span class="token punctuation">${</span><span class="token variable">num_2</span><span class="token punctuation">}</span></span>"</span><span class="token punctuation">)</span>
|
||
<span class="token keyword">endforeach</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
|
||
|
||
<span class="token keyword">foreach</span><span class="token punctuation">(</span>en ba ch IN ZIP_LISTS English Bahasa Chinese<span class="token punctuation">)</span>
|
||
<span class="token keyword">message</span><span class="token punctuation">(</span>STATUS <span class="token string">"en=<span class="token interpolation"><span class="token punctuation">${</span><span class="token variable">en</span><span class="token punctuation">}</span></span>, ba=<span class="token interpolation"><span class="token punctuation">${</span><span class="token variable">ba</span><span class="token punctuation">}</span></span>, ch=<span class="token interpolation"><span class="token punctuation">${</span><span class="token variable">ch</span><span class="token punctuation">}</span></span>"</span><span class="token punctuation">)</span>
|
||
<span class="token keyword">endforeach</span><span class="token punctuation">(</span><span class="token punctuation">)</span></code></pre>
|
||
<p> </p>
|
||
<p><strong>while循环</strong></p>
|
||
<pre><code class="fenced-code-block language-cmake"><span class="token keyword">while</span><span class="token punctuation">(</span><condition<span class="token punctuation">></span><span class="token punctuation">)</span>
|
||
<commands<span class="token punctuation">></span>
|
||
<span class="token keyword">endwhile</span><span class="token punctuation">(</span><span class="token punctuation">)</span></code></pre>
|
||
<p><code>condition</code>为真时循环,真假的处理情况与<code>if()</code>相同。可以用<code>continue()</code>结束本次循环,用<code>break()</code>终止循环</p>
|
||
<pre><code class="fenced-code-block language-cmake"><span class="token keyword">set</span><span class="token punctuation">(</span>i <span class="token number">0</span><span class="token punctuation">)</span>
|
||
<span class="token keyword">while</span><span class="token punctuation">(</span>i <span class="token operator">LESS</span> <span class="token number">10</span><span class="token punctuation">)</span>
|
||
<span class="token keyword">message</span><span class="token punctuation">(</span><span class="token string">"i = <span class="token interpolation"><span class="token punctuation">${</span><span class="token variable">i</span><span class="token punctuation">}</span></span>"</span><span class="token punctuation">)</span>
|
||
<span class="token keyword">math</span><span class="token punctuation">(</span>EXPR i <span class="token string">"<span class="token interpolation"><span class="token punctuation">${</span><span class="token variable">i</span><span class="token punctuation">}</span></span> + 1"</span><span class="token punctuation">)</span>
|
||
<span class="token keyword">endwhile</span><span class="token punctuation">(</span><span class="token punctuation">)</span></code></pre>
|
||
<p> </p>
|
||
<p> </p>
|
||
<h4 class="atx" id="字符串操作">字符串操作</h4>
|
||
<p><strong>查找与替换</strong></p>
|
||
<p>查找:</p>
|
||
<pre><code class="fenced-code-block language-cmake"><span class="token keyword">string</span><span class="token punctuation">(</span>FIND <string<span class="token punctuation">></span> <substring<span class="token punctuation">></span> <output_variable<span class="token punctuation">></span> [REVERSE]<span class="token punctuation">)</span></code></pre>
|
||
<ul>
|
||
<li><code>string</code>文本内容</li>
|
||
<li><code>substring</code>需要在文本内容中查找的子串</li>
|
||
<li><code>output_variable</code>存放子串第一次出现的索引,查找不到则为-1,只针对单字节字符,多字节字符会返回字节数据的索引</li>
|
||
<li><code>REVERSE</code>如果写上,则从文本末尾开始查找</li>
|
||
</ul>
|
||
<pre><code class="fenced-code-block language-cmake"><span class="token keyword">string</span><span class="token punctuation">(</span>FIND <span class="token string">"Hello World Hello World Hello World"</span> <span class="token string">"Hello2"</span> index REVERSE<span class="token punctuation">)</span>
|
||
<span class="token keyword">message</span><span class="token punctuation">(</span>STATUS <span class="token punctuation">${</span>index<span class="token punctuation">}</span><span class="token punctuation">)</span></code></pre>
|
||
<p>替换:</p>
|
||
<pre><code class="fenced-code-block language-cmake"><span class="token keyword">string</span><span class="token punctuation">(</span>REPLACE <match_string<span class="token punctuation">></span> <replace_string<span class="token punctuation">></span> <output_variable<span class="token punctuation">></span> <input<span class="token punctuation">></span> [<input<span class="token punctuation">></span>...]<span class="token punctuation">)</span></code></pre>
|
||
<ul>
|
||
<li><code>match_string</code>需要被替换的内容</li>
|
||
<li><code>replace_string</code>用来替换的内容</li>
|
||
<li><code>output_variable</code>存放替换后的结果</li>
|
||
<li><code>input</code>原始文本,可以有多项</li>
|
||
</ul>
|
||
<pre><code class="fenced-code-block language-cmake"><span class="token keyword">string</span><span class="token punctuation">(</span>REPLACE <span class="token string">"Hello"</span> <span class="token string">"好"</span> result <span class="token string">"Hello World"</span> <span class="token string">"Nod Hello "</span> <span class="token string">" And what"</span><span class="token punctuation">)</span>
|
||
<span class="token keyword">message</span><span class="token punctuation">(</span>STATUS <span class="token string">"<span class="token interpolation"><span class="token punctuation">${</span><span class="token variable">result</span><span class="token punctuation">}</span></span>"</span><span class="token punctuation">)</span></code></pre>
|
||
<p>正则匹配</p>
|
||
<pre><code class="fenced-code-block language-cmake"><span class="token keyword">string</span><span class="token punctuation">(</span>REGEX MATCH <regular_expression<span class="token punctuation">></span> <output_variable<span class="token punctuation">></span> <input<span class="token punctuation">></span> [<input<span class="token punctuation">></span>...]<span class="token punctuation">)</span>
|
||
<span class="token keyword">string</span><span class="token punctuation">(</span>REGEX MATCHALL <regular_expression<span class="token punctuation">></span> <output_variable<span class="token punctuation">></span> <input<span class="token punctuation">></span> [<input<span class="token punctuation">></span>...]<span class="token punctuation">)</span></code></pre>
|
||
<ul>
|
||
<li><code>regular_expression</code>正则表达式</li>
|
||
<li><code>output_variable</code>存放匹配结果</li>
|
||
<li><code>input</code>原始文本,可以有多项,匹配前会被拼接到一起</li>
|
||
</ul>
|
||
<pre><code class="fenced-code-block language-cmake"><span class="token keyword">string</span><span class="token punctuation">(</span>REGEX MATCH [<span class="token number">0</span>-<span class="token number">9</span>] result <span class="token string">"hello123world456hello444cmake"</span><span class="token punctuation">)</span>
|
||
<span class="token keyword">message</span><span class="token punctuation">(</span>STATUS <span class="token string">"<span class="token interpolation"><span class="token punctuation">${</span><span class="token variable">result</span><span class="token punctuation">}</span></span>"</span><span class="token punctuation">)</span>
|
||
<span class="token keyword">string</span><span class="token punctuation">(</span>REGEX MATCHALL [<span class="token number">0</span>-<span class="token number">9</span>] result <span class="token string">"hello123world456hello444cmake"</span><span class="token punctuation">)</span>
|
||
<span class="token keyword">message</span><span class="token punctuation">(</span>STATUS <span class="token string">"<span class="token interpolation"><span class="token punctuation">${</span><span class="token variable">result</span><span class="token punctuation">}</span></span>"</span><span class="token punctuation">)</span></code></pre>
|
||
<p>正则替换</p>
|
||
<pre><code class="fenced-code-block language-cmake"><span class="token keyword">string</span><span class="token punctuation">(</span>REGEX REPLACE <regular_expression<span class="token punctuation">></span> <replacement_expression<span class="token punctuation">></span> <output_variable<span class="token punctuation">></span> <input<span class="token punctuation">></span> [<input<span class="token punctuation">></span>...]<span class="token punctuation">)</span></code></pre>
|
||
<ul>
|
||
<li><code>regular_expression</code>正则表达式</li>
|
||
<li><code>replacement_expression</code>替换内容</li>
|
||
<li><code>output_variable</code>存放结果</li>
|
||
<li><code>input</code>原始文本,可以有多项,匹配前会被拼接到一起</li>
|
||
</ul>
|
||
<pre><code class="fenced-code-block language-cmake"><span class="token keyword">string</span><span class="token punctuation">(</span>REGEX REPLACE [<span class="token number">0</span>-<span class="token number">9</span>] + result <span class="token string">"hello123world456hello444cmake"</span><span class="token punctuation">)</span>
|
||
<span class="token keyword">message</span><span class="token punctuation">(</span>STATUS <span class="token string">"<span class="token interpolation"><span class="token punctuation">${</span><span class="token variable">result</span><span class="token punctuation">}</span></span>"</span><span class="token punctuation">)</span></code></pre>
|
||
<p> </p>
|
||
<p><strong>修改</strong></p>
|
||
<p>前后追加:</p>
|
||
<pre><code class="fenced-code-block language-cmake"><span class="token keyword">string</span><span class="token punctuation">(</span>APPEND <string_variable<span class="token punctuation">></span> [<input<span class="token punctuation">></span>...]<span class="token punctuation">)</span>
|
||
<span class="token keyword">string</span><span class="token punctuation">(</span>PREPEND <string_variable<span class="token punctuation">></span> [<input<span class="token punctuation">></span>...]<span class="token punctuation">)</span></code></pre>
|
||
<p>……</p>
|
||
<p>更多字符串操作见<a href="https://cmake.org/cmake/help/v3.26/command/string.html">官方文档</a></p>
|
||
<p> </p>
|
||
<h4 class="atx" id="列表操作">列表操作</h4>
|
||
<pre><code class="fenced-code-block language-cmake"><span class="token comment"># 列表长度</span>
|
||
<span class="token keyword">list</span><span class="token punctuation">(</span>LENGTH <list<span class="token punctuation">></span> <out-var<span class="token punctuation">></span><span class="token punctuation">)</span>
|
||
<span class="token comment"># 获取指定索引处的元素</span>
|
||
<span class="token keyword">list</span><span class="token punctuation">(</span>GET <list<span class="token punctuation">></span> <element index<span class="token punctuation">></span> [<index<span class="token punctuation">></span> ...] <out-var<span class="token punctuation">></span><span class="token punctuation">)</span>
|
||
<span class="token comment"># 用指定符号连接列表中的每一项</span>
|
||
<span class="token keyword">list</span><span class="token punctuation">(</span>JOIN <list<span class="token punctuation">></span> <glue<span class="token punctuation">></span> <out-var<span class="token punctuation">></span><span class="token punctuation">)</span>
|
||
<span class="token comment"># 获取子列表</span>
|
||
<span class="token keyword">list</span><span class="token punctuation">(</span>SUBLIST <list<span class="token punctuation">></span> <begin<span class="token punctuation">></span> <length<span class="token punctuation">></span> <out-var<span class="token punctuation">></span><span class="token punctuation">)</span>
|
||
<span class="token comment"># 查询指定元素索引,不存在返回-1</span>
|
||
<span class="token keyword">list</span><span class="token punctuation">(</span>FIND <list<span class="token punctuation">></span> <value<span class="token punctuation">></span> <out-var<span class="token punctuation">></span><span class="token punctuation">)</span>
|
||
|
||
<span class="token comment"># 往列表后追加内容</span>
|
||
<span class="token keyword">list</span><span class="token punctuation">(</span>APPEND <list<span class="token punctuation">></span> [<element<span class="token punctuation">></span>...]<span class="token punctuation">)</span>
|
||
<span class="token comment"># 用正则筛选列表内容</span>
|
||
<span class="token keyword">list</span><span class="token punctuation">(</span>FILTER <list<span class="token punctuation">></span> {INCLUDE | EXCLUDE<span class="token punctuation">}</span> REGEX <regex<span class="token punctuation">></span><span class="token punctuation">)</span>
|
||
<span class="token comment"># 在指定的位置插入元素</span>
|
||
<span class="token keyword">list</span><span class="token punctuation">(</span>INSERT <list<span class="token punctuation">></span> <index<span class="token punctuation">></span> [<element<span class="token punctuation">></span>...]<span class="token punctuation">)</span>
|
||
<span class="token comment"># 移出末尾一个或多个元素</span>
|
||
<span class="token keyword">list</span><span class="token punctuation">(</span>POP_BACK <list<span class="token punctuation">></span> [<out-var<span class="token punctuation">></span>...]<span class="token punctuation">)</span>
|
||
<span class="token comment"># 移出头部一个或多个元素</span>
|
||
<span class="token keyword">list</span><span class="token punctuation">(</span>POP_FRONT <list<span class="token punctuation">></span> [<out-var<span class="token punctuation">></span>...]<span class="token punctuation">)</span>
|
||
<span class="token comment"># 向前追加元素</span>
|
||
<span class="token keyword">list</span><span class="token punctuation">(</span>PREPEND <list<span class="token punctuation">></span> [<element<span class="token punctuation">></span>...]<span class="token punctuation">)</span>
|
||
<span class="token comment"># 删除指定值的元素</span>
|
||
<span class="token keyword">list</span><span class="token punctuation">(</span>REMOVE_ITEM <list<span class="token punctuation">></span> <value<span class="token punctuation">></span>...<span class="token punctuation">)</span>
|
||
<span class="token comment"># 删除指定索引位置的元素</span>
|
||
<span class="token keyword">list</span><span class="token punctuation">(</span>REMOVE_AT <list<span class="token punctuation">></span> <index<span class="token punctuation">></span>...<span class="token punctuation">)</span>
|
||
<span class="token comment"># 删除重复的元素</span>
|
||
<span class="token keyword">list</span><span class="token punctuation">(</span>REMOVE_DUPLICATES <list<span class="token punctuation">></span><span class="token punctuation">)</span>
|
||
<span class="token comment"># 对列表每项进行一些操作</span>
|
||
<span class="token keyword">list</span><span class="token punctuation">(</span>TRANSFORM <list<span class="token punctuation">></span> <ACTION<span class="token punctuation">></span> [<SELECTOR<span class="token punctuation">></span>] [OUTPUT_VARIABLE <output variable<span class="token punctuation">></span>]<span class="token punctuation">)</span>
|
||
|
||
<span class="token comment"># 逆序列表</span>
|
||
<span class="token keyword">list</span><span class="token punctuation">(</span>REVERSE <list<span class="token punctuation">></span><span class="token punctuation">)</span>
|
||
<span class="token comment"># 排序</span>
|
||
<span class="token keyword">list</span><span class="token punctuation">(</span>SORT <list<span class="token punctuation">></span> [COMPARE <compare<span class="token punctuation">></span>] [CASE <case<span class="token punctuation">></span>] [ORDER <order<span class="token punctuation">></span>]<span class="token punctuation">)</span></code></pre>
|
||
<p><code>TRANSFORM</code>中的<code>ACTION</code>有以下操作</p>
|
||
<ul>
|
||
<li><p><code>APPEND</code>, <code>PREPEND</code>:为每一项向前或向后追加内容</p>
|
||
<pre><code class="fenced-code-block language-cmake"><span class="token keyword">set</span><span class="token punctuation">(</span>LS AA <span class="token number">11</span> <span class="token number">11</span> B <span class="token number">22</span> <span class="token number">11</span> C <span class="token number">33</span> D <span class="token number">11</span> <span class="token number">44</span> E<span class="token punctuation">)</span>
|
||
<span class="token keyword">list</span><span class="token punctuation">(</span>TRANSFORM LS APPEND .exe<span class="token punctuation">)</span>
|
||
<span class="token keyword">message</span><span class="token punctuation">(</span>STATUS <span class="token string">"<span class="token interpolation"><span class="token punctuation">${</span><span class="token variable">LS</span><span class="token punctuation">}</span></span>"</span><span class="token punctuation">)</span></code></pre>
|
||
</li>
|
||
<li><p><code>TOUPPER</code>, <code>TOLOWER</code>:转换大小写</p>
|
||
<pre><code class="fenced-code-block language-cmake"><span class="token keyword">set</span><span class="token punctuation">(</span>LS AA <span class="token number">11</span> <span class="token number">11</span> B <span class="token number">22</span> <span class="token number">11</span> C <span class="token number">33</span> D <span class="token number">11</span> <span class="token number">44</span> E<span class="token punctuation">)</span>
|
||
<span class="token keyword">list</span><span class="token punctuation">(</span>TRANSFORM LS TOLOWER<span class="token punctuation">)</span>
|
||
<span class="token keyword">message</span><span class="token punctuation">(</span>STATUS <span class="token string">"<span class="token interpolation"><span class="token punctuation">${</span><span class="token variable">LS</span><span class="token punctuation">}</span></span>"</span><span class="token punctuation">)</span></code></pre>
|
||
</li>
|
||
<li><p><code>STRIP</code>:去除头尾空格</p>
|
||
</li>
|
||
<li><p><code>GENEX_STRIP</code>:去除生成器表达式</p>
|
||
</li>
|
||
<li><p><code>REPLACE</code>:正则替换</p>
|
||
<pre><code class="fenced-code-block language-cmake"><span class="token keyword">set</span><span class="token punctuation">(</span>LS AA <span class="token number">11</span> <span class="token number">11</span> B <span class="token number">22</span> <span class="token number">11</span> C <span class="token number">33</span> D <span class="token number">11</span> <span class="token number">44</span> E<span class="token punctuation">)</span>
|
||
<span class="token keyword">list</span><span class="token punctuation">(</span>TRANSFORM LS REPLACE [<span class="token number">0</span>-<span class="token number">9</span>] <span class="token string">"X"</span><span class="token punctuation">)</span>
|
||
<span class="token keyword">message</span><span class="token punctuation">(</span>STATUS <span class="token string">"<span class="token interpolation"><span class="token punctuation">${</span><span class="token variable">LS</span><span class="token punctuation">}</span></span>"</span><span class="token punctuation">)</span></code></pre>
|
||
</li>
|
||
</ul>
|
||
<p><code>SELECTOR</code>用来决定需要对哪些元素进行操作</p>
|
||
<ul>
|
||
<li><p><code>AT</code>: 按索引指定需要操作的元素</p>
|
||
<pre><code class="fenced-code-block language-cmake"><span class="token keyword">list</span><span class="token punctuation">(</span>TRANSFORM <list<span class="token punctuation">></span> <ACTION<span class="token punctuation">></span> AT <index<span class="token punctuation">></span> [<index<span class="token punctuation">></span> ...] ...<span class="token punctuation">)</span></code></pre>
|
||
<pre><code class="fenced-code-block language-cmake"><span class="token keyword">set</span><span class="token punctuation">(</span>LS AA <span class="token number">11</span> <span class="token number">11</span> B <span class="token number">22</span> <span class="token number">11</span> C <span class="token number">33</span> D <span class="token number">11</span> <span class="token number">44</span> E<span class="token punctuation">)</span>
|
||
<span class="token keyword">list</span><span class="token punctuation">(</span>TRANSFORM LS TOLOWER AT <span class="token number">0</span> <span class="token number">3</span><span class="token punctuation">)</span>
|
||
<span class="token keyword">message</span><span class="token punctuation">(</span>STATUS <span class="token string">"<span class="token interpolation"><span class="token punctuation">${</span><span class="token variable">LS</span><span class="token punctuation">}</span></span>"</span><span class="token punctuation">)</span></code></pre>
|
||
</li>
|
||
<li><p><code>FOR</code>:用指定起点、终点、步长的方式进行操作</p>
|
||
<pre><code class="fenced-code-block language-cmake"><span class="token keyword">list</span><span class="token punctuation">(</span>TRANSFORM <list<span class="token punctuation">></span> <ACTION<span class="token punctuation">></span> FOR <start<span class="token punctuation">></span> <stop<span class="token punctuation">></span> [<step<span class="token punctuation">></span>] ...<span class="token punctuation">)</span></code></pre>
|
||
<pre><code class="fenced-code-block language-cmake"><span class="token keyword">set</span><span class="token punctuation">(</span>LS AA <span class="token number">11</span> <span class="token number">11</span> B <span class="token number">22</span> <span class="token number">11</span> C <span class="token number">33</span> D <span class="token number">11</span> <span class="token number">44</span> E<span class="token punctuation">)</span>
|
||
<span class="token keyword">list</span><span class="token punctuation">(</span>TRANSFORM LS TOLOWER FOR <span class="token number">0</span> <span class="token number">10</span> <span class="token number">2</span><span class="token punctuation">)</span>
|
||
<span class="token keyword">message</span><span class="token punctuation">(</span>STATUS <span class="token string">"<span class="token interpolation"><span class="token punctuation">${</span><span class="token variable">LS</span><span class="token punctuation">}</span></span>"</span><span class="token punctuation">)</span></code></pre>
|
||
</li>
|
||
<li><p><code>REGEX</code>: 用正则匹配来决定需要进行操作的</p>
|
||
<pre><code class="fenced-code-block language-cmake"><span class="token keyword">list</span><span class="token punctuation">(</span>TRANSFORM <list<span class="token punctuation">></span> <ACTION<span class="token punctuation">></span> REGEX <regular_expression<span class="token punctuation">></span> ...<span class="token punctuation">)</span></code></pre>
|
||
<pre><code class="fenced-code-block language-cmake"><span class="token keyword">set</span><span class="token punctuation">(</span>LS AA <span class="token number">11</span> <span class="token number">11</span> B <span class="token number">22</span> <span class="token number">11</span> C <span class="token number">33</span> D <span class="token number">11</span> <span class="token number">44</span> E<span class="token punctuation">)</span>
|
||
<span class="token keyword">list</span><span class="token punctuation">(</span>TRANSFORM LS APPEND .exe REGEX [A-Z]<span class="token punctuation">)</span>
|
||
<span class="token keyword">message</span><span class="token punctuation">(</span>STATUS <span class="token string">"<span class="token interpolation"><span class="token punctuation">${</span><span class="token variable">LS</span><span class="token punctuation">}</span></span>"</span><span class="token punctuation">)</span></code></pre>
|
||
</li>
|
||
</ul>
|
||
<p>更多详情见<a href="https://cmake.org/cmake/help/v3.26/command/list.html">官方文档</a></p>
|
||
<p> </p>
|
||
<h4 class="atx" id="数学表达式">数学表达式</h4>
|
||
<pre><code class="fenced-code-block language-cmake"><span class="token keyword">math</span><span class="token punctuation">(</span>EXPR <variable<span class="token punctuation">></span> <span class="token string">"<expression>"</span> [OUTPUT_FORMAT <format<span class="token punctuation">></span>]<span class="token punctuation">)</span></code></pre>
|
||
<ul>
|
||
<li><code>variable</code>:运算结果</li>
|
||
<li><code>expression</code>:数学表达式</li>
|
||
<li><code>format</code>:输出格式,值为<code>DECIMAL</code>十进制和<code>HEXADECIMAL</code>十六进制</li>
|
||
</ul>
|
||
<pre><code class="fenced-code-block language-cmake"><span class="token keyword">math</span><span class="token punctuation">(</span>EXPR value <span class="token string">"100 * 100"</span> OUTPUT_FORMAT DECIMAL<span class="token punctuation">)</span>
|
||
<span class="token keyword">math</span><span class="token punctuation">(</span>EXPR value <span class="token string">"100 * 0xA"</span> OUTPUT_FORMAT HEXADECIMAL<span class="token punctuation">)</span></code></pre>
|
||
<p> </p>
|
||
<h4 class="atx" id="系统信息查询">系统信息查询</h4>
|
||
<pre><code class="fenced-code-block language-cmake"><span class="token keyword">cmake_host_system_information</span><span class="token punctuation">(</span>RESULT <variable<span class="token punctuation">></span> QUERY <key<span class="token punctuation">></span> ...<span class="token punctuation">)</span></code></pre>
|
||
<ul>
|
||
<li><code>variable</code>存放查询结果</li>
|
||
<li><code>key</code>需要查询的信息,可以为多项,空格隔开</li>
|
||
</ul>
|
||
<p>示例:</p>
|
||
<pre><code class="fenced-code-block language-cmake"><span class="token keyword">cmake_host_system_information</span><span class="token punctuation">(</span>RESULT info QUERY HOSTNAME OS_NAME<span class="token punctuation">)</span>
|
||
<span class="token keyword">message</span><span class="token punctuation">(</span>STATUS <span class="token string">"<span class="token interpolation"><span class="token punctuation">${</span><span class="token variable">info</span><span class="token punctuation">}</span></span>"</span><span class="token punctuation">)</span></code></pre>
|
||
<p>更多细节见<a href="https://cmake.org/cmake/help/v3.26/command/cmake_host_system_information.html">官方文档</a></p>
|
||
<p> </p>
|
||
<h4 class="atx" id="函数">函数</h4>
|
||
<p><strong>1. 函数定义</strong></p>
|
||
<pre><code class="fenced-code-block language-cmake"><span class="token keyword">function</span><span class="token punctuation">(</span><name<span class="token punctuation">></span> [<arg1<span class="token punctuation">></span> ...]<span class="token punctuation">)</span>
|
||
<commands<span class="token punctuation">></span>
|
||
<span class="token keyword">endfunction</span><span class="token punctuation">(</span><span class="token punctuation">)</span></code></pre>
|
||
<p><strong>2. 函数定义会创建一个作用域</strong></p>
|
||
<p>没有指定了变量的<code>PARENT_SCOPE</code>时,在函数内部修改变量值在外部无法访问。</p>
|
||
<pre><code class="fenced-code-block language-cmake"><span class="token keyword">set</span><span class="token punctuation">(</span>OUT_VAR <span class="token number">100</span><span class="token punctuation">)</span>
|
||
|
||
<span class="token keyword">function</span><span class="token punctuation">(</span>func arg1 arg2<span class="token punctuation">)</span>
|
||
<span class="token keyword">set</span><span class="token punctuation">(</span>OUT_VAR <span class="token number">11</span> PARENT_SCOPE<span class="token punctuation">)</span> <span class="token comment"># PARENT_SCOPE修改外部变量,没有PARENT_SCOPE则修改不到外部变量</span>
|
||
<span class="token keyword">message</span><span class="token punctuation">(</span>STATUS <span class="token string">"OUT_VAR IN func = <span class="token interpolation"><span class="token punctuation">${</span><span class="token variable">OUT_VAR</span><span class="token punctuation">}</span></span>"</span><span class="token punctuation">)</span>
|
||
<span class="token keyword">endfunction</span><span class="token punctuation">(</span>func<span class="token punctuation">)</span>
|
||
|
||
<span class="token function">func</span><span class="token punctuation">(</span><span class="token number">1</span> <span class="token number">2</span><span class="token punctuation">)</span>
|
||
<span class="token keyword">message</span><span class="token punctuation">(</span>STATUS <span class="token string">"OUT_VAR = <span class="token interpolation"><span class="token punctuation">${</span><span class="token variable">OUT_VAR</span><span class="token punctuation">}</span></span>"</span><span class="token punctuation">)</span></code></pre>
|
||
<p><strong>3. 函数支持可变参数</strong></p>
|
||
<p>函数可以在定义的时候指定一些参数名,但在使用的时候可以传递比已定义参数数量多的数据。可以用以下几个变量来获取参数:</p>
|
||
<ul>
|
||
<li><code>ARGC</code> :参数数量</li>
|
||
<li><code>ARGV</code> :所有参数组成的列表</li>
|
||
<li><code>ARGN</code>:没有命名的参数列表</li>
|
||
<li><code>ARGV0,ARGV1,ARGV2,...ARGVn</code>:分别表示第0、1、2、……n个参数</li>
|
||
</ul>
|
||
<pre><code class="fenced-code-block language-cmake"><span class="token keyword">function</span><span class="token punctuation">(</span>func arg1 arg2<span class="token punctuation">)</span>
|
||
<span class="token keyword">message</span><span class="token punctuation">(</span>STATUS <span class="token string">"ARGC = <span class="token interpolation"><span class="token punctuation">${</span><span class="token variable">ARGC</span><span class="token punctuation">}</span></span>"</span><span class="token punctuation">)</span>
|
||
<span class="token keyword">message</span><span class="token punctuation">(</span>STATUS <span class="token string">"ARGV = <span class="token interpolation"><span class="token punctuation">${</span><span class="token variable">ARGV</span><span class="token punctuation">}</span></span>"</span><span class="token punctuation">)</span>
|
||
<span class="token keyword">message</span><span class="token punctuation">(</span>STATUS <span class="token string">"ARGN = <span class="token interpolation"><span class="token punctuation">${</span><span class="token variable">ARGN</span><span class="token punctuation">}</span></span>"</span><span class="token punctuation">)</span>
|
||
<span class="token keyword">message</span><span class="token punctuation">(</span>STATUS <span class="token string">"arg1 = <span class="token interpolation"><span class="token punctuation">${</span><span class="token variable">arg1</span><span class="token punctuation">}</span></span>"</span><span class="token punctuation">)</span>
|
||
<span class="token keyword">message</span><span class="token punctuation">(</span>STATUS <span class="token string">"arg2 = <span class="token interpolation"><span class="token punctuation">${</span><span class="token variable">arg3</span><span class="token punctuation">}</span></span>"</span><span class="token punctuation">)</span>
|
||
<span class="token keyword">message</span><span class="token punctuation">(</span>STATUS <span class="token string">"ARGV2 = <span class="token interpolation"><span class="token punctuation">${</span><span class="token variable">ARGV2</span><span class="token punctuation">}</span></span>"</span><span class="token punctuation">)</span>
|
||
|
||
<span class="token keyword">foreach</span><span class="token punctuation">(</span>ARG IN LISTS ARGN<span class="token punctuation">)</span>
|
||
<span class="token keyword">message</span><span class="token punctuation">(</span>STATUS <span class="token string">"ARG = <span class="token interpolation"><span class="token punctuation">${</span><span class="token variable">ARG</span><span class="token punctuation">}</span></span>"</span><span class="token punctuation">)</span>
|
||
<span class="token keyword">endforeach</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
|
||
<span class="token keyword">endfunction</span><span class="token punctuation">(</span>func<span class="token punctuation">)</span>
|
||
|
||
<span class="token function">func</span><span class="token punctuation">(</span><span class="token number">1</span> <span class="token number">2</span> <span class="token number">3</span> <span class="token number">4</span> <span class="token number">5</span> <span class="token number">6</span> <span class="token number">7</span><span class="token punctuation">)</span></code></pre>
|
||
<p><strong>4. 参数含关键字的函数</strong></p>
|
||
<p>例如函数<code>target_link_library</code>中的<code>PUBLIC | PRIVATE | INTERFACE</code>即为关键字,如果需要在自定义函数中使用类似的关键字,需要用到<code>cmake_parse_arguments</code></p>
|
||
<pre><code class="fenced-code-block language-cmake"><span class="token keyword">cmake_parse_arguments</span><span class="token punctuation">(</span><prefix<span class="token punctuation">></span> <options<span class="token punctuation">></span> <one_value_keywords<span class="token punctuation">></span> <multi_value_keywords<span class="token punctuation">></span> <args<span class="token punctuation">></span>...<span class="token punctuation">)</span>
|
||
|
||
<span class="token keyword">cmake_parse_arguments</span><span class="token punctuation">(</span>PARSE_ARGV <N<span class="token punctuation">></span> <prefix<span class="token punctuation">></span> <options<span class="token punctuation">></span> <one_value_keywords<span class="token punctuation">></span> <multi_value_keywords<span class="token punctuation">></span><span class="token punctuation">)</span></code></pre>
|
||
<p>第一种方式可以在函数和宏中使用,第二种方式只能在函数中使用。第二种方式自动从<code>ARGV</code>里获取函数参数值,从第<code><N></code>个参数开始解析。其他参数如下:</p>
|
||
<ul>
|
||
<li><code>prefix</code>:前缀,可以用<code>prefix_<KEYWORD></code>的形式访问对应的参数值</li>
|
||
<li><code>options</code>:不接收数据的关键字列表</li>
|
||
<li><code>one_value_keywords</code>:接收一项数据的关键字列表</li>
|
||
<li><code>multi_value_keywords</code>:接收多项数据关键字列表</li>
|
||
<li><code>args</code>:函数的参数,可以直接放<code>${ARGV}</code>或<code>${ARGN}</code></li>
|
||
</ul>
|
||
<p>示例:</p>
|
||
<p>不接收数据的关键字函数</p>
|
||
<pre><code class="fenced-code-block language-cmake"><span class="token keyword">function</span><span class="token punctuation">(</span>test_parse<span class="token punctuation">)</span>
|
||
<span class="token keyword">cmake_parse_arguments</span><span class="token punctuation">(</span><span class="token string">"CPA"</span> <span class="token string">"INSTALL_INCLUDE;INSTALL_LIB"</span> <span class="token string">""</span> <span class="token string">""</span> <span class="token punctuation">${</span>ARGV<span class="token punctuation">}</span><span class="token punctuation">)</span>
|
||
<span class="token keyword">message</span><span class="token punctuation">(</span>STATUS <span class="token string">"INSTALL_INCLUDE = <span class="token interpolation"><span class="token punctuation">${</span><span class="token variable">CPA_INSTALL_INCLUDE</span><span class="token punctuation">}</span></span> INSTALL_LIB = <span class="token interpolation"><span class="token punctuation">${</span><span class="token variable">CPA_INSTALL_LIB</span><span class="token punctuation">}</span></span>"</span><span class="token punctuation">)</span>
|
||
<span class="token keyword">endfunction</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
|
||
|
||
<span class="token function">test_parse</span><span class="token punctuation">(</span>INSTALL_LIB<span class="token punctuation">)</span></code></pre>
|
||
<p>接收一项数据的关键字函数</p>
|
||
<pre><code class="fenced-code-block language-cmake"><span class="token keyword">function</span><span class="token punctuation">(</span>test_parse<span class="token punctuation">)</span>
|
||
<span class="token keyword">cmake_parse_arguments</span><span class="token punctuation">(</span><span class="token string">"CPA"</span> <span class="token string">""</span> <span class="token string">"FILE"</span> <span class="token string">""</span> <span class="token punctuation">${</span>ARGV<span class="token punctuation">}</span><span class="token punctuation">)</span>
|
||
<span class="token keyword">message</span><span class="token punctuation">(</span>STATUS <span class="token string">"FILE = <span class="token interpolation"><span class="token punctuation">${</span><span class="token variable">CPA_FILE</span><span class="token punctuation">}</span></span>"</span><span class="token punctuation">)</span>
|
||
<span class="token keyword">endfunction</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
|
||
|
||
<span class="token function">test_parse</span><span class="token punctuation">(</span>FILE test.cpp<span class="token punctuation">)</span></code></pre>
|
||
<p>接收多项数据的关键字函数</p>
|
||
<pre><code class="fenced-code-block language-cmake"><span class="token keyword">function</span><span class="token punctuation">(</span>test_parse<span class="token punctuation">)</span>
|
||
<span class="token keyword">cmake_parse_arguments</span><span class="token punctuation">(</span><span class="token string">"CPA"</span> <span class="token string">""</span> <span class="token string">""</span> <span class="token string">"LIBS"</span> <span class="token punctuation">${</span>ARGV<span class="token punctuation">}</span><span class="token punctuation">)</span>
|
||
<span class="token keyword">message</span><span class="token punctuation">(</span>STATUS <span class="token string">"LIBS = <span class="token interpolation"><span class="token punctuation">${</span><span class="token variable">CPA_LIBS</span><span class="token punctuation">}</span></span>"</span><span class="token punctuation">)</span>
|
||
<span class="token keyword">endfunction</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
|
||
|
||
<span class="token function">test_parse</span><span class="token punctuation">(</span>LIBS libmath.a libpng.a libtool.a<span class="token punctuation">)</span></code></pre>
|
||
<p>综合示例</p>
|
||
<pre><code class="fenced-code-block language-cmake"><span class="token keyword">function</span><span class="token punctuation">(</span>test_parse<span class="token punctuation">)</span>
|
||
<span class="token keyword">cmake_parse_arguments</span><span class="token punctuation">(</span><span class="token string">"CPA"</span> <span class="token string">"INSTALL_INCLUDES;INSTALL_LIBS"</span> <span class="token string">"CONFIG_FILE"</span> <span class="token string">"LIBS;CPPFILES;HEADFILES"</span> <span class="token punctuation">${</span>ARGV<span class="token punctuation">}</span><span class="token punctuation">)</span>
|
||
<span class="token keyword">message</span><span class="token punctuation">(</span>STATUS <span class="token string">"INSTALL_INCLUDES = <span class="token interpolation"><span class="token punctuation">${</span><span class="token variable">CPA_INSTALL_INCLUDES</span><span class="token punctuation">}</span></span>"</span><span class="token punctuation">)</span>
|
||
<span class="token keyword">message</span><span class="token punctuation">(</span>STATUS <span class="token string">"INSTALL_LIBS = <span class="token interpolation"><span class="token punctuation">${</span><span class="token variable">CPA_INSTALL_LIBS</span><span class="token punctuation">}</span></span>"</span><span class="token punctuation">)</span>
|
||
<span class="token keyword">message</span><span class="token punctuation">(</span>STATUS <span class="token string">"CONFIG_FILE = <span class="token interpolation"><span class="token punctuation">${</span><span class="token variable">CPA_CONFIG_FILE</span><span class="token punctuation">}</span></span>"</span><span class="token punctuation">)</span>
|
||
<span class="token keyword">message</span><span class="token punctuation">(</span>STATUS <span class="token string">"LIBS = <span class="token interpolation"><span class="token punctuation">${</span><span class="token variable">CPA_LIBS</span><span class="token punctuation">}</span></span>"</span><span class="token punctuation">)</span>
|
||
<span class="token keyword">message</span><span class="token punctuation">(</span>STATUS <span class="token string">"CPPFILES = <span class="token interpolation"><span class="token punctuation">${</span><span class="token variable">CPA_CPPFILES</span><span class="token punctuation">}</span></span>"</span><span class="token punctuation">)</span>
|
||
<span class="token keyword">message</span><span class="token punctuation">(</span>STATUS <span class="token string">"HEADFILES = <span class="token interpolation"><span class="token punctuation">${</span><span class="token variable">CPA_HEADFILES</span><span class="token punctuation">}</span></span>"</span><span class="token punctuation">)</span>
|
||
<span class="token keyword">endfunction</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
|
||
|
||
<span class="token function">test_parse</span><span class="token punctuation">(</span>LIBS libmath.a libfun.a CONFIG_FILE config.cmake CPPFILES main.cpp hello.cpp INSTALL_LIBS<span class="token punctuation">)</span></code></pre>
|
||
<h4 class="atx" id="宏定义">宏定义</h4>
|
||
<p>CMake中宏指令定义与用法类似函数的定义与用法。区别类似于C语言中宏函数定义与普通函数定义。</p>
|
||
<pre><code class="fenced-code-block language-cmake"><span class="token keyword">macro</span><span class="token punctuation">(</span><name<span class="token punctuation">></span> [<arg1<span class="token punctuation">></span> ...]<span class="token punctuation">)</span>
|
||
<commands<span class="token punctuation">></span>
|
||
<span class="token keyword">endmacro</span><span class="token punctuation">(</span><span class="token punctuation">)</span></code></pre>
|
||
<pre><code class="fenced-code-block language-cmake"><span class="token keyword">macro</span><span class="token punctuation">(</span>macrofun arg1 arg2<span class="token punctuation">)</span>
|
||
<span class="token keyword">message</span><span class="token punctuation">(</span>STATUS <span class="token string">"<span class="token interpolation"><span class="token punctuation">${</span><span class="token variable">arg1</span><span class="token punctuation">}</span></span> - <span class="token interpolation"><span class="token punctuation">${</span><span class="token variable">arg2</span><span class="token punctuation">}</span></span>"</span><span class="token punctuation">)</span>
|
||
<span class="token keyword">endmacro</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
|
||
|
||
<span class="token function">macrofun</span><span class="token punctuation">(</span><span class="token number">100</span> hello<span class="token punctuation">)</span>
|
||
<span class="token function">MACROFUN</span><span class="token punctuation">(</span><span class="token number">200</span> nice<span class="token punctuation">)</span> <span class="token comment"># 不区分大小写</span>
|
||
<span class="token function">cmake_language</span><span class="token punctuation">(</span>CALL macrofun <span class="token number">300</span> Hug<span class="token punctuation">)</span> <span class="token comment"># 另外的调用方式</span></code></pre>
|
||
<p>宏定义中可变参数与关键字参数用法与函数相同。</p>
|
||
<p>宏定义与函数不同点:</p>
|
||
<ul>
|
||
<li>宏定义不会创建新的使作用域</li>
|
||
<li>函数中所有参数、包括<code>ARGC</code>、<code>ARGV</code>等都是变量,但宏定义中这些参数不是变量,因此不能用类似<code>if(DEFINED ...)</code>的形式来检测宏定义中对应的参数是否已定义</li>
|
||
<li>宏定义的调用类似于把宏的内容直接复制到调用的地方</li>
|
||
</ul>
|
||
<p> </p>
|
||
<h4 class="atx" id="configure_file">configure_file</h4>
|
||
<pre><code class="fenced-code-block language-cmake"><span class="token keyword">configure_file</span><span class="token punctuation">(</span><input<span class="token punctuation">></span> <output<span class="token punctuation">></span>
|
||
[NO_SOURCE_PERMISSIONS | USE_SOURCE_PERMISSIONS | FILE_PERMISSIONS <perms<span class="token punctuation">></span>...]
|
||
[COPYONLY] [ESCAPE_QUOTES] [@ONLY]
|
||
[NEWLINE_STYLE [<span class="token variable">UNIX</span>|DOS|<span class="token variable">WIN32</span>|LF|CRLF] ]<span class="token punctuation">)</span></code></pre>
|
||
<p>后续的参数分为三个部分:</p>
|
||
<ul>
|
||
<li>输出文件权限(主要用于Linux及其他类Unix系统)<ul>
|
||
<li><code>NO_SOURCE_PERMISSIONS</code>不使用源文件权限,使用默认644权限</li>
|
||
<li><code>USE_SOURCE_PERMISSIONS</code>保持与源文件权限一致</li>
|
||
<li><code>FILE_PERMISSIONS</code>自定义权限</li>
|
||
</ul>
|
||
</li>
|
||
<li>模板处理行为<ul>
|
||
<li><code>COPYONLY</code>只复制,不进行变量替换</li>
|
||
<li><code>ESCAPE_QUOTES</code>是否对双引号进行转义。不能和<code>NEWLINE_STYLE</code>同时使用</li>
|
||
<li><code>@ONLY</code>只替换<code>@VAR@</code>形式的变量,<code>${VAR}</code>形式的不进行替换</li>
|
||
</ul>
|
||
</li>
|
||
<li>换行方式<ul>
|
||
<li><code>UNIX</code>和 <code>LF</code> 用 <code>\n</code> 换行</li>
|
||
<li><code>DOS</code>、 <code>WIN32</code>、 <code>CRLF</code> 用 <code>\r\n</code> 换行</li>
|
||
</ul>
|
||
</li>
|
||
</ul>
|
||
<p> </p>
|
||
<h4 class="atx" id="文件操作">文件操作</h4>
|
||
<p>文件读取</p>
|
||
<pre><code class="fenced-code-block language-cmake"><span class="token keyword">file</span><span class="token punctuation">(</span>READ <filename<span class="token punctuation">></span> <variable<span class="token punctuation">></span> [OFFSET <offset<span class="token punctuation">></span>] [LIMIT <max-in<span class="token punctuation">></span>] [HEX]<span class="token punctuation">)</span></code></pre>
|
||
<ul>
|
||
<li><code>filename</code>:要读取的文件名</li>
|
||
<li><code>variable</code>:保存读取内容的变量名</li>
|
||
<li><code>offset</code>:开始读的位置</li>
|
||
<li><code>max-in</code>:读取的字节数</li>
|
||
<li><code>HEX</code>:是否转为十六进制,在读取二进制文件时常用</li>
|
||
</ul>
|
||
<pre><code class="fenced-code-block language-cmake"><span class="token keyword">file</span><span class="token punctuation">(</span>READ config.h.in result OFFSET <span class="token number">15</span> LIMIT <span class="token number">20</span> HEX<span class="token punctuation">)</span>
|
||
|
||
<span class="token keyword">message</span><span class="token punctuation">(</span>STATUS <span class="token string">"<span class="token interpolation"><span class="token punctuation">${</span><span class="token variable">result</span><span class="token punctuation">}</span></span>"</span><span class="token punctuation">)</span></code></pre>
|
||
<p> </p>
|
||
<p>文件写入</p>
|
||
<pre><code class="fenced-code-block language-cmake"><span class="token keyword">file</span><span class="token punctuation">(</span>WRITE <filename<span class="token punctuation">></span> <content<span class="token punctuation">></span>...<span class="token punctuation">)</span> <span class="token comment"># 写入</span>
|
||
<span class="token keyword">file</span><span class="token punctuation">(</span>APPEND <filename<span class="token punctuation">></span> <content<span class="token punctuation">></span>...<span class="token punctuation">)</span> <span class="token comment"># 追加</span></code></pre>
|
||
<pre><code class="fenced-code-block language-cmake"><span class="token keyword">file</span><span class="token punctuation">(</span>APPEND config.h <span class="token string">"Hello Worl from cmake file"</span> <span class="token string">"123456 555"</span><span class="token punctuation">)</span></code></pre>
|
||
<p>更多文件操作见<a href="https://cmake.org/cmake/help/v3.26/command/file.html">官方文档</a></p>
|
||
<p> </p>
|
||
<h4 class="atx" id="路径操作">路径操作</h4>
|
||
<p>详细介绍及例子见<a href="https://cmake.org/cmake/help/v3.26/command/cmake_path.html">官方文档</a></p>
|
||
<p>一些示例:</p>
|
||
<pre><code class="fenced-code-block language-cmake"><span class="token keyword">set</span><span class="token punctuation">(</span>path <span class="token string">"./config.h"</span><span class="token punctuation">)</span>
|
||
<span class="token keyword">file</span><span class="token punctuation">(</span>REAL_PATH <span class="token punctuation">${</span>path<span class="token punctuation">}</span> path<span class="token punctuation">)</span> <span class="token comment"># 将相对路径转为绝对路径</span>
|
||
|
||
<span class="token function">cmake_path</span><span class="token punctuation">(</span>GET path EXTENSION result<span class="token punctuation">)</span> <span class="token comment"># 取出文件后缀部分</span>
|
||
<span class="token keyword">message</span><span class="token punctuation">(</span>STATUS <span class="token string">"<span class="token interpolation"><span class="token punctuation">${</span><span class="token variable">result</span><span class="token punctuation">}</span></span>"</span><span class="token punctuation">)</span>
|
||
|
||
<span class="token function">cmake_path</span><span class="token punctuation">(</span>GET path FILENAME result<span class="token punctuation">)</span> <span class="token comment"># 取出文件名称部分</span>
|
||
<span class="token keyword">message</span><span class="token punctuation">(</span>STATUS <span class="token string">"<span class="token interpolation"><span class="token punctuation">${</span><span class="token variable">result</span><span class="token punctuation">}</span></span>"</span><span class="token punctuation">)</span></code></pre>
|
||
<p> </p>
|
||
<h4 class="atx" id="文件查找">文件查找</h4>
|
||
<p><strong>在指定路径下查找指定文件</strong></p>
|
||
<pre><code class="fenced-code-block language-cmake"><span class="token keyword">find_file</span> <span class="token punctuation">(</span><VAR<span class="token punctuation">></span> name1 [path1 path2 ...]<span class="token punctuation">)</span></code></pre>
|
||
<ul>
|
||
<li><code>VAR</code>:存放查找结果,找到则为文件绝对路径,找不到则为<code><VAR>-NOTFOUND</code></li>
|
||
<li><code>name1</code>:需要查找的文件名</li>
|
||
<li><code>path</code>:指定查找路径,可以有多个</li>
|
||
</ul>
|
||
<p>更多操作见<a href="https://cmake.org/cmake/help/v3.26/command/find_file.html">官方文档</a></p>
|
||
<p> </p>
|
||
<p><strong>在指定路径下查找指定的库文件</strong></p>
|
||
<pre><code class="fenced-code-block language-cmake"><span class="token keyword">find_library</span> <span class="token punctuation">(</span><VAR<span class="token punctuation">></span> name1 [path1 path2 ...]<span class="token punctuation">)</span></code></pre>
|
||
<p>参数与操作与文件查找相同。不同点在于库文件名可以简写,如<code>libMathFunctions.a</code>可以写为<code>MathFunctions</code>。</p>
|
||
<p>更多操作见<a href="https://cmake.org/cmake/help/v3.26/command/find_library.html">官方文档</a></p>
|
||
<p> </p>
|
||
<p><strong>在指定路径下查找指定的目录</strong></p>
|
||
<pre><code class="fenced-code-block language-cmake"><span class="token keyword">find_path</span> <span class="token punctuation">(</span><VAR<span class="token punctuation">></span> name1 [path1 path2 ...]<span class="token punctuation">)</span></code></pre>
|
||
<p>用法同上。更多操作见<a href="https://cmake.org/cmake/help/v3.26/command/find_path.html">官方文档</a></p>
|
||
<p> </p>
|
||
<h4 class="atx" id="find_package">find_package</h4>
|
||
<pre><code class="fenced-code-block language-cmake"><span class="token keyword">find_package</span><span class="token punctuation">(</span><PackageName<span class="token punctuation">></span> [version] [EXACT] [QUIET] [MODULE]
|
||
[REQUIRED] [[COMPONENTS] [components...]] <span class="token punctuation">)</span></code></pre>
|
||
<ul>
|
||
<li><p><code>PackageName</code>:需要查找的库名</p>
|
||
</li>
|
||
<li><p><code>version</code>:版本号</p>
|
||
</li>
|
||
<li><p><code>EXACT</code>:是否要精确匹配版本号</p>
|
||
</li>
|
||
<li><p><code>REQUIRED</code>:是否为必需的,加上之后如果找不到则会报错</p>
|
||
</li>
|
||
<li><p><code>COMPONENTS</code>:对于分了很多组件的包,可以指定组件</p>
|
||
</li>
|
||
</ul>
|
||
<p> </p>
|
||
<h3 class="atx" id="项目指令">项目指令</h3>
|
||
<h4 class="atx" id="add_dependencies">add_dependencies</h4>
|
||
<p>添加同级目标之间的相互依赖,保证依赖先生成。</p>
|
||
<p> </p>
|
||
<h4 class="atx" id="add_custom_target">add_custom_target</h4>
|
||
<p>添加自定义目标。</p>
|
||
<p> </p>
|
||
<h4 class="atx" id="属性设置">属性设置</h4>
|
||
<p>设置</p>
|
||
<pre><code class="fenced-code-block language-cmake"><span class="token keyword">set_property</span><span class="token punctuation">(</span><GLOBAL |
|
||
DIRECTORY [<dir<span class="token punctuation">></span>] |
|
||
TARGET [<target1<span class="token punctuation">></span> ...] |
|
||
SOURCE [<src1<span class="token punctuation">></span> ...]
|
||
[DIRECTORY <dirs<span class="token punctuation">></span> ...]
|
||
[TARGET_DIRECTORY <targets<span class="token punctuation">></span> ...] |
|
||
INSTALL [<file1<span class="token punctuation">></span> ...] |
|
||
TEST [<test1<span class="token punctuation">></span> ...] |
|
||
<span class="token variable">CACHE</span> [<entry1<span class="token punctuation">></span> ...] <span class="token punctuation">></span>
|
||
[APPEND] [APPEND_STRING]
|
||
PROPERTY <name<span class="token punctuation">></span> [<value1<span class="token punctuation">></span> ...]<span class="token punctuation">)</span></code></pre>
|
||
<p>读取</p>
|
||
<pre><code class="fenced-code-block language-cmake"><span class="token keyword">get_property</span><span class="token punctuation">(</span><variable<span class="token punctuation">></span>
|
||
<GLOBAL |
|
||
DIRECTORY [<dir<span class="token punctuation">></span>] |
|
||
TARGET <target<span class="token punctuation">></span> |
|
||
SOURCE <source<span class="token punctuation">></span>
|
||
[DIRECTORY <dir<span class="token punctuation">></span> | TARGET_DIRECTORY <target<span class="token punctuation">></span>] |
|
||
INSTALL <file<span class="token punctuation">></span> |
|
||
TEST <test<span class="token punctuation">></span> |
|
||
<span class="token variable">CACHE</span> <entry<span class="token punctuation">></span> |
|
||
VARIABLE <span class="token punctuation">></span>
|
||
PROPERTY <name<span class="token punctuation">></span>
|
||
[SET | <span class="token operator">DEFINED</span> | BRIEF_DOCS | FULL_DOCS]<span class="token punctuation">)</span></code></pre>
|
||
<ul>
|
||
<li><p><code>SET</code>:将<code><variable></code>设为该属性是否已设置</p>
|
||
</li>
|
||
<li><p><code>DEFINED</code>:将<code><variable></code>设为该属性是否已定义</p>
|
||
</li>
|
||
</ul>
|
||
<p><strong>全局属性</strong></p>
|
||
<pre><code class="fenced-code-block language-cmake"><span class="token keyword">set_property</span><span class="token punctuation">(</span>GLOBAL PROPERTY <name<span class="token punctuation">></span> [<value1<span class="token punctuation">></span> ...]<span class="token punctuation">)</span>
|
||
|
||
<span class="token keyword">get_property</span><span class="token punctuation">(</span><variable<span class="token punctuation">></span> GLOBAL PROPERTY <name<span class="token punctuation">></span><span class="token punctuation">)</span>
|
||
<span class="token keyword">get_cmake_property</span><span class="token punctuation">(</span><var<span class="token punctuation">></span> <property<span class="token punctuation">></span><span class="token punctuation">)</span></code></pre>
|
||
<p><strong>目录属性</strong></p>
|
||
<pre><code class="fenced-code-block language-cmake"><span class="token keyword">set_property</span><span class="token punctuation">(</span>DIRECTORY [<dir<span class="token punctuation">></span>] PROPERTY <name<span class="token punctuation">></span> [<value1<span class="token punctuation">></span> ...]<span class="token punctuation">)</span>
|
||
<span class="token keyword">set_directory_properties</span><span class="token punctuation">(</span><span class="token namespace">PROPERTIES</span> prop1 value1 [prop2 value2] ...<span class="token punctuation">)</span>
|
||
|
||
<span class="token keyword">get_property</span><span class="token punctuation">(</span><variable<span class="token punctuation">></span> DIRECTORY [<dir<span class="token punctuation">></span>] PROPERTY <name<span class="token punctuation">></span><span class="token punctuation">)</span>
|
||
<span class="token keyword">get_directory_property</span><span class="token punctuation">(</span><variable<span class="token punctuation">></span> [DIRECTORY <dir<span class="token punctuation">></span>] <prop-name<span class="token punctuation">></span><span class="token punctuation">)</span></code></pre>
|
||
<p><strong>目标属性</strong></p>
|
||
<pre><code class="fenced-code-block language-cmake"><span class="token keyword">set_property</span><span class="token punctuation">(</span>TARGET <target1<span class="token punctuation">></span> PROPERTY <name<span class="token punctuation">></span> [<value1<span class="token punctuation">></span> ...]<span class="token punctuation">)</span>
|
||
<span class="token keyword">set_target_properties</span><span class="token punctuation">(</span>target1... <span class="token namespace">PROPERTIES</span> prop1 value1 prop2 value2 ...<span class="token punctuation">)</span>
|
||
|
||
<span class="token keyword">get_property</span><span class="token punctuation">(</span><variable<span class="token punctuation">></span> TARGET <target<span class="token punctuation">></span> PROPERTY <name<span class="token punctuation">></span><span class="token punctuation">)</span>
|
||
<span class="token keyword">get_target_property</span><span class="token punctuation">(</span><VAR<span class="token punctuation">></span> target property<span class="token punctuation">)</span></code></pre>
|
||
<p><strong>源文件属性</strong></p>
|
||
<pre><code class="fenced-code-block language-cmake"><span class="token keyword">set_property</span><span class="token punctuation">(</span>SOURCE [<src1<span class="token punctuation">></span> ...] [DIRECTORY <dirs<span class="token punctuation">></span> ...] [TARGET_DIRECTORY <targets<span class="token punctuation">></span> ...] PROPERTY <name<span class="token punctuation">></span> [<value1<span class="token punctuation">></span> ...]<span class="token punctuation">)</span>
|
||
<span class="token keyword">set_source_files_properties</span><span class="token punctuation">(</span><files<span class="token punctuation">></span> ...
|
||
[DIRECTORY <dirs<span class="token punctuation">></span> ...]
|
||
[TARGET_DIRECTORY <targets<span class="token punctuation">></span> ...]
|
||
<span class="token namespace">PROPERTIES</span> <prop1<span class="token punctuation">></span> <value1<span class="token punctuation">></span>
|
||
[<prop2<span class="token punctuation">></span> <value2<span class="token punctuation">></span>] ...<span class="token punctuation">)</span>
|
||
|
||
|
||
<span class="token keyword">get_property</span><span class="token punctuation">(</span><variable<span class="token punctuation">></span> SOURCE <source<span class="token punctuation">></span> PROPERTY <name<span class="token punctuation">></span><span class="token punctuation">)</span>
|
||
<span class="token keyword">get_source_file_property</span><span class="token punctuation">(</span><variable<span class="token punctuation">></span> <file<span class="token punctuation">></span>
|
||
[DIRECTORY <dir<span class="token punctuation">></span> | TARGET_DIRECTORY <target<span class="token punctuation">></span>]
|
||
<property<span class="token punctuation">></span><span class="token punctuation">)</span></code></pre>
|
||
<p><strong>测试属性</strong></p>
|
||
<pre><code class="fenced-code-block language-cmake"><span class="token keyword">set_tests_properties</span><span class="token punctuation">(</span>test1 [test2...] <span class="token namespace">PROPERTIES</span> prop1 value1 prop2 value2<span class="token punctuation">)</span>
|
||
|
||
<span class="token keyword">get_test_property</span><span class="token punctuation">(</span>test property VAR<span class="token punctuation">)</span></code></pre>
|
||
<h4 class="atx" id="添加预编译定义">添加预编译定义</h4>
|
||
<pre><code class="fenced-code-block language-cmake"><span class="token keyword">add_compile_definitions</span><span class="token punctuation">(</span><definition<span class="token punctuation">></span> ...<span class="token punctuation">)</span>
|
||
|
||
<span class="token keyword">target_compile_definitions</span><span class="token punctuation">(</span><target<span class="token punctuation">></span>
|
||
<<span class="token namespace">INTERFACE</span>|<span class="token namespace">PUBLIC</span>|<span class="token namespace">PRIVATE</span><span class="token punctuation">></span> [items1...]
|
||
[<<span class="token namespace">INTERFACE</span>|<span class="token namespace">PUBLIC</span>|<span class="token namespace">PRIVATE</span><span class="token punctuation">></span> [items2...] ...]<span class="token punctuation">)</span></code></pre>
|
||
<p>可用生成器表达式。</p>
|
||
<p>示例:</p>
|
||
<pre><code class="fenced-code-block language-cmake"><span class="token keyword">target_compile_definitions</span><span class="token punctuation">(</span>Tutorial <span class="token namespace">PUBLIC</span> HAVE_MAX_NUM MAX_NUM=<span class="token number">100</span><span class="token punctuation">)</span>
|
||
<span class="token keyword">add_compile_definitions</span><span class="token punctuation">(</span>HAVE_MIN_NUM MIN_NUM=-<span class="token number">999</span><span class="token punctuation">)</span></code></pre>
|
||
<h4 class="atx" id="添加编译选项">添加编译选项</h4>
|
||
<pre><code class="fenced-code-block language-cmake"><span class="token keyword">add_compile_options</span><span class="token punctuation">(</span><option<span class="token punctuation">></span> ...<span class="token punctuation">)</span>
|
||
<span class="token keyword">target_compile_options</span><span class="token punctuation">(</span><target<span class="token punctuation">></span> [BEFORE]
|
||
<<span class="token namespace">INTERFACE</span>|<span class="token namespace">PUBLIC</span>|<span class="token namespace">PRIVATE</span><span class="token punctuation">></span> [items1...]
|
||
[<<span class="token namespace">INTERFACE</span>|<span class="token namespace">PUBLIC</span>|<span class="token namespace">PRIVATE</span><span class="token punctuation">></span> [items2...] ...]<span class="token punctuation">)</span></code></pre>
|
||
<p>可用生成器表达式。</p>
|
||
<pre><code class="fenced-code-block language-cmake"><span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token variable">MSVC</span><span class="token punctuation">)</span>
|
||
<span class="token keyword">add_compile_options</span><span class="token punctuation">(</span>/W4<span class="token punctuation">)</span>
|
||
<span class="token keyword">else</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
|
||
<span class="token keyword">add_compile_options</span><span class="token punctuation">(</span>-Wall -Wextra -Wpedantic<span class="token punctuation">)</span>
|
||
<span class="token keyword">endif</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
|
||
|
||
|
||
|
||
<span class="token keyword">target_compile_options</span><span class="token punctuation">(</span>tutorial_compiler_flags <span class="token namespace">INTERFACE</span>
|
||
<span class="token string">"$<<span class="token interpolation"><span class="token punctuation">${</span><span class="token variable">gcc_like_cxx</span><span class="token punctuation">}</span></span>:$<BUILD_INTERFACE:-Wall;-Wextra;-Wshadow;-Wformat=2;-Wunused>>"</span>
|
||
<span class="token string">"$<<span class="token interpolation"><span class="token punctuation">${</span><span class="token variable">msvc_cxx</span><span class="token punctuation">}</span></span>:$<BUILD_INTERFACE:-W3>>"</span>
|
||
<span class="token punctuation">)</span></code></pre>
|
||
<h4 class="atx" id="mark_as_advanced">mark_as_advanced</h4>
|
||
<p>将缓存变量设为高级,在<code>cmake-gui</code>需要选择高级才能看到。</p>
|
||
<h4 class="atx" id="target_sources">target_sources</h4>
|
||
<p>为目标添加源文件</p>
|
||
<p> </p>
|
||
<h3 class="atx" id="生成器表达式">生成器表达式</h3>
|
||
<h1 class="atx" id="下一步">下一步</h1>
|
||
<p>接下来该怎么学?</p>
|
||
<ul>
|
||
<li>重做CMake Tutorial,尽量自己完成,可以通过查文档复习、加深印象</li>
|
||
<li>读开源项目CMake文件的写法:<a href="https://github.com/fffaraz/awesome-cpp">https://github.com/fffaraz/awesome-cpp</a></li>
|
||
<li>继续熟悉文档,对有兴趣的地方自行深入研究</li>
|
||
<li>在应用中学习,通过使用CMake,遇到问题之后针对性地学习</li>
|
||
</ul>
|
||
<p> </p>
|
||
<p> </p>
|
||
</article>
|
||
</body>
|
||
</html> |