Inject FetchContent logic#105
Conversation
|
This is an alternative and mutually exclusive approach to #92. Note that it uses yet another approach to letting the same repo use either This approach is more code compared to #92, but I would expect if we liked this approach, the entirety of the Another merit of this approach compared to #92 is that pinned dependency information is in legible JSON format, so automation (like a |
|
On the failing CI checks, they are due to a missing googletest dependency, which isn't a large concern. It's not too difficult to have presets that prefer First, I'd like to hear whether this is a design we would like to pursue before investing time in troubleshooting CI failures. |
wusatosi
left a comment
There was a problem hiding this comment.
Is this too much complexity for supporting using local GTest package? Looks like you are trying to implement a package manager.
|
@wusatosi Using Using it explicitly is an incomplete approach to dependency management since it doesn't have the features (sandbox-friendliness, portability to existing packaging systems, trivial version bumping) that I'm looking for with this PR. This PR demonstrates how Another approach to consider would be to use
|
7cf679e to
a29153f
Compare
|
This latest commit fixes the linting checks, especially CMake formatting issues. The remaining CI failures revolve around actually installing |
|
I made a PR against the Beman Standard to land alongside this change that recommends |
32a71f1 to
44d4fa5
Compare
|
Forgive the CI-driven-development, but the HEAD commit on this PR now works. This is ready for review, and if acceptable, merging. |
| name: "Unit: ${{ matrix.platform.description }} ${{ matrix.cpp_version }} ${{ matrix.cmake_args.description }}" | ||
| name: "Unit: | ||
| ${{ matrix.platform.description }} | ||
| ${{ matrix.cpp_version }} | ||
| ${{ matrix.cmake_args.description }}" |
There was a problem hiding this comment.
I edited this line and a few others like it to make the file easier to read, diff, and review. Hopefully everyone's OK with doing that as part of this PR.
| -S . | ||
| -DCMAKE_CXX_STANDARD=${{ matrix.cpp_version }} | ||
| -DCMAKE_TOOLCHAIN_FILE="${{ matrix.platform.toolchain }}" | ||
| -DCMAKE_PROJECT_TOP_LEVEL_INCLUDES="./cmake/use-fetch-content.cmake" |
There was a problem hiding this comment.
Let me note since the formatting changes obscure the change a little. This argument referencing use-fetch-content.cmake is added. It makes this CI workflow use FetchContent.
Pay attention to the other cmake commands in this file as well. If you do not see a mention of use-fetch-content.cmake, the workflow uses find_package and system installed dependencies.
There was a problem hiding this comment.
Config priority
Do we really want searching for local libgtest to be the default behavior?
For people hacking around beman or downstream paper/implementation authors, I don't think they will be more likely to care about offline run with libgtest installed than being able configure the project with one click.
I think the priority is off, it should be:
First: People with generic environment (cmake, gcc, a network connection and no libgtest) should have the ability to configure the project with one click.
Second: People that want to configure the project for offline configuration (e.g. they are so interested in the project that they bring the project on a plane or into their company) should have the option via an explicit parameter to do an offline build.
Need docs for downstream library authors
Missing docs for downstream library author that want to add a beman project (e.g. iterator-interface or execution) as sub-dependency. Do they have to do -DCMAKE_PROJECT_TOP_LEVEL_INCLUDES="./cmake/use-fetch-content.cmake" all the time?
The internals of lockfile.json is not documented (why not dependencies.json btw), and it's not clear how offline functionality will interact with them. I think this is significant enough of a change to require documentation before merging.
Using fetch content shouldn't look like magic
I would prefer if we can switch this behavior with something like: BEMAN_DEPENDENCY_FETCH=LOCAL (as enum option with local, fetch. so we can add maybe vcpkg in the future).
This would be a lot more declarative and obvious to change for downstream than adding: CMAKE_PROJECT_TOP_LEVEL_INCLUDES="./cmake/use-fetch-content.cmake.
We want
I'm opposed to implementing bits and pieces of a dependency management system in every Beman library. It makes more sense to move the whole community to supported and widely adopted technologies like Conan, vcpkg, and/or a number of other systems that already support fetching dependencies from the internet (or not) in all sorts of configurations. I'll be clear about this. Downloading dependencies from github.com is supported by both Conan and vcpkg (and all the other options too!). It's really easy and covered by the introductory tutorials of both options. They both support building against a local cloned and modified of the
A One of the biggest problems with I also don't want users to type
That's fair, and I can update the PR quickly to add some docs, though they are more developer documentation for maintainers of Exemplar than something I expect users will need to interact with. Meaning I'm not sure if I'll put them in a user-facing I'm fairly flexible on the name, for what it's worth. If we can get consensus but only if the file is named To explain my reasoning, I chose the name "lockfile" because that's one term of art for files like these. If you ask your search engine or your favorite programmer-oriented LLM tool will turn up full explanations, I expect, but here's the Conan Lockfile documentation for a quick and relevant example PS. By linking the Conan docs on the subject of dependency pinning, I'm throwing shade at |
|
Cool! I don't and can't claim to know enough about CMake or package managers to provide more judgement, but as long as my concerns are seen I am happy to sit aside and learn by observation. My only concern would be loss of one-click setup, I think a cheaty way would be to do this would be adding |
44d4fa5 to
6ff2015
Compare
Problem ------- **Given**: A sandbox environment is an environment where dependencies are all provided but access to the internet is not. Also take as a given that the build for this project happens in an environment that meets that description. **When**: Configuring this project with any of the provided approaches. For instance: ``` cmake -B build -S . ``` **Then**: The configuration step hangs or fails, depending on the nature of the sandboxed environment. Solution -------- Move to a `find_package` first implementation for the `CMakeLists.txt` of this project. Using `FetchContent` is still trivial, using the new functionality in `cmake/use-fetch-content.cmake` as documented in the updates to `README.md` included in this commit. Signed-off-by: Bret Brown <[email protected]>
* Use the `libgtest-dev` package on Ubuntu for the compiler-test workflow. * Use the `use-fetch-content.cmake` flag in other workflows. * Discontinue use of `--workflow` for CMake as it does not support use of any `-D` flags, which are required to use `FetchContent` via `use-fetch-content.cmake` on Windows and MacOS. The approach in this commit provides coverage for both FetchContent and find_package approaches to the project. Signed-off-by: Bret Brown <[email protected]>
37bf0d0 to
fc0b45f
Compare
|
This PR is updated and ready for final review. If it's basically OK, I would like to merge so I can push up pull requests to initially support Conan and vcpkg. I'm happy to collaborate on followon PRs to provide more polish, iterate on how we inject FetchContent, etc. @wusatosi I added some documentation for |
wusatosi
left a comment
There was a problem hiding this comment.
CI and docs looks good to me with minor suggestions.
This is a CMake heavy PR that I am not qualified to approve. I think @camio should take a crack at this.
I am still bit salty about the loss of ergonomics here, but I guess we can bring it back later.
I encourage reviewer to read through my comments and @bretbrownjr 's reply, there are significant decisions made in this PR.
|
Can you add this patch so the devcontainer still work? diff --git a/.devcontainer/postcreate.sh b/.devcontainer/postcreate.sh
index bddba03..81d2420 100644
--- a/.devcontainer/postcreate.sh
+++ b/.devcontainer/postcreate.sh
@@ -1,3 +1,6 @@
# Setup pre-commit
pre-commit
pre-commit install
+
+# Install GoogleTest
+sudo apt-get -y install libgtest-dev |
fc0b45f to
e5bc7df
Compare
|
@wusatosi I added more docs walking through how to add a Catch2 dependency. Does that help? I also added |
These docs were added to `docs/README.md` since that file is targeted at people looking to contribute to this project. Signed-off-by: Bret Brown <[email protected]>
* Add libgtest-dev to devcontainer. * Restructure devcontainer to group repository tweaks, debian package installs, and pip package installs into separate sections. * Within each group, sort installed packages alphabetically, and put each on its own line. This makes code review and conflict resolution easier.
e5bc7df to
51c5d96
Compare
wusatosi
left a comment
There was a problem hiding this comment.
👌 no more complaints from me
| @@ -88,16 +88,13 @@ This project requires at least the following to build: | |||
|
|
|||
| * C++17 | |||
There was a problem hiding this comment.
| * C++17 | |
| * C++20 |
Below we're now defaulting to 20, which seems to be the right default - suggest we update here too.
There was a problem hiding this comment.
I didn't change this detail. for what it's worth.
I believe the library supports C++17 entirely, but certain test cases require C++20 to run.
I'm pretty sure we could backport the library to C++03, even. I think all of the build requirements are related to the unit tests, but I've been focusing mostly on tooling details, so I haven't followed up on this detail.
Given you've approved the PR, I'll assume that means we're OK addressing the C++ standard compatibility in a separate PR or issue.
There was a problem hiding this comment.
This shouldn't affect this PR, but I was writing a convenience utility for processing json in cmake in a more declarative way instead of the convoluted string function that currently exists. Maybe unnecessary if we don't expect to write too much of this cmake code like this
JeffGarland
left a comment
There was a problem hiding this comment.
Overall this looks like a good step forward -- I've made a couple small suggestions, but overall I think we should merge and improve from here. Approving.
* Bulleted lists should be a complete sentence with a period. Co-authored-by: Jeff Garland <[email protected]>
|
I'm merging this change given the approving reviews. @wusatosi, I'm happy to team up on follow up on issues and PRs addressing ergonomic concerns. |
Problem
Given:
A sandbox environment is an environment where dependencies are all provided but access to the internet is not. Also take as a given that the build for this project happens in an environment that meets that description.
When:
Configuring this project with any of the provided approaches. For instance:
Then:
The configuration step hangs or fails, depending on the nature of the sandboxed environment.
Solution
Move to a
find_packagefirst implementation for theCMakeLists.txtof this project.Using
FetchContentis still trivial, using the new functionality incmake/use-fetch-content.cmakeas documented in the updates toREADME.mdincluded in this commit.