-
-
Notifications
You must be signed in to change notification settings - Fork 40.2k
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
Placing #ifdefs inside or outside of source files #452
Comments
I'm reasonably sure it is smart enough, or can be made smart enough with minimal instrumentation, but I'll do some testing when I have a bit of time.
I'm not convinced it's less clear, but that is likely a matter of taste. I find tons of
It does affect compile time a little, but there aren't that many files, I'd think the increase is not significant. But I'll do a full On the other hand, this all being C may increase the build speed with |
There's not that many files right now, but when we have 20 similar features that all get compiled no matter what, I'd be a little more concerned with the time it takes to pull each file. I'd really like this format to be the way people can experiment and contribute new behaviors. If we're able to remove the options from the Makefile to the config.h completely, we'll have no need for the I'm certain there are ways to clean-up the Makefile a bit - there's some fancier stuff in there that might take a bit longer, especially since some of it gets called quite a few times during compilation. |
Yeah, with 20 files, a second each would add up indeed. I'll see what I can do to speed things up! There are ways to tell make to calculate a value only once, for example, so if you use it a thousand times, it still does not get recalculated - that's a significant speedup. If all else fails, we can ask the Makefile to generate a header file (to a temporary name), compare it to the existing, and only overwrite if it differs. This way we have the dependencies in a header, and we preserve the timestamp if options did not change, so can default to But nevertheless, I'll have a closer look, to be sure. |
I also think it's cleaner if the functions are called, even if they are empty. But that might be because I come from a C++ background, where it's quite common to have virtual functions that does nothing. Regarding the optimization, I haven't been testing it, but I'm pretty sure the compiler won't optimize the empty functions away, at least unless link-time optimizations, which would considerably slow down the linking is enabled. The reason for this, is that the compiler is forced to threat each compilation unit in isolation, it can't really know if a function is empty or not, therefore it has to generate the calling code for it. That said, there's a quite clean way of doing it, and have the compiler optimize the functions away. If the functionality is not enabled, then the empty functions should be defined as static inline functions in the header file. This way, the compiler will see that it's empty, and optimize it away. That would work like this.
This will clutter the public header files though, so we could also do it like this.
And implement the empty definitions in the nop file. For compile time optimizations, I think we could try to do things a bit differently. It's not really an issue to compile a single keyboard, at least not if you are using the quick option, but compiling multiple keyboards and keymaps takes quite long time currently. It wouldn't actually have to take this long though, considering that most of them could actually share quite a bit of readily compiled code, and let the linker resolve the differences. We basically have two different variations for generated code. The first is the target processor, and perhaps it's clock configuration and stuff like that. Different processor's can share nothing. Then we have the features, and their configuration. Many keyboards and keymaps share the same processor and features, and should be able to take advantage of the fact that the feature is already compiled. One way to do this, would be to turn each feature into a static library, that is compiled once. This static library could in turn be dependent on other features, for example debug output. In that case we could to compile several variations of the library(on demand) and encode the configuration into the library name for example.
This of course requires each feature to be defined in the make file, and not in the config.h file like Jack proposed above. I don't think that's a major drawback though. Since features that require other features need special handling in the make files, we should also make sure that this dependency is enforced. That means that a feature, can not include a header file from another feature, unless it's allowed and handled by the make file. This can be done by putting each feature into it's own directory, and setup the include directories correctly from the make file. I wrote this extremely quickly, but have been thinking about it for a few days, so I hope it makes sense. I didn't want to go into too many details, unless you think it's a good idea to do it this way. |
Empty function optimization However if we enable link time optimizations The drawback of LTO, is slighty slower compile times, but the other bigger drawback could be that something stops working. I didn't test it at all, but if the option was to be enabled, then it would have to be carefully tested. It's also possible to enable it just for some files. So that means that we could write empty stubs either in the c file or the h file as inline functions as I explained previously. Note that we wouldn't need to write emtpy stubs for all the functions, as most of the functions would never be called from keyboards and keymaps not supporting some feature. In that case we can just let the linker generate the errors instead. Config.h vs makefile What I don't like is to have two different places of defining things, so I think we should either migrate the options to either file. Compile time polymorphism I think the best way of doing this would be to have a common We can of course also have an |
Was this a topic that we should leave open, or close? |
I think this has largely been addressed - thanks! |
* Add default keymap for S7 Elephant * Update Satan default keymap Add commit key. * Add default keymap for Scarlet Bandana * Add default keymap for Scythe * Add default keymap for Sentraq Number Pad * Add default keymap for Sentraq S65-Plus * Add default keymap for Shiro * Add default keymap for Singa * Add default keymap for Sirius Unigo66 * Add default keymap for SixKeyBoard * Add default keymap for Skog * Add default keymap for Snagpad * Add default keymap for Snampad * Add default keymap for Southpole * Add default keymaps for Spacetime revs. 1 and 2 * Add default keymap for Speedo * Add default keymap for Stand Aside * Add default keymap for Staryu * Add default keymaps for Suihankey alpha and rev1 * Add default keymaps for Suihankey Split alpha and rev1
Mentioned in #451, I'd like to look at the possibility of moving a large portion of the
code blocks to having a wrapper on the entire
feature.c
file to disable it, and include dummy functions where necessary (they likely won't be needed that often).Pros:
config.h
instead ofMakefile
(doesn't really cleaning, easier/more straight-forward to modify, all being c)#ifdef
s around calls (somethingaction.c
is suffering from)#ifdef
s required inkeymap.c
Cons:
feature.c
will always be compiled (I believe) - does this have an effect on compile time?Comments are welcome!
The text was updated successfully, but these errors were encountered: