This is a bit complicated scenario - and even more complicated in practice, but I managed to minimize it for this question.
I have defined two Delphi packages: BasePackage.dpk and AnotherPackage.dpk
package BasePackage;
requires
rtl;
contains
Base in 'Base.pas';
end.
and
package AnotherPackage;
requires
BasePackage;
contains
Another in 'Another.pas';
end.
and units
unit Base;
interface
type
TMethod = procedure;
TEncodeableType = record
Method: TMethod;
end;
PEncodeableType = ^TEncodeableType;
procedure Method_Impl;
const
TestMethod_Type: TEncodeableType = (
Method: Method_Impl;
);
implementation
procedure Method_Impl;
begin
end;
end.
and
unit Another;
interface
uses
Base;
implementation
const
ResponseType: PEncodeableType = #TestMethod_Type;
end.
Everything compiles fine basically, and I can even generate the basic C++Builder units with 'dcc32 -JPHNEK --BCB' but when I try to generate the library files for C++Builder using 'dcc32 -JPHNEK --BCB -JL' I get
>dcc32 -JPHNEK --BCB -JL BasePackage.dpk
Embarcadero Delphi for Win32 compiler version 32.0
Copyright (c) 1983,2017 Embarcadero Technologies, Inc.
BasePackage.dpk(10)
11 lines, 0.09 seconds, 3688 bytes code, 176 bytes data.
>dcc32 -JPHNEK --BCB -JL AnotherPackage.dpk
Embarcadero Delphi for Win32 compiler version 32.0
Copyright (c) 1983,2017 Embarcadero Technologies, Inc.
AnotherPackage.dpk(10)
Error: E2201 Need imported data reference ($G) to access 'TestMethod_Type' from unit 'Another'
I have tried to play with different compile options (and of course introduce {$G+} or {$IMPORTEDDATA ON} to the units and packages (although it's the default anyway), but haven't seen them make any difference.
The packages are compiled without any or with these options in .cfg:
-$A+
-$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
-cg
-AWinTypes=Windows;WinProcs=Windows;DbiTypes=BDE;DbiProcs=BDE;DbiErrs=BDE;
-H+
-W+
-M
-$M16384,1048576
-K$00300000
-Z
and either without any or with these options in .dpk:
{$ALIGN 8}
{$ASSERTIONS ON}
{$BOOLEVAL OFF}
{$DEBUGINFO ON}
{$EXTENDEDSYNTAX ON}
{$IMPORTEDDATA ON}
{$IOCHECKS ON}
{$LOCALSYMBOLS ON}
{$LONGSTRINGS ON}
{$OPENSTRINGS ON}
{$OPTIMIZATION ON}
{$OVERFLOWCHECKS ON}
{$RANGECHECKS ON}
{$REFERENCEINFO OFF}
{$SAFEDIVIDE OFF}
{$STACKFRAMES OFF}
{$TYPEDADDRESS OFF}
{$VARSTRINGCHECKS ON}
{$WRITEABLECONST ON}
{$MINENUMSIZE 1}
{$IMAGEBASE $300000}
{$DESIGNONLY}
{$IMPLICITBUILD OFF}
Any idea if I could make this work (I really need the functionalities in different packages)?
I have been compiling with Delphi 10.2 Tokyo and XE4 with the same result.
I believe this is a compiler issue and therefore it might be impossible to solve for my case exactly like this. But, I can declare the mapping with variables, instead of constants (in practice I have several of these inside structures).
So, this version of Another.pas compiles and works:
unit Another;
interface
uses
Base;
implementation
var
ResponseType: PEncodeableType;
initialization
ResponseType := #TestMethod_Type;
end.
Recently I developed and installed VlControls Delphi package with own components.
Now when any developer on any machine takes other, one year old, CmGUI package, which existed long before VlControls, and tries to build it, following window pops up:
The following changes are necessary to make this package compatible with other installed packages.
Choose OK to apply these changes and rebuild the package.
Add VlControls.
VlControls contains implicit unit(s) TeeBlockCanvas, TeeMesh, TeeBlockEditor, TeeBlockGallery, TeeBlockClasses, TeeWater, TeeBlocks, TeeMakerConst, TeeLoadError, TeeTarga, TeeGLSLShaders, TeeViewBlock, TeeCamera, TeeMakerControl, TeePlayMP3, TeeTextureSelector, TeeMakerEditor, TeeSelectProperty, TeeClipBlock, TeePointEditor, Tee3DSFormat, TeeFacesBlock, TeeObjFormat, TeeSubdivideMesh, TeePointItemEditor, TeeActionGallery, TeeSoundSelector, TeeMakerLibrary, TeeLoadBlock, TeeExtruded, TeeRoundRect, TeeMoveAnimation, TeeNumberAnimation, TeeExtrudedEditor, TeeActionAnimation, TeeBlockAnimations, TeeBlockReplacer, TeeHelix, TeeRain, TeeBlockFormat, TeePipe, TeeProperties, TeeDraw3DEditor, TeeKinematics, TeeColorPalette, TeeRevolutionEditor, TeeRevolution, TeeAnimationGallery, VCLTee.TeeAnimateEditor, TeeTerrain, TeeEdgeStyle, TeeStairs, TeeChartBlock3DEditor, TeeChartBlock, TeeChart3D.
I do not know why this happens, because both packages are completely independent from each other. There are no files in CmGUI which contain "VlControls" string. What both packages have in common, are Tee chart components.
This happens only to this CmGUI package and other old packages are intact.
What could it be?
I am using Delphi 10.
CmGUI.dpk:
package CmGUI;
{$R *.res}
{$IFDEF IMPLICITBUILDING This IFDEF should not be used by users}
{$ALIGN 8}
{$ASSERTIONS OFF}
{$BOOLEVAL OFF}
{$DEBUGINFO ON}
{$EXTENDEDSYNTAX ON}
{$IMPORTEDDATA ON}
{$IOCHECKS OFF}
{$LOCALSYMBOLS ON}
{$LONGSTRINGS ON}
{$OPENSTRINGS ON}
{$OPTIMIZATION OFF}
{$OVERFLOWCHECKS OFF}
{$RANGECHECKS OFF}
{$REFERENCEINFO OFF}
{$SAFEDIVIDE OFF}
{$STACKFRAMES ON}
{$TYPEDADDRESS OFF}
{$VARSTRINGCHECKS ON}
{$WRITEABLECONST OFF}
{$MINENUMSIZE 1}
{$IMAGEBASE $400000}
{$DEFINE DEBUG}
{$ENDIF IMPLICITBUILDING}
{$IMPLICITBUILD ON}
requires
rtl,
vcl,
vclx,
dbrtl,
adortl,
tee923,
designide,
vclactnband,
dclstd,
OurPackageNumber1,
OurPackageNumber2,
vcltouch,
NxCommonRun_d10,
NxGridRun_d10,
TeePro923,
TeeUI923,
TeeImage923,
TeeGL923,
VclSmp,
vclFireDAC,
FireDACIBDriver,
FireDACPgDriver,
IndyProtocols,
NxCollectionRun_d10;
contains
//Here come units from this package only. No external units are included.
end.
VlControls.dpk:
package VlControls;
{$R *.res}
{$IFDEF IMPLICITBUILDING This IFDEF should not be used by users}
{$ALIGN 8}
{$ASSERTIONS ON}
{$BOOLEVAL OFF}
{$DEBUGINFO OFF}
{$EXTENDEDSYNTAX ON}
{$IMPORTEDDATA ON}
{$IOCHECKS ON}
{$LOCALSYMBOLS OFF}
{$LONGSTRINGS ON}
{$OPENSTRINGS ON}
{$OPTIMIZATION ON}
{$OVERFLOWCHECKS OFF}
{$RANGECHECKS OFF}
{$REFERENCEINFO OFF}
{$SAFEDIVIDE OFF}
{$STACKFRAMES OFF}
{$TYPEDADDRESS OFF}
{$VARSTRINGCHECKS ON}
{$WRITEABLECONST OFF}
{$MINENUMSIZE 1}
{$IMAGEBASE $400000}
{$DEFINE RELEASE}
{$ENDIF IMPLICITBUILDING}
{$IMPLICITBUILD ON}
requires
rtl,
vcl,
vclimg,
vclx,
TeePro923,
TeeUI923,
Tee923,
DesignIDE,
TeeImage923,
TeeGL923,
dbrtl,
FireDAC,
FireDACCommonDriver,
FireDACCommon,
IndySystem,
IndyCore;
contains
//Here come units from this package only. No external units are included.
end.
Update
Ok, I looked closely at my package and handled all warnings it displayed at compile time. Now the contains section has following units:
TeeBlockCanvas,
TeeChart3D,
TeeChartBlock3DEditor,
TeeAnimationGallery,
TeeColorPalette,
TeeDraw3DEditor,
TeeProperties,
TeeBlockReplacer,
TeeEdgeStyle,
TeeLoadBlock,
TeeSoundSelector,
TeeActionGallery,
TeeMakerLibrary,
TeeMakerControl,
TeeCamera,
TeePointItemEditor,
TeeSelectProperty,
TeeTextureSelector,
TeeBlockFormat,
TeeSubdivideMesh,
TeePointEditor,
TeeGLSLShaders,
TeeLoadError,
TeeChartBlock,
TeeMesh,
TeeTerrain,
TeeMakerEditor,
TeeClipBlock,
TeeMoveAnimation,
TeeActionAnimation,
TeeBlockAnimations,
TeeNumberAnimation,
TeeKinematics,
TeeBlockEditor,
TeeBlockGallery,
TeeBlockClasses,
TeeViewBlock,
TeeExtrudedEditor,
TeeHelix,
TeeRevolution,
TeeRevolutionEditor,
TeeStairs,
TeeRain,
TeeWater,
VCLTee.TeeAnimateEditor,
TeePlayMP3,
Tee3DSFormat,
TeeObjFormat,
TeeFacesBlock,
TeePipe,
TeeExtruded,
TeeRoundRect,
TeeBlocks,
TeeMakerConst,
TeeTarga;
As I understand, next step would be to look at each unit and find out which package it belongs to and then add package name to requires section removing unit name from contains section.
How to find out which package the unit belongs to if I have no *.pas files, but only *.bpl and *.dcu?
Obviously your package uses a lot of units from a TeeChart package (or several packages? I don't know TeeChart very well). Do not implicitly import them, just put the packages your explicit units (i.e. the units you explicitly name in the contains section) need in the requires section.
Not only does that make your package a lot slimmer, it also avoids such naming conflicts. Anyone who uses your package will face a naming conflict when using other packages that contain units with the same name. That is why the IDE, recognizing that all or most of the packages the other package uses, are in your package, recommends linking to your package.
If your package did not contain these units, that wouldn't happen. That is why you should always, really always, avoid having implicitly imported units. If that happens, you get a warning (during compilation of the package). Heed it.
Example (package MyControls):
contains
MyUnit;
and in MyUnit:
unit MyUnit;
uses
TeeThis, TeeThat, TeeOther;
Now the TeeThis, TeeThat and TeeOther units are implicitly linked into your package. But if your package references the other package that contains these TeeXXX units (say, TeeChart.bpl), the compiler will not add them to your package, it will use them indirectly (reference them) from the TeeChart package. That makes your package smaller, and allows other packages to use the same TeeXXX units in the same way. There will be no naming conflict between your and other packages regarding the TeeXXX units.
requires
TeeChart,
etcetera;
Of course this puts on you the burden to ensure that everyone who uses your package will have the TeeChart package too, if necessary by distributing that package too (assuming licenses allow that).
UPDATE
Your update shows that you now have the TeeChart packages in your requires. If the message is correct, the compiler also includes the units TeeBlockCanvas, TeeMesh, TeeBlockEditor, TeeBlockGallery, TeeBlockClasses, etc.etc. in your package, so the units you explicitly include (in the containssection) seem to use these units too. Put the packages that contain these units (probably TeePro923, TeeUI923 and Tee923) in the requires section too:
requires
rtl,
vcl,
vclx,
// etc...
TeePro923,
TeeUI923,
Tee923,
TeeImage923,
TeeGL923,
// etc...
Now you should not get the message, that all those units were implicitly included into your package, anymore.
I have written 2 packages: MEComps_DXE5 and AMLComps_DXE5. The latter depends on the former. Both should be multi-platform: Win32, Win64, and (in the future) OSX.
When I open the first package MEComps_DXE5, I am able to compile it, build it and install it. I get some warnings, as this library contains code that must also compile on old D5, but the build succeeds and creates the dcu and dcp files where expected.
When I open the second package AMLComps_DXE5, I find this situation:
If I do not declare the dependency on MEComps_DXE5, the package will compile and build correctly (no errors, dcu and dcp files are generated), but Delphi will warn me that it has implicitly imported units from MEComps_DXE5, and ask me to add the package to the dependency list (Requires)
If the dependency is declared, then the compilation will fail with "[dcc32 Fatal Error] MEComps_DXE5.dpk(52): F2063 Could not compile used unit 'MEClasses.pas'", where MEClasses is the first unit of the MEComps_DXE5 package.
I've been trying to solve this for a few days now, but to no avail. I'm working on two fronts:
Why is Delphi even trying to compile the other package? I have just built and installed it, and have all dcus and the dcp.
Why is the compilation failing?
As to the first question I have no clue whatsoever.
As to the second question, the documentation is useless in this case. It explains why not being able to compile a used unit is fatal, and states that the cause is determined by looking at the previous errors. But in this case, there are NO previous errors.
As MEComps_DXE5 actually compiles and builds on its own, I doubt this has anything to do with syntax or code. It would seem to be that the compiler is not able to find something it needs to compile those units.
The two packages reside each in their own directory. I put the MEComps\Win32 dcu directory on the library path and on the browsing path. The IDE actually has no problems looking up the used units.
I also checked the dcc32 command line and it seems that all envolved directories are known to the compiler.
Other info I can add:
Both packages have their own include file (in their source directory). I'm not sure if these are to be included in the package contains list or not, but I've tried both ways and nothing seemed to change.
Both packages have a corresponding Delphi 5 package which includes some of the same units and code (different dpk though). These compile and build correctly. Delphi 5 dcu files are generated in the source directory. Can this create problems with the XE5 compiler?
Here is the complete code for the MEComps_DXE5 package. I see a lot of compiler directives that Delphi inserted when it created the empty package. I didn't touch those:
package MEComps_DXE5;
{$R *.res}
{$IFDEF IMPLICITBUILDING This IFDEF should not be used by users}
{$ALIGN 8}
{$ASSERTIONS ON}
{$BOOLEVAL OFF}
{$DEBUGINFO ON}
{$EXTENDEDSYNTAX ON}
{$IMPORTEDDATA ON}
{$IOCHECKS ON}
{$LOCALSYMBOLS ON}
{$LONGSTRINGS ON}
{$OPENSTRINGS ON}
{$OPTIMIZATION OFF}
{$OVERFLOWCHECKS OFF}
{$RANGECHECKS OFF}
{$REFERENCEINFO ON}
{$SAFEDIVIDE OFF}
{$STACKFRAMES ON}
{$TYPEDADDRESS OFF}
{$VARSTRINGCHECKS ON}
{$WRITEABLECONST OFF}
{$MINENUMSIZE 1}
{$IMAGEBASE $400000}
{$DEFINE DEBUG}
{$ENDIF IMPLICITBUILDING}
{$IMPLICITBUILD ON}
requires
rtl,
fmx,
dbrtl,
xmlrtl;
contains
MEClasses in 'MEClasses.pas',
MEConsts in 'MEConsts.pas',
MEDataReader in 'MEDataReader.pas',
MEDateUtils in 'MEDateUtils.pas',
MEEncoding in 'MEEncoding.pas',
MEEncodingISO2022 in 'MEEncodingISO2022.pas',
MEFileUtils in 'MEFileUtils.pas',
MELists in 'MELists.pas',
MEMath in 'MEMath.pas',
MENumUtils in 'MENumUtils.pas',
MESQLUtils in 'MESQLUtils.pas',
MEStrUtils in 'MEStrUtils.pas',
MESysUtils in 'MESysUtils.pas',
METypes in 'METypes.pas',
MEURIUtils in 'MEURIUtils.pas',
MEXMLUtils in 'MEXMLUtils.pas';
end.
Delphi IDE is far from perfect when it comes to editing/compiling packages but you should solve the problem on your side - configure your packages better and Delphi will compile them correctly.
I can only give you general advices addressing the info given:
If you need a common include file for 2 packages create a separate directory for the file and add this directory to the search paths of both packages (in Base build configuration).
Never keep .dcu's in the same folders with source files; always set "unit output directory" option for your packages (also in Base build configuration); I recommend $(BDSCOMMONDIR)\MyPacks\$(Config)\$(Platform) as such directory for your packages; if you already have .dcu's in the source (.pas) folders delete them, does not matter which Delphi version created these .dcu's.
Never add paths to dependent package's sources to the search path, only paths to compiled .dcu's (would be $(BDSCOMMONDIR)\MyPacks\$(Config)\$(Platform) if you follow previous advice).
When I compile my application under Delphi 2006 I get the following warning
[Pascal Warning]- W1002 Symbol 'FileSetDate' is specific to a platform
What must I do to suppress this warning?
The code
MyLastError:= FileSetDate( Files[ i ].Handle, DateTimeToFileDate( arcDate ) );
1) In the project options you can choose the compiler messages you want to see.
If you don't care about platform independency you can just switch off the platform warning there.
2) Another way is disabling the warning for a certain part of the code:
{$WARN SYMBOL_PLATFORM OFF}
// Your code
{$WARN SYMBOL_PLATFORM ON}
For a complete list of options look at the Delphi help file at the topic '$WARN'
3) A last way would be adding
{$WARNINGS OFF}
// Your code
{$WARNINGS ON}
but that is dangerous, because all warnings will be suppressed.
4) Additionally, as the other answers have already suggested, you could just switch to the platform independant variant of FileSetDate which works on file names (i.e. Strings), but as far as I understand that was not your question.
Although the answer of DR solves the warning, it is not the correct solution.
You should use the platform independent version of FileSetDate:
function FileSetDate(const FileName: string; Age: Integer): Integer; overload;
Also in SysUtils.
You can turn off the platform unit and platform symbol compiler warnings. They are obsolete (and disabled in Delphi 2009 by default). They were introduced when there was a Delphi for Linux (Kylix). They do not have a meaning anymore. Especially with the replacement of Delphi.NET with Delphi Prism.
You can turn them off for the whole project in the Project Options dialog (Compiler Messages).