Verilog has a preprocessor, so conditional compilation can be achieved basically in the same way as for C programming.
I would be glad to have a similar means in VHDL, but it's not provided by the standard. Tricky is right, that it can be achieved with "Generics and Generates".
Generate allows to instantiate different versions of a component for different branches, e.g. a parallel versus a serially interfaced peripheral. Of course any part of the concurrent code, a single assignment line as well as a process block can be conditionally generated.
Inside sequential code blocks (processes or functions), you have to use
if constructs with constant arguments to achieve conditional compilation.
VHDL does not provide conditional compilation for interfaces. If you want to share the same top level entity for all branches (or
revisions, as they are named in the Quartus software) without generating unused pins, you can give them a
virtual assignment.
By using Quartus
revisions for branches, you have individual *.qsf files, including a set of assignments and a project file list for each revision. So everything up to different pin mapping, FPGA package and type, even different FPGA family can be implemented.