{"id":29391558,"url":"https://github.com/tdjastrzebski/cppbuild","last_synced_at":"2026-03-12T02:32:20.296Z","repository":{"id":49674957,"uuid":"215370819","full_name":"tdjastrzebski/cppbuild","owner":"tdjastrzebski","description":"C/C++ Multi-Step Incremental Build Tool","archived":false,"fork":false,"pushed_at":"2024-12-13T16:17:06.000Z","size":340,"stargazers_count":2,"open_issues_count":1,"forks_count":1,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-10-04T04:54:42.217Z","etag":null,"topics":["build","build-automation","build-tool","build-tools","c","c-plus-plus","cli","command-line","cpp"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/tdjastrzebski.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2019-10-15T18:37:44.000Z","updated_at":"2025-08-23T06:47:59.000Z","dependencies_parsed_at":"2024-12-13T17:25:28.774Z","dependency_job_id":"4c73a01e-13e4-487a-8d52-60fbe9abb532","html_url":"https://github.com/tdjastrzebski/cppbuild","commit_stats":{"total_commits":76,"total_committers":2,"mean_commits":38.0,"dds":"0.013157894736842146","last_synced_commit":"e3afa3737b4d2345e7309d89699f753f48a892e4"},"previous_names":[],"tags_count":14,"template":false,"template_full_name":null,"purl":"pkg:github/tdjastrzebski/cppbuild","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tdjastrzebski%2Fcppbuild","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tdjastrzebski%2Fcppbuild/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tdjastrzebski%2Fcppbuild/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tdjastrzebski%2Fcppbuild/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/tdjastrzebski","download_url":"https://codeload.github.com/tdjastrzebski/cppbuild/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tdjastrzebski%2Fcppbuild/sbom","scorecard":{"id":871105,"data":{"date":"2025-08-11","repo":{"name":"github.com/tdjastrzebski/cppbuild","commit":"49d3b24e1de7b9f24df707231a5a1dafb503811e"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":2.7,"checks":[{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#binary-artifacts"}},{"name":"Token-Permissions","score":-1,"reason":"No tokens found","details":null,"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#token-permissions"}},{"name":"Code-Review","score":0,"reason":"Found 0/28 approved changesets -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#code-review"}},{"name":"Packaging","score":-1,"reason":"packaging workflow not detected","details":["Warn: no GitHub/GitLab publishing workflow detected."],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#packaging"}},{"name":"Dangerous-Workflow","score":-1,"reason":"no workflows found","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#dangerous-workflow"}},{"name":"Pinned-Dependencies","score":-1,"reason":"no dependencies found","details":null,"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#pinned-dependencies"}},{"name":"Maintained","score":0,"reason":"0 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#cii-best-practices"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#security-policy"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#fuzzing"}},{"name":"License","score":10,"reason":"license file detected","details":["Info: project has a license file: LICENSE:0","Info: FSF or OSI recognized license: MIT License: LICENSE:0"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"name":"Signed-Releases","score":-1,"reason":"no releases found","details":null,"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}},{"name":"Branch-Protection","score":0,"reason":"branch protection not enabled on development/release branches","details":["Warn: branch protection not enabled for branch 'master'"],"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#branch-protection"}},{"name":"SAST","score":0,"reason":"SAST tool is not run on all commits -- score normalized to 0","details":["Warn: 0 commits out of 2 are checked with a SAST tool"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}},{"name":"Vulnerabilities","score":7,"reason":"3 existing vulnerabilities detected","details":["Warn: Project is vulnerable to: GHSA-968p-4wvh-cqc8","Warn: Project is vulnerable to: GHSA-v6h2-p8h4-qcjw","Warn: Project is vulnerable to: GHSA-76p7-773f-r4q5"],"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}}]},"last_synced_at":"2025-08-24T04:14:31.273Z","repository_id":49674957,"created_at":"2025-08-24T04:14:31.274Z","updated_at":"2025-08-24T04:14:31.274Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":30413066,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-03-12T00:40:14.898Z","status":"online","status_checked_at":"2026-03-12T02:00:07.260Z","response_time":114,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["build","build-automation","build-tool","build-tools","c","c-plus-plus","cli","command-line","cpp"],"created_at":"2025-07-10T09:38:42.708Z","updated_at":"2026-03-12T02:32:20.269Z","avatar_url":"https://github.com/tdjastrzebski.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# What is it?\r\n**cppbuild** is a multi-step incremental build command line tool based on JSON, string templates and [glob syntax](https://en.wikipedia.org/wiki/Glob_(programming)).  \r\n**cppbuild** has originally been designed to work together with the popular [vscode-cpptools](https://marketplace.visualstudio.com/items?itemName=ms-vscode.cpptools) extension and uses its variables combined with its own build steps.  \r\nSince version 1.2.0 **cppbuild** can be used without [vscode-cpptools](https://marketplace.visualstudio.com/items?itemName=ms-vscode.cpptools) and is not limited to C/C++ builds.\r\n\r\n# Why?\r\nWhile working on C/C++ for embedded devices in VS Code I wanted to simplify multi-step build process configuration and maintenance. Also, I wanted to eliminate duplication of the settings (**include paths** and **defines**) between `c_cpp_properties.json` and widely used MAKE/CMake files. Although these tools are industry standard, I am not a big fan of them. All that led me to the development of a completely new build tool.  \r\nSince [ms-vscode.cpptools](https://marketplace.visualstudio.com/items?itemName=ms-vscode.cpptools) extension is popular and widely used, I adjusted to the status quo and used `c_cpp_properties.json` as it was, instead of supplying my own settings via [vscode-cpptools-api](https://github.com/Microsoft/vscode-cpptools-api).  \r\nInitially **cppbuild** had to use [vscode-cpptools](https://marketplace.visualstudio.com/items?itemName=ms-vscode.cpptools) `c_cpp_properties.json` file. This dependency has been eliminated since version 1.1.0 and now **cppbuild** can be used to run any other builds.\r\n\r\n# What does it do?\r\nThe way **cppbuild** works is very simple. The tool executes build steps, by default defined in `c_cpp_build.json` file. Each build step defines `command` to be executed. `command` is actually a string template where both single and multi-value ($$) variables like `${fileName}`, `${outputDirectory}` or `$${defines}` can be used. If `filePattern` is specified as well the `command` will be executed for every file matching the pattern. In addition, a build step can define one or more **build types** like `debug` or `release`. Build types simply define additional variables, typically compiler options, to be added or changed.\r\n\r\nWhen **cppbuild** is used with [vscode-cpptools](https://marketplace.visualstudio.com/items?itemName=ms-vscode.cpptools), **includePath**, **defines** and **forcedInclude** multi-value variables defined in `c_cpp_properties.json` config file can be used in build step `command`. For this to happen, the corresponding configurations, which have the same name, must be present in both `c_cpp_build.json` and `c_cpp_properties.json` files.\r\n\r\nAdditional variables may be supplied on all levels and as command line arguments.\r\n\r\n# How to use it?\r\nInstall: `npm install cppbuild -g`  \r\n\r\n* From VS Code folder run: `cppbuild \u003cconfig name\u003e [build type] -w [workspace root]`  \r\n**cppbuild** will use `c_cpp_build.json` and `c_cpp_properties.json` files from `.vscode` folder in current or specified workspace root.\r\n\r\n* Otherwise run: `cppbuild \u003cconfig name\u003e [build type] [-b \u003cJSON build file\u003e]`  \r\nBy default, **cppbuild** will use `c_cpp_build.json` file from local folder or any other file specified.\r\n\r\nThe only required argument is **config name** - one of the configurations defined in build file. **Build type** name can be supplied optionally.\r\n\r\nFor more options run: `cppbuild --help`\r\n\r\n# Configuration file syntax\r\n[c_cpp_build.json](test-cpp/.vscode/c_cpp_build.json) file defines multiple configurations, build types and build steps.  \r\nSee the content of the [c_cpp_build.json](test-cpp/.vscode/c_cpp_build.json) file for a sample build configuration.\r\n\r\nSample build type:\r\n```yaml\r\n{\r\n  \"name\": \"debug\",\r\n  \"params\": { \"buildTypeParams\": \"-O0 -g\" }\r\n}\r\n```\r\n\r\nSample build step:\r\n```yaml\r\n{\r\n  \"name\": \"C++ Compile\",\r\n  \"filePattern\": \"**/*.cpp\",\r\n  \"outputFile\": \"build/${buildTypeName}/${fileDirectory}/${fileName}.o\",\r\n  \"command\": \"g++ -c ${buildTypeParams} (-I[$${includePath}]) (-D$${defines}) [${filePath}] -o [${outputFile}]\"\r\n}\r\n```\r\nRun: `cppbuild gcc gcc-x64 --initialize c_cpp_build.json` to create sample build file with typical **gcc** settings. Other supported settings: **msvc** and **clang**\r\n\r\nHere is how it works:\r\n1. **command** (here g++ compiler) is run for every file matching **filePattern** (**/*.cpp).\r\n1. `(-I[$${includePath}])` and `(-D$${defines})` define sub-templates repeated for every **includePath** and **defines** value listed in corresponding configuration from **c_cpp_properties.json** file.\r\n1. `${fileName}`, `${filePath}` and `${fileDirectory}` are substituted by the name, path and relative directory of the file being processed.\r\n1. `${outputFile}` value is built as defined by **outputFile** template. Note that **outputFile** can be build using relative path of the file being processed. As a result, inside the output **build** folder directory structure will resemble the input directory structure. Required directory will be created if it does not exists.\r\n1. `${buildTypeParams}` is defined in **build type** section. For DEBUG build type `-O0 -g` switches will be added.\r\n1. Strings in `[]` are treated as file paths and will be quoted if path contains whitespace. Path separators may be modified depending on the OS.\r\n1. Be default, if **outputFile** already exists and is more recent than the processed input file, build for this file will not be performed. As a result, only modified files will be built (incremental build).\r\n\r\n# Notes\r\n1. **filePattern**/**fileList** build step properties use [glob syntax](https://en.wikipedia.org/wiki/Glob_(programming)). Tool internally relies on [glob module](https://github.com/isaacs/node-glob) so more advanced file patterns and exclusions are supported.\r\n1. **filePattern**/**fileList** are mutually exclusive. If **filePattern** is used, command will be executed for every file matching the pattern.  \r\nIn contrast, **fileList** only populates `$${fileDirectory}`, `$${filePath}` and `$${fileName}` multi-valued variables.\r\n1. Standard `${name}` variable syntax is used for single-valued variables. `$${name}` denotes multi-valued variable.\r\n1. Strings in `()` (e.g. `(-D$${defines})`) are sub-templates repeated for every variable value inside. Therefore, only one multi-valued variable inside `()` is allowed. If sub-template contains path or file name which may require quoting, `[]` can be used instead, e.g. `[$${fileName}.cpp]`.\r\n1. Environment values (`${env:name}`) and standard variables **workspaceRoot**/**workspaceFolder** and **workspaceRootFolderName**/**workspaceFolderBasename** can be used.\r\n1. **filePattern** and **outputDirectory** are not required. Command without **filePattern** will be executed just once.\r\n1. **build types** do not have to be defined - they are optional and they can define multiple additional variables. If specified, **buildTypeName** variable is added.\r\n1. If **outputDirectory** or **outputFile** are specified, the required directory will be created if it does not exist.\r\n1. **includePath** and **forcedInclude** multi-value variables defined in `c_cpp_properties.json` can contain [glob patterns](https://en.wikipedia.org/wiki/Glob_(programming)). Paths will be expanded.\r\n1. Variables can be defined globally, on configuration, task and build type level. Low level variables override higher levels variables. Command line provided variables have the highest priority.\r\n1. Variable values can contain other variables and templates. For that reason special characters like `\\${}[]()` in simple literals (e.g. file paths) must be escaped using `\\`, e.g. `\"C:\\\\Program Files \\\\(x86\\\\)\"`.\r\n1. Order in which variables are defined does not matter. Variables defined first can be used later, variables defined in higher level can be included on lower level, e.g. `\"paths\": [\"$${paths}\", \"c:\\additional_path\"]`.\r\n1. Multi-value variables can contain variable name, glob expression or comma-separated list of quoted values or templates, e.g. `[$${paths}]`, `[$${**/*.c}]`, `[$${'main.h', 'main.c'}]`, `[$${'**/*.h', '**/*.c'}]`.\r\n1. JSON file can contain comments - internally [MS JSONC](https://github.com/microsoft/node-jsonc-parser) parser is used.\r\n1. **cppbuild** can be run without `c_cpp_properties.json` file. Use `-p` flag with no file name.\r\n1. It is possible to provide root folder, alternative configuration file paths and names using command line options.  \r\n1. Run: `cppbuild --help` for all supported options.\r\n\r\n# Predefined variables\r\nThe following variables have been predefined:\r\n1. **workspaceRoot**/**workspaceFolder** (full folder path) and **workspaceRootFolderName**/**workspaceFolderBasename** (just the folder name)\r\n1. **configName** - selected build configuration name\r\n1. **buildTypeName** - selected build type name (optional)\r\n1. **filePath** (relative file path), **fileDirectory** (relative file directory), **fileName** (file name without extension), **fullFileName** (file name with extension), **fileExtension** (without '.')  \r\nThe above variables are available when **filePattern** or **fileList** build step property is defined. When **filePattern** is defined, variables have single values and `command` is executed for every file matching the specified pattern. When **fileList** is defined, variables have multiple values but build step `command` is executed just once.\r\n1. **outputDirectory** - output directory, available when build step **outputDirectory** template is specified. Path will be created if it does not exist.\r\n1. **includePath**, **defines** and **forcedInclude** - multi-valued variables populated from `c_cpp_properties.json` (if used)\r\n1. **outputFile** - available only when **filePattern** is specified, triggers incremental build.\r\n\r\n# Release notes\r\n* 1.0 Initial release\r\n* 1.1 `params` can be added on all levels, tool can work without C/C++ extension and `c_cpp_properties.json` file.\r\n* 1.2 Added support for incremental builds and `outputFile` build step property and variable.\r\n* 1.2.8 Output information improved\r\n* 1.3.0\r\n    * Much better structured and more capable recursive parser.\r\n    * Multi-value variables can be glob expressions, lists or lists of glob expressions. Example: `[$${'**/*.h', '**/*.c'}]`  \r\n    Another example: `(-include [$${${fileDirectory}/include/*.h}])`. This sub-template includes all the header files from the given file `include` sub-folder.\r\n    * Variables can contain templates and reference previously defined variables of the same name. This way values defined previously can be merged with new values.\r\n    * Escape character `\\` support. Special characters like []{}() defining sub-templates have to be escaped if used for other purpose, e.g. in file paths. **This change is breaking.**\r\n    * `-t` option  and `trimIncludePaths` build step property added. When set to `true`, static analysis is performed and only required include paths are used. This option can greatly reduce command length, helping to avoid Windows **8192** characters command length limit.\r\n    * `-d` option added for debug output.\r\n    * `-i` option added for creating sample build configuration.\r\n    * `-c` option added to continue on errors.\r\n* 1.3.11 Bug fixes\r\n* 1.3.12 TSLint -\u003e ESLint\r\n* 1.3.14 commented out `#define` directives are correctly ignored, packages updated\r\n* 1.3.15 **c_cpp_properties** schema updated, minor fixes\r\n* 1.3.16 **c_cpp_properties** schema updated again, serious parser bug fix, packages updated, first attempt at full dependency analysis (and rebuild)\r\n* 1.3.17 lodash updated to ver 4.17.20 to eliminate its known vulnerabilities\r\n* 1.3.19 warning color change, numerous packages updated, c_cpp_properties.schema updated\r\n* 1.3.20 c_cpp_properties.schema updated\r\n\r\n# Further improvements\r\nI am certain this tool could be further improved in many ways, including both functionality and code structure. This is the second TypeScript program I have ever written (the first one was \"hello world\" app).  \r\nFor example, multi-valued variables currently cannot be specified from command line.\r\n\r\nPlease do not hesitate to suggest fixes and improvements. Pull requests are more than welcome.\r\n\r\nFinally, if you find this tool useful, please give it a star. This way others will be able to find it more easily.\r\n\r\n# TODO\r\n* fix unhandled error if a file in \"forcedInclude\" does not exist\r\n* fix missing includes when actual file name casing does not match the one specified in #include\r\n* use already implemented full dependency analysis and rebuild all the dependent file branch\r\n* test dependency on `defines` in `c_cpp_properties.json`\r\n* replace depreciated typescript methods\r\n* update components to last major versions\r\n* allow `filePattern` to accept array\r\n* make `trimIncludePaths` default true\r\n* add `excludeFiles` param, also accepting array\r\n* change `name` -\u003e `configName` and allow to be used as r/o variable\r\n* parse #include \u003cfile\u003e\r\n* read settings (variables) from `.vscode/settings.json`","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftdjastrzebski%2Fcppbuild","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftdjastrzebski%2Fcppbuild","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftdjastrzebski%2Fcppbuild/lists"}