-
-
Notifications
You must be signed in to change notification settings - Fork 3.1k
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
cmake: set cpp17 standard #8922
Conversation
@vtnerd Could c++17's |
You think it's unreadable? I think it's relatively straightforward, but then again I wrote it. And no, constexpr-if won't help much. Afaik, it could only useful in the adaptation for the old style macros. Nothing else does tag dispatching really. |
I'm generally against updating base requirements without a really good reason. Bumping the C++ standard to 17 will almost certainly require bumping the minimum version of GCC we support (currently 5). See https://gcc.gnu.org/projects/cxx-status.html#cxx17 for the GCC support. |
Sorry lol I meant to type more readable didn't mean to make that sound so rude. Is there really that little tag dispatching in the new lib? |
I tend to agree with @jtgrassie on this one, though we could replace the boost classes with their new counterparts |
Yes, minimum GCC would increase from 5 to 7. GCC 5 means Ubuntu 16.04 which has been EOL for 2 years now. Bitcoin Core moved to C++17 2 years ago, but they have the advantage that users can continue to run old versions. |
But still on ESM. And what about FreeBSD etc etc? I've still yet to see a compelling argument to update.
Bitcoin whataboutism shouldn't steer the conversation. |
I forgot that it's used in the read.h/write.h too. There are overloads for optional vs not optional fields. But the bulk of the code is overloading+adl. |
Other than variant/optional, I have not personally encountered anything that made me wish we had C++17. There are a couple minor things in C++20 ( |
I don't think we should take enterprise support programs like Ubuntu's ESM into consideration. |
std::filesystem might be interesting for new wallet code. Would allow us to eventually drop Boost's filesystem module. |
Abseil issue
Goal: Builds with Trezor support should work without manual intervention with system dependencies installed. Option 1/n:
Option 2/n:
Option 3/n:
Option 4/n:
Option 5/n:
Option 6/n:
[1] Currently: Arch Linux, Alpine Edge, Homebrew, MSYS2. [2] Compiler defaults
|
Both of which are optional dependencies. I get the desire to drop supporting older distros, but using optional dependencies as the argument feels a little weak to me. As of today, I can compile and run on Debian Jessie and Ubuntu Xenial with very minimal build flag changes (as I'm sure is the case with older BSDs). IMO the preferred approach should be to set the minimum std based on the options selected. E.g. if a user wants to build with Trezor support and the minimum std for that is c++17, that then becomes a cmake check to ensure the machines compiler is new enough (or rather simply bump the std when trezor/protobuf is selected). As it stands right now, we've set a global minimum of c++14, so we know all the required dependencies and Monero source code build with. But this isn't a hill I'm going to die on! I'd just personally like to see some solid reasons to up the forced minimum. Perhaps our some of our more expert c++ devs (e.g. @vtnerd), could weigh in? |
Trezor becomes a required dependency if #8752 is merged. Currently (without aforementioned PR), Trezor support is enabled by default if its dependencies are found and a test passes, otherwise it fails gracefully and builds continue without Trezor support. This has lead to a number of cases where Trezor support was unintentionally missing from official releases, Monero packages and downstream projects. From what I recall:
I'm sympathetic towards forcing Trezor support unless explicitly disabled (even just considering time wasted on handling support queries and rebuilds), but with that I do not want development builds to be broken by default on the increasing number of distributions that ship Protobuf 22+. Setting the C++ standard to 17 is IMO the least hacky way to avoid this. I don't see why security-sensitive software like Monero should guarantee support for distributions that no longer receive security updates. If you have to use an EOL distribution you can install a newer compiler from a PPA or use a release binary if your glibc is recent enough. |
This is the correct path. If an optional feature's dependencies are not met, it shouldn't be included, regardless if the optional feature is enabled by default.
This falls in the category of user error (if someone needs Trezor support they should ensure the dependencies are met and the cmake output reports Trezor is being included). Forcing an update of the c++ std simply for an optional feature is a slippery slope.
You assume the sysadmin isn't manually addressing security issues. Just because the distribution maintainers no longer "support" doesn't mean the user stops. As you brought up security-sensitive, a counter argument could also be: Why does Monero even support Trezor given their recently reported cooperation with chainanalysis companies?
Of course, but this is digressing from the point. Arguing for bumping the std, globally, to simply support an optional dependency is weak. Especially when the make files can be updated to only bump the std when the user elects to use a feature that requires a certain std (like I mentioned: "or rather simply bump the std when trezor/protobuf is selected"). |
My thoughts on this: Changing between C++14 and C++17 depending on Trezor disabled/enabled is a bad idea - we can't use C++17 features in this case, so what's the point in having C++17 then? Today it's Protobuf and Abseil, tomorrow it will be more and more dependencies requiring C++17 (or newer), so we'll have to switch eventually. As correctly pointed out, we must update dependencies from time to time because new versions can have critical fixes. I did a quick search, and I didn't find any "silent changes" caused by switching to C++17. There's no |
@jtgrassie my responses are going to be slanted because I abhor protobuf. I had basically the same thoughts. We're bumping the minimum compiler version just for trezor/protobuf, which doesn't seem right. As an example, how far do we go - bump to c++20 or newer because the same dependencies require it? |
The compilers we currently use to compile release binaries support C++17, that's why I opened this PR. We can reduce our boost usage and some of the C++17 features might be useful for the new wallet / Seraphis development, or maybe not but at least there's the option. It solving the Abseil issue is a nice side effect. If a dependency suddenly requires C++20 we will have to find another solution because switching to C++20 is not up for debate. |
As @SChernykh mentioned, now it is Abseil, but when there is a new vulnerability in a required core dependency, it may happen that security fix will not be available for the old version. When that starts happening, you can either maintain own patches, which is error prone, costly, etc or bump to newer versions, which may require C++17 minimum (it is our for quite some time already). And solution may be needed fast. I don't have a strong opinion here. Trezor is OK for now, users can still install Protobuf v21 and use that to compile binary, official builds will be compiled also with Protobuf v21. Also the idea with switchable C++17 support sounds good.
How long do you wish to support EOL distros in general? I mean, if sysadmin does security patching manually (can, but improbable) they could also install newer compiler, right? 😅 |
Relevant for GUI: Qt 5.15 is out of support since May 26 and Qt 6 requires C++17. Qt is still publishing patches for CVEs for 5.15, but it's unclear how long that will last. |
I don't have a strong opinion on c++17 but this thread brings up an interesting issue: Handing conflicts with rather large third-party components like ledger/trezor. Of course different concrete scenarios may suggest alternate resolutions, but integrating substantial third-party components with large dependency chains into the build tree seems a bit destabilizing. For example, if a new minor release works except for some issue building trezor, is that a blocker, or should there be a policy to only care about these hardware wallets at major releases/hardforks? |
I am not in favour of switchable C++17 support. As far as I can remember, I haven't seen something like that in any modern code bases (unless I am forgetting something). But I am very in favour of switching to C++17 by default. Most modern C++ libraries are moving fast right now. |
@vtnerd & @jtgrassie - you've both been vocal in this thread regarding not wanting to move to C++ 17 just to support the Trezor PR/update. Since then @tobtoht has surfaced an issue with QT 5.15 being out of support since May 26, and Qt 6 requiring C++ 17. The GUI runs Qt, and thus in the not too distant future may needn Qt 6 (and thus C++ 17) in order to keep getting security patches. Just wanted to circle back on the discussion to date and see if this new issue with Qt support is enough, in your minds, to justify upgrading to C++ 17. Doing a quick scan of the thread, it seems that so far, @selsta, @tobtoht, @ph4r05 and @SChernykh are generally in favour of the upgrade, or at least, not opposed to it. (if I'm misrepresenting anyone I apologize, and please correct me). |
So I was right about it:
|
The GUI can enable c++17 separately from monero core code (since it's a superset of c++14). However, I'm not really opposed to the upgrade, as it looks like the relevant platforms support c++17. |
c++17 is not exactly a superset of c++14 - it removed I went through changes in c++17 and so far I don't see any changes that would break the program behavior without also breaking code compilation first, so it should be relatively safe to update - but it will need extensive testing. Edit: There are some changes in expression evaluation order in c++17: https://en.cppreference.com/w/cpp/language/eval_order but they are directed at defining the previously undefined behavior, so it should be also safe - assuming we don't have undefined behavior in the code. If we have it, we must fix it anyway. |
Keep in mind there are quite silent incompatibilities (and semantic change) between C++14 and C++17 (Annex C [1]). But most of those features are never used. In any case, it wouldn't hurt to double-check. |
The argument against upgrading for an optional dependency is solid, but, in line with @SChernykh's argument that more dependencies in the future will likely require C++17 (or newer), then it makes sense to get ahead of this and not be on the back foot when the time eventually does come. Ideally we would be prepared to upgrade with minimal disruption. As of now, there is loose consensus that this PR would need extensive testing before making its way to release. In my view, the best chance to get a switch to C++17 tested on as wide an array of machines as possible is to make the switch on the master branch. Therefore I think it makes sense to move forward with this PR on master, and keep this change out of the release branch until A) it's extensively tested, and B) it's a required change (or at least until stronger reasoning arises to make the switch). |
We set a deployment target that is lower than 10.14, which means we have to disable aligned allocation otherwise compilation fails.
Why the changes for locks? We used boost locks because mingw didn't have support - so the windows build might fail now. |
@vtnerd compilation failed without the lock change, I don't remember the exact error message but can look it up.
CI includes mingw Windows builds and everything compiled without issues after this change. |
The Windows CI hasn't completed yet, did you do something manual? I would like to see the error, because we use |
It was green, I just force pushed to rebase that's why it's running again. Will try to get that error message. |
This was for ARMv7 cross compilation. |
So I guess mingw now supports locks, and maybe threads. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm ready for C++17; I will immediately make some changes to the new serialization stuff I've been working on.
We need this on the release branch now since PRs which depend on c++17 cannot yet be ported to the release branch. |
It has almost been two years since we switched from C++11 to C++14, last year that we have updated our macOS build SDK which means we could move to C++17.
There's still extensive testing to do with the release binaries before this can be merged.
Any feedback for / against this change?