Can anyone point me to the rules on Delphi dcu compatibility, ie if unit b uses unit a, what changes to unit a will break dcu compatibility with unit b? I know generally interface changes will cause that, but wondering if there are others.

Can anyone point me to the rules on Delphi dcu compatibility, ie if unit b uses unit a, what changes to unit a will break dcu compatibility with unit b? I know generally interface changes will cause that, but wondering if there are others.

Google isn't helping me here as everything that comes up is about compatibilty between delphi versions, which is not what I am after.

Comments

  1. /sub - not sure if I understand the question fully but it sounds interesting (to me)

    ReplyDelete
  2. AFAIK changes to a unit's interface section cause all units that use this unit to need a recompile. Changes to the implementation section don't.

    ReplyDelete
  3. 64bit / 32bit / compiler version / unit interface are to check

    ReplyDelete
  4. I ask because I've seen compatibility break even when not changing the interface section. I'm thinking about this in the context of a package manager and dependencies, just working out the rules for compatibility.

    ReplyDelete
  5. Once it was so, that changing the value of a typed const in the interface section will not cause others to recompile.

    ReplyDelete
  6. I think you can add new content without breaking compatibility.

    ReplyDelete
  7. Very interesting question. From partial experiments with interface changes in the past, if memory serves me well enough, comments and whitespace are excluded but anything else counted as change. It's been a long long time ago though (think D1/D2 era).

    ReplyDelete
  8. I've also seen incompatibilities without changing the interface of a class (at least I coudn't find any change). I think that you can add new content but not to an existing class. At least this is what I understand from this article from Allen Bauer here:
    http://blogs.embarcadero.com/abauer/2007/02/24/32322

    ReplyDelete
  9. Ok, this is an interesting subject and one that many folks seem to think is voodoo and magic. The rules are deceptively simple...

    Any material change to an existing interfaced symbol, directly or indirectly, will render that dcu incompatible with prebuilt units that depend on this unit.

    Let's break this down a little more. What is a "material" change?

    1. Anything that could change the layout of a structured type (object, class, record, etc).
    2. A change in symbols within a structured scope. This means even the addition of a non-virtual method to a base class is a "material" change.
    3. A change in method or global function signature.

    Remember, I also said indirectly... For instance, a change to a type used as the parameter of a given global function will also cause a compatibility error. Even if that type is the same size and semantic.

    The key points here are changes to existing symbols. What this means is that you can, many times, get away with adding another symbol to the unit without rendering it incompatible with existing pre-built dcu files. This is logical be cause there cannot be a reference to a symbol that didn't previously exist. However, this can also backfire, because you once new code references the new symbols, that new code cannot be used with the old version of the dcu. Logically because of the above "material change" rule. Deleting a symbol is a "material" change.

    Even if you think you followed all those rules, there can still be cases where dcus can be rendered incompatible. Some of those are the result of a compiler change in a patch that fixes something critical but could render dcus built with the new version incompatible with older versions of the compiler. The newer, fixed version would usually be made resilient enough to load the older dcu files and compile against them, but new dcus written cannot be used with the older compiler. This is rare, but has happened a few times over the last couple of decades.

    ReplyDelete
  10. Thanks Allen Bauer -  you should copy n paste your answer into the doco ;) 

    I know the dcu/dcp formats are undocumented, but is there a hash header or something I can use to determine a unique 'version' - so if I have a library that is dcus/dcps only, I can calculate a collective hash that I can then test agains another newer (or older) copy of the library to determine compatibility?

    The context for this is a package/library manager, and recording package meta data so that dependencies can be determined.. if I my package A depends on someone elses package B v1.0, and package B delivers only dcu's, I'm looking for a way to determine is package B v1.0.1 is compatable with v1.0 - at the moment I'm just specc'ing it up and thinking about possible challenges.. solving the dreaded F2051 error once and for all would be a bonus!

    ReplyDelete
  11. Vincent Parrett You should never get an internal error due to dcu incompatibility, even across major versions. That you are getting an internal error, indicates a broader problem in the compiler. If you have some set of dcu files that reproduce this, we'd like to have them to try and analyze.

    Are those units using constant floating point expressions or IsConstValue() standard function? What version of the product?

    ReplyDelete
  12. Allen Bauer F2051 is not an internal error - its the "Unit was compiled with a different version." error

    ReplyDelete
  13. Yes, Stefan has it right, it's not an internal error, it's a common compiler error when working with dcu only libraries.. and quite often happens when not using dcu only libraries if another copy of the dcu is found somewhere else on your library path. It wouldn't be so bad if there was a way to get a bill of materials from a dcu (ie if it stored the paths of other units it referenced). I stopped using the library path because of this error and only ever use the project search path now.. but without a package manger that supports this (and dependencies) it can be quite painful getting a project up and running.. I had high hopes for GetIt but it doesn't do what I need/want, so I resurrected a project I shelved a while back when GetIt was first announced.

    ReplyDelete
  14. Stefan Glienke Oh... right... I feel sheepish..

    ReplyDelete

Post a Comment