How to disable warnings from given unit without modifying that unit? - delphi

So I am including in my unit some other units and after building application I receive a huge amount of warnings from those units. The amount is so large that I'am having problems in finding my own warnings on the list. ;-)
Is there some compiler directive which would allow me to turn those warnings off? But please note, that I don't want to modify those units in any way. I would like to achieve something like this:
unit MyUnit;
interface
uses
UnitA, {$WARN EMIT_WARNNIGS OFF} UnitB, {$WARN EMIT_WARNNIGS ON} UnitC, UnitD.
implementation
uses
UnitE, {$WARN EMIT_WARNNIGS OFF} UnitF, UnitG, {$WARN EMIT_WARNNIGS ON} UnitH.
This is an imaginary compiler directive which I would like to have, or maybe it exists and I don't know about it?
Thanks for your time.

There is a compiler directive to turn warnings off, but this can only be set in either project options in which case it applies to all units, or in a unit itself in which case it applies to that unit alone.
So, you're left with a few options.
Unrealistic option that does exactly what you ask:
So the only solution would be to disable warnings in your project and then enable them in all your own units using that directive.
Easiest and most realistic option:
Compile the units once and only use the DCUs by removing the source from your library path. That's easiest if you do not want to edit them anyway.
You can still add them in your browsing path which is different from the library path. In that case, the DCUs are used, but Delphi can still find the sources, so you can still navigate them whilst debugging.
Small advantage is that building your project is faster too, because these units don't need to be recompiled on each build.
Best option:
Stop using those units at all. Units with so many warnings are inferior software and can cause serious problems.
Other solutions:
Set aside your wishes of not modifying the units and add the compiler directives to those units anyway
Solve the warnings

I use Delphi 7 and here's how I do it...
Do not include the unit it the project .dpr or this will not work, add the folder of the unit on the search path of the Project Options.
Then in every unit you use it, use these compiler directives:
uses
{$WARNINGS OFF}{$HINTS OFF}
TheUnitHere;
{$WARNINGS ON}{$HINTS ON}

No, I don't believe there is such a directive.
The only way I have found to achieve this, is to
compile everything
put the dcu of the offending unit somewhere where the compiler will find it
make sure the dcu is found BEFORE the source for that dcu, or make sure the source cannot be found by the compiler
This will ensure that the pas is not compiled so you won't be swamped by the warnings from the offending units.
It is an approach I often take with library units (which we always compile from source) when I do not want the debugger stepping into them. I compile the release configuration (debug = off) then pick up the dcu's of the units that I do not want to step into and make sure that they are found by the compiler before their corresponding pas files.
One caveat: make sure that when you (need to) work on the offending units, the dcu gets removed, or you will be in for a lot of confusion. GExperts' "Clean directories' can help with this.

Related

How to remove unused units from all source files on Delphi XE2?

How to automatically remove unused units from uses section on all source files of the project on Delphi XE2?
P.S. IDE will work much faster after that.
There is no way to fully automate this.
There are a few tools I'm aware of that take a wizard approach:
CnPack Uses Units Cleaner
Peganza's Pascal Analyzer (and it's sidekick icarus).
The Lazarus IDE has a "Unused Units" dialog in it's CodeTools package.
Peganza's tools simply show a report. CnPack will prompt to remove the unused units for you but you must confirm. Lazarus presents you with a list of unit's it thinks are unused and gives you the choice of removing some or all of them.
Why isn't it automated?
Because this is static analysis. Even the most sophisticated tools cannot determine with 100% certainty whether a specific line of code will be used at runtime let alone an entire unit. These tools have implemented their own parsers to accomplish this feat but they aren't fool proof.
In any case the main benefit of cleaning up the uses clause is removing visual clutter from both the source itself and the code completion feature. Yes there is some performance gained during compiling and certain IDE background operations will speed up slightly but I think you'll be disappointed if you think the IDE will miraculously speed up.
You'll see better IDE and compiler performance by:
Breaking your projects into smaller pieces that can be worked on independently.
Eliminating duplicate code.
Disabling unneeded IDE packages.
I'm certainly not trying to dissuade you from removing unused unit references. As I said it will help unclutter your source. Just make sure you're doing it for the right reasons.
We have a utility called the Delphi Unit Dependency Scanner (DUDS). It scans your entire project and builds a fully searchable tree of the units and dependencies. It can be very useful in finding unused units.
The application is Freeware and you can find it here.
Disclaimer-I am the author.
Don't think I would want a tool that would automatically rip out unnecessary units in the Uses section...
but there are tools out there to identify them...look at Icarus...freeware that you can get at http://www.peganza.com/downloads.htm
CnPack has "Use Cleaner..." option that I have used unit by unit basis without a problem. It also has the ability to do the entire project - which I haven't tried due to the size of the project.
Use reFind.exe utility provided since Delphi XE, use this command
reFind *.pas /X:unuse.txt
And unuse.txt is a text file with something like this:
#unuse Unit1
#unuse Unit2
#unuse Unit3
And that's it. It will remove the units in the uses clause taking care if the unit is the last one used and there is a ; after the unit.

How to change VCL code?

I need (to make some quick and dirty tests) to modify the code of Variants and SysUtils.
What I need to do to "compile" the changes?
I can of course open those units in the IDE, but if I change them and I buoild a project again I don't see those units recompiled.
What is needed to be done?
The problem is you would need to compile ALL of the RTL/VCL against the 'new' units.
Instead modify a copy of the units in question and add them to your project when you want to use them. Delphi should use these over those in the RTL/VCL.
Unless you do not change the interface part of the unit (that is, you only modify the implementation side), you can make your own version of the RTL units (only exception is System.pas and SysInit.pas, but this is not in your scope - see our blog site for some enhancements of those units).
What you need is to put your own version of Variants.pas and SysUtils.pas in the search path of your project. They will be taken in account instead of the default RTL.
But be aware that you may easily break anything.
For testing purpose, this is OK, but if you want to use those modifications, you shall better use some automated regression tests, and know explicitly what you are doing.
Please note that you can use the "debug" version of the RTL units (from the project options), then step with the debugger within the official source code. It may help finding issues without touching the source.
If you change the interface part of the unit, you'll have to recompile all units which call the modified unit - for SysUtils and Variants, this is almost all RTL.
Delphi runtime DCUs are precompiled. It would be a waste of time to compile them at every build.
If the code you are trying to modify is a method of a built-in class, then a class helper may help:
http://docwiki.embarcadero.com/RADStudio/en/Class_and_Record_Helpers
So the question is which part of code do you want to modify in the runtime?
If you really wish to recompile the RTL you can do so (Make a backup first!). Versions of Delphi prior to Delphi 2010 had a makefile in the source folder that could be run from the command line to rebuild the rtl/vcl. I don't know for sure (I'm still using D2009) but from what I've heard this file is no longer present in newer versions. Hopefully there is an alternative. Otherwise you would wind up wasting a lot of time trying to guess that the compiler settings for each unit.
If you wish to "patch" a bug in the rtl for your project only you can copy the unit you want to modify into your project's folder and make your change. If the unit your modifying is used throughout the RTL/VCL you may find yourself copying quite a few dependent units into your project folder in order for it to compile.
If this significantly slows down the compile time for your project you can always do your initial compile then remove the "patched" units, leaving behind the compiled dcus.

Compiler directive in IDE rather than Project files?

Delphi 7: Is it possible to put a compiler conditionals in the IDE (like Tools, Environment options) rather than in a project under Project, Options, Conditionals?
We have a compiler directive that needs to be defined when compiling on developers' machines, but undefined when we build releases.
We don't want to use IFDEF DEBUG, since occasionally we ship code with debugging on.
We don't want to use an include file, because we'd risk it getting swept up into our source code control system.
Ideally, we would be able to create a compiler directive like we can an IDE environment variable where it wouldn't be saved in our source tree.
Any suggestions??
The solution is to use a build tool like FinalBuilder to do your building. This way you can be completely sure that you ship a good build every time, and not forget to set some option back to what it should be. I used to take a real day doing builds, now it is a click and I'm done.
Automating it will be hard (although your restriction on include files sounds a bit artifical, simply put the thing in source control and replace the version on disk with a different one during build script), why not force your individual developers to turn it on manually?
Introduce an extra DEFINE in the build script (e.g. FINAL_BUILD)
Introduce a compile time error in the source code forcing your developers to turn it on.
{$IFNDEF FINAL_BUILD}
{$IFNDEF VERY_SPECIAL_COMPILER_DIRECTIVE_YOU_WANT_TURNED_ON
You should have really turned option X on. Now things don't compile.
{$ENDIF}
{$ENDIF}
Finally, introduce a similar compile time error to make sure the FINAL_BUILD and special directive are never turned on at the same time.
You can use Conditional defines in project options
this will pass your custom defines to compiler when begin compile of project
follow this in Delphi IDE
Project > Options > Delphi Compiler > Conditional defines
Of course, adding {$DEFINE MYCONDITION} in your code would add a custom directive which you could check with {$IFDEF MYCONDITION} but this you should already know. However, if you compile your project from the commandline DCC32 -D MYCONDITION ... then you can compile it with (or without) that option.

How can I set the $RTTI directive for the entire project?

I'm working on migrating an old project from Delphi 2007 to Delphi 2010. One thing I've found is that the resulting executable has more than doubled in size, and the original was already quite big. (Over 50 MB.) I suspect that a lot of it has to do with extended RTTI.
Since the project predates Delphi 2010, it doesn't use extended RTTI anywhere, and I'd like to be conservative about including it. Is there any way to use the Project Options dialog to globally set {$RTTI EXPLICIT METHODS([]) PROPERTIES([]) FIELDS([])} as the default? I'd have expected there to be an option for this (and for $WEAKLINKRTTI) somewhere, but I don't see them.
Does anyone know if this can be done from the "Additional options to pass to the compiler" field, or some other way? I'd really prefer not to have to add an include file to every single unit in the project, as there are a few thousand of them...
The behavior of the $RTTI directive has been changed since XE6 because actually it was a bug because it was supposed to be local to the current unit (and it was actually documented as that since Delphi 2010).
Also it could have fatal affects using the directive at all even in one unit because due to the bug it basically switched a global flag affecting the following units (as in the order of compilation).
You can try with the dcc32 –$weaklinkrtti command-line option. (like {$WEAKLINKRTTI ON}).
But that has not the impact of {$RTTI EXPLICIT METHODS([]) PROPERTIES([]) FIELDS([])} in each unit.
Your best bet would be to have it at the top of each unit in an include file.
But then it wouldn't do it for the VCL/RTL which would still be inflated....
Update: Also make sure you compare what's comparable. For instance verify if you don't include debug information in the Linker Options in the new D2010 project where you may not have it in the D2007 one...
In a comment on Mason's own blog, in response to a comment of mine, Mason answered this question.
Try putting these two lines at the top
of your DPR, before the USES clause:
{$WEAKLINKRTTI ON}
{$RTTI EXPLICIT METHODS([]) PROPERTIES([]) FIELDS([])}
This will make sure that no RTTI gets
generated for your own code or any
third-party libraries you use, unless
they’re in a unit where RTTI
generation is explicitly enabled. You
can’t turn it off for the RTL or VCL,
but that shouldn’t add very much to
your size anyway.
Are you certain this is caused by the new RTTI info? While it's a lot of data it shouldn't really double the size of your application.
Check that it's not including debug info in the release build executable.
(Project options -> Delphi Compiler -> Debug information should be False)
As for the question, I use {$WEAKLINKRTTI ON} before the uses clause in the dpr file and it seems to work fine.
I don't know of such an option, but I still would use an include file.
I wont be a problem for any experienced Delphi programmer to write a small program to add an {$i ProjectIncludeFile.inc} to any unit in your folders (immediatly after the unit line).
And that way you can use it for whatever purpose you like.
I myself use if f.i. to set a WriteTempFiles compiler directive (which I use f.i. to save stringlist contents at various places when developing the program), that way I can disable it in one place when the program is ready for deployment.
Since most of my projects involve multiple executables and/or dll's, this is the easiest way to accomplish this globaly for the whole project.

Delphi compiler warnings pointing to Delphi's own units

In Delphi 2007, working on a project which includes a custom component, I'm getting this set of warnings as the first four in Messages when I do a full build (but not when I do a straight compile):
[DCC Warning] Dialogs.pas(1426): W1002 Symbol 'TFileOpenDialog' is specific to a platform
[DCC Warning] Dialogs.pas(1446): W1002 Symbol 'TFileSaveDialog' is specific to a platform
[DCC Warning] ComCtrls.pas(6757): W1036 Variable 'Section' might not have been initialized
[DCC Warning] ComCtrls.pas(19268): W1023 Comparing signed and unsigned types - widened both operands
I generally try to eliminate compiler warnings where I can, but these are "stock" Delphi units. Are these warnings the indirect result of something in my code? If so, how do I figure out what/where? If not, what should I do about them?
I believe it is because you have the stock Delphi source in your build path. If you remove the Delphi source directories, then it should build without these warnings.
The reason they show up only when doing a Build is that the compile command only compiles source which has changed since the previous compile. While the Build command recompiles everything in the project regardless of changes.
The warnings are most likely caused by the Delphi source folder being included in the project search path. Removing it and deleting the dcus in your project's folder will tell you if anything in the project required the Delphi source when you recompile. In my experience you should need the Delphi source if you have found a bug in Delphi's implementation and made a custom copy of a Delphi class to correct the bug. If this is the case when you try to build without the Delphi source you will usually get:
Unit '%s' is compiled with unit '%s'
in '%s' but different version '%s'
found (F2446)
Where %s will be some low level Delphi class.
If you don't get any error's it didn't really need the Delphi source.
This can also happen if the Delphi source is in the environment search path.
The first two warnings you mention (along with a few others) are to make you aware that the code you're currently using won't compile across different platforms Delphi supports. For Delphi 2007, there isn't much, but it carries the remnants of Kylix (the Linux version that's gone) and Delphi for .NET (which is also gone).
More recent versions of Delphi support cross-platform (Win32/Win64, OS X, iOS, and Android), where these messages are relevant again when developing Firemonkey applications (or VCL apps if there are differences between Win32 and Win64). They indicate the points in your code where you will have to make adjustments in your code for different operating systems. (For instance, the two you cite are for Windows-specific dialogs; you'd need to use a different dialog based on the target platform, and use {$IFDEF} statements around the areas that are platform-specific to keep them from being compiled in for other platforms.
As your current code can't be ported directly (even in a modern Delphi version) to anything other than Windows because it's VCL-based, you can safely turn off those warnings. Use Project->Options->Compiler Messages, and uncheck the following messages (or use the compiler define I've included in your code):
Library Symbol {$WARN SYMBOL_LIBRARY OFF}
Platform Symbol {$WARN SYMBOL_PLATFORM OFF}
Library Unit {$WARN UNIT_LIBRARY OFF}
Platform Unit {$WARN UNIT_PLATFORM OFF}
Unsafe type (.NET remnant) {$WARN UNSAFETYPE OFF}
Unsafe code (.NET remnant) {$WARN UNSAFECODE OFF}
Unsafe typecast (.NET remnant) {$WARN UNSAFECAST OFF}
The last two you've mentioned I can't reproduce with D2007 (IDE version 11.0.2804.9245), so I'd suspect that skamradt's answer is correct - it's because you have the VCL source directories in your search path, and you shouldn't. It should be set to $(BDS)\Lib. If you need to be able to step through the source, use the Project->Options->Compiler page, and check the Use debug DCUs option under Debugging instead.
I spent ages getting these problems (well, your first two anyway) and in my ignorance actually uninstalled Delphi and reinstalled it to no avail. I finally found that it is caused by the lack of project settings. At least atfirst, if you migrate a projects from an earlier Delphi, your existing project settings get converted but for no apparent reason Delphi can start forgetting about this and gives you a 'blank' set of project settings. You can see this by opening Project-Options where you will find Base, Release and Debug. Check out the active one (it is bold in the project manager) and you should see that it has no directory paths as well as all hints and warnings at their defaults. Most of these defaults are fine but 'Platform Symbol' and 'Platform unit' should be disabled (at least for Win32 stuff).
Regards,
Brian
If you want to continue explicitly compiling the VCL source into your project you can make a copy of the units that are raising the compiler hints/warnings and "fix" the hints/warnings in that copy.
Put the updated/"fixed" copies of those VCL units in another folder and make sure you add the path to that folder to your project's Search path BEFORE the path to the Delphi VCL source.
E.g. my project search path looks something like this: "C:\Dev\Source\MyFixedVCLUnits;C:\Program Files\CodeGear\RAD Studio\6.0\source"
To give an example of the simple fixes required to remove these warnings, here is one of the functions in the Dialogs.pas that now lives in my
"C:\Dev\Source\MyFixedVCLUnits" folder:
{$WARNINGS OFF}
function TFileOpenDialogWrapper.CreateFileDialog: TCustomFileDialog;
begin
Result := TFileOpenDialog.Create(nil);
Result.OnExecute := OnExecuteEvent;
end;
{$WARNINGS ON}
In this case, just add the {$WARNINGS OFF} etc as required.
TFileOpenDialog will work only on Windows Vista and up. You should use TOpenDialog instead of TFileOpenDialog, in newer Delphi versions it will detect what OS it is running and display proper dialog.
https://forums.embarcadero.com/thread.jspa?threadID=70498
If you develop only for specific platform open project source and add
{$WARN SYMBOL_PLATFORM OFF}
Compiler warnings can be disabled individually (separate per warning type) in the project options under 'Delphi Compiler | Hints and Warnings'

Resources