-
Notifications
You must be signed in to change notification settings - Fork 27
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Dependency scanner does not recognize one-line dependencies #17
Comments
I'll look into this. Got an idea already. |
The dependency scanner at the moment only recognizes "Boost::foo" in a line of its own, it doesn't contain a full CMake parser. |
Checked the relevant sources of the includer/scanner. My approach would change it quite a lot, so I want to put it up for discussion first:
I'm sure it works for all libraries where it currently works and now also handles cases as in filesystem. It requires authors to follow a naming convention so we can convert between path-name and target name, but at least for the auto-installation to work this is already the case (although a soft failure, which I'd make a hard failure as otherwise we'll miss dependencies): Line 146 in bd981bf
However the current scanner includes(supposed) dependencies that are conditional, i.e. atomic, if formatted correctly: https://github.com/boostorg/filesystem/blob/41d076ace558cfae01e233f9746dc955dcf78dba/CMakeLists.txt#L195-L198 The described approach would only include atomic if it is actually added as a dependency, i.e. earlier than C++20-mode. I'd see this as a bonus. Any comments? Possible issues? Quick solution: Enhance the heuristic at Line 176 in bd981bf
The above described solution uses CMake to handle the deps, so all valid CMake constructs will be recognized and conditional dependencies only included, when actually added. That might cause issues too, i.e. if someone adds/links Boost::filesystem and assumes Boost::atomic to be available even in C++20 mode which due to the if -condition above won't be with the new algorithm.
|
That's possible and I've had this in mind as an alternative, but it has its own issues, although on balance it may still be better than what we have now. It will change the order of add_subdirectory calls, but only sometimes, so order dependence will sometimes work and sometimes not. It also doesn't handle libraries that aren't named "correctly", such as Test and Stacktrace, but maintaining an exception list for those is probably more manageable than fixing the scanner to support whatever people write. |
Oh, it also breaks one interesting case that currently works and is in use: setting BOOST_INCLUDE_LIBRARIES and BOOST_EXCLUDE_LIBRARIES to the same value of e.g. |
I think CMLs of independent libs relying on order are ill-formed. Any dependency between 2 (boost) libs more than
Hm, interesting indeed. Where is this used? However I think we could say that this is be undefined behavior and worked by accident ;-) I mean: What is a system supposed to do when told to do opposites? As a slight alternative: How about using:
And then do the loop at Lines 174 to 183 in bd981bf
${deps} but replace the regex by the above variable.I.e. search the whole file for possible boost libs anywhere. Again conditional dependencies will be always included but the only requirement would be to not use a variable (e.g. I think I still prefer the CMake-Target-approach as it does not introduce any kind of subdialect library-authors would need to follow and any valid CMake suffices. |
|
I fear that this will pick up more than we need, although it's an option if all else fails. |
Nifty! I'm actually surprised this works... Couldn't that still be done by putting that at the top without the exclude, guarding the if against re-entry and returning after including the super-project CML? Basically abuse that file(-part) as a launcher script for the super-project build.
For example? We filter already against the existing libs via the paths. |
I do like the idea of using CMake to discover all dependencies. This solution is future-proof, too.
I think, if the scanner has to parse CMakeLists.txt by itself, it should be more robust than that. I.e. it should recognize |
I'm not particularly thrilled by the prospect of having to perform proper tokenization and maintain state across lines in order to parse every possible |
Yeah, either we simply use the enhanced regex matcher and maybe filter comment lines or do the "proper" approach with targets. Writing a cmake parser in cmake is to much. |
The conflict between maintainer hand rolling free-form CML and strict-form expectations from Boost CMake is inevitable. A not entirely crazy idea: split the two sets of CML-s into mandatory generated CMakeLists.boost.txt and optional manually maintained by a lib maintainer CMakeLists.txt |
I'm not sure how that would work with non-trivial dependency selection. Such as what Boost.Filesystem does. |
I assumed the CMakeLists.boost.txt is generated with The CMakeLists.txt is what maintainer(s) desires for their development and testing workflows. It's it used by any of Boost CMake part. Like in pre Boost CMake days, every lib had Jamfile-s, some libs had CMakeLists.txt, and a lib maintainers and users relied on both for own purposes. Let's treat CMakeLists.boost.txt as a new third actor on the stage. |
|
I wasn't aware of that.
I assume there's practically no maintenance of Boost CMake configuration required - it's all generated. However, now there seem to be two (modes of) configurations in single CMakeLists.txt file which I find troublesome - I enjoyed the ability to call my CMakeLists.txt an unofficial configuration and that I could stick any rubbish in it I desired without worrying I could break anything Boost-wide. |
Well the limitation to put dependencies onto own lines is a very minor one IMO. A fix for the issue as it came up here is very easy if one knows that. We could even improve the scanner to output potential but ignored dependencies to provide more guidance to library authors. I also agree that having to maintain 3 build systems is to much. Combining the Boost.CMake and the (more or less) standalone (or better: top-level-build) CML is OK as the difference is quite minor.
You can still do that. Maybe simply put a
Just as a note: This is impossible for |
Yes, that's what GIL's CML does. |
That is why I made the dependency scanner stupid on purpose, to minimize the probability of it picking up things in your rubbish part. But since it appears Andrey can't be arsed to press Enter twice, we'll need to figure something out. |
We simply have to decide for one solution. Fastest would be the current parser, with the following change:
I'm pretty sure this would work and due to the first regex even exclude comments. Well until someone does
If no one does that currently no library needs changes now. With the CMake-based scanner at least Boost.Json needs to change. With the current scanner Boost.Filesystem needs to change. So choose your poison I guess. Maybe circulate this on the list? |
No, this will pick up much more than I'd have liked. I think I'll just hardcode Andrey's line as-is. |
Ouch! Yes, I can add newlines, and I probably will if I have to before the next release. But I think the current parser needs to be fixed as well, hence this issue. It's not just my spite, it is simply reasonable to expect a valid CMakeLists.txt to work. BTW, this whole issue was the first time I ever heard that there is some sort of a parser at all. I was writing CMakeLists.txt on the premise that CMake is the only tool that will interpret it. I have a hard time believing that I'm the only one ignorant like that.
If you're going to add something in the spirit of "if Filesystem then add Atomic dependency" then I'd rather you didn't. |
Yeah, I can't in good conscience hold others responsible for not reading the document I'm writing for more than a year now and haven't yet published. :-/ But in short, the dependency parser doesn't have anything to do with the CMake correctness of the CML files, they don't depend on it in order to work, it's only engaged when the user does And the problem is that CMake is very picky when there's install support, and mandates that the dependencies are 100% correct even if one doesn't install anything. It's obviously not possible to somehow parse an arbitrary CML file with a parser written in CMake - that's madness. And making the scanner pick up anything resembling a dependency isn't good either, because people have all sorts of things in their CML files that are only active when the library is used as a root project. So as a compromise I've settled on only picking up a dependency if it's alone on a line. This allows the portion of the CML that needs to be scanned to be written in a way such that the scanner picks up exactly what one wants, and no more. |
So, what's it going to be? Is the scanner going to employ the target-based approach? Because if your plan is to hardcode Filesystem I'd rather add newlines (with a promise to break it from time to time ;) ). |
Ping? |
Originally reported in boostorg/filesystem#226.
If
CMakeLists.txt
of a library contains one-line dependency such as this:the dependency scanner does not recognize this. This affects Boost.Filesystem, so issuing this command on Boost root:
results in this error:
The dependency on Boost.Atomic is here.
The text was updated successfully, but these errors were encountered: