{$WARN SYMBOL_PLATFORM OFF} does not turn off warnings - delphi

I have this piece of code:
INTERFACE
{$WARN SYMBOL_PLATFORM OFF}
USES
Winapi.Windows, etc, {$IFDEF MSWINDOWS}Vcl.FileCtrl, {$ENDIF} System.IniFiles;
{$WARN SYMBOL_PLATFORM ON}
The compiler shows:
[dcc32 Warning] W1005 Unit 'Vcl.FileCtrl' is
specific to a platform
even though the {$WARN SYMBOL_PLATFORM OFF} is there.
Why?

You are using the wrong directive. SYMBOL_PLATFORM controls warnings for symbols marked platform specific. Your warning relates to a unit marked platform specific.
Control these warnings with UNIT_PLATFORM.
The whole unit is tagged (using the platform hint directive) as one that contains material that might not be available on all platforms. If you are writing multi-device applications, the unit might cause a problem. For example, a unit that uses objects defined in OleAuto might be tagged using the PLATFORM directive.
The $WARN UNIT_PLATFORM ON/OFF compiler directive turns on or off all warnings about the platform directive in units where the platform directive is specified.
There's a really easy way for you to work this out for yourself. Take a look at the two documentation topics I linked to above. Their titles are:
W1002 Symbol '%s' is specific to a platform (Delphi)
W1005 Unit '%s' is specific to a platform (Delphi)
The compiler warning that you received names the warning as W1005. This is all you need to know to determine which directive to use to control it. If you have any trouble finding them simply search for the warning name, W1005 in this instance. Or refer to the documentation that lists them all.

Related

The initialization part is not called

I'm maintaining the VirtualTreeView component for Delphi and C++Builder. With Delphi everything is okay but when I compile the packages with the C++Builder the code in the initialization part in the Delphi units is not called. Any ideas?
When a Delphi unit's initialization/finalization sections are not being called in a C++Builder project, it usually means the Delphi unit is not being linked into the final executable, typically because the C++ code is not directly referencing any code in the unit, so it gets optimized out. C++Builder is a bit more aggressive about removing unused code than Delphi is. In Delphi, simply adding a unit to a uses clause forces that unit to be linked to. That is not the case in C++. #includeing a Delphi unit's .hpp file in C++ code is not enough to guarantee the unit is linked to, if the C++ code does not use anything from the .hpp file.
Indy ran into this problem in several of its units, most notably IdAllAuthentications, IdAllFTPListParsers, and IdAllHeaderCoders. These units all contain only initialization/finalization code, no interface code, so their generated .hpp files were basically empty. To force linkage, I had to add {$HPPEMIT} statements to the interface section to output #pragma link statements in the generated .hpp files. For example:
unit IdAllAuthentications;
interface
{
Note that this unit is simply for listing ALL Authentications in Indy.
The user could then add this unit to a uses clause in their program and
have all Authentications linked into their program.
ABSOLUTELY NO CODE is permitted in this unit.
}
{$I IdCompilerDefines.inc}
// RLebeau 2/14/09: this forces C++Builder to link to this unit so
// the units can register themselves correctly at program startup...
{$IFDEF HAS_DIRECTIVE_HPPEMIT_LINKUNIT}
{$HPPEMIT LINKUNIT}
{$ELSE}
{$HPPEMIT '#pragma link "IdAllAuthentications"'}
{$ENDIF}
implementation
// uses units that self-register in their initialization sections ...
end.
{$HPPEMIT LINKUNIT} was introduced in XE5 Update 2, to help with linking units that use unit-scope names:
New: You can now use HPPEMIT Delphi compiler directives for linking and generating C++ namespace declarations.
...
{$HPPEMIT LINKUNIT} replaces #pragma link for the iOS device target platform.
For more information, see HPPEMIT.
For C++ applications, {$HPPEMIT LINKUNIT} replaces #pragma link on mobile platforms.
The Delphi run time has units that must be linked in order to enable some functionality. In C++, auto-linking was previously achieved using the following directive:
{$HPPEMIT '#pragma link "<unitname>"'}
Now you should use the following directive instead:
{$HPPEMIT LINKUNIT}
LINKUNIT generates a #pragma link statement that references the calling unit using the correct decorated/namespaced unit name.

Error F2063 Could not compile used unit (of dependent package)

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).

Unit GIFImg was compiled with a different version of CCR.Exif.Consts.SOutOfResources

I was trying to use the EXIF library in one of my packages. It worked before but now I get strange messages:
[DCC Fatal Error] F2051 Unit GIFImg was compiled with a different
version of CCR.Exif.Consts.SOutOfResources
I don't really get it... Why Delphi tries to recompile one of its files? How do I fix this?
GifImg is located here:
c:\Program Files\Embarcadero\RAD Studio\8.0\source\vcl\GIFImg.pas
Update:
I looked at the date of that file (1 PAS and 2 DCUs) and it has the same date as any other file in RAD Studio\8.0\source\vcl folder. So, the file was not accidentally modified.
Update2:
This is my uses clause:
USES Windows, SysUtils, AnsiStrings, Graphics, Dialogs, Classes, jPeg,
pngImage,
janFX, //CCR.Exif,
{$IFDEF VER150}
GIFImageFinn {Delphi 7}
{$ELSE}
GIFImg {Delphi 2010/XE}
{$ENDIF}
;
If I comment the CCR.EXIF unit, it starts to compile my package. So, adding EXIF to my package breaks something.
What you report doesn't quite add up. The GIFImg unit that is part of the Delphi source does not refer to CCR.Exif.Consts.SOutOfResources. And none of the units used by GIFImg refer to it either.
So the explanations that seem plausible to me are:
You are including a unit called GIFImg somewhere in your project.
You've found a compiler bug.
The error message F2051 is emitted typically, in my experience, when you attempt to recompile an RTL/VCL unit but fail to set the project options to match that used by the true RTL/VCL. Alternatively it will be emitted when you recompile an RTL/VCL unit that has modifications in its interface section.
Solved:
I removed the dots in the name of the files.
CCRExif instead of CCR.Exif.
That was a nasty one.

Is there any way to get the current unit's name from an include file?

I'm porting some code from one framework library to another, which requires me to comment out large sections of code just to get it to compile, and then carefully restore them. In the meantime, I get tons of warnings because of all the commented-out code. So I decided to write a quick include file to suppress them:
{$MESSAGE WARN 'Warnings suppressed for unported unit with commented-out code'}
{$WARN NO_RETVAL OFF}
{$WARN USE_BEFORE_DEF OFF}
I included this in all the units that are giving me tons of warnings, but now when I compile, the compiler's returning the message as follows:
[DCC Warning] unfinished.inc(1): W1054 Warnings suppressed for unported unit with commented-out code
I'd like it to tell me that the warning is coming from the unit doing the including, not the include file itself. Is there any way to do that, or to work the name of the unit into the message, without actually moving the $MESSAGE directive out of the include file and into every single unit where I did this?
Here is a trick, which uses the fact that the compiler hint for "unused private methods" contains the name of the unit, the class is declared in, even if the class with the private method is declared in an include file.
This requires that the include-directive for your include file appears in a part of the unit, where declarations are allowed, so either after the uses clause in the interface section or after the uses clause of the implementation section.
interface
uses Foo, Bar, Socks;
{$include Unfinished.inc}
Your include file should look like this:
{$MESSAGE WARN 'Warnings suppressed for unported unit with commented-out code, Unit name see next line'}
type
TUnit_With_Suppressed_Warnings = class
private
procedure UnitWithSuppressedWarnings; virtual; abstract;
end;
{$WARN NO_RETVAL OFF}
{$WARN USE_BEFORE_DEF OFF}
Now, you will get the following two messages for every unit that includes that include file:
[DCC Warning] unfinished.inc(1): W1054 Warnings suppressed for unported unit with commented-out code, Unit name see next line
[DCC Hint] actualunitname.pas(5): The private symbol UnitWithSuppressedWarnings was declared but never used.
Notice that the name of the actual unit appears in the second line.
Remark: You will not see the second line, if compiler hints are switched off.

Delphi warning - W1002 Symbol 'FileSetDate' is specific to a platform

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).

Resources