The key to portability is to avoid compiler extensions and OS-dependent functions or classes that don't have equivalents. Nothing is more annoying than dealing with a bunch of code full of #if WIN32 directives. Your OS dependencies should be wrapped such that your code hides these details.
template <class what>class CWhatever{};class CTwo : public CWhatever<int>{ CTwo () : CWhatever () { }};
Also, DON'T use constructs in your code like __CC_DEPENDENCY_H__ with leading/trailing underscores. Functions, variables and constants with leading underscores are reserved to the implementation, (the compiler writers) not user namespace. Functions with leading underscores for example, are compiler extensions or non-standard C runtime functions that are platform/implementation dependent and you should not use this namespace for your application code. If you find yourself using leading underscores or double leading underscores this is supposed to be a clue that you are venturing into non-portable territory.
There should be almost nothing in a Q2 mod that is OS dependent. The only exception is the code necessary to support the different DLL implementation and names. (Although I confess to using OutputDebugString occasionally, I undefine it in the header on non-windows platforms.) All the OS dependent code is in the engine, the mod only needs to call the engine API. All other functions in the mod should be completely contained and defined in the mod code, dependency on outside packages makes modding harder, not easier. If he downloads the wrong version of the package the modder ends up debugging the package, not his code. If you import package code then ship that code with the project. Make no use of Windows API or classes.
You should consider creating a VM and running your code through the GCC compiler concurrently with your Windows development since the vast majority of active servers are on Linux. idSoftware made the mistake of not paying enough attention to this and they ended up massaging the entire Quake 2 code base for Linux and the 3.21 release. OO helps you in this case since you can conceal platform dependencies inside a class but again, this should not be necessary at the mod level.
ALWAYS test your conditional switches and pathways to be sure they work. Test all cases to be sure your project builds successfully under all conditions of switches and packaging. Obviously, the more switches and special configurations you have the harder it becomes to maintain.