Skip fetch only works when `CPM_SOURCE_CACHE` is defined
When the environment variable CPM_SOURCE_CACHE is set, re-running cmake does not cause a fetch and patch.
When unset, fetch and patch both occur.
The problem observed (see #572 for more discussion) is that the unset path fetch does not overwrite the source and so the patch command fails.
#572 suggests a fix that could ignore errors during patching. I think this could be an issue when a user is testing version updates; it would be nice if we just, say, updated package A to latest version and running CMake told us the patches were incompatible/not applied. I don't think -t reports that?
In my testing, I see that when the environment variable is set, we skip the fetch and patch steps. Maybe we can add a cache variable to indicate the initial fetch and patch skips were successful?
Recreation of this is relatively simple, see https://github.com/ScottBailey/cpm-cmake-test-577 for an automated working example.
@lemire
A simple solution seems to be to always enable the cache.
--- a/cmake/CPM.cmake
+++ b/cmake/CPM.cmake
@@ -154,7 +154,7 @@ set(CPM_DRY_RUN
if(DEFINED ENV{CPM_SOURCE_CACHE})
set(CPM_SOURCE_CACHE_DEFAULT $ENV{CPM_SOURCE_CACHE})
else()
- set(CPM_SOURCE_CACHE_DEFAULT OFF)
+ set(CPM_SOURCE_CACHE_DEFAULT ${CMAKE_CURRENT_BINARY_DIR}/.cpm-cache)
endif()
set(CPM_SOURCE_CACHE
Intriguing.
Would be nice to have some sort of fix for this.
One option would be to do a git checkout . before every patch, at least for the case where there CPM_SOURCE_CACHE_DEFAULT is not set.
Would be nice to have some sort of fix for this.
One option would be to do a
git checkout .before every patch, at least for the case where thereCPM_SOURCE_CACHE_DEFAULTis not set.
I'd love to see this fixed myself. I started working on it, but it's a significant time investment for me. I've done the leg work to easily, repeatable recreate the defect and was hoping someone else might lend a hand. I may have time over the holidays to look deeper into this, but I'm not gonna hold my breath.
If you dig into this, I think you'll find significant complexity around this problem. Enough that a quick fix isn't likely to happen. Still, I'd appreciate someone else taking a look and providing feedback.
@ScottBailey What do you think of @wolfpld's solution?
@ScottBailey What do you think of @wolfpld's solution?
I feel like this is unexpected behavior? I think it's better for the end user to decide how to work around this problem rather than band-aid the repo.
The actual defect is probably an easy fix as we can trace the path between working and failing and compare them. Someone just needs to have the time to do it.
I feel like this is unexpected behavior?
Here is how I view things.
We have two code paths. One that were the cache location is set. This code path works.
We have another code path where the cache location is not set. This code path is broken.
The fix is to have just one code path. If the cache location is not set, we just set it. This drops the broken code path and solves the problem... further simplifying the logic.
That is, that the code is so complicated is part of the bug. Why is it so difficult to understand what is going on?
As a counter, the code path without a cache in fact works except when a patch is added. If we force a cache path we reduce functionality for others. And if we make a band-aid fix we increase technical debt. Like you, I am just a contributor, not a maintainer. But were I a maintainer I don't think I'd want to take a patch that increased technical debt.
Frankly, I've been hoping I'd done enough prep work to make this an easy fix for someone else. And I think it should be an easy fix, just a little time consuming to compare the traces.
(I also have no power here. I am just a user.)
If we force a cache path we reduce functionality for others.
Concretely, what would be lost?
But were I a maintainer I don't think I'd want to take a patch that increased technical debt
How does the patch proposed by @wolfpld increases the technical debt?
My point above is that it reduces the technical debt by reducing the number of code paths.
The workaround generates dead code, no? Unless one were to take it out. Personally, I wouldn't mind a default of "${CMAKE_BINARY_DIR}/CPM_cache" if it didn't already exists because I ALWAYS want to cache and a simplification of the code. :-) I imagine we might get that in. But that is also not a small change.
Very pedantically: the band-aid only reduces the number of code paths executed and does so by generating dead code. That's technical debt. The process of properly removing that code path should is, I'd wager, greater than the cost of fixing the code.
With the band-aid, one would lose the ability to NOT cache downloads. I am uncertain of the impact this might have on others. Furthermore, I'm in no position to hazard a guess. Which means I'm not comfortable supporting its removal. Does that make sense?
Edited to fix a typo.
@ScottBailey
(So we are clear, I have no power here and I am not claiming you are wrong.)
I think that the patch we are discussing is equivalent to making the cache be versioned by default.
With the band-aid, one would lose the ability to NOT cache downloads.
Can't one just set CPM_ARGS_NO_CACHE to avoid cache downloads? Wouldn't that be the proper way?
Very pedantically: the band-aid only reduces the number of code paths executed and does so by generating dead code. That's technical debt. The process of properly removing that code path should is, I'd wager, greater than the cost of fixing the code.
Can you point at the dead code that would result? Which lines of code are you thinking about?
What I see in the code is a handful of case where we check whether CPM_SOURCE_CACHE is truthy.
There is a code region from line 773 to 849 where we check several times that CPM_SOURCE_CACHE is truth (in redundant manners):
https://github.com/cpm-cmake/CPM.cmake/blob/0bc73f41cedb561efe5643826891dcb705c680de/cmake/CPM.cmake#L773-L849
Specifically, they occur at these lines:
https://github.com/cpm-cmake/CPM.cmake/blob/0bc73f41cedb561efe5643826891dcb705c680de/cmake/CPM.cmake#L773
https://github.com/cpm-cmake/CPM.cmake/blob/0bc73f41cedb561efe5643826891dcb705c680de/cmake/CPM.cmake#L792
https://github.com/cpm-cmake/CPM.cmake/blob/0bc73f41cedb561efe5643826891dcb705c680de/cmake/CPM.cmake#L797
There is one additional trivial check...
https://github.com/cpm-cmake/CPM.cmake/blob/0bc73f41cedb561efe5643826891dcb705c680de/cmake/CPM.cmake#L896-L897
Importantly, I do not see any block of code that becomes dead when we add the assumption that CPM_SOURCE_CACHE is always truthy.
Shoot! Your halfway there, why not just fix the defect?
More usefully: when I did the trace between cache set vs cache not set the path was significantly different. At the time I didn't have the bandwidth to really dig in and follow what was going on. I'd have to rerun the trace to have a defensible opinion - I'm really working from memory/gut here. I might have time to go back and look at it during the year end holiday, but probably not before then.