Recently there has been some discussion about how we deal with optional dependencies in LLDB. The common approach in LLVM is to make things work out of the box. If the dependency isn't there, we just move on. This is not true in LLDB. Unless you explicitly disable the dependency with LLDB_DISABLE_*, you'll get a configuration-time error.
When a dependency is not found in LLVM, it prints a status message. This is something I don't like, because there are quite a lot, and they're easy to miss. I'd rather not build all of LLDB only to find out that it couldn't find Python and now I can't run the test suite. Given how "important" some of our dependencies really are, I think a warning isn't unreasonable.
For the first approach we'd need 3 variables for every CMake option.
- The default value.
- The user provided value, which can override the default value. If the user says they want to disable Python, we shouldn't print the aforementioned warning.
- The value actually used by LLDB. This needs to be different from the one provided by the user, because maybe they enabled Python, but the library couldn't be found.
What I don't like about this approach is there needs to be a discrepancy between the variable provided by the user and the one used in the code. If I pass LLDB_DISABLE_PYTHON I want to grep for that and see what it affects.
The second approach is printing the warning once, and modifying the user-provided variable in the cache. So if you pass LLDB_DISABLE_PYTHON=OFF and CMake can't find it, it would update LLDB_DISABLE_PYTHON=ON, which is what you'd probably do in the current situation. This also means the warning is only printed once, because once LLDB_DISABLE_PYTHON is set, you wouldn't try looking for it again.
What I don't like about this approach is that this is messing with my user provided variables behind my back. Sure it prints a warning, but if there were other configuration issue I might need to rerun CMake and be oblivious what happened.
The third and final approach is doing what LLVM does. If the dependency is found, turn the option on (unless the value is overwritten by the user) and vice versa. This is by far the cleanest approach from a CMake and UX perspective, but I've already stated what I don't like about this.
PS: The diff shows what (2) would look like.
It's not fully clear to me what will happen when this code is run for the first time (when CURSES_INCLUDE_DIRS, etc. is not defined yet). Who will set CURSES_PANEL_FOUND in that case? Could you make sure this works correctly when run for the first time on a fully clean build?
I don't know whether this is the standard way of writing find_package files, but I'd consider just removing the caching and letting find_package(Curses) and find_library(panel) just run every time -- they already contain some internal caching so we're not saving much here anyway...