so if i go the runtime compiling of shader way i would have to pass a ... to every compiling call of a shader that includes that common include like so:
Generally, this is correct. Each shader will have its own set of defines. The same is true for C++. The compiler passes some set of defines to each individual file as it gets compiled.
In C++,#ifndef/#define is used to prevent a cpp file from including two headers that both include the same header which would lead to something being defined multiple times in the cpp file. The same is true for shaders. So if your shader header is being included in other headers that are then being included in your shader, it's a good idea to put an #ifndef/#define to prevent multiple declarations in the same file. If you are just including the header file directly in your shader, then it's not totally necessary, although it might still be good practice.
As to which method you described you should use, it depends on what you want to accomplish. If you want to prevent things from being multiply defined, use #ifndef/#define. If you want to conditionally use one struct or another struct, or one block of code or another block of code, use the #ifdef with the define passed to the compile function.
One usage example for passing a define to the compile function would be to use a different vertex layout struct for passing into the vertex shader. You can define two structs, say one with normals and the other without normals and use an #ifdef to control which is used. Then compile the shader twice, one with the value defined, and the other without. Now you have two shader objects, one that can handle vertex inputs with normals, and one without. This allows you to write one shader that you can use in multiple ways with different types of geometry.