Compiler option for "Use Debug DCU's"?
Asked Answered
N

2

5

In a component I am writing, I want to include automatic detection of registered image formats, but it is a solution that only works if the Use Debug DCU's compiler option is disabled.

What I really would like to know is an alternative for this solution that does not involve compiler option dependency.

But for the time being, I just want to know how I can check at runtime whether the Use Debug DCU's compiler option is set.

Nievesniflheim answered 3/2, 2013 at 17:5 Comment(13)
What if the IDE isn't used? Command line build.Hierarchize
AFAICT, checking that option simply changes the path provided to the compiler to the VCL/RTL dcu files. It doesn't actually change anything else, like range checks or other options do. I'm not sure there's any way to detect that path change in your component.Chadd
@KenWhite, it changes allot: an executable linked to "debug" DCU's has a different version of the code, more tests, less optimization; If a low-level hack depends on some hard-coded offset to grab the data it wants, then the different layout would make a world of difference.Catechumen
@Cosmin What do you mean? It changes what Ken says. Nothing more, nothing less.Hierarchize
@Cosmin, read what I wrote again. I said it changes the path used to locate DCUs. I never said that use of those DCUs didn't change anything.Chadd
@David, @Ken, I assume the test NGLN is talking about is performed at "runtime", and not the runtime-in-the-IDE (as in design-time for the rest of the world); If that were the case then there's be no need to test for the "Use Debug DCU" as the IDE itself is not built with debug information. It's true that the command line option only changes the search path, but that in turn changes the version of Graphics.dcu that's linked in, and that's a significant change. Apparently NGLN's linked hack brakes depending on the DCU version linked. I was probably going a step too far with my analyses.Catechumen
@CosminPrund I didn't look at the hack. You've done a good job of working out what the real problem is and proposing a solution to that.Hierarchize
@Nievesniflheim You have asked an XY question. You have decided what the solution is to your problem. And then asked us how to implement that solution. However, your solution is the wrong solution. Instead you should have simply told us the problem asked us how to solve it. It's not too late to edit the question.Hierarchize
So I'm confused now. Cosmin is accurate in saying that the code you link to is runtime rather than designtime. In which case, how does the question relate to it. Please do tell us more about the underlying problem.Hierarchize
Then I really don't understand the question you are asking. When you say "How can I check whether this option is set?", what does that mean at runtime? And at designtime, I presume you are interested in the code that you are compiling, rather than the code that is running in the IDE. Is that right? And if the interest is in the code that you are compiling, how does the linked code apply? Perhaps I'm just being stupid.Hierarchize
@Nievesniflheim Why do you need to know at designtime? The Graphics unit that executes then is the one in the VCL package loaded by the IDE. And Debug DCUs was disabled. It has no relation to the setting of that compiler option.Hierarchize
This is why it is an XY question. You should have told us more. Would you like me to answer saying that there is nothing in the ToolsAPI that exposes this information?Hierarchize
Posted my answer as an answer to the other question: https://mcmap.net/q/615274/-how-to-get-all-of-the-supported-file-formats-from-graphics-unitCatechumen
C
6

There is no reliable way to get that information at runtime

The Use Debug DCUs compiler option only switches the search path; What the compiler will eventually find there is unknown. An (misguided) user might have copied the Release dcu's over the debug directory, or vice-versa.

Even without misugided users, one might have some files added to the project (and compiled with the project) in order to include some bug-fix. For example, if the user has the Graphics.pas added to the project, does a release/no-debug build, but keeps the Use Debug DCU's compiler option, then the Graphics.dcu that's actually linked is not a debug build, because it's re-built with the executable. So you get a "mixed" bag of debug and non-debug dcus.

You could attempt detecting the presence of debug information related to certain objects or methods, but this too would be unreliable: If you use "Build with Debug Dcus" but then set "Debug Information" to false, then you're essentially throwing away the debug information so you can no longer look for it.

But that linked code fails on Debug DCU's

The code from the GLScene project is not a good hack, it uses hard-coded offsets into the code for the TPicture.RegisterFileFormat, then continues to use hard-coded offsets to get the address of the global FileFormats variable (doesn't call the GetFileFormats routine). Too many magic numbers in there!

My first though was to compare the TList identified using the GLScene method to the TList I've identified, but guess what: On my machine there was no problem, both routines got the same result, in both circumstances. On my machine the GLScene, ugly as it is, is not broken with Debug DCUs.

I've even tried "fingerprinting" some of the rtl/vcl units (SysUtils, Graphics, Classes); I made a list of all the public classes, generated some code that uses RTTI for each method in each class and dumps the first 1024 bytes of the code to a string file. Ran that program with Debug DCUs and non-Debug DCUs and I got the same result. My text files contain the fingerprints for some 3500 methods!

Not a good idea

Since that option doesn't really affect the way the compiler compiles (only what the linker links), creating code that depends on this option is highly unreliable and not a good idea. This only affects low-level hacks, and you don't want low-level hacks that might crash your application under circumstances that are absolutely out of your control.

The only true option is replacing the potentially failing hack with one that's not going to fail (or at least fails in controllable ways).

Catechumen answered 3/2, 2013 at 20:59 Comment(3)
Re "If you use "Build with Debug Dcus" but then set "Debug Information" to false, then you're essentially throwing away the debug information" - This is simply incorrect. 'Debug information' in DCUs is not removed, you can test this by adding browsing path (or debug source path in your project) to the PAS file, set breakpoints and the debugger would break on them. Disabling debug information just affects the source you're compiling in your project. I believe enabling debug information on the linker would then embed this debug information from DCUs into the exe. Ditto for map file.Centuplicate
You're right in saying that the 'Debug DCUs' option should pretty much just set the path to a different set of DCUs, and any source or even precompiled DCUs would now point to a different set of DCUs (the debug ones). This is exactly what happens. The linker just uses a different set of DCUs (if their interface still has the same procs). But for some reason, there is a small difference in size - 60K extra for about 1000 DCUs (random units I've built) linked with the 'Debug DCUs' option enabled. There is obviously some other difference(s), something extra embedded in DCUs built with Debug DCUs.Centuplicate
Also I think you meant the Debug information option on the linker settings, in which case you're correct, my bad! leaving my comments anyway :)Centuplicate
N
3

As Ken comments, there is probably no way to detect the path change this compiler option involves. The command line compiler documentation does not mention a compiler switch, thus meaning that it simply does not exist. Without compiler switch, it isn't possible to check whether that compiler option is set


...but it is a solution that only works if the Use Debug DCU's compiler option is disabled.

If only works means that it otherwise results in an exception, then you could use the following alternative:

try
  // AutoDetectRegisteredImageFormats
except
  // Handle case when Use Debug DCU's is on
end;
Nievesniflheim answered 3/2, 2013 at 19:21 Comment(1)
This also does not answer the question that was asked.Hierarchize

© 2022 - 2024 — McMap. All rights reserved.