View Issue Details [ Jump to Notes ] | [ Print ] | ||||||||
ID | Project | Category | View Status | Date Submitted | Last Update | ||||
0016013 | CMake | CMake | public | 2016-03-11 05:44 | 2016-06-10 14:21 | ||||
Reporter | Ruslan Baratov | ||||||||
Assigned To | Roger Leigh | ||||||||
Priority | normal | Severity | minor | Reproducibility | always | ||||
Status | closed | Resolution | fixed | ||||||
Platform | OS | OS Version | |||||||
Product Version | CMake 3.5 | ||||||||
Target Version | CMake 3.5.1 | Fixed in Version | CMake 3.5.1 | ||||||
Summary | 0016013: FindBoost: iostreams depends on regex [3.5 regression] | ||||||||
Description | Looks like the fact that boost.iostreams depends on boost.regex hardcoded in new version of FindBoost module. So such code no longer works: find_package(Boost REQUIRED COMPONENTS iostreams) and produce an error: Could not find the following static Boost libraries: boost_regex if I have only boost.iostreams installed (without boost.regex). Example works fine (build/run) without boost.regex with CMake 3.4.3 | ||||||||
Tags | No tags attached. | ||||||||
Attached Files | |||||||||
Relationships | ||||||
|
Relationships |
Notes | |
(0040660) Ruslan Baratov (reporter) 2016-03-11 05:51 |
I don't know where the information about dependency comes from. Here is `otool -L` result on `libboost_iostreams-mt.dylib` installed by brew on OSX: /usr/local/opt/boost/lib/libboost_iostreams-mt.dylib (compatibility version 0.0.0, current version 0.0.0) /usr/lib/libbz2.1.0.dylib (compatibility version 1.0.0, current version 1.0.5) /usr/lib/libz.1.dylib (compatibility version 1.0.0, current version 1.2.5) /usr/lib/libc++.1.dylib (compatibility version 1.0.0, current version 120.1.0) /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1226.10.1) |
(0040662) Brad King (manager) 2016-03-11 08:23 |
For reference, the dependency table was added here: FindBoost: Embed component dependency table https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=5183c6e5 [^] |
(0040665) Roger Leigh (developer) 2016-03-12 15:02 |
Dear Ruslan, The information comes from the headers, and is supplementary to the dependencies in the shared lib itself. It's akin to the autolink behaviour you get with MSVC--in fact, it's derived directly from the autolink header usage for each header in each component. See Utilities/Scripts/BoostScanDeps.cmake for the script which scans the headers to generate the dependency information. You can run this against your Boost headers to see what it generates. The instructions for doing this are in FindBoost.cmake. If you look at boost/iostreams/filter/{grep|regex}.hpp, you will see that the regex headers are included here (and by extension, a dependency upon libboost_regex). This is the reason why it's included. But on systems the unused libraries will be culled by the linker. When developing the feature, this behaviour was discussed. The current approach is conservative: when you use Boost::Iostreams, the dependencies include all dependencies of all the boost/iostreams headers, which will guarantee a successful link under all circumstances with shared or static libs for a typical boost build. But if you don't use (in this case) boost/iostreams/filter, you are getting a dependency you don't need. But it might *potentially* be needed; at the granularity of a single component, we have no means to determine that when FindBoost is run. If we went the other way, and restricted ourselves only to dependencies under our component, we would avoid this, but require the user to manually specify all indirect dependencies (which are Boost-version-specific and are the main reason for adding the support in the first place). It would also remove *essential* dependencies such as boost_filesystem on boost_system. Having these dependencies work consistently was the primary driver for this support--it obviates the need for every use of FindBoost to hard-code the indirect dependencies, which are often done incorrectly given the variation between boost releases. I'd certainly be happy to consider any change which would improve things, but I think it's also fair to say that it's behaving as designed. The issue here is the granularity of the cmake find_package components. If you say you want iostreams, we have no way to determine which specific bits of iostreams you will be using at the header level. And we have no way at present of classifying dependencies as essential or optional--maybe something to consider? We currently scan all headers in each component and then follow all their inter- and intra-component includes to find the libraries. That's a simple but consistent rule, but if there are headers which are rarely used and for which an explicit dependency would make sense, we could potentially hard-code such behaviour in the scanner. But it's a non-trivial task--you'd have to assess this for every header with an intra-component include and do it for all boost versions. Which is why we opted for the simple and conservative approach. But if you have any ideas for improving the behaviour, please do suggest them! Kind regards, Roger |
(0040666) Roger Leigh (developer) 2016-03-12 15:08 |
I should also mention that building without regex isn't the only case where this can break. It can also break e.g. on Windows when you build with a custom zlib or bzip2. The autolink information is static and doesn't know what name to link against so is fragile, and our generated dependencies are likewise as fragile. But it's the best we can do, both in FindBoost and as an end user--the compile-time options are not something we can easily cope with. One other thought. Maybe we should make component dependencies optional, so if they aren't present we don't raise an error. That would be a simple solution to the problem. It would cater for different compile options, and would still fail if a directly-requested dependency is missing, but would handle system-specific linker variations gracefully. The only downside is not handling broken installations with missing parts, but it might be an acceptable compromise. |
(0040667) Ruslan Baratov (reporter) 2016-03-12 22:49 |
tl;dr It's a bug, I don't need regex when I do link iostreams. It broke correct/existing/working code. > If you look at boost/iostreams/filter/{grep|regex}.hpp, you will see that the regex headers are included here If library use some header-only stuff (like inline members) there is no need to do link. > When developing the feature, this behaviour was discussed Yep, and I've mentioned that such approach is broken by design. See ZLIB/BZip2 optional dependencies note: * http://www.mail-archive.com/cmake-developers%40cmake.org/msg14835.html [^] > If you say you want iostreams, we have no way to determine which specific bits of iostreams you will be using at the header level But user know. Also it's not boost specific feature. Same way you can create CMake package that has optional dependencies and the fact that optional dependency used is known only by user. > I'd certainly be happy to consider any change which would improve things Only required dependency should be listed, optional dependencies should be removed. |
(0040671) Roger Leigh (developer) 2016-03-14 10:03 |
Please could you try the patch here: https://github.com/Kitware/CMake/compare/master...rleigh-dundee:boost-fix?expand=1 [^] and let me know if it fixes the problem for you. This is what I proposed above as a potential solution, but you didn't provide any comment upon that. Note that the determination of whether a dependency is "required" or "optional" is not at all clear-cut. While we might say that regex is optional in this context, since it depends upon the headers included, we can't generalise this for all cases. We could need to be able to determine that boost_system is a requirement of boost_filesystem, and this means that we need to have some heuristic for which headers in each component are "used as standard" and which are less commonly used. This *isn't* akin to cmake packages with optional dependencies since it's based upon *how* a package is used--we can't encode this at the level of the package, it's finer-grained than that. There's no way to manage that level of complexity across all the Boost versions. While you say that "the user knows", that's not really true except in the most trivial case--these dependencies vary between boost versions, and the user's choice may well break with different boost versions; making this work robustly across all versions for all components is the entire purpose of this change, so that the end-user doesn't have to hardcode things and potentially make incorrect assumptions. That said, I hope that the patch as proposed is a good enough compromise to satisfy both points of view. |
(0040682) Ruslan Baratov (reporter) 2016-03-14 14:18 |
> Please could you try the patch here Works fine for me, thanks. By the way is there a way to disable imported libraries creation? Like to turn on some option before `find_package`? |
(0040683) Roger Leigh (developer) 2016-03-14 14:50 |
OK, I'll push it into next soon. Regarding import libraries, no user-settable variable exists to disable them. Do you have need of such a feature? If so, what's the rationale for that? |
(0040685) Ruslan Baratov (reporter) 2016-03-14 23:23 |
> Do you have need of such a feature? It would be nice. > If so, what's the rationale for that? I have my own BoostConfig.cmake module which do call standard FindBoost.cmake. I think it will conflict with new Boost::* targets. Just want to avoid maintaining cmake-find code from FindBoost.cmake myself. |
(0040686) Ruslan Baratov (reporter) 2016-03-14 23:26 |
Note to admins: Sometimes I've wrote a message, push "Add Note" and got error: "Invalid form security token. This could be caused by a session timeout, or accidentally submitting the form twice." When I push back button in my browser my comment is lost and I have to write it again from scratch. |
(0040687) Roger Leigh (developer) 2016-03-15 05:28 |
Merged to next for testing. Regarding your BoostConfig.cmake, what's the reason it can't use the FindBoost imported targets? The expectation would be that users would use the FindBoost ones by default over needing addititional custom macros. How do your macros differ? Why would the custom macro need to dictate the behaviour of the upstream FindBoost? I would expect that given the ability to export library configurations with use of the imported targets, and their other advantages, that we would always provide them by default. |
(0040688) Ruslan Baratov (reporter) 2016-03-15 05:52 |
> Regarding your BoostConfig.cmake, what's the reason it can't use the FindBoost imported targets? I got errors with another example, something about Boost::regex. Not sure what is the cause so I just suggest easy-simple solution. > How do your macros differ? It works with CMake 3.0. I don't want to up the requirement just because of FindBoost.cmake. Implementation diff is that it is configured/installed on Boost build stage so it has information about how Boost is configured. E.g. user can run Boost.iostreams build with option NO_BZIP2=1 and NO_ZLIB=0 and additional ZLIB dependency will be added, BZIP2 dependency will not be added to BoostConfig.cmake. This information simply lost (uneasy to recover) when Boost already installed. |
(0040690) Brad King (manager) 2016-03-15 09:46 |
Re 0016013:0040687: Thanks. I rebased the fix on the 'release' branch: FindBoost: Tolerate missing indirect dependencies https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=17a1faa7 [^] |
(0040691) Brad King (manager) 2016-03-15 10:02 |
A problem with the call to list(REMOVE_ITEM) was exposed by nightly testing. Please try this revised version to make sure it still solves the problem: FindBoost: Tolerate missing indirect dependencies https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=e2f387fa [^] |
(0040697) Ruslan Baratov (reporter) 2016-03-15 13:38 |
> Please try this revised version to make sure it still solves the problem Works for me |
(0040701) Brad King (manager) 2016-03-16 13:16 |
Thanks for testing. The change linked in 0016013:0040691 has been merged to the 'release' branch for inclusion in CMake 3.5.1. |
(0040704) Dan Kegel (reporter) 2016-03-16 14:25 |
The patch seems to work here, too. Thanks. For completeness, here's how I layered the patch on top of the cmake that brew installed: wget 'https://cmake.org/gitweb?p=cmake.git;a=patch;h=e2f387fa' [^] mv gitweb* /tmp/findboost.patch cd /usr/local/Cellar/cmake/3.5.0/share/cmake sudo patch -p1 < /tmp/findboost.patch |
(0041223) Kitware Robot (administrator) 2016-06-10 14:21 |
This issue tracker is no longer used. Further discussion of this issue may take place in the current CMake Issues page linked in the banner at the top of this page. |
Notes |
Issue History | |||
Date Modified | Username | Field | Change |
2016-03-11 05:44 | Ruslan Baratov | New Issue | |
2016-03-11 05:51 | Ruslan Baratov | Note Added: 0040660 | |
2016-03-11 08:22 | Brad King | Assigned To | => Roger Leigh |
2016-03-11 08:22 | Brad King | Status | new => assigned |
2016-03-11 08:23 | Brad King | Note Added: 0040662 | |
2016-03-12 15:02 | Roger Leigh | Note Added: 0040665 | |
2016-03-12 15:08 | Roger Leigh | Note Added: 0040666 | |
2016-03-12 22:49 | Ruslan Baratov | Note Added: 0040667 | |
2016-03-14 10:03 | Roger Leigh | Note Added: 0040671 | |
2016-03-14 10:11 | Roger Leigh | Status | assigned => feedback |
2016-03-14 14:18 | Ruslan Baratov | Note Added: 0040682 | |
2016-03-14 14:18 | Ruslan Baratov | Status | feedback => assigned |
2016-03-14 14:50 | Roger Leigh | Note Added: 0040683 | |
2016-03-14 23:23 | Ruslan Baratov | Note Added: 0040685 | |
2016-03-14 23:26 | Ruslan Baratov | Note Added: 0040686 | |
2016-03-15 05:28 | Roger Leigh | Note Added: 0040687 | |
2016-03-15 05:52 | Ruslan Baratov | Note Added: 0040688 | |
2016-03-15 08:56 | Brad King | Relationship added | related to 0016020 |
2016-03-15 09:46 | Brad King | Note Added: 0040690 | |
2016-03-15 10:02 | Brad King | Note Added: 0040691 | |
2016-03-15 10:05 | Brad King | Target Version | => CMake 3.5.1 |
2016-03-15 13:38 | Ruslan Baratov | Note Added: 0040697 | |
2016-03-16 13:16 | Brad King | Note Added: 0040701 | |
2016-03-16 13:16 | Brad King | Status | assigned => resolved |
2016-03-16 13:16 | Brad King | Resolution | open => fixed |
2016-03-16 13:16 | Brad King | Fixed in Version | => CMake 3.5.1 |
2016-03-16 14:25 | Dan Kegel | Note Added: 0040704 | |
2016-06-10 14:21 | Kitware Robot | Note Added: 0041223 | |
2016-06-10 14:21 | Kitware Robot | Status | resolved => closed |
Issue History |
Copyright © 2000 - 2018 MantisBT Team |