I've run into a bit of an issue with the find_package interface. Let's say I want to use a library libsemver:
find_package(semver REQUIRED) Now, I want my code to work even when libsemver releases new versions with breaking API changes, and I happen to know they follow the semantic versioning system. So, I lock my project to any version where the major version is 1: find_package(semver 1 EXACT REQUIRED) This works for a while, but then I discover that version 1.0 is not sufficient and I need at least version 1.1 - but there's a problem. There are other versions after 1.1, such as 1.2, which contain new features and bug fixes that many users will want, but I still want to let my users use 1.1 if that's all they have installed on their system and/or they cannot upgrade to the newer versions. If I write `find_package(semver 1.1 REQUIRED)`, this allows it to find version 2 which has breaking API changes and will not allow my project to compile. If I write `find_package(semver 1.1 EXACT REQUIRED)` this does not allow it to find version 1.2 which my users may want to use for the new features and bug fixes. I don't currently see any direct way to say that the major version must be 'exact' and the minor version must be 'at least'. The only options I see are messy - for example, writing my own find module instead of using the existing one provided by libsemver, or trying to optionally find each known minor version in order of preference. Neither of these is a good option because it now forces my project to stay in sync with libsemver. As a result, the latter option will not allow me to go back to previous commits and try to compile them because their version lists will be out of date, and the former option will require me to manually keep my find module in sync with libsemver's find module by constantly patching it with the version hack instead of just simply copying it without changes. So it seems I am stuck between a rock and a hard place. If there is a better alternative or a way around this I don't know of, please enlighten me. I have done some thinking on this and I believe I have thought of a good way to fix this problem while retaining compatibility in CMake - that is, I know the general idea of what I would need to change in CMake itself and would be willing to create such a patch if it were simple enough. However, I want feedback before I go any further - this is my idea: Instead of only allowing EXACT in find_package, which requires all the specified version numbers to match (or whatever custom logic the find module uses), I would make it so you could instead specify one of EXACT_MAJOR, EXACT_MINOR, EXACT_PATCH, or EXACT_TWEAK. For example: find_package(semver 1.1 EXACT_MAJOR REQUIRED) The above would require the major version to be exactly 1, but the minor version need only be at least 1. Thus, 2.0 would not match, but 1.1 and 1.2 would. find_package(semver 1.2.3 EXACT_MINOR REQUIRED) The above would require the major version to be exactly 1, the minor version to be exactly 2, and the patch version to be at least 3. EXACT_MAJOR is implicitly set. Of course, implementing this in CMake itself would not be the end of the story - this would also require that the find module be aware of the new options. For existing find modules, they would behave as if EXACT were specified, and would need to be manually updated to account for the new EXACT_* options. But, EXACT would still be a valid option to use, so existing projects need not update all their find_package calls, and find modules don't need to be updated if nobody wants to support the new functionality. If you are wondering about edge cases, I have already thought of some and know how to deal with them - for example, `find_package(semver 1.1 EXACT_TWEAK REQUIRED)` would issue either an error or warning (not sure which is better). I think edge case discussion would be better suited to when/if this is actually being implemented - for now I just want general feedback. The basic functionality within CMake would probably be simple to implement (I assume), but CMake has a lot of find modules included with it that would need to be individually updated to support the new functionality, and I'm not sure if that should be in the same patch or not. Any feedback on this subject would be great - I'd love to resolve this problem or, even better, find out it isn't a problem in the first place. Again, if implementing the changes aren't too complicated I would even be willing to do the work and create the patch myself. I have implemented find modules with good versioning support myself and am familiar with how they work from that perspective, but I don't know how the internals of CMake look. About package config files - I'm really not sure what to do here, because the documentation for them explicitly states "When multiple package configuration files are available whose version files claim compatibility with the version requested it is unspecified which one is chosen. No attempt is made to choose a highest or closest version number." - it is for this reason that I personally prefer to use find modules instead so I can control the version selection behavior. I think it would still be possible to implement my changes with that no-guarantee clause in mind for package config files, but as I have never actually used a library with package config files nor implemented any myself, I'm not very sure. I feel much more confident about find modules. I think only package config version files would need to be updated in order to understand the new EXACT_* options, correct? And of course they could fall back on the original EXACT behavior. Thank you all for reading carefully, and I look forward to your thoughts and ideas. Nicholas "LB" Braden -- Powered by www.kitware.com Please keep messages on-topic and check the CMake FAQ at: http://www.cmake.org/Wiki/CMake_FAQ Kitware offers various services to support the CMake community. For more information on each offering, please visit: CMake Support: http://cmake.org/cmake/help/support.html CMake Consulting: http://cmake.org/cmake/help/consulting.html CMake Training Courses: http://cmake.org/cmake/help/training.html Visit other Kitware open-source projects at http://www.kitware.com/opensource/opensource.html Follow this link to subscribe/unsubscribe: http://public.kitware.com/mailman/listinfo/cmake