Jump to content
Sign in to follow this  
Larry Hengen

Automated Way to Detect Interface Breaking Changes

Recommended Posts

If you have an application that uses run-time packages and are supporting an older release, you cannot change the interface of any package or you have to re-distribute all dependent packages instead just the one you're updating.  Is there anyway to detect interface breaking changes automatically (that it could be put on a build server)?  Any advice on maintaining apps using run-time packages?

Share this post


Link to post
1 hour ago, Larry Hengen said:

Is there anyway to detect interface breaking changes automatically

I would think that the compiler would do that for you - i.e. give you a compile or linker error.

I must admit that my experience with run-time packages are a couple of decades old but AFAIR the dcu files of the packages are stored in a dcp file. If the linker uses the dcp file instead of the dcu files then a interface change should result in a linker error - but I might of course be remembering this completely wrong.

 

1 hour ago, Larry Hengen said:

Is there anyway to detect interface breaking changes automatically (that it could be put on a build server)?

Since run-time packages are just statically linked DLLs I believe you just need to determine if all DLL dependencies can be resolved. It would be trivial to create a small utility that loaded you application with LoadLibraryEx  and have that do it, but unfortunately LoadLibraryEx only resolves dependencies when you load DLLs.

 

Try Dependency Walker instead. It has a command line mode that you can probably use. I don't know what the output looks like though.

 

1 hour ago, Larry Hengen said:

Any advice on maintaining apps using run-time packages?

Get rid of them (the packages, not the apps).

Share this post


Link to post
44 minutes ago, Anders Melander said:

I would think that the compiler would do that for you - i.e. give you a compile or linker error.

I must admit that my experience with run-time packages are a couple of decades old but AFAIR the dcu files of the packages are stored in a dcp file. If the linker uses the dcp file instead of the dcu files then a interface change should result in a linker error - but I might of course be remembering this completely wrong.

 

Since run-time packages are just statically linked DLLs I believe you just need to determine if all DLL dependencies can be resolved. It would be trivial to create a small utility that loaded you application with LoadLibraryEx  and have that do it, but unfortunately LoadLibraryEx only resolves dependencies when you load DLLs.

 

Try Dependency Walker instead. It has a command line mode that you can probably use. I don't know what the output looks like though.

 

Get rid of them (the packages, not the apps). 

Thanks for the response and pointing me to Dependency Walker.

 

As for the run-time packages, it's not my choice.  I was asking about best practices because I have normally been using Monolithic EXEs.  Didn't realize I was already using the best practices for package based apps ;-0

Share this post


Link to post

You can use SemVer versioning scheme to determine breaking changes and parse project/package files to determine dependency tree so you'll get a list of packages that need to be updated.

  • Like 1

Share this post


Link to post

As far as I remember with packages it's the same as with units: If you don't change the interface section, you don't have to recompile depending units. For packages the dcp file contains the interface sections of all units in the package.

Share this post


Link to post
1 hour ago, dummzeuch said:

As far as I remember with packages it's the same as with units: If you don't change the interface section, you don't have to recompile depending units. For packages the dcp file contains the interface sections of all units in the package.

Unless you use generics - they are off limits to be changed (interface and implementation section) in both cases - also for units inline methods are off limits - for packages they are ok because inlining does not happen across binary module boundaries.

Share this post


Link to post

I've always worked with runtime packages, but I always deploy all of them

 

The easiest way to check if a package can be loaded, is just loading it:

function LoadPackage(const Name: string): HMODULE; overload;
function LoadPackage(const Name: string; AValidatePackage: TValidatePackageProc): HMODULE; overload;

LoadPackage loads the package specified by the Name parameter, checks for duplicate units, and calls the initialization blocks of all units contained in the package

 

 

Share this post


Link to post
35 minutes ago, Javier Tarí said:

The easiest way to check if a package can be loaded, is just loading it

That only resolves inter-package dependencies. Not application dependencies.

Share this post


Link to post
On 8/26/2020 at 6:04 PM, Anders Melander said:

That only resolves inter-package dependencies. Not application dependencies.

My fault... I'm so used to work with an app that is just the launcher for the main package, that didn't thought on it at all

My exe just loads the main package and launches a given exporte procedure there, that's almost all it does

Share this post


Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this  

×