Idiomatic way to structure multi platform code

we have a graphical framework we are working on that we want to be able to use on a wide range of platform from the web to linux embedded devices, so far we made it all work everywhere by creating platform specific feature flags to swap out pieces of code depending on what's available on every plaform eg cpu vs gpu rendering windowing vs raw screen control etc. the thing is i am not entirely sure of this approach and was wondering what's considered the most idiomatic solution for these cases

The best case for using a cfg to change implementations is when things are genuinely different between platforms — like “on Linux make this syscall and on Windows make this syscall” — and it doesn’t make sense to ever execute the code on another platform.

However, for things more like “CPU vs. GPU rendering”, it’s better to arrange things so that it’s still possible to execute the CPU rendering, so that you have the option of testing the CPU rendering even on platforms where it’s not the only option. This could look like two structs implementing a trait, where features control whether one or both of the structs exist. Or — depending on how your application is structured — it could be two different initialization functions that set up the two renderers, without any trait.

The best solutions for any case depend a lot on the details and the acceptable tradeoffs.