Dependencies management is an important aspect of a project's organization, to my eyes. You exposed in great details various solutions, based on the subrepos feature of Mercurial, and I agree with all the pros/cons that you gave.
I think SCMs are not well suited for dependencies management. I prefer having a dedicated tool for that (this would be your solution n°3).
My current project is in Java. It was built with Apache Ant, and I first set up Apache Ivy as a dependencies management tool. In the end, the setup consisted of some Ivy configuration files in a shared directory, and one XML file listing the dependencies for each module of the project. Ivy can be invoked by Ant targets, so I added two new actions in each module : "resolve dependencies", and "deploy the built artifact". The deployment adds the result of the buid (called an artifact) in the shared directory. The dependencies resolution means transitively resolving the dependencies of the module, and copying the resolved artifacts in the "lib" folder of the module's sources.
This solution is applicable to a C++ project, since Ivy is not specific to managing Java dependencies : artifacts can be anything. In C++, the artifacts produced by a module would be :
- a so/dll at runtime
- the header files at compile time.
This is not a perfect solution: Ivy is not easy to set up, you still have to tell your build script what dependencies to use, and you do not have direct access to the sources of the dependencies for debugging purpose. But you do end up with independent SCM repositories.
In our project, we then switched form Ant+Ivy to Apache Maven, which takes care of both the build and the dependencies management. The artifacts are deployed in an Apache Archiva instead of a shared folder. This is a huge improvement, but it will work well for Java projects only.