{"id":23007141,"url":"https://github.com/dkorolev/pls","last_synced_at":"2026-02-11T07:33:37.768Z","repository":{"id":251355830,"uuid":"837174204","full_name":"dkorolev/pls","owner":"dkorolev","description":"One-liner build and run commands for C++ binaries and libraries. Transitive dependency management. Generates `CMakeLists.txt`-s and `Makefile`-s as needed. Out-of-the-box integration with VS Code.","archived":false,"fork":false,"pushed_at":"2025-02-15T02:51:11.000Z","size":157,"stargazers_count":1,"open_issues_count":6,"forks_count":1,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-06-18T08:49:40.615Z","etag":null,"topics":["cmake","cpp","git","makefile"],"latest_commit_sha":null,"homepage":"","language":"Python","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/dkorolev.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":"2024-08-02T11:21:59.000Z","updated_at":"2025-02-15T02:51:15.000Z","dependencies_parsed_at":"2025-06-18T08:44:52.413Z","dependency_job_id":null,"html_url":"https://github.com/dkorolev/pls","commit_stats":null,"previous_names":["dkorolev/pls"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/dkorolev/pls","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dkorolev%2Fpls","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dkorolev%2Fpls/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dkorolev%2Fpls/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dkorolev%2Fpls/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/dkorolev","download_url":"https://codeload.github.com/dkorolev/pls/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dkorolev%2Fpls/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29329493,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-11T06:13:03.264Z","status":"ssl_error","status_checked_at":"2026-02-11T06:12:55.843Z","response_time":97,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"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":["cmake","cpp","git","makefile"],"created_at":"2024-12-15T08:14:48.598Z","updated_at":"2026-02-11T07:33:37.746Z","avatar_url":"https://github.com/dkorolev.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"[![Self-test the HEAD](https://github.com/dkorolev/pls/actions/workflows/run_selftest.yml/badge.svg)](https://github.com/dkorolev/pls/actions/workflows/run_selftest.yml)\n\n# `pls`\n\nThe build system for `CMakeLists.txt` projects, mostly C and C++. Designed for predictability and ease of use.\n\n## Setup\n\nYou will need `pls` in your path. Cloning this repo and `alias`-ing it in your `.bashrc` / `.zshrc` would do.\n\nAlternatively, if you have a Python environment set up, `pip3 install plsbuild` does the trick.\n\nIf `pls version` or `pls v` works, you're good.\n\nYou will also need the usual shenanigans of course, the C++ compiler and `cmake`.\n\n## Links\n\nFor a quick start, scroll down to the Examples section. The more detailed manual is (`TODO(dkorolev)`: Links.):\n\n* Goals, assumptions, and principles.\n* Operational logic.\n* The complete feature set.\n\n## Examples\n\nMost examples here assume an otherwise empty directory.\n\nIf this directory is a git repo (cloned, or `git init .`), the `.gitignore` magic will work its way too.\n\n### Trivial\n\nFor the following `example.cc`:\n\n```\n#include \u003ciostream\u003e\n\nint main() {\n  std::cout \u003c\u003c \"Hello, World!\" \u003c\u003c std::endl;\n}\n```\n\nJust running `pls build` and `pls run` would do exactly what you assume.\n\nThe binary will be created in `.debug/example` for `pls build`. Also, `TODO(dkorolev):` there should be a release target.\n\nNote that these runs of `pls` will create a `CMakeLists.txt`, so that you can open your favorite CMake-aware IDE and run / trace into this code. VS Code would do just fine.\n\nAlso, if this `CMakeLists.txt` was created by `pls`, it will be added to `.gitignore`. If this is not the intended behavior, check it in, or just manually remove it from `.gitignore`. This would do.\n\nThe idea behind `pls` is that if the user intends to have a `CMakeLists.txt` file, this user-provided `CMakeLists.txt` file will be kept. If not, then the user likely does not want `CMakeLists.txt`, so the \"trivial\" boilerplate `CMakeLists.txt` that is being created should be treated as ephemeral. Simplicity first is key.\n\nAlso, by default `pls` looks into the root project directory and its `src/` subdirectory. Dirs beyond these two are non-standard, and require an explicit mention in `pls.json`, see below. `TODO(dkorolev):` Implement and test this.\n\n### Dependency\n\nNow, let's use a [trivial dependency](https://github.com/dkorolev/trivial_cmake_lib).\n\n```\n#include \u003ciostream\u003e\n\n#include \"pls.h\"\n\nPLS_ADD(\"trivial_cmake_lib\", \"https://github.com/dkorolev/trivial_cmake_lib\");\nPLS_DEP(\"trivial_cmake_lib\");\n\n#include \"trivial_cmake_lib.h\"\n\nint main() {\n  std::cout \u003c\u003c \"2+2=\" \u003c\u003c trivial_cmake_lib_add(2, 2) \u003c\u003c std::endl;\n}\n```\n\nThis works as a standalone example, with `pls build` or `pls run`.\n\nBesides, after the first run of `pls`, either `pls build` or `pls run`, the created `CMakeLists.txt` can be used with an IDE.\n\nNote that you do not need the `\"pls.h\"` file. The `pls`-provided build setup handles this. `TODO(dkorolev):` Make sure it works for non-`pls` users to some day.\n\nWhen it comes to where the `PLS_*` statements should go in the code, just make sure it takes place before `#include`-ing any headers from the libraries to be imported. Otherwise the preprocessor will fail on missing header files, will never get to processing the `PLS_*` statements, and the auto-import magic will not work.\n\nThe semicolon after `PLS_*` statements is optional.\n\nBehind the scenes, in the \"true\" build, the `PLS_*`-s are macros that only check that the passed-in parameters are compile-time strings. During the pre-build phase, prior to `cmake` cofiguration, these `PLS_*` statements are interpreted differently, so that the dependencies are extracted by `pls`.\n\n### The `pls.json` File\n\nWhile `pls` strives for simplicity, `PLS_*()` statements in code are not the only, or even the recommended way to define dependencies.\n\nThe long-form way is to use the `pls.json` file:\n\n```\n{\n  \"import\": {\n    \"trivial_cmake_lib\": \"https://github.com/dkorolev/trivial_cmake_lib\"\n  }\n}\n```\n\nFor toy projects using `pls.json` might be too much, since `PLS_*()`-s would do the job just fine. Personally, I'm a huge fan of having small self-contained sources for simple tasks. On the other hand, if you are maintaining a library, you may want to have a `pls.json` file, which has an extra benefit of not having to modify source files.\n\nAlso, `TODO(dkorolev):` need to support some `pls add ...` command to add dependencies into `pls.json` automatically.\n\n### Nested Dependencies\n\nWhen running `pls build` (or `pls install`, or `pls b` or `pls i` for short), the dependencies will be installed recursively. They will be cloned into `.pls/deps`, symlinked into the root directory of the repository, and `.gitignore`-d accordingly.\n\nEffectively, `pls`-installed dependencies are designed to be \"included\" straight away as `add_subdirectory(dep_name)` from the project's `CMakeLists.txt`. If the project does have its own `CMakeLists.txt`, it should require these dependencies as such. If it does not, the respective `CMakeLists.txt` will be created by `pls`, included in the project, and `.gitignore`-d, since it is meant to be ephemeral.\n\nRecursively, if and when a particular respective dependency does not have the `CMakeLists.txt` file by itself, it will also be created the same way, as well as all the sub-dependencies for this particular dependency, if they are listed in the `.cc` file(s) via `PLS_*()` statements, or in the `pls.json` file directly.\n\nThe `pls` tool does not attempt to parse existing `CMakeLists.txt` files. When a dependency has the `CMakeLists.txt` file, `pls` assumes this is the terminal dependency that should be `add_subdirectory()`-d by itself.\n\n`TODO(dkorolev):` To clone dependencies alongside it, to be used by this external library, we need some `\"inject\": ...` syntax in `pls.json`.\n\nAlso, when creating these dependencies, `pls` will wrap each and every one into a \"singleton\" `CMakeLists.txt`, with another layer of indirection via symlinking the `impl` directory. This is to make sure that if a dependency is used more than once, there are no errors on the `cmake` level.\n\n### Remains To Do\n\n* Test targets.\n* Debug vs. release.\n* Versioning and conflicts.\n* Proper \"unit\" tests, Github actions, links to them.\n* Branch protection so that I drop the habit of pushing straight into `main`. =)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdkorolev%2Fpls","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdkorolev%2Fpls","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdkorolev%2Fpls/lists"}