Jump to content
Dave Novo

recompiling delphi source for Delphi Sydney

Recommended Posts

Does anyone have the trick for recompiling Delphi source in Delphi Sydney (10.4.2)? We had this working well in Delphi Seattle.

We just copied the Delphi source unit to our path, and made sure the default compiler directives were at the top. With the usual caveat that you can only change the implementation code, not the interface.

This is documented well in

https://stackoverflow.com/questions/10470943/how-to-recompile-modifications-to-vcl-source-file-menus-pas

 

However, for Delphi Sydney it does not work for me.

 

Just create a blank VCL forms application

Copy System.Classes.pas to the folder with your unit1.pas and compile.

It will fail with

 

[dcc32 Fatal Error] System.Classes.pas(21328): F2051 Unit Vcl.ExtCtrls was compiled with a different version of System.Classes.TCollectionEnumerator.GetCurrent

 

if you press Ctrl+O+O you get the directives I list below. Even if you paste these to the top of your modified System.Classes.pas it still will not compile with the same error.

 

Does anyone know the compiler directives you are supposed to use to recompile the delphi source for Delphi Sydney?

 

{$A8,B-,C+,D+,E-,F-,G+,H+,I+,J-,K-,L+,M-,N-,O+,P+,Q-,R-,S-,T-,U-,V+,W-,X+,Y+,Z1}
{$MINSTACKSIZE $00004000}
{$MAXSTACKSIZE $00100000}
{$IMAGEBASE $00400000}
{$APPTYPE GUI}
{$WARN SYMBOL_DEPRECATED ON}
{$WARN SYMBOL_LIBRARY ON}
{$WARN SYMBOL_PLATFORM ON}
{$WARN SYMBOL_EXPERIMENTAL ON}
{$WARN UNIT_LIBRARY ON}
{$WARN UNIT_PLATFORM ON}
{$WARN UNIT_DEPRECATED ON}
{$WARN UNIT_EXPERIMENTAL ON}
{$WARN HRESULT_COMPAT ON}
{$WARN HIDING_MEMBER ON}
{$WARN HIDDEN_VIRTUAL ON}
{$WARN GARBAGE ON}
{$WARN BOUNDS_ERROR ON}
{$WARN ZERO_NIL_COMPAT ON}
{$WARN STRING_CONST_TRUNCED ON}
{$WARN FOR_LOOP_VAR_VARPAR ON}
{$WARN TYPED_CONST_VARPAR ON}
{$WARN ASG_TO_TYPED_CONST ON}
{$WARN CASE_LABEL_RANGE ON}
{$WARN FOR_VARIABLE ON}
{$WARN CONSTRUCTING_ABSTRACT ON}
{$WARN COMPARISON_FALSE ON}
{$WARN COMPARISON_TRUE ON}
{$WARN COMPARING_SIGNED_UNSIGNED ON}
{$WARN COMBINING_SIGNED_UNSIGNED ON}
{$WARN UNSUPPORTED_CONSTRUCT ON}
{$WARN FILE_OPEN ON}
{$WARN FILE_OPEN_UNITSRC ON}
{$WARN BAD_GLOBAL_SYMBOL ON}
{$WARN DUPLICATE_CTOR_DTOR ON}
{$WARN INVALID_DIRECTIVE ON}
{$WARN PACKAGE_NO_LINK ON}
{$WARN PACKAGED_THREADVAR ON}
{$WARN IMPLICIT_IMPORT ON}
{$WARN HPPEMIT_IGNORED ON}
{$WARN NO_RETVAL ON}
{$WARN USE_BEFORE_DEF ON}
{$WARN FOR_LOOP_VAR_UNDEF ON}
{$WARN UNIT_NAME_MISMATCH ON}
{$WARN NO_CFG_FILE_FOUND ON}
{$WARN IMPLICIT_VARIANTS ON}
{$WARN UNICODE_TO_LOCALE ON}
{$WARN LOCALE_TO_UNICODE ON}
{$WARN IMAGEBASE_MULTIPLE ON}
{$WARN SUSPICIOUS_TYPECAST ON}
{$WARN PRIVATE_PROPACCESSOR ON}
{$WARN UNSAFE_TYPE OFF}
{$WARN UNSAFE_CODE OFF}
{$WARN UNSAFE_CAST OFF}
{$WARN OPTION_TRUNCATED ON}
{$WARN WIDECHAR_REDUCED ON}
{$WARN DUPLICATES_IGNORED ON}
{$WARN UNIT_INIT_SEQ ON}
{$WARN LOCAL_PINVOKE ON}
{$WARN MESSAGE_DIRECTIVE ON}
{$WARN TYPEINFO_IMPLICITLY_ADDED ON}
{$WARN RLINK_WARNING ON}
{$WARN IMPLICIT_STRING_CAST ON}
{$WARN IMPLICIT_STRING_CAST_LOSS ON}
{$WARN EXPLICIT_STRING_CAST OFF}
{$WARN EXPLICIT_STRING_CAST_LOSS OFF}
{$WARN CVT_WCHAR_TO_ACHAR ON}
{$WARN CVT_NARROWING_STRING_LOST ON}
{$WARN CVT_ACHAR_TO_WCHAR ON}
{$WARN CVT_WIDENING_STRING_LOST ON}
{$WARN NON_PORTABLE_TYPECAST ON}
{$WARN XML_WHITESPACE_NOT_ALLOWED ON}
{$WARN XML_UNKNOWN_ENTITY ON}
{$WARN XML_INVALID_NAME_START ON}
{$WARN XML_INVALID_NAME ON}
{$WARN XML_EXPECTED_CHARACTER ON}
{$WARN XML_CREF_NO_RESOLVE ON}
{$WARN XML_NO_PARM ON}
{$WARN XML_NO_MATCHING_PARM ON}
{$WARN IMMUTABLE_STRINGS OFF}

 

 

Edited by Dave Novo

Share this post


Link to post

This has nothing to do with the compiler options but with the inlining - in Vcl.ExtCtrls.TCustomGridPanel.Loaded there is a for in loop over a TCollection and the GetCurrent implemenentation is different in 10.4 as it was in 10.0.

 

To my knowledge there is no way to compile individual units that have methods that are inlined when being used in other units - so you have to compile the other units as well - in this case you also have to add Vcl.ExtCtrls to your project and recompile that as well even though you did not change anything in that unit but because of the inlined method. This can pile up quite significantly causing the necessity to recompile almost the entire codebase depending on which unit you modified and recompile.

Share this post


Link to post

@Stefan Glienke

Thanks, thats very interesting, I thought about these issues too, which would be the reasons though, and I assumed there could be many reasons (inline, generics, other references).

Do you know if the "inlining" is the only reason that causes this issue ?

 

Share this post


Link to post
16 minutes ago, Rollo62 said:

@Stefan Glienke

Thanks, that's very interesting, I thought about these issues too, which would be the reasons though, and I assumed there could be many reasons (inline, generics, other references).

Do you know if the "inlining" is the only reason that causes this issue?

Generics as well but that is related to inlining because generics use a similar mechanism as inlining does.

That's why we had some breaking changes in some updates in the past because some devs at Embarcadero obviously forgot about that and fixed some issues in Generics.Collections.

 

I think there are more reasons for F2051 to happen but those that are not solvable by switching around compiler options are those I mentioned to my knowledge.

To be honest I am still not fully understanding how inlining is being controlled exactly.

For example when I write a for in loop over a TCollection in my code and add System.Classes to my project causing a recompile I see that it does not fully inline but does a call to TList<TCollectionItem>.GetItems which is marked as inline.

When I use the dcu shipped with Delphi that call is not there. Changing $INLINE option does not change anything about that.

 

Example code - when looking at the asm you will see the call I mentioned before. When the path to the pas file is removed and it uses the dcu the call is not there. I did not find a compiler option that makes it go away when compiling the pas file.

 

uses
  System.Classes in 'c:\program files (x86)\embarcadero\studio\21.0\source\rtl\common\System.Classes.pas';

procedure Main;
var
  list: TCollection;
  item: TCollectionItem;
begin
  list := TCollection.Create(TCollectionItem);
  list.Add;
  for item in list do;
end;

begin
  Main;
end.

 

Edited by Stefan Glienke
  • Like 1

Share this post


Link to post

@Stefan Glienke - thank you so much. We never encountered this before in Delphi Seattle.

 

In Delphi Seattle we managed to recompile

  • System.Classes
  • System.IOUtils
  • System.SysUtils
  • WinApi.GDIApi.pas
  • DAta.Win.ADoDb

and did not need to pull in other units that we did not need. I guess EMB has increased their use of inlining/generics over the years.

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

×