What's a good way to organize projects with shared dependencies in Mercurial? [closed]

前提是你 提交于 2019-11-28 02:50:55
barjak

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 :

  1. a so/dll at runtime
  2. 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.

What you want to do is have each project in its own directory like in (1). Then you tag working versions of your dependencies and save the tag in some file for build like:

App1/.dependencies:
CommonLib1 tag-20100515
CommonLib2 tag-20100510

App2/.dependencies:
CommonLib1 tag-20100510
CommonLib2 tag-20100510

Then you use your build scripts to build the libraries based on the specific tag and include those built libraries as derived objects for your applications. If build time is an issue, you can have the tagged version that are in use for those libraries pre-built and saved somewhere.

Note (design principles are same if designing database schema, object model or product build):

  • Do not link to the code in other projects (breaks encapsulation)
  • Do not have multiple copies of the libraries in your repository (modularity)

We solved a similar problem using subversion.

Each app and each Common Lib have their own repositories.

Every app has a directory Libs that contain the dependent dlls.

so the app only gets an update of Common Lib if a new set of dlls is provided.

however upgrading the lib folder is not trivial because depending sub-dlls must match the correct version.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!