-
Notifications
You must be signed in to change notification settings - Fork 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
Make all source and header files self-contained #1039
Comments
It's complicated. The _impl.h files in modules/* aren't really standalone pieces of code, as they are included by secp256k1.c / tests.c / bench.c respectively. I tend to think of them not as separate things, but as "parts" of those respective .c files that have been moved elsewhere for organization purposes. |
Indeed but I don't see the point. What you say is true also for the _impl.h files not in src/modules/*, they're also included by the .c files. So I think the rules should roughly be:
|
What if we renamed the |
Yeah, I think that will be a very related goal. What I propose is to ensure that every file (incl. However, I don't know if it's worth supporting that as an official compilation method. The reason why we have unity builds is the (former) lack of LTO. I think it was a good idea to separate the precomputed stuff (#1042) because it rarely changes and nothing is lost without LTO. But for the "normal" (not precomputed) files, I don't know: we wouldn't want to drop support for unity builds for people that still use compilers without LTO. And compilation times are still very manageable with the existing code base. |
@real-or-random Hmm, perhaps my point is more philosophical than practical. The way I like to think about source code organization is that the .h and .c file (or in our case, .h and _impl.h file) are one "unit". And to think about dependencies in the code, you think about "which unit cannot be used without which other unit". When you have units that depend in that way on each other, you have a "semantic" cyclic dependency between those units, which is a sign that those two units should really be one unit, or organized differently. So specifically, if you have a situation where a.c includes b.h, and b.c includes a.h, while not being a cyclic dependency between the actual files, it is a cyclic dependency between the units. And in that sense, e.g. the modules//tests_impl.h files aren't proper separate units: modules//tests_impl.h depend on functions in tests.c, and simultaneously tests.c includes modules/*/tests_impl.h. In that sense, they're really better thought of as "part of tests.c, but moved elsewhere to make conditional compilation easy" than as separate units. Just adding non-impl .h files, without disentangling things, wouldn't change that. But Of course, there is no requirement that the situation stay that way. We could properly separate the modules//tests_impl.h files; which would probably involve moving some of the shared helper functions in tests.c to a separate file, which can then be included by both tests.c and modulus//tests_impl.h I think that would be a good idea, actually. And if we do, @apoelstra's suggestion to try compiling all the impl files separately would be a nice way of testing that. Do you imagine that as actually renaming all the _impl.h files to .c in the repository, but just leaving the default compilation mode to still #include them into each other as now? Or do you mean e.g. having the CI script doing the renaming for this particular test? One concern I'd have with actually doing the renaming in-repo is that people building the project in an environment without our build system would actually build that way and get abysmal performance due to lack of inlining of field routines (actually, that's perhaps not uninteresting to test). |
If the goal is just to solve this issue and test this, then it would suffice to have CI compile the |
My intention was to do the bare minimum to test compiling the I didn't consider just having the CI script do the renaming though. I think that might get us exactly what we want (a CI test of @sipa's semantic model of dependencies, as approximated by |
…de/secp256k1.h` 8e142ca Move `SECP256K1_INLINE` macro definition out from `include/secp256k1.h` (Hennadii Stepanov) 7744589 Remove `SECP256K1_INLINE` usage from examples (Hennadii Stepanov) Pull request description: From [IRC](https://gnusha.org/secp256k1/2023-01-31.log): > 06:29 \< hebasto\> What are reasons to define the `SECP256K1_INLINE` macro in user's `include/secp256k1.h` header, while it is used internally only? > 06:32 \< hebasto\> I mean, any other (or a new dedicated) header in `src` looks more appropriate, no? > 06:35 \< sipa\> I think it may just predate any "utility" internal headers. > 06:42 \< sipa\> I think it makes sense to move it to util.h Pros: - it is a step in direction to better organized headers (in context of #924, #1039) Cons: - code duplication for `SECP256K1_GNUC_PREREQ` macro ACKs for top commit: sipa: utACK 8e142ca real-or-random: utACK 8e142ca Tree-SHA512: 180e0ba7c2ef242b765f20698b67d06c492b7b70866c21db27c18d8b2e85c3e11f86c6cb99ffa88bbd23891ce3ee8a24bc528f2c91167ec2fddc167463f78eac
This week I noticed that the includes in this project are a mess. Actually, each file should be self-contained, i.e., include the stuff that it needs (and ideally only the stuff that it needs) but at the moment neither of these are true for a lot of files in the repo. Just try compiling a random
.h
or_impl.h
file.This is not per se a problem for our "single translation unit" compilation (I learned that the cool kids call this "unity builds") that we use in order to leverage the full potential of compiler optimizations without the need for LTO. The more important point (at least for me personally--though I may be the only regular contributor suffering here), it prevents the use of advanced tooling/IDE, e.g., my editor supports language servers such as ccls or clangd which "compile" the open file internally and provide a ton of features, e.g., completion, display of compile errors etc. But none of this works properly if you can't compile individual files. You can say that's the fault of these tools but self-contained files are also just good style and good engineering practice.
PR #924 was an attempt to clean up the includes but even the
include-what-you-use
tool there used there (or at least the way it has been used there) fixes includes only for the.c
files.Here are some things we'd need to do:
_impl.h
file insrc
has a corresponding.h
file for other files to include. But we don't do this properly insrc/modules
. For example, the schnorrsig module uses function from the extrakeys module but there are only_impl.h
files insrc/modules/extrakeys
and no.h
file for schnorrsig to include.secp256k1.c
. There's no just header for other files to include.Again, I understand that I may the only one suffering, so fixing this may be on me but I still wanted to document my findings here. I don't except anyone disagreeing with the changes the mentioned here but please raise your hand if you do.
The text was updated successfully, but these errors were encountered: