Jump to content
uligerhardt

Tool to sort units used in project by dependency

Recommended Posts

I'd like to sort the units used in our projects (*.dpr/*.dpk) by dependency. (I hope for faster compilations.) Are there tools to do that?

 

PAL from Peganza outputs an "Optimal uses list" but that is rather "untidy" - e.g. third party units, my base units and the "business logic" all mixed together.

 

Share this post


Link to post
40 minutes ago, Anders Melander said:
  • Sorted by dependency
  • Sorted by "some other criteria"

Pick one

These are not mutually exclusive. E.g. PAL gives something like

BusinessLogicA
ThirdPartyA
MyBaseStuffA
BusinessLogicB
ThirdPartyB
MyBaseStuffB

which satisfies the first bullet. I'd like to have

ThirdPartyA
ThirdPartyB
MyBaseStuffA
MyBaseStuffB
BusinessLogicA
BusinessLogicB

which satifies both criteria. I guess this would be some kind of stable sorting based on the original uses order.

Share this post


Link to post
Posted (edited)
2 hours ago, uligerhardt said:

These are not mutually exclusive. E.g. PAL gives something like

Yeah, they are indeed mutually exclusive. Each unit has it's own dependencies. If you want the units listed in order of when they are needed, you aren't going to be able to make them look "tidy."

 

Sounds like you want a hybrid approach. I don't see how that could be done without manual work, but besides, it would defeat your originally stated goal.

 

Personally, I find the overhead of locating units during compilation to be insignificant, so I always prefer a logical ordering because my brain will be slowed down by illogical ordering more than the compiler will be sped up by it!

 

I my experience, the only thing that really matters is not having unnecessary units in the interface section. Anything that isn't needed should be removed, and anything that isn't needed before the implementation section should be moved to the implementation section.

Edited by Brandon Staggs
  • Like 2

Share this post


Link to post

Probably you both are right and I'm asking too much.

FWIW: I don't want the units in the order they are first needed, just - as far as possible - dependent units after the units they use.

If i find time I'll try to go with PAL's list and check if it makes a difference in compile time.

Share this post


Link to post
2 hours ago, Brandon Staggs said:

the only thing that really matters is not having unnecessary units in the interface section. Anything that isn't needed should be removed, and anything that isn't needed before the implementation section should be moved to the implementation section.

This would be a whole lot easier if Delphi had such a feature. Is it that hard to implement that?

Share this post


Link to post
7 minutes ago, havrlisan said:

This would be a whole lot easier if Delphi had such a feature. Is it that hard to implement that?

Give it a shot and let us know. :classic_wink:

  • Like 1

Share this post


Link to post
12 minutes ago, havrlisan said:

This would be a whole lot easier if Delphi had such a feature. Is it that hard to implement that?

I can think of a lot of reasons why it isn't trivial to do. I have only used analysis tools for this once or twice. personally, when I think a unit needs this kind of housecleaning, I just comment out the uses clauses and add each one back in (also checking whether it needs to be in interface or not) as needed. Even that can be less-than-easy, since sometimes a unit is included just to get its initialization section executed.

Share this post


Link to post
9 minutes ago, JonRobertson said:

Give it a shot and let us know. :classic_wink:

I'm genuinely curious about how hard it is to implement. I remember seeing it in the Android Studio, which seemed like an awesome feature.

2 minutes ago, Brandon Staggs said:

I can think of a lot of reasons why it isn't trivial to do. I have only used analysis tools for this once or twice. personally, when I think a unit needs this kind of housecleaning, I just comment out the uses clauses and add each one back in (also checking whether it needs to be in interface or not) as needed. Even that can be less-than-easy, since sometimes a unit is included just to get its initialization section executed.

I agree; it is the same thing I do on rare occasions. I wonder how much of an impact the unused units have on compilation time, and whether it is even noticeable on medium-sized projects (~500.000 lines of code).

Share this post


Link to post
Just now, havrlisan said:

whether it is even noticeable on medium-sized projects (~500.000 lines of code)

Yes, it is noticeable. My last four projects have been migrating applications from Delphi 7 to 11.3. There were dozens of units referenced that could be either moved to implementation or removed completely. I've been able to get rid of numerous circular dependencies. Although the compile time reduction is not huge, it is noticeable even on a 200K loc project.

 

Sadly, it takes Azure DevOps longer to check out the repo than building the source. :classic_biggrin:

  • Like 1

Share this post


Link to post
40 minutes ago, havrlisan said:

I agree; it is the same thing I do on rare occasions. I wonder how much of an impact the unused units have on compilation time, and whether it is even noticeable on medium-sized projects (~500.000 lines of code).

For me the issue has always been LSP and code insight, which seem to work better with tidy uses clauses.

  • Like 1

Share this post


Link to post

Pro tip, don't use the Library Path for anything other than the rtl/vc/fmx. Only add the third party libs your project actually needs to the project search path. That avoids the compler trawling through a bunch of paths that it doesn't need to.

  • Like 5

Share this post


Link to post

The new unit order can have unintended side effects - if two unites define procedures with the same names and their order is swapped, the code will use a different procedure than before (such as System.Math and Neslib.FastMath do).

Share this post


Link to post
13 hours ago, havrlisan said:

This would be a whole lot easier if Delphi had such a feature. Is it that hard to implement that?

cnpack has a tool to remove unused units from the uses list. It's not perfect, but a good starting point.

  • Like 2

Share this post


Link to post
34 minutes ago, Vandrovnik said:

The new unit order can have unintended side effects - if two unites define procedures with the same names and their order is swapped, the code will use a different procedure than before (such as System.Math and Neslib.FastMath do).

This would only apply if we're rearranging the used units inside a pas file. My question is about the project file, where you typically don't have much code.

Share this post


Link to post
5 hours ago, dummzeuch said:

cnpack has a tool to remove unused units from the uses list

Unfortunately cnpack causes an AV in rtl*.dll when LiveBindings packages are disabled, and a couple other AVs in the IDE. I had to uninstall cnpack until this issue is resolved:

 

AV after exit RAD Studio 10.2.3 - 12.1

 

And hopefully this AV in coreide.bpl:


Access violation in module 'coreide250.bpl' #170

Access violation in module 'coreide290.bpl' #192

Share this post


Link to post
3 hours ago, JonRobertson said:

Unfortunately cnpack causes an AV in rtl*.dll when LiveBindings packages are disabled, and a couple other AVs in the IDE. I had to uninstall cnpack until this issue is resolved:

 

AV after exit RAD Studio 10.2.3 - 12.1

 

And hopefully this AV in coreide.bpl:


Access violation in module 'coreide250.bpl' #170

Access violation in module 'coreide290.bpl' #192

You could try the nightly build or get the source code and compile it yourself (I do that once in a while, it's not rocket science but more complex than with GExperts). But I don't know whether this might solve the problem.

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

×