Painless update of third party libraries

Introduction

Sometimes you need to recompile several or all third party libraries in the project you develop. This may happen if you need to switch to another compiler or upgrade version of existing ones.

If you have a lot of libraries in the project you will fix error by error. Third party interfaces are changed. But you can not test everything while you complete fixing all errors.

So it would be good to update piece by piece.

Approaches to achieve update with small pieces described below. Probably you will not find something tricky, but it is good to have small tricks collected in one place. This may be especially useful when you are stuck and bored. This article may help quickly refresh approaches which may be considered to go on.

Sandboxes

You may create simple application for every third party library you use. You may experiment while familiarizing with that third party library. It is more convenient to try third party library than make modification in the project. This is especially applicable if your product is large. This is what I call sandbox

Such approach may looks like overhead, but on my experience it save time indeed and makes development more predictable.

It is good idea to add check/assert to sandboxes to compare actual and expected values. This is somewhat similar to unit tests. You can move even further, and transform this sandboxes to real unit tests.
This is especially useful if third party interface changes significantly. When adjusting your project you may introduce errors, and such tests expose them early.

Sometimes you you may find two sandboxes for one thirdparty library useful. One of them is simple, it should be build first with new third party. In such a way you assure that your sandbox and third party libraries compatible, it is at least run without crashes. Another one is more complex, this is which contains all functionality you tried with third party, and it can also depend on other third parties. So you should update it after simple one.

Small sandboxes are especially convenient when you want to check some simple functionality, values of constant etc. in new third party just after update. In complex sandbox it may not be easy because code may compile with errors yet.

You may also use one large sandbox. But in this case it is good to have possibility to comment most part of the code at the beginning and not to forget to uncomment it at the end and have it working. To avoid confusion between ordinar comments and comments made for update by small pieces you may mark them specially, e.g. /*TODO: compile ... TODO: compile*/. Such approach simplifies finding all such comments not to forget to compile something. When you have code which can be already run you may test it, trace and you don’t need to postpone such verification.

Note, sandboxes may be used for trying new functionality in third party, not only for upgrading third party itself.

Young library

If you use very young or immature libraries, then there is large chance that interface will be changed and probably broke your project. So it is good idea to write unit tests for most essential functionality for your project. Actually you write unit tests for third party, not your own code.

In practice you may think that it requires extra time, but after all it appears that this is quite robust approach with less obstacles and eventually it saves the time and effort.

Old and new. Run and compare

It is good idea to have compilable old and new version versions of the project and sandboxes along with third parties and other components of your environment. In such case you may compare behavior of your code before and after update.

Update third party – switch environment – compile

If you recompile third party library usually new versions available. So you may update libraries on old environment, adjust your project for new third party libraries, then switch environment of your project and recompile third libraries again.
You may consider if it reasonable approach on not in your case because you need to spend time to rebuild third party library twice.

This approach is strongly suggested when you feel that you can get complete mess.

You may move even further. You may create separate unit test library for every third party to reduce dependencies of them. This allows you to check every third party separately after update. You should consider either it worth to do or not. In such case you will get many test libraries just for checking third party.

Compiling and running

When you update the code because of changed third party interface you not always have a chance to run it and examine that it works as before. It is good idea to create list of functions which you want to check when sandbox or project can be run. You may either create a list or add special comment to the source code, e.g. “TODO: test”.

After making your sandbox compiled you may just compare behavior of new and old non-modified sandbox or code in your project.

Better unit tests you have implemented less probably you need to run other code non covered by unit tests.

Commenting/removing old code

When you adjust some piece of code it may be convenient not to delete old code code, but to comment. Then remove it just before commit when this code is already tested and unlikely will be reverted.

Third party sources with history

If third party changed significanly you may also find useful to have source with history of that library. If some functionality disappeared in new version you may check context and probably find replacement. Documentation and change history for it also very useful but not all library provide such documentation.

This is especially useful if you need to modify third party or to call non-documented funtionality, copy code partially to your project. These are not good practices, but sometimes this is an only solution, e.g. when third party contains bug. As an alternative approach you may fix third party locally but this wil require support of such modification.

Source control for partial changes

If you need to make many changes you may find saving intermediate results handy. Saving intermediate version to source control is quite useful, even code is not completely fixed. This is to avoid mess with many local changes. Commits should be not be done in production branch for your project of course.

Conclusion

Approaches described above allows to split large task of updating all third party libraries for your projects to small tasks.
Actually technics quite obvious but they can missed in hurry to update. So they are collected in one place to review them easily.

Leave a Reply

Your email address will not be published. Required fields are marked *