I particularly like submodules for this.
For each instance where I need conditional compilation, I like to have a single module file which provides consistent interfaces, and then each conditional option has a submodule file which implements the interfaces in the module file in an option-specific way. IMO this minimises the room for error, removes the preprocessor dependence, and as a bonus minimises re-compilation when options are changed.