I am writing a designtime package in Delphi 2007.
I decided to move some event type declarations into their own Eventsunit so they can be used in multiple units. When I did the compiler started complaining Undeclared identifier: 'Event Name' in the units where these events were originally declared. The type declarations are all in the interface section of the Events unit and I have added the Events unit to the other units' uses clause but its like the compiler is completely ignoring the Events unit.
The IDE has no trouble finding the declarations when you CTRL + Click in the type name from another unit. Hovering the mouse over the type name displays the unit its declared in along with its parameters. Even the usually craptastic and paranoid Error Insight feature of the IDE doesn't see a problem. Only the compiler complains about it.
I tried reproducing this problem in another, simpler package project to try to isolate it but I can't reproduce it.
Has anyone else seen this behavior before and is there a work around?
I had already tried all the common sense suggestions like making sure the file was in the project and in the uses clause of the other units.
Since no one has posted a solution I tried Ken White's and Wouter van Nifterick's suggestions.
closed the project and restarted the IDE - no change
Searched every drive on my system for Events.pas or Events.dcu - the one in my project was the only one.
The only thing that worked, and I have no idea why, was to rename the Events.pas to something else. I renamed it using the Project Manager and recompiled. All the Undeclared Identifiererrors simply disappeared. I renamed it back to Events and the errors came back. Who knew?
Just out of curiosity I did a text search over every pas and inc file on my system to see if Events was used as an identifier somewhere (I know it shouldn't make a difference but... ya never know). Nothing. No variables, types or functions called Events.
As a sanity check I created a simple project with a handful of units, one of which was called Events with a few type declarations. All the other units included it in their uses clause. The compiler had no trouble resolving the type identifiers. I have absolutely no clue why it choked on the Events unit in my other project.
Update
I finally figured out why I was getting this error. The package I was writing used the open tools api(OTA) so it required the DesignIDE package. DesignIDE is provided only as a precompiled dcp and bpl so the source is missing for everything except the handful of interface units exposed as extension points for the IDE. It turns out that one of the hidden units compiled into DesignIDE is called Events. I did not discover this until I migrated my package to a later version of Delphi and started getting E2200 Package 'designide' already contains unit 'Events'. This error message did not appear in Delphi 2007.
My attempt to isolate the problem in a simpler package could not reproduce it because I had excluded the DesignIDE package from it's dependencies, not realizing that it was the source of the error.
Related
Here's my problem:
UnitA.pas fails to be compiled as UnitB.dcu cannot be found.
So why don't I just add UnitB.pas to my project? - Because UnitA.pas shouldn't even be part of my project but is somehow contained by another unit. I want to find out, which unit that is.
How can I do that (I am using Delphi XE4)?
Note: I think there was some option in Delphi 2007 to get the desired information in compilation log but I don't remember where it was...
One of my workmates gave me the hint to just rename the units that should not be part of the project. Thus, I get an error in the depending unit. I continued with this until I found the unit reference I need to erase at almost root level.
I'm using the Synapse library in a Delphi project to do some networking.
When I try and use one of the Types that are defined in the external units, i.e: 'TTCPBlockSocket', it has the red underline and says "Undeclared Identifier 'TTCPBlockSocket'".
The files are all in the correct folders and the 'uses' statement can find them and shows no errors.
The strange thing is that I've had an identical setup in another project and there have been no errors in that project.
As a note: I can't install/edit the software/settings, so I can't add any fixes.
This is a well-known bug in Error Insight. It has existed since Error Insight was first introduced in Delphi 2005 or 2006, and still exists today in Delphi XE5.
It's caused by a different compiler being used for Error Insight, apparently, that doesn't have access to the same symbol set used by the Code Insight compiler (the one that helps you find symbols in the Code Editor) or the command-line compiler (the one used to actually compile your code for an application or package). It therefore only uses files that are actually referenced in the project (.dpr) file to locate symbols, and since the majority of files in the uses clause in your code aren't in the .dpr, it can't find them.
There are two fixes (one that is very easy, and one that works but is a pain in the backside):
(The easy one). Turn off Error Insight totally, in Tools->Options, the Editor Options section, Code Insight; just uncheck the box for Error Insight. I prefer this one because Error Insight doesn't work properly anyway, and it avoids the annoyance of having to use the other option every 10 minutes. This is the first thing I do when I install a new version of the IDE and see the red underlines.
(The pain way). Use Project->Add to project for every unit that contains one of the underlined symbols. This adds a reference to every unit to the project .dpr file, which causes it to increase in size drastically. It's a pain because you typically have to do that for every single unit (in my experience, including those that are part of the standard VCL/RTL) that hasn't already been added, and it very quickly becomes irritating. Error Insight doesn't tell you anything that a quick Ctrl+F9 won't anyway, IMO.
How can i fix this error and from where I get dxDBGrid file,i'm a new in Delphi,i'm getting the: [Fatal Error] File not found: 'dxDBGrid.dcu'
As others have already told you, that's the file that contains Developer Express's TdxDBGrid. It's quite an expensive product, so before you go off and purchase it, it would be wise to see if you actually need it (I'll explain why I have a hunch you might not in a moment).
First thing to do is do a Find in Files search through all the units in your project, to see which of them lists dxDBGrid in the Uses list in its Interface section. Once you've found the file try and open it and see if the form contains a component of type TdxDBGrid. If it doesn't, remove dxDBGrid from the unit's uses list and try recompiling.
The error may go away, in which case, problem solved. The reason I think the error might go away is that typically, using a TdxDBGrid on a form causes a lot of other units from the DevEx package to be added to the unit, in addition to dxDBGrid, and usually they would appear in the unit's Uses list ahead of dxDBGrid, so if Delphi really can't find the files of the DevEx library, it's surprising Delphi isn't complaining about not being able to find those before it gets to dxDBGrid. So if it uses dxDBGrid alone of the Devex package (other units in their package typically begin with dx or cx), it's possibly only there is a historical hangover. Otoh, if the unit does use other dxXXX or cxXXX units and Delphi isn't complaining about not being able to find their DCU files, it must be finding them (in .DCU or .PAS form) ok.
If you're still stuck, post the Interface section of the unit which provokes the compiler error you described.
We are trying to split up our monolithic EXE into a combination of an EXE and several packages. So far, we have one package that we're trying to use, and when running the EXE Codeguard shows the following error on startup:
CG Error
Two different CRTLDLLs are loaded. CG might report false errors
(C:\Windows\system32\CC32100MT.DLL)
(D:\Projects\Foo\Bar.bpl)
OK
I read this as two different runtime libraries being loaded - one, the correct one (CC32100MT.dll), one incorrect, which is the package we're trying to use.
Continuing to run the program shows odd errors, especially casting between classes or passing a pointer to a class as a parameter in a method that crosses the EXE/DLL boundary. Codeguard itself doesn't show any other errors at all though. Edit: This is now resolved, and wasn't related. The program appears to run correctly, but the warning Codeguard shows is still worrying.
How do we solve this?
Some more details
We've looked at as many things as we (the developer working on this and I) can collectively think of:
Each project is built using runtime packages. The EXE host lists Bar in its package list.
Each project is set to compile with dynamic RTL. However, changing this does not solve the problem.
The package is linked to the EXE via its BPI file, but linking via a LIB makes no difference either.
The EXE and BPL are compiled with the same project settings, where the same options exist for both types of project. We think, anyway :)
There is only one copy of the BPL and BPI on the system: it's definitely linking to the right one.
Examining the EXE and BPL with Depends and TDump show they are both using C:\Windows\system32\CC32100MT.DLL. They should both be using the one RTL.
Creating a new project (a plain VCL forms application) and linking to the BPL (via its BPI) works fine. Something in the process of adding all the files and LIBs that make our EXE contain the code it needs to changes this, but we haven't been able to figure out what.
The LIBs all either correspond to DLLs we use (flat C interface, usually look as though they were built with MSVC) or are simple projects with lots of related files, compiled to a lib for the purpose of linking into the EXE - these correspond roughly to the areas of the program we want to split to BPLs, by the way. There don't seem to be project options for the LIB projects that would affect RTL linking, unless we've missed them.
I have exhaustively hunted through Depends and looked at all RTL and CC32*.dll files the EXE and every single DLL references. All are identical: rtl140.bpl and CC32100MT.DLL. Fully qualified paths show they are the same files, too. Everything should be using the one same run-time library.
Edit: The final EXE is complex, built with several libs, several DLLs, etc. All these, when built with C++Builder, are built with the current version. Is it possible there's something in one of these DLLs or LIBs that could cause a problem? I don't know enough about how the RTL is linked in to be sure about where to look... my (naive?) assumption is that the linker would normally link in one set of RTL functions, but that of course doesn't seem to be happening... and I don't know how things change when using packages. Is it possible this error has always existed and Codeguard has not flagged it before, because we haven't used something dynamic like a package?
Perhaps another question is, Why would a package have its own RTL anyway, or what would make it count as 'a RTL DLL' to Codeguard?
We're stumped. Absolutely stumped. We've had other problems using BPLs (they seem to be surprisingly tricky things, especially using C++) but have managed to solve them all. This one we've had no luck at all and we'd really appreciate any insights :)
We're using C++Builder 2010 (as part of RAD Studio actually, but with little Delphi code apart from components.)
Edit: Started a bounty. I'd really like to solve this!
Edit 2: Thanks to David Dean for his help (marked as answered below.) Via email, he pointed out this issue was reproduced in a simple test case by someone else, and is logged in Embarcadero QC as report 86335. Currently there is no fix, but the warning does not appear to indicate a genuine problem (ie, it's probably a spurious error, and while it's a pity to have to click past the dialog when you run, hopefully there's nothing in the error to worry about.)
Since one of these is coming from a .bpl, did you try turning off "Build with runtime packages" in the project options?
We had a similar problem. We tracked it down to a (non VCL) .cbproj that was created without the "Multithreaded" option.
As far as I can tell, the only time you get chance to set this option is when you create a new .cbproj, it cannot be changed afterwards using the GUI. We ended up "hacking" the .cbproj to include the following:
<Multithreaded>true</Multithreaded>
To determine which dll is causing the issue, it should be the last dll loaded in the output window just before you see the CG message.
Did you check if you use _TCHAR as char. We had some similar problems with RAD Studio and we found a workaround using _TCHAR as char. As soon as one DLL or BPL Project is compiled with wchar_t, this code guard error appears.
We also figured out, that EXE projects can be compiled with TCHAR = wchar_t without any problem (the main function will be WIDE).
The settings does not affect the GUI being able to handle UNICODE.
A customer logged a similar case in our public bug tracking system and the bug has been identified and fixed in the latest release.
We have the following in our codebase, in a component file:
{$IFDEF ADO}
FDatabase : TADODatabase;
{$ELSE}
FDatabase : TODBCDatabase;
{$ENDIF}
The reason is that for various legacy applications, one or the other type of database connection and set of classes is to be used.
However, while configuring a new machine, it seems that our conditionals aren't taken into account. In the project settings, it says "ADO;DEBUG", and yet it compiles the above code with the odbc type instead.
The odd thing is that it isn't consistent. Two different units built as part of the same project uses separate settings. In other words, in one place our conditional is visible, in another it is not.
The file that compiles wrong does not have any {$UNDEF or similar directives, nor does it include any files.
What am I missing here?
Solved (ugh): Right, Delphi is just being boneheaded, or whatnot.
We found these:
I get “F1026 File not found”, OR some compiler options are not passed to the compiler from the IDE.
Configuration='Debug' Platform='BNB'
Which both mention the "Platform=BNB" setting. By enabling the diagnostic output, we see that exact value. So we try to override it per the articles, no luck, still BNB. Then we go to the project settings, turns out it can be overriden there as well, so we do that too, still no luck.
Turns out the Delphi installer, or whatnot, has added a "Platform=BNB" environment variable on operating system level, removing that, restarting Delphi, and all is well.
Well, as well as can be expected. We still have to use Delphi though.
You should always make a "build all" when you change those conditions.
It could be that one unit is actually not re-compiled. Check the following:
Is the .pas file included into the project?
Is there another file (.pas or .dcu) with the same name in the search path? It's possible the IDE sees a different file than the compiler.
Is the file actually compiled? Compare the timestamps of the .pas and the .dcu file.
Do you compile for another platform? Some compiler options are not passed unless the platform is "AnyCPU".
Whenever I encounter problems like this I brute-force delete every .dcu file in my project and component folders just in case the "Build all" doesn't remove all stale .dcus. The following recompile either solves the problem or reveals if any wrong .dcu was used.