First draft of build and custom configuration integration with cpptools

This commit is contained in:
Andreea Isac 2019-08-14 15:48:05 -07:00
Родитель 19fddb2bc6
Коммит 66942492c9
11 изменённых файлов: 1328 добавлений и 83 удалений

Просмотреть файл

@ -1,4 +1,4 @@
First packaging
# Contributing
This project welcomes contributions and suggestions. Most contributions require you to agree to a
@ -14,8 +14,6 @@ For more information see the [Code of Conduct FAQ](https://opensource.microsoft.
contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with any additional questions or comments.
# vscode-makefile-tools README
This is the README for your extension "vscode-makefile-tools". After writing up a brief description, we recommend including the following sections.
## Features
Describe specific features of your extension including screenshots of your extension in action. Image paths are relative to this README file.

414
package-lock.json сгенерированный
Просмотреть файл

@ -5,18 +5,18 @@
"requires": true,
"dependencies": {
"@babel/code-frame": {
"version": "7.0.0",
"resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.0.0.tgz",
"integrity": "sha512-OfC2uemaknXr87bdLUkWog7nYuliM9Ij5HUcajsVcMCpQrcLmtxRbVFTIqmcSkSeYRBFBRxs2FiUqFJDLdiebA==",
"version": "7.5.5",
"resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.5.5.tgz",
"integrity": "sha512-27d4lZoomVyo51VegxI20xZPuSHusqbQag/ztrBC7wegWoQ1nLREPVSKSW8byhTlzTKyNE4ifaTA6lCp7JjpFw==",
"dev": true,
"requires": {
"@babel/highlight": "^7.0.0"
}
},
"@babel/highlight": {
"version": "7.0.0",
"resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.0.0.tgz",
"integrity": "sha512-UFMC4ZeFC48Tpvj7C8UgLvtkaUuovQX+5xNWrsIoMG8o2z+XFKjKaN9iVmS84dPwVN00W4wPmqvYoZF3EGAsfw==",
"version": "7.5.0",
"resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.5.0.tgz",
"integrity": "sha512-7dV4eu9gBxoM0dAnj/BCFDW9LFU0zvTrkq0ugM7pnHEgguOEeOz1so2ZghEdzviYzQEED0r4EAgpsBChKy1TRQ==",
"dev": true,
"requires": {
"chalk": "^2.0.0",
@ -33,8 +33,7 @@
"@types/node": {
"version": "10.14.7",
"resolved": "https://registry.npmjs.org/@types/node/-/node-10.14.7.tgz",
"integrity": "sha512-on4MmIDgHXiuJDELPk1NFaKVUxxCFr37tm8E9yN6rAiF5Pzp/9bBfBHkoexqRiY+hk/Z04EJU9kKEb59YqJ82A==",
"dev": true
"integrity": "sha512-on4MmIDgHXiuJDELPk1NFaKVUxxCFr37tm8E9yN6rAiF5Pzp/9bBfBHkoexqRiY+hk/Z04EJU9kKEb59YqJ82A=="
},
"agent-base": {
"version": "4.3.0",
@ -61,7 +60,6 @@
"version": "3.2.1",
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
"integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
"dev": true,
"requires": {
"color-convert": "^1.9.0"
}
@ -70,7 +68,6 @@
"version": "1.0.10",
"resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz",
"integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==",
"dev": true,
"requires": {
"sprintf-js": "~1.0.2"
}
@ -108,11 +105,21 @@
"integrity": "sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ==",
"dev": true
},
"azure-devops-node-api": {
"version": "7.2.0",
"resolved": "https://registry.npmjs.org/azure-devops-node-api/-/azure-devops-node-api-7.2.0.tgz",
"integrity": "sha512-pMfGJ6gAQ7LRKTHgiRF+8iaUUeGAI0c8puLaqHLc7B8AR7W6GJLozK9RFeUHFjEGybC9/EB3r67WPd7e46zQ8w==",
"requires": {
"os": "0.1.1",
"tunnel": "0.0.4",
"typed-rest-client": "1.2.0",
"underscore": "1.8.3"
}
},
"balanced-match": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz",
"integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=",
"dev": true
"integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c="
},
"bcrypt-pbkdf": {
"version": "1.0.2",
@ -123,11 +130,15 @@
"tweetnacl": "^0.14.3"
}
},
"boolbase": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz",
"integrity": "sha1-aN/1++YMUes3cl6p4+0xDcwed24="
},
"brace-expansion": {
"version": "1.1.11",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
"integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
"dev": true,
"requires": {
"balanced-match": "^1.0.0",
"concat-map": "0.0.1"
@ -139,6 +150,11 @@
"integrity": "sha1-81HTKWnTL6XXpVZxVCY9korjvR8=",
"dev": true
},
"buffer-crc32": {
"version": "0.2.13",
"resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz",
"integrity": "sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI="
},
"buffer-from": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz",
@ -161,18 +177,29 @@
"version": "2.4.2",
"resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
"integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
"dev": true,
"requires": {
"ansi-styles": "^3.2.1",
"escape-string-regexp": "^1.0.5",
"supports-color": "^5.3.0"
}
},
"cheerio": {
"version": "1.0.0-rc.3",
"resolved": "https://registry.npmjs.org/cheerio/-/cheerio-1.0.0-rc.3.tgz",
"integrity": "sha512-0td5ijfUPuubwLUu0OBoe98gZj8C/AA+RW3v67GPlGOrvxWjZmBXiBCRU+I8VEiNyJzjth40POfHiz2RB3gImA==",
"requires": {
"css-select": "~1.2.0",
"dom-serializer": "~0.1.1",
"entities": "~1.1.1",
"htmlparser2": "^3.9.1",
"lodash": "^4.15.0",
"parse5": "^3.0.1"
}
},
"color-convert": {
"version": "1.9.3",
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
"integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
"dev": true,
"requires": {
"color-name": "1.1.3"
}
@ -180,8 +207,7 @@
"color-name": {
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
"integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=",
"dev": true
"integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU="
},
"combined-stream": {
"version": "1.0.8",
@ -195,14 +221,12 @@
"commander": {
"version": "2.20.0",
"resolved": "https://registry.npmjs.org/commander/-/commander-2.20.0.tgz",
"integrity": "sha512-7j2y+40w61zy6YC2iRNpUe/NwhNyoXrYpHMrSunaMG64nRnaf96zO/KMQR4OyN/UnE5KLyEBnKHd4aG3rskjpQ==",
"dev": true
"integrity": "sha512-7j2y+40w61zy6YC2iRNpUe/NwhNyoXrYpHMrSunaMG64nRnaf96zO/KMQR4OyN/UnE5KLyEBnKHd4aG3rskjpQ=="
},
"concat-map": {
"version": "0.0.1",
"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
"integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=",
"dev": true
"integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s="
},
"core-util-is": {
"version": "1.0.2",
@ -210,6 +234,22 @@
"integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=",
"dev": true
},
"css-select": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/css-select/-/css-select-1.2.0.tgz",
"integrity": "sha1-KzoRBTnFNV8c2NMUYj6HCxIeyFg=",
"requires": {
"boolbase": "~1.0.0",
"css-what": "2.1",
"domutils": "1.5.1",
"nth-check": "~1.0.1"
}
},
"css-what": {
"version": "2.1.3",
"resolved": "https://registry.npmjs.org/css-what/-/css-what-2.1.3.tgz",
"integrity": "sha512-a+EPoD+uZiNfh+5fxw2nO9QwFa6nJe2Or35fGY6Ipw1R3R4AGz1d1TEZrCegvw2YTmZ0jXirGYlzxxpYSHwpEg=="
},
"dashdash": {
"version": "1.14.1",
"resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz",
@ -234,12 +274,53 @@
"integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=",
"dev": true
},
"denodeify": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/denodeify/-/denodeify-1.2.1.tgz",
"integrity": "sha1-OjYof1A05pnnV3kBBSwubJQlFjE="
},
"didyoumean": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/didyoumean/-/didyoumean-1.2.1.tgz",
"integrity": "sha1-6S7f2tplN9SE1zwBcv0eugxJdv8="
},
"diff": {
"version": "3.5.0",
"resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz",
"integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==",
"dev": true
},
"dom-serializer": {
"version": "0.1.1",
"resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.1.1.tgz",
"integrity": "sha512-l0IU0pPzLWSHBcieZbpOKgkIn3ts3vAh7ZuFyXNwJxJXk/c4Gwj9xaTJwIDVQCXawWD0qb3IzMGH5rglQaO0XA==",
"requires": {
"domelementtype": "^1.3.0",
"entities": "^1.1.1"
}
},
"domelementtype": {
"version": "1.3.1",
"resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.3.1.tgz",
"integrity": "sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w=="
},
"domhandler": {
"version": "2.4.2",
"resolved": "https://registry.npmjs.org/domhandler/-/domhandler-2.4.2.tgz",
"integrity": "sha512-JiK04h0Ht5u/80fdLMCEmV4zkNh2BcoMFBmZ/91WtYZ8qVXSKjiw7fXMgFPnHcSZgOo3XdinHvmnDUeMf5R4wA==",
"requires": {
"domelementtype": "1"
}
},
"domutils": {
"version": "1.5.1",
"resolved": "https://registry.npmjs.org/domutils/-/domutils-1.5.1.tgz",
"integrity": "sha1-3NhIiib1Y9YQeeSMn3t+Mjc2gs8=",
"requires": {
"dom-serializer": "0",
"domelementtype": "1"
}
},
"ecc-jsbn": {
"version": "0.1.2",
"resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz",
@ -250,6 +331,11 @@
"safer-buffer": "^2.1.0"
}
},
"entities": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/entities/-/entities-1.1.2.tgz",
"integrity": "sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w=="
},
"es6-promise": {
"version": "4.2.8",
"resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.8.tgz",
@ -268,8 +354,7 @@
"escape-string-regexp": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
"integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=",
"dev": true
"integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ="
},
"esprima": {
"version": "4.0.1",
@ -278,9 +363,9 @@
"dev": true
},
"esutils": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.2.tgz",
"integrity": "sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs=",
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz",
"integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==",
"dev": true
},
"extend": {
@ -307,6 +392,14 @@
"integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=",
"dev": true
},
"fd-slicer": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz",
"integrity": "sha1-JcfInLH5B3+IkbvmHY85Dq4lbx4=",
"requires": {
"pend": "~1.2.0"
}
},
"forever-agent": {
"version": "0.6.1",
"resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz",
@ -327,8 +420,7 @@
"fs.realpath": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
"integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=",
"dev": true
"integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8="
},
"getpass": {
"version": "0.1.7",
@ -343,7 +435,6 @@
"version": "7.1.4",
"resolved": "https://registry.npmjs.org/glob/-/glob-7.1.4.tgz",
"integrity": "sha512-hkLPepehmnKk41pUGm3sYxoFs/umurYfYJCerbXEyFIWcAzvpipAgVkBqqT9RBKMGjnq6kMuyYwha6csxbiM1A==",
"dev": true,
"requires": {
"fs.realpath": "^1.0.0",
"inflight": "^1.0.4",
@ -378,8 +469,7 @@
"has-flag": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
"integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=",
"dev": true
"integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0="
},
"he": {
"version": "1.1.1",
@ -387,6 +477,19 @@
"integrity": "sha1-k0EP0hsAlzUVH4howvJx80J+I/0=",
"dev": true
},
"htmlparser2": {
"version": "3.10.1",
"resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-3.10.1.tgz",
"integrity": "sha512-IgieNijUMbkDovyoKObU1DUhm1iwNYE/fuifEoEHfd1oZKZDaONBSkal7Y01shxsM49R4XaMdGez3WnF9UfiCQ==",
"requires": {
"domelementtype": "^1.3.1",
"domhandler": "^2.3.0",
"domutils": "^1.5.1",
"entities": "^1.1.1",
"inherits": "^2.0.1",
"readable-stream": "^3.1.1"
}
},
"http-proxy-agent": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-2.1.0.tgz",
@ -422,7 +525,6 @@
"version": "1.0.6",
"resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
"integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=",
"dev": true,
"requires": {
"once": "^1.3.0",
"wrappy": "1"
@ -431,8 +533,7 @@
"inherits": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
"integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=",
"dev": true
"integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4="
},
"is-typedarray": {
"version": "1.0.0",
@ -498,6 +599,41 @@
"verror": "1.10.0"
}
},
"linkify-it": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-2.2.0.tgz",
"integrity": "sha512-GnAl/knGn+i1U/wjBz3akz2stz+HrHLsxMwHQGofCDfPvlf+gDKN58UtfmUquTY4/MXeE2x7k19KQmeoZi94Iw==",
"requires": {
"uc.micro": "^1.0.1"
}
},
"lodash": {
"version": "4.17.15",
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz",
"integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A=="
},
"markdown-it": {
"version": "8.4.2",
"resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-8.4.2.tgz",
"integrity": "sha512-GcRz3AWTqSUphY3vsUqQSFMbgR38a4Lh3GWlHRh/7MRwz8mcu9n2IO7HOh+bXHrR9kOPDl5RNCaEsrneb+xhHQ==",
"requires": {
"argparse": "^1.0.7",
"entities": "~1.1.1",
"linkify-it": "^2.0.0",
"mdurl": "^1.0.1",
"uc.micro": "^1.0.5"
}
},
"mdurl": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/mdurl/-/mdurl-1.0.1.tgz",
"integrity": "sha1-/oWy7HWlkDfyrf7BAP1sYBdhFS4="
},
"mime": {
"version": "1.6.0",
"resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz",
"integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg=="
},
"mime-db": {
"version": "1.40.0",
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.40.0.tgz",
@ -517,7 +653,6 @@
"version": "3.0.4",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
"integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
"dev": true,
"requires": {
"brace-expansion": "^1.1.7"
}
@ -598,12 +733,30 @@
}
}
},
"module-alias": {
"version": "2.2.1",
"resolved": "https://registry.npmjs.org/module-alias/-/module-alias-2.2.1.tgz",
"integrity": "sha512-LTez0Eo+YtfUhgzhu/LqxkUzOpD+k5C0wXBLun0L1qE2BhHf6l09dqam8e7BnoMYA6mAlP0vSsGFQ8QHhGN/aQ=="
},
"ms": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
"integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
"dev": true
},
"mute-stream": {
"version": "0.0.8",
"resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz",
"integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA=="
},
"nth-check": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/nth-check/-/nth-check-1.0.2.tgz",
"integrity": "sha512-WeBOdju8SnzPN5vTUJYxYUxLeXpCaVP5i5e0LF8fg7WORF2Wd7wFX/pk0tYZk7s8T+J7VLy0Da6J1+wCT0AtHg==",
"requires": {
"boolbase": "~1.0.0"
}
},
"oauth-sign": {
"version": "0.9.0",
"resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz",
@ -614,16 +767,54 @@
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
"integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
"dev": true,
"requires": {
"wrappy": "1"
}
},
"os": {
"version": "0.1.1",
"resolved": "https://registry.npmjs.org/os/-/os-0.1.1.tgz",
"integrity": "sha1-IIhF6J4ZOtTZcUdLk5R3NqVtE/M="
},
"os-homedir": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz",
"integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M="
},
"os-tmpdir": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz",
"integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ="
},
"osenv": {
"version": "0.1.5",
"resolved": "https://registry.npmjs.org/osenv/-/osenv-0.1.5.tgz",
"integrity": "sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g==",
"requires": {
"os-homedir": "^1.0.0",
"os-tmpdir": "^1.0.0"
}
},
"parse-semver": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/parse-semver/-/parse-semver-1.1.1.tgz",
"integrity": "sha1-mkr9bfBj3Egm+T+6SpnPIj9mbLg=",
"requires": {
"semver": "^5.1.0"
}
},
"parse5": {
"version": "3.0.3",
"resolved": "https://registry.npmjs.org/parse5/-/parse5-3.0.3.tgz",
"integrity": "sha512-rgO9Zg5LLLkfJF9E6CCmXlSE4UVceloys8JrFqCcHloC3usd/kJCyPDwH2SOlzix2j3xaP9sUX3e8+kvkuleAA==",
"requires": {
"@types/node": "*"
}
},
"path-is-absolute": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
"integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=",
"dev": true
"integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18="
},
"path-parse": {
"version": "1.0.6",
@ -631,6 +822,11 @@
"integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==",
"dev": true
},
"pend": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz",
"integrity": "sha1-elfrVQpng/kRUzH89GY9XI4AelA="
},
"performance-now": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz",
@ -661,6 +857,24 @@
"integrity": "sha512-w7fLxIRCRT7U8Qu53jQnJyPkYZIaR4n5151KMfcJlO/A9397Wxb1amJvROTK6TOnp7PfoAmg/qXiNHI+08jRfA==",
"dev": true
},
"read": {
"version": "1.0.7",
"resolved": "https://registry.npmjs.org/read/-/read-1.0.7.tgz",
"integrity": "sha1-s9oZvQUkMal2cdRKQmNK33ELQMQ=",
"requires": {
"mute-stream": "~0.0.4"
}
},
"readable-stream": {
"version": "3.4.0",
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.4.0.tgz",
"integrity": "sha512-jItXPLmrSR8jmTRmRWJXCnGJsfy85mB3Wd/uINMXA65yrnFo0cPClFIUWzo2najVNSl+mx7/4W8ttlLWJe99pQ==",
"requires": {
"inherits": "^2.0.3",
"string_decoder": "^1.1.1",
"util-deprecate": "^1.0.1"
}
},
"request": {
"version": "2.88.0",
"resolved": "https://registry.npmjs.org/request/-/request-2.88.0.tgz",
@ -696,9 +910,9 @@
"dev": true
},
"resolve": {
"version": "1.11.0",
"resolved": "https://registry.npmjs.org/resolve/-/resolve-1.11.0.tgz",
"integrity": "sha512-WL2pBDjqT6pGUNSUzMw00o4T7If+z4H2x3Gz893WoUQ5KW8Vr9txp00ykiP16VBaZF5+j/OcXJHZ9+PCvdiDKw==",
"version": "1.12.0",
"resolved": "https://registry.npmjs.org/resolve/-/resolve-1.12.0.tgz",
"integrity": "sha512-B/dOmuoAik5bKcD6s6nXDCjzUKnaDvdkRyAk6rsmsKLipWj4797iothd7jmmUhWTfinVMU+wc56rYKsit2Qy4w==",
"dev": true,
"requires": {
"path-parse": "^1.0.6"
@ -707,8 +921,7 @@
"safe-buffer": {
"version": "5.1.2",
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
"integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==",
"dev": true
"integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="
},
"safer-buffer": {
"version": "2.1.2",
@ -719,8 +932,7 @@
"semver": {
"version": "5.7.0",
"resolved": "https://registry.npmjs.org/semver/-/semver-5.7.0.tgz",
"integrity": "sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA==",
"dev": true
"integrity": "sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA=="
},
"source-map": {
"version": "0.6.1",
@ -741,8 +953,7 @@
"sprintf-js": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz",
"integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=",
"dev": true
"integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw="
},
"sshpk": {
"version": "1.16.1",
@ -761,15 +972,30 @@
"tweetnacl": "~0.14.0"
}
},
"string_decoder": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.2.0.tgz",
"integrity": "sha512-6YqyX6ZWEYguAxgZzHGL7SsCeGx3V2TtOTqZz1xSTSWnqsbWwbptafNyvf/ACquZUXV3DANr5BDIwNYe1mN42w==",
"requires": {
"safe-buffer": "~5.1.0"
}
},
"supports-color": {
"version": "5.5.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
"integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
"dev": true,
"requires": {
"has-flag": "^3.0.0"
}
},
"tmp": {
"version": "0.0.29",
"resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.29.tgz",
"integrity": "sha1-8lEl/w3Z2jzLDC3Tce4SiLuRKMA=",
"requires": {
"os-tmpdir": "~1.0.1"
}
},
"tough-cookie": {
"version": "2.4.3",
"resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.4.3.tgz",
@ -795,9 +1021,9 @@
"dev": true
},
"tslint": {
"version": "5.17.0",
"resolved": "https://registry.npmjs.org/tslint/-/tslint-5.17.0.tgz",
"integrity": "sha512-pflx87WfVoYepTet3xLfDOLDm9Jqi61UXIKePOuca0qoAZyrGWonDG9VTbji58Fy+8gciUn8Bt7y69+KEVjc/w==",
"version": "5.18.0",
"resolved": "https://registry.npmjs.org/tslint/-/tslint-5.18.0.tgz",
"integrity": "sha512-Q3kXkuDEijQ37nXZZLKErssQVnwCV/+23gFEMROi8IlbaBG6tXqLPQJ5Wjcyt/yHPKBC+hD5SzuGaMora+ZS6w==",
"dev": true,
"requires": {
"@babel/code-frame": "^7.0.0",
@ -824,6 +1050,11 @@
"tslib": "^1.8.1"
}
},
"tunnel": {
"version": "0.0.4",
"resolved": "https://registry.npmjs.org/tunnel/-/tunnel-0.0.4.tgz",
"integrity": "sha1-LTeFoVjBdMmhbcLARuxfxfF0IhM="
},
"tunnel-agent": {
"version": "0.6.0",
"resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz",
@ -839,12 +1070,31 @@
"integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=",
"dev": true
},
"typed-rest-client": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/typed-rest-client/-/typed-rest-client-1.2.0.tgz",
"integrity": "sha512-FrUshzZ1yxH8YwGR29PWWnfksLEILbWJydU7zfIRkyH7kAEzB62uMAl2WY6EyolWpLpVHeJGgQm45/MaruaHpw==",
"requires": {
"tunnel": "0.0.4",
"underscore": "1.8.3"
}
},
"typescript": {
"version": "3.5.1",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-3.5.1.tgz",
"integrity": "sha512-64HkdiRv1yYZsSe4xC1WVgamNigVYjlssIoaH2HcZF0+ijsk5YK2g0G34w9wJkze8+5ow4STd22AynfO6ZYYLw==",
"dev": true
},
"uc.micro": {
"version": "1.0.6",
"resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-1.0.6.tgz",
"integrity": "sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA=="
},
"underscore": {
"version": "1.8.3",
"resolved": "https://registry.npmjs.org/underscore/-/underscore-1.8.3.tgz",
"integrity": "sha1-Tz+1OxBuYJf8+ctBCfKl6b36UCI="
},
"uri-js": {
"version": "4.2.2",
"resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz",
@ -854,6 +1104,11 @@
"punycode": "^2.1.0"
}
},
"url-join": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/url-join/-/url-join-1.1.0.tgz",
"integrity": "sha1-dBxsL0WWxIMNZxhGCSDQySIC3Hg="
},
"url-parse": {
"version": "1.4.7",
"resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.4.7.tgz",
@ -864,6 +1119,11 @@
"requires-port": "^1.0.0"
}
},
"util-deprecate": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
"integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8="
},
"uuid": {
"version": "3.3.2",
"resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz",
@ -881,6 +1141,33 @@
"extsprintf": "^1.2.0"
}
},
"vsce": {
"version": "1.66.0",
"resolved": "https://registry.npmjs.org/vsce/-/vsce-1.66.0.tgz",
"integrity": "sha512-Zf4+WD4PhEcOr7jkU08SI9lwFqDhmhk73YOCGQ/tNLaBy+PnnX4eSdqj9LdzDLuI2dsyomJLXzDSNgxuaInxCQ==",
"requires": {
"azure-devops-node-api": "^7.2.0",
"chalk": "^2.4.2",
"cheerio": "^1.0.0-rc.1",
"commander": "^2.8.1",
"denodeify": "^1.2.1",
"didyoumean": "^1.2.1",
"glob": "^7.0.6",
"lodash": "^4.17.10",
"markdown-it": "^8.3.1",
"mime": "^1.3.4",
"minimatch": "^3.0.3",
"osenv": "^0.1.3",
"parse-semver": "^1.1.1",
"read": "^1.0.7",
"semver": "^5.1.0",
"tmp": "0.0.29",
"typed-rest-client": "1.2.0",
"url-join": "^1.1.0",
"yauzl": "^2.3.1",
"yazl": "^2.2.2"
}
},
"vscode": {
"version": "1.1.34",
"resolved": "https://registry.npmjs.org/vscode/-/vscode-1.1.34.tgz",
@ -896,6 +1183,11 @@
"vscode-test": "^0.4.1"
}
},
"vscode-cpptools": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/vscode-cpptools/-/vscode-cpptools-2.1.2.tgz",
"integrity": "sha512-oMx/wsLQM6NggnmWn4t8lIrt1K7Zpl5G34zxNu+J6KHGnCxBzc+NHnxXS1Vu1hLxGWwANAvdxr3mEcA2LMe7hQ=="
},
"vscode-test": {
"version": "0.4.3",
"resolved": "https://registry.npmjs.org/vscode-test/-/vscode-test-0.4.3.tgz",
@ -909,8 +1201,24 @@
"wrappy": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
"integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=",
"dev": true
"integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8="
},
"yauzl": {
"version": "2.10.0",
"resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz",
"integrity": "sha1-x+sXyT4RLLEIb6bY5R+wZnt5pfk=",
"requires": {
"buffer-crc32": "~0.2.3",
"fd-slicer": "~1.1.0"
}
},
"yazl": {
"version": "2.5.1",
"resolved": "https://registry.npmjs.org/yazl/-/yazl-2.5.1.tgz",
"integrity": "sha512-phENi2PLiHnHb6QBVot+dJnaAZ0xosj7p3fWl+znIjBDlnMI2PsZCJZ306BPTFOaHf5qdDEI8x5qFrSOBN5vrw==",
"requires": {
"buffer-crc32": "~0.2.3"
}
}
}
}

Просмотреть файл

@ -3,6 +3,7 @@
"displayName": "vscode-makefile-tools",
"description": "Provide makefile integration in VSCode",
"version": "0.0.1",
"publisher": "ms-vscode",
"engines": {
"vscode": "^1.35.0"
},
@ -10,16 +11,65 @@
"Other"
],
"activationEvents": [
"onCommand:extension.helloWorld"
"onCommand:make.build.current",
"onCommand:make.setConfiguration",
"onCommand:make.setTarget",
"workspaceContains:**/makefile",
"workspaceContains:**/Makefile"
],
"main": "./out/extension.js",
"contributes": {
"commands": [
{
"command": "extension.helloWorld",
"title": "Hello World"
"command": "make.build.current",
"title": "MAKE: Run the MAKEFILE target of the current configuration"
},
{
"command": "make.setConfiguration",
"title": "MAKE: Set the current workspace configuration"
},
{
"command": "make.setTarget",
"title": "MAKE: Set the target to be run by make"
}
]
],
"configuration": {
"type": "object",
"title": "Makefile",
"properties": {
"Make.Configuration.Current": {
"type": [
"string",
"null"
],
"default": null,
"description": "The makefile current configuration",
"scope": "resource"
},
"Make.Build.Target": {
"type": [
"string",
"null"
],
"default": null,
"description": "The current target to be run by make",
"scope": "resource"
},
"Make.Logging.Level": {
"type": [
"string",
"null"
],
"enum": [
"Normal",
"Verbose"
],
"default": "Normal",
"description": "The logging level for the makefile tools extension",
"scope": "resource"
}
}
}
},
"scripts": {
"vscode:prepublish": "npm run compile",
@ -29,13 +79,15 @@
"test": "npm run compile && node ./node_modules/vscode/bin/test"
},
"devDependencies": {
"typescript": "^3.3.1",
"vscode": "^1.1.28",
"tslint": "^5.12.1",
"@types/mocha": "^2.2.42",
"@types/node": "^10.12.21",
"@types/mocha": "^2.2.42"
"tslint": "^5.18.0",
"typescript": "^3.3.1",
"vscode": "^1.1.28"
},
"dependencies": {
"module-alias": "^2.0.6",
"vsce": "^1.66.0",
"vscode-cpptools": "^2.1.2"
}
}

219
src/configuration.ts Normal file
Просмотреть файл

@ -0,0 +1,219 @@
import * as child_process from 'child_process';
import * as fs from 'fs';
import * as logger from './logger';
import * as make from './make';
import * as parser from './parser';
import * as ui from './ui';
import * as util from './util';
import * as vscode from 'vscode';
let statusBar: ui.UI = ui.getUI();
// Each different scenario of building the same makefile, in the same environment, represents a configuration.
// Example: "make BUILD_TYPE=Debug" and "make BUILD_TYPE=Release" can be the debug and release configurations.
// The user can save several different such configurations in .vscode\make_configurations.json,
// from which one can be picked via the VSCode Makefile Tools Extension and saved in settings.
export interface MakeConfiguration {
// A name associated with a particular build command process and args/options
name: string;
// make, nmake, specmake...
// This is sent to spawnChildProcess as process name
// It can have full path, relative path or only tool name
// Don't include args in command_name
command_name: string;
// options used in the build invocation
// don't use more than one argument in a string
commandArgs: string[];
// TODO: investigate how flexible this is to integrate with other build systems than the MAKE family
// (basically anything that can produce a dry-run output is sufficient)
// Implement set-able dry-run, verbose, change-directory and always-make switches
// since different tools may use different arguments for the same behavior
}
// Last configuration name picked from the set defined in .vscode\make_configurations.json.
// Saved into the settings storage. Also reflected in the configuration status bar button.
// If no particular current configuration is defined in settings, set to 'Default'.
let currentMakeConfiguration: string | undefined;
export function getCurrentMakeConfiguration(): string | undefined { return currentMakeConfiguration; }
export function setCurrentMakeConfiguration(configuration: string) {
currentMakeConfiguration = configuration;
statusBar.SetConfiguration(currentMakeConfiguration);
getCommandForConfiguration(currentMakeConfiguration);
}
// Read current configuration from settings storage, update status bar item
function readCurrentMakeConfiguration() {
let workspaceConfiguration: vscode.WorkspaceConfiguration = vscode.workspace.getConfiguration();
currentMakeConfiguration = workspaceConfiguration.get<string>("Make.Configuration.Current");
if (!currentMakeConfiguration) {
logger.Message("No current configuration is defined in the settings file");
currentMakeConfiguration = "Default";
}
statusBar.SetConfiguration(currentMakeConfiguration);
}
// Command name and args are used when building from within the VSCode Makefile Tools Extension,
// when parsing all the targets that exist and when updating the cpptools configuration provider
// for IntelliSense.
let configurationCommandName: string;
export function getConfigurationCommandName(): string { return configurationCommandName; }
export function setConfigurationCommandName(name: string) { configurationCommandName = name; }
let configurationCommandArgs: string[] = [];
export function getConfigurationCommandArgs(): string[] { return configurationCommandArgs; }
export function setConfigurationCommandArgs(args: string[]) { configurationCommandArgs = args; }
// Read from settings storage, update status bar item
// Current make configuration command = process name + arguments
function readCurrentMakeConfigurationCommand() {
// Read from disk instead of from the MakeConfiguration array, to get up to date content
readMakeConfigurations();
getCommandForConfiguration(currentMakeConfiguration);
}
// Helper to find in the array of MakeConfiguration which command/args correspond to a configuration name
export function getCommandForConfiguration(configuration: string | undefined) {
let makeConfiguration: MakeConfiguration | undefined = makeConfigurations.find(k => {
if (k.name === currentMakeConfiguration) {
return { ...k, keep: true };
}
});
if (makeConfiguration) {
configurationCommandName = makeConfiguration.command_name;
configurationCommandArgs = makeConfiguration.commandArgs;
logger.Message("Found command '" + configurationCommandName + " " + configurationCommandArgs.join(" ") + "' for configuration " + currentMakeConfiguration);
} else {
configurationCommandName = "make";
configurationCommandArgs = [];
logger.Message("Couldn't find explicit command for configuration " + currentMakeConfiguration + ". Assuming make.exe with no arguments.");
}
}
// The data type mapping to the content of .vscode\make_configurations.json.
// The file is allowed to be missing, in which case the MakeConfiguration array remains empty.
let makeConfigurations: MakeConfiguration[] = [];
export function getMakeConfigurations(): MakeConfiguration[] { return makeConfigurations; }
export function setMakeConfigurations(configurations: MakeConfiguration[]) { makeConfigurations = configurations; }
function readMakeConfigurations() {
let configurationsJsonPath: string = vscode.workspace.rootPath + "\/.vscode\/make_configurations.json";
if (util.checkFileExistsSync(configurationsJsonPath)) {
logger.Message("Reading configurations from file \/.vscode\/make_configurations.json");
const jsonConfigurationsContent: Buffer = fs.readFileSync(configurationsJsonPath);
makeConfigurations = JSON.parse(jsonConfigurationsContent.toString());
} else {
logger.Message("Configurations file \/.vscode\/make_configurations.json not found");
}
}
// Last target picked from the set of targets that are run by the makefiles
// when building for the current configuration.
// Saved into the settings storage. Also reflected in the configuration status bar button
let currentTarget: string | undefined;
export function getCurrentTarget(): string | undefined { return currentTarget; }
export function setCurrentTarget(target: string | undefined) { currentTarget = target; }
// Read current target from settings storage, update status bar item
function readCurrentTarget() {
// If no particular target is defined in settings, use 'Default' for the button
// but keep the variable empty, to not apend it to the make command.
let workspaceConfiguration: vscode.WorkspaceConfiguration = vscode.workspace.getConfiguration();
currentTarget = workspaceConfiguration.get<string>("Make.Build.Target");
if (!currentTarget) {
logger.Message("No target defined in the settings file");
statusBar.SetTarget("Default");
currentTarget = "";
} else {
statusBar.SetTarget(currentTarget);
}
}
// Initialization from settings (or backup default rules), done at activation time
export function initFromSettings() {
readCurrentMakeConfiguration();
readCurrentMakeConfigurationCommand();
readCurrentTarget();
}
// Fill a drop-down with all the configuration names defined by the user in .vscode\make_configurations.json
// Triggers a cpptools configuration provider update after selection.
export async function setNewConfiguration() {
// read from the configurations file instead of currentMakefileConfiguration
// just in case the content changed on disk.
await readMakeConfigurations();
const items: string[] = makeConfigurations.map((k => {
return k.name;
}));
const chosen = await vscode.window.showQuickPick(items);
if (chosen) {
let workspaceConfiguration: vscode.WorkspaceConfiguration = vscode.workspace.getConfiguration();
workspaceConfiguration.update("Make.Configuration.Current", currentMakeConfiguration);
setCurrentMakeConfiguration(chosen);
make.DryRun();
}
}
export async function setNewTarget() {
let commandArgs: string[] = [];
// all: must be first argument, to make sure all targets are evaluated and not a subset
// --dry-run: to ensure no real build is performed for the targets analysis
// -p: creates a verbose log from which targets are easy to parse
commandArgs = commandArgs.concat(["all", "--dry-run", "-p"], configurationCommandArgs);
let stdoutStr: string = "";
let stderrStr: string = "";
logger.Message("Parsing the targets in the makefile ... Command: " + configurationCommandName + " " + commandArgs.join(" "));
let process: child_process.ChildProcess;
try {
var stdout = (result: string): void => {
stdoutStr += result;
};
var stderr = (result: string): void => {
stderrStr += result;
};
var closing = (retCode: number, signal: string): void => {
if (retCode !== 0) {
logger.Message("The verbose make dry-run command for parsing targets failed.");
logger.Message(stderrStr);
}
// Don't log stdoutStr in this case, because -p output is too verbose to be useful in any logger area
let makefileTargets : string[] = parser.parseTargets(stdoutStr);
selectTarget(makefileTargets);
};
await util.spawnChildProcess(configurationCommandName, commandArgs, vscode.workspace.rootPath || "", stdout, stderr, closing);
} catch (error) {
logger.Message('Failed to launch make command. Make sure it is on the path. ' + error);
return;
}
}
// Fill a drop-down with all the target names run by building the makefile for the current configuration
// Triggers a cpptools configuration provider update after selection.
export async function selectTarget(makefileTargets : string[]) {
const chosen = await vscode.window.showQuickPick(makefileTargets);
if (chosen) {
currentTarget = chosen;
statusBar.SetTarget(currentTarget);
let workspaceConfiguration: vscode.WorkspaceConfiguration = vscode.workspace.getConfiguration();
workspaceConfiguration.update("Make.Build.Target", currentTarget);
make.DryRun();
}
}

130
src/cpptools.ts Normal file
Просмотреть файл

@ -0,0 +1,130 @@
import * as logger from './logger';
import * as path from 'path';
import * as util from './util';
import * as vscode from 'vscode';
import * as cpp from 'vscode-cpptools';
let cummulativeBrowsePath: string[] = [];
export function emptyCummulativeBrowsePath() {
cummulativeBrowsePath = [];
}
export class CppConfigurationProvider implements cpp.CustomConfigurationProvider {
readonly name = 'Makefile Tools';
readonly extensionId = 'microsoft.vscode-makefile-tools';
private workspaceBrowseConfiguration: cpp.WorkspaceBrowseConfiguration = { browsePath: [] };
private getConfiguration(uri: vscode.Uri): cpp.SourceFileConfigurationItem | undefined {
const norm_path = path.normalize(uri.fsPath);
return this.fileIndex.get(norm_path);
}
async canProvideConfiguration(uri: vscode.Uri) {
return !!this.getConfiguration(uri);
}
async provideConfigurations(uris: vscode.Uri[]) {
return util.dropNulls(uris.map(u => this.getConfiguration(u)));
}
async canProvideBrowseConfiguration() {
return true;
}
async provideBrowseConfiguration() { return this.workspaceBrowseConfiguration; }
dispose() {}
private readonly fileIndex = new Map<string, cpp.SourceFileConfigurationItem>();
// TODO: Finalize the content parsed from the dry-run output:
// - incorporate relevant settings from the environment
// INCLUDE= for include paths
// _CL_= parse for defines, undefines, standard and response files
// Attention for defines syntax: _CL_=/DMyDefine#1 versus /DMyDefine1
// - take into account the effect of undefines /U
// In case of conflicting switches, the command prompt overwrites the makefile
buildCustomConfigurationProvider(
defines: string[],
includePath: string[],
forcedInclude: string[],
standard: util.StandardVersion,
intelliSenseMode: util.IntelliSenseMode,
compilerPath: string,
windowsSdkVersion: string,
filesPaths: string[]) {
const configuration: cpp.SourceFileConfiguration = {
defines,
standard,
includePath,
forcedInclude,
intelliSenseMode,
compilerPath,
windowsSdkVersion
};
// cummulativeBrowsePath incorporates all the files and the includes paths
// of all the compiler invocations of the current configuration
filesPaths.forEach(filePath => {
this.fileIndex.set(path.normalize(filePath), {
uri: vscode.Uri.file(filePath).toString(),
configuration,
});
let folder: string = path.dirname(filePath);
if (!cummulativeBrowsePath.includes(folder)) {
cummulativeBrowsePath.push(folder);
}
});
includePath.forEach(incl => {
if (!cummulativeBrowsePath.includes(incl)) {
cummulativeBrowsePath.push(incl);
}
});
forcedInclude.forEach(fincl => {
if (!cummulativeBrowsePath.includes(fincl)) {
cummulativeBrowsePath.push(fincl);
}
});
this.workspaceBrowseConfiguration = {
browsePath: cummulativeBrowsePath,
standard,
compilerPath,
windowsSdkVersion
};
}
LogConfigurationProvider() {
logger.Message("Sending Workspace Browse Configuration: -----------------------------------");
logger.Message("Browse Path: " + this.workspaceBrowseConfiguration.browsePath.join(";"));
logger.Message("Standard: " + this.workspaceBrowseConfiguration.standard);
logger.Message("Compiler Path: " + this.workspaceBrowseConfiguration.compilerPath);
if (process.platform === "win32") {
logger.Message("Windows SDK Version: " + this.workspaceBrowseConfiguration.windowsSdkVersion);
}
logger.Message("-----------------------------------");
this.fileIndex.forEach(filePath => {
logger.Message("Sending configuration for file " + filePath.uri.toString() + "-----------------------------------");
logger.Message("Defines: " + filePath.configuration.defines.join(";"));
logger.Message("Includes: " + filePath.configuration.includePath.join(";"));
if (filePath.configuration.forcedInclude) {
logger.Message("Force Includes: " + filePath.configuration.forcedInclude.join(";"));
}
logger.Message("Standard: " + filePath.configuration.standard);
logger.Message("IntelliSense Mode: " + filePath.configuration.intelliSenseMode);
logger.Message("Compiler Path: " + filePath.configuration.compilerPath);
if (process.platform === "win32") {
logger.Message("Windows SDK Version: " + filePath.configuration.windowsSdkVersion);
}
logger.Message("-----------------------------------");
});
}
}

Просмотреть файл

@ -1,27 +1,134 @@
// The module 'vscode' contains the VS Code extensibility API
// Import the module and reference it with the alias vscode in your code below
'use strict';
require('module-alias/register');
import * as configuration from './configuration';
import * as cpptools from './cpptools';
import * as fs from 'fs';
import * as logger from './logger';
import * as make from './make';
import * as parser from './parser';
import * as ui from './ui';
import * as util from './util';
import * as vscode from 'vscode';
import * as cpp from 'vscode-cpptools';
// this method is called when your extension is activated
// your extension is activated the very first time the command is executed
export function activate(context: vscode.ExtensionContext) {
let statusBar: ui.UI = ui.getUI();
export let extension: MakefileToolsExtension | null = null;
// Use the console to output diagnostic information (console.log) and errors (console.error)
// This line of code will only be executed once when your extension is activated
console.log('Congratulations, your extension "vscode-makefile-tools" is now active!');
export class MakefileToolsExtension {
private readonly cppConfigurationProvider = new cpptools.CppConfigurationProvider();
private cppToolsAPI?: cpp.CppToolsApi;
private cppConfigurationProviderRegister?: Promise<void>;
// The command has been defined in the package.json file
// Now provide the implementation of the command with registerCommand
// The commandId parameter must match the command field in package.json
let disposable = vscode.commands.registerCommand('extension.helloWorld', () => {
// The code you place here will be executed every time your command is executed
constructor(public readonly extensionContext: vscode.ExtensionContext) {
}
// Display a message box to the user
vscode.window.showInformationMessage('Hello VSCode!');
});
// Parse the dry-run output and populate data for cpptools
constructIntellisense(dryRunOutputStr: string) {
parser.parseDryRunOutput(dryRunOutputStr);
}
context.subscriptions.push(disposable);
dispose() {
if (this.cppToolsAPI) {
this.cppToolsAPI.dispose();
}
}
// Register this extension as a new provider or request an update
async registerCppToolsProvider() {
await this.ensureCppToolsProviderRegistered();
if (this.cppToolsAPI) {
this.cppConfigurationProvider.LogConfigurationProvider();
if (this.cppToolsAPI.notifyReady) {
this.cppToolsAPI.notifyReady(this.cppConfigurationProvider);
} else {
this.cppToolsAPI.didChangeCustomConfiguration(this.cppConfigurationProvider);
}
}
}
ensureCppToolsProviderRegistered() {
// make sure this extension is registered as provider only once
if (!this.cppConfigurationProviderRegister) {
this.cppConfigurationProviderRegister = this.registerCppTools();
}
return this.cppConfigurationProviderRegister;
}
async registerCppTools() {
if (!this.cppToolsAPI) {
this.cppToolsAPI = await cpp.getCppToolsApi(cpp.Version.v2);
}
if (this.cppToolsAPI) {
this.cppToolsAPI.registerCustomConfigurationProvider(this.cppConfigurationProvider);
}
}
buildCustomConfigurationProvider(
defines: string[],
includePath: string[],
forcedInclude: string[],
standard: util.StandardVersion,
intelliSenseMode: util.IntelliSenseMode,
compilerPath: string,
windowsSdkVersion: string,
filesPaths: string[]
) {
this.cppConfigurationProvider.buildCustomConfigurationProvider(defines, includePath, forcedInclude, standard,intelliSenseMode, compilerPath, windowsSdkVersion, filesPaths);
}
}
// this method is called when your extension is deactivated
export function deactivate() {}
// A change of target or configuration triggered a new dry-run,
// which produced a new output string to be parsed
export async function UpdateProvider(dryRunOutputStr: string) {
logger.Message("Updating the CppTools IntelliSense Configuration Provider.");
if (extension) {
extension.constructIntellisense(dryRunOutputStr);
extension.registerCppToolsProvider();
}
}
export async function activate(context: vscode.ExtensionContext) {
vscode.window.showInformationMessage('The extension "vscode-makefile-tools" is now active');
statusBar = ui.getUI();
extension = new MakefileToolsExtension(context);
context.subscriptions.push(vscode.commands.registerCommand('make.setConfiguration', () => {
configuration.setNewConfiguration();
}));
context.subscriptions.push(vscode.commands.registerCommand('make.setTarget', () => {
configuration.setNewTarget();
}));
context.subscriptions.push(vscode.commands.registerCommand('make.build.current', () => {
vscode.window.showInformationMessage('Building current MAKEFILE configuration ' + configuration.getCurrentMakeConfiguration() + "/" + configuration.getCurrentTarget());
make.BuildCurrentTarget();
}));
// Read configuration info from settings
configuration.initFromSettings();
// Generate the dry-run output used for parsing the info to be sent to CppTools
make.DryRun();
}
export async function deactivate() {
vscode.window.showInformationMessage('The extension "vscode-makefile-tools" is de-activated');
const items = [
extension,
statusBar
];
for (const item of items) {
if (item) {
item.dispose();
}
}
}

32
src/logger.ts Normal file
Просмотреть файл

@ -0,0 +1,32 @@
import * as vscode from 'vscode';
// todo: implement more verbosity levels (currently loggingLevel is read but never used)
let loggingLevel: string | undefined;
let makeOutputChannel: vscode.OutputChannel | undefined;
function getCurrentLoggingLevel() {
if (!loggingLevel) {
let workspaceConfiguration: vscode.WorkspaceConfiguration = vscode.workspace.getConfiguration();
loggingLevel = workspaceConfiguration.get<string>("Make.Logging.Level");
}
return loggingLevel;
}
function GetOutputChannel() {
if (!makeOutputChannel) {
makeOutputChannel = vscode.window.createOutputChannel("Makefile tools");
}
return makeOutputChannel;
}
export function Message(message: string) {
GetOutputChannel().appendLine(message);
}
// This is used for a few scenarios where the message already has end of line incorporated.
// Example: stdout/stderr of a child process read before the stream is closed.
export function MessageNoCR(message: string) {
GetOutputChannel().append(message);
}

93
src/make.ts Normal file
Просмотреть файл

@ -0,0 +1,93 @@
import * as child_process from 'child_process';
import * as configuration from './configuration';
import * as ext from './extension';
import * as logger from './logger';
import * as util from './util';
import * as vscode from 'vscode';
export async function BuildCurrentTarget() {
let process: child_process.ChildProcess;
let commandArgs: string[] = [];
// Prepend the target to the arguments given in the configurations json.
let currentTarget = configuration.getCurrentTarget();
if (currentTarget) {
commandArgs.push(currentTarget);
}
commandArgs = commandArgs.concat(configuration.getConfigurationCommandArgs());
logger.Message("Building the current target ... Command: " + configuration.getConfigurationCommandName() + " " + commandArgs.join(" "));
try {
// Append without end of line since there is one already included in the stdout/stderr fragments
var stdout = (result: string): void => {
logger.MessageNoCR(result);
};
var stderr = (result: string): void => {
logger.MessageNoCR(result);
};
var closing = (retCode: number, signal: string): void => {
if (retCode !== 0) {
logger.Message("The current target failed to build.");
} else {
logger.Message("The current target built successfully.");
}
};
await util.spawnChildProcess(configuration.getConfigurationCommandName(), commandArgs, vscode.workspace.rootPath || "", stdout, stderr, closing);
} catch (error) {
logger.Message('Failed to launch make command. Make sure it is on the path. ' + error);
return;
}
}
export async function DryRun() {
let process: child_process.ChildProcess;
let commandArgs: string[] = [];
// Prepend the target to the arguments given in the configurations json.
let currentTarget = configuration.getCurrentTarget();
if (currentTarget) {
commandArgs.push(currentTarget);
}
// Append --dry-run (to not perform any real build operation) and --always-make
// (to not skip over targets when timestamps indicate nothing needs to be done)
commandArgs = commandArgs.concat(configuration.getConfigurationCommandArgs());
commandArgs.push("--dry-run");
commandArgs.push("--always-make");
logger.Message("Generating the make dry-run output for parsing IntelliSense information... Command: " +
configuration.getConfigurationCommandName() + " " + commandArgs.join(" "));
try {
let stdoutStr: string = "";
let stderrStr: string = "";
var stdout = (result: string): void => {
stdoutStr += result;
};
var stderr = (result: string): void => {
stderrStr += result;
};
var closing = (retCode: number, signal: string): void => {
if (retCode !== 0) {
logger.Message("The make dry-run command failed.");
logger.Message(stderrStr);
}
console.log("Make dry-run output to parse is:\n" + stdoutStr);
ext.UpdateProvider(stdoutStr);
};
await util.spawnChildProcess(configuration.getConfigurationCommandName(), commandArgs, vscode.workspace.rootPath || "", stdout, stderr, closing);
} catch (error) {
logger.Message('Failed to launch make command. Make sure it is on the path. ' + error);
return;
}
}

199
src/parser.ts Normal file
Просмотреть файл

@ -0,0 +1,199 @@
import * as cpptools from './cpptools';
import * as ext from './extension';
import * as logger from './logger';
import * as path from 'path';
import * as util from './util';
import * as vscode from 'vscode';
export function parseTargets(verboseLog: string): string[] {
// extract the text between "# Files" and "# Finished Make data base" lines
let regexp = /(# Files\n*)([\s\S]*?)(# Finished Make data base)/;
let result: string[] | null = verboseLog.match(regexp);
if (result) {
verboseLog = result[2];
}
var matches: string[] = [];
var match: string[] | null;
// skip lines starting with {#,.} or preceeded by "# Not a target" and extract the target
regexp = /^(?!\n?[#\.])(?<!^\n?# Not a target:\s*)\s*(\S+):\s+/mg;
while (match = regexp.exec(verboseLog)) {
matches.push(match[1]);
}
if (matches) {
matches.sort();
logger.Message("Found the following targets:" + matches.join(";"));
} else {
logger.Message("No targets found");
}
return matches;
}
// TODO:
// - account for changes of directory when resolving relative paths
// - support for response files (@) and compiler wrappers (example: cl.cmd)
export async function parseDryRunOutput(dryRunOutputStr: string) {
// Empty the cummulative browse path built with the previous dry-run parsing
cpptools.emptyCummulativeBrowsePath();
// {space} | compiler w/o path, w/o .exe, w/o quotes | switches - or / | files
// Compilers: cl, clang, clang++, gcc, g++, icc, icl
// Include also the most common aliases cc and c++
// todo: any other scenarios of aliases and symlinks
// that would make this parsing helper to skip over compilation lines?
// find lines containing compilers
// todo: fix bug with a path containing "cl " in the middle
let regexp = /^[\s\"]*(.*?)(clang|cl\.exe|cl|gcc|cc|icc|icl|g\+\+|c\+\+)[\s\"]*(.*)$/mg;
var matches: string[] = [];
var match: string[] | null;
logger.Message('Parsing dry-run output ...');
// Current path starts with workspace root path and can be modified
// with prompt commands like cd, cd-, pushd/popd or with -C make switch
// todo: implement the current path updates to provide correct information
// to IntelliSense in such scenarios
let currentPath: string = vscode.workspace.rootPath || "";
while (match = regexp.exec(dryRunOutputStr)) {
logger.Message('Full line: ' + match[0]);
let compilerPathInMakefile: string = match[1];
let compilerNameInMakefile: string = match[2];
if (process.platform === "win32" && !path.extname(compilerNameInMakefile)) {
compilerNameInMakefile += ".exe";
}
let compilerFullPath: string = compilerPathInMakefile + compilerNameInMakefile;
// find out full compiler path if missing or partial
if (!util.checkFileExistsSync(compilerFullPath)) {
logger.Message(compilerFullPath + ' does not exist. Searching through the paths in the PATH environment variable...');
let envPath: string | undefined = process.env["PATH"];
let envPathSplit: string[] = [];
if (envPath) {
envPathSplit = envPath.split(path.delimiter);
}
envPathSplit.forEach(p => {
let fullPath: string = path.join(p, path.basename(compilerFullPath));
if (util.checkFileExistsSync(fullPath)) {
logger.Message("Found compiler path " + fullPath);
compilerFullPath = fullPath;
return;
}
});
// todo: if the compiler is not found in path, scan on disk and point the user to all the options
// (the concept of kit for cmake extension)
}
// Parse the includes from a compilation line
let regexp_inc = /(\/I\s*|-I\s*)(\".*?\"|\S+)/mg;
var match_inc: string[] | null;
var includes: string[] = [];
while (match_inc = regexp_inc.exec(match[3])) {
let result_inc: string = match_inc[2].trim();
result_inc = result_inc.replace(/"/g, "");
includes.push(util.makeFullPath(result_inc, currentPath));
}
logger.Message('Includes:' + includes.join(";"));
// Parse the forced includes from a compilation line
let regexp_finc = /(\/FI\s*|-FI\s*)(\".*?\"|\S+)/mg;
var match_finc: string[] | null;
var forced_includes: string[] = [];
while (match_finc = regexp_finc.exec(match[3])) {
let result_finc: string = match_finc[2].trim();
result_finc = result_finc.replace(/"/g, "");
includes.push(util.makeFullPath(result_finc, currentPath));
}
logger.Message('Forced includes:' + forced_includes.join(";"));
// Parse the defines from a compilation line
let regexp_def = /(\/D\s*|-D\s*)(\".*?\"|\S+)/mg;
var match_def: string[] | null;
var defines: string[] = [];
while (match_def = regexp_def.exec(match[3])) {
let result_def: string = match_def[2].trim();
result_def = result_def.replace(/"/g, "");
defines.push(result_def);
}
logger.Message('Defines:' + defines.join(";"));
// Parse the C/C++ standard
let regexp_std = /(\/|-)std(:|=)(\S+)/mg;
var match_std: string[] | null;
var stds: string[] = [];
while (match_std = regexp_std.exec(match[3])) {
let result_std: string = match_std[3].trim();
result_std = result_std.replace(/"/g, "");
stds.push(result_std);
}
// todo:
// - implement standard defaults (c++11 for .c, c++17 for .cpp)
// - account for /TC and /TP
let lastStd: util.StandardVersion;
if (stds.length) {
// If more than one std switch, take the last one
lastStd = <util.StandardVersion>stds.pop();
} else {
lastStd = "c++17";
}
logger.Message('Standard:' + lastStd);
// Parse IntelliSense mode
// how to deal with aliases and symlinks (CC, C++), which can point to any toolsets
var intelliSenseMode: util.IntelliSenseMode = "msvc-x64";
if (compilerNameInMakefile.startsWith("clang")) {
intelliSenseMode = "clang-x64";
} else if (compilerNameInMakefile.startsWith("gcc") || compilerNameInMakefile.startsWith("g++")) {
intelliSenseMode = "gcc-x64";
}
// Parse the source files that are compiled
// todo: consider non standard extensions (or no extension at all) in the presence of TC/TP.
// Attention to obj or pdb files tied to /FO /FD
let regexp_files = /(\".*?\.cpp\"|\S+\.cpp|\".*?\.c\"|\S+\.c|\".*?\.cxx\"|\S+\.cxx)/mg;
var match_file: string[] | null;
var files: string[] = [];
while (match_file = regexp_files.exec(match[3])) {
let result_file: string = match_file[1].trim();
result_file = result_file.replace(/"/g, "");
files.push(util.makeFullPath(result_file, currentPath));
}
logger.Message('Files:' + files.join(";"));
// todo: scan on disk for most recent sdk installation
var windowsSDKVersion: string | undefined = "";
if (process.platform === "win32") {
windowsSDKVersion = process.env["WindowsSDKVersion"];
if (!windowsSDKVersion) {
windowsSDKVersion = "8.1";
}
logger.Message('Windows SDK Version: ' + windowsSDKVersion);
}
if (ext.extension) {
ext.extension.buildCustomConfigurationProvider(defines, includes, forced_includes, lastStd, intelliSenseMode, compilerFullPath, windowsSDKVersion, files);
}
}
}

48
src/ui.ts Normal file
Просмотреть файл

@ -0,0 +1,48 @@
import * as vscode from 'vscode';
let ui: UI;
export class UI {
private configurationButton : vscode.StatusBarItem;
private targetButton : vscode.StatusBarItem;
private buildButton : vscode.StatusBarItem;
SetConfiguration(configuration : string) {
this.configurationButton.text = "Configuration: " + configuration;
}
SetTarget(target : string) {
this.targetButton.text = "Target: " + target;
}
constructor() {
this.configurationButton = vscode.window.createStatusBarItem(vscode.StatusBarAlignment.Left, 3);
this.configurationButton.command = "make.setConfiguration";
this.configurationButton.tooltip = "Click to select the workspace make configuration";
this.configurationButton.show();
this.targetButton = vscode.window.createStatusBarItem(vscode.StatusBarAlignment.Left, 2);
this.targetButton.command = "make.setTarget";
this.targetButton.tooltip = "Click to select the target to be run by make";
this.targetButton.show();
this.buildButton = vscode.window.createStatusBarItem(vscode.StatusBarAlignment.Left, 1);
this.buildButton.command = "make.build.current";
this.buildButton.tooltip = "Click to build the target of the current workspace configuration";
this.buildButton.text = "Build";
this.buildButton.show();
}
public dispose(): void {
this.configurationButton.dispose();
this.targetButton.dispose();
this.buildButton.dispose();
}
}
export function getUI(): UI {
if (ui === undefined) {
ui = new UI();
}
return ui;
}

59
src/util.ts Normal file
Просмотреть файл

@ -0,0 +1,59 @@
import * as fs from 'fs';
import * as child_process from 'child_process';
import * as path from 'path';
// TODO: c++20, c++latest
export type StandardVersion = 'c89' | 'c99' | 'c11' | 'c++98' | 'c++03' | 'c++11' | 'c++14' | 'c++17';
export type IntelliSenseMode = "msvc-x64" | "gcc-x64" | "clang-x64";
export function checkFileExistsSync(filePath: string): boolean {
try {
return fs.statSync(filePath).isFile();
} catch (e) {
}
return false;
}
// Helper to spawn a child process, hooked to callbacks that are processing stdout/stderr
export function spawnChildProcess(process: string, args: string[], workingDirectory: string,
stdoutCallback: (stdout: string) => void,
stderrCallback: (stderr: string) => void,
closingCallback: (retc: number, signal: string) => void): Promise<void> {
return new Promise<void>(function (resolve, reject): void {
const child: child_process.ChildProcess = child_process.spawn(process, args, { cwd: workingDirectory });
child.stdout.on('data', (data) => {
stdoutCallback(`${data}`);
});
child.stderr.on('data', (data) => {
stderrCallback(`${data}`);
});
child.on('close', (retCode: number, signal: string) => {
closingCallback(retCode, signal);
});
if (child.pid === undefined) {
throw new Error("PID undefined");
}
});
}
// Helper to eliminate empty items in an array
export function dropNulls<T>(items: (T | null | undefined)[]): T[] {
return items.filter(item => (item !== null && item !== undefined)) as T[];
}
// Helper to reinterpret the relative paths (to the workspace folder) printed by make as full paths
export function makeFullPath(relPath: string, curPath: string | undefined): string {
let fullPath: string = relPath;
if (!path.isAbsolute(fullPath) && curPath) {
fullPath = path.join(curPath, relPath);
}
return fullPath;
}