How do I tell Delphi to use the local project's Security.pas file rather than Winapi.Security.pas in DXS? - delphi

Delphi 10 Seattle introduces Winapi.Security.pas. The project (a package) I'm trying to upgrade already has a Security.pas file. Short of removing Winapi from the list of scope names for the project (huge undesirable ripple effect), is there a way to tell the IDE and compiler to use the project's Security.pas file instead of Winapi.Security.pas?
I already tried renaming the projects Security.pas, but that caused even more problems with the compiler generating errors that have nothing to do with the code it was complaining about, so that's a rathole I'd rather not go down right now. This project builds just fine unchanged in XE7, FWIW, so this isn't due to any code changes in the project.
Updates:
Renaming the file and using a unit alias doesn't work.
The compiler behavior for a package differs from an application.

Looks like this might actually be related to the Winapi.Security unit rather than something as generic as you suggest in the question. For instance, the following package compiles just fine:
package Package1;
requires
rtl;
contains
Windows in 'Windows.pas'; // blank unit named Windows.pas in project folder
end.
Note that I have, like you, included Winapi in the project's list of unit scope names.
On the other hand, this package does not compile:
package Package1;
requires
rtl;
contains
Security in 'Security.pas'; // blank unit named Security.pas in project folder
end.
The compiler fails with:
[dcc32 Error] Package1.dpk(7): E2200 Package 'rtl' already contains unit 'Winapi.Security'
If the issue was purely related to unit scope names then either both packages would compile, or both would fail. Hence my conclusion that there is something out of whack with Winapi.Security.
I can find no source code for Winapi.Security. I wonder what it actually is. [Nicholas Ring located the source for me, inside the rtl\win\winrt directory.]
Anyway, I think it's time to submit a QP report. The package below that fails to compile is probably the starting point for that QP report. [Your submitted report is here RSP-12469.]
It seems clear to me that in the short term you must rename your unit if you wish to adopt Seattle.
FWIW, here are some other units that behave the same way as Winapi.Security:
Winapi.ApplicationModel
Winapi.CommonTypes
Winapi.Devices
Winapi.Foundation
Winapi.Gaming
Winapi.Globalization
Winapi.GraphicsRT
Winapi.Management
Winapi.Media
Winapi.Networking
Winapi.Storage
Winapi.UI
Winapi.WebRT
These are all newly added WinRT units which I expect is important.

If you put both Winapi.Security and your local Security in the same uses clause then you are able to access the members of both of them without issue. If you put them in separate uses clauses (Interface vs. Implementation) then you will get the error:
E2004 Identifier redeclared: 'Winapi.Security'
If I only include Security.pas in the uses clause (and it is included in the project) then it accesses its members just fine.
Perhaps I need more information about what error you are running into? I'll send you a sample project that shows this working.

I might well be wrong, but I believe that if Security.pas is in the uses clause of the dpr file, along with its full path, it will be preferred over whichever file can be found via the namespaces and search paths.

Open project settings, in the Delphi Compiler section remove "Winapi" from "Unit scope names".
This way, when you need the Security unit shipped with Delphi, you'll have to write Winapi.Security, and if you write Security, it will use your custom Security unit.

Related

How to use PathCchCanonicalizeEx with C++Builder 10.2?

I have a legacy Windows project using the legacy 32 Bit C++ compiler. For various reasons I need to use the Windows 8+ function PathCchCanonicalizeEx. C++Builder seems to provide the header and some module definition file for that, but I can't find any library to link against:
[ilink32 Error] Error: Unresolved external 'PathCchCanonicalizeEx' referenced from C:\[...]\WIN32\DEBUG\TMP\FILE.OBJ
How am I supposed to fix this? Do I need to add a Windows 8.1 SDK? Is the necessary lib simply named differently and I can't find it? Something completely different?
According my tests, one has two options:
IMPLIB/MKEXP
I'm developing/testing a some Windows 10 21H2, which provides an implementation for PathCchCanonicalizeEx in some DLL already. So if that source DLL is known, one can use IMPLIB or MKEXP to create an import library manually. I did that and after adding the created library from IMPLIB to my project, the linker errors were instantly gone.
Though, it's not that easy to know where PathCchCanonicalizeEx is placed in. One pretty easily finds the api-ms-win-core-path-l1-1-0.dll, but that thing is NOT an actual file on the disk and therefore can't be used by IMPLIB or MKEXP. That name is only a virtual concept for the library loader to address the same named API set of modern Windows, the extension .dll doesn't mean it's a file at all.
You can use an API set name in the context of a loader operation such as LoadLibrary or P/Invoke instead of a DLL module name to ensure a correct route to the implementation no matter where the API is actually implemented on the current device. However, when you do this you must append the string .dll at the end of the contract name. This is a requirement of the loader to function properly, and is not considered actually a part of the contract name. Although contract names appear similar to DLL names in this context, they are fundamentally different from DLL module names and do not directly refer to a file on disk.
https://learn.microsoft.com/en-us/windows/win32/apiindex/windows-apisets#api-set-contract-names
What you really need to work with is KernelBase.dll, which is even documented by MS.
implib "KernelBase x86.lib" C:\Windows\SysWOW64\KernelBase.dll
implib "KernelBase x86-64.lib" C:\Windows\System32\KernelBase.dll
Module Definition File
The downside of manually creating LIB files is that one needs to maintain those with the project. Things depend on if the target is 32 or 64 Bit, DEBUG or RELEASE, so paths might become a bit complex, one might need to create relative paths for libraries in the project settings using placeholders for the target and stuff like that.
It seems that all of this can be avoided with Module Definition Files, which's purpose is to provide IMPORT and EXPORT statements to either consume exported functions by other DLLs or make that possible for others with own functions. I've successfully resolved my linker problems by simply creating a file named like my app using the extension .def alongside my other project files. That file needs to be added to the project, though.
dbxml.cbproj
dbxml.cbproj.local
dbxml.cpp
dbxml.def
dbxml.res
[...]
The following content made the app use the correct function from the correct DLL. Though, what didn't work was using the API set name, which resulted in an error message by the linker.
IMPORTS
KernelBase.PathCchCanonicalizeEx
IMPORTS
api-ms-win-core-path-l1-1-0.PathCchCanonicalizeEx
[ilink32 Error] Invalid command line switch for "ilink32". Parameter "ItemSpec" cannot be null.
[ilink32 Error] Fatal: Error processing .DEF file
The latter is after restarting C++Builder, so I guess the format of the file is simply wrong because of the API set name.

EPackageError caused by a unit that is implicitely imported

I'm currently involved in a Delphi XE5 project and I'm facing a problem that I could not solve. I have a Delphi project group that conists of one EXE; this EXE loads multiple runtime BPL's dynamically. These BPL's are also part of the project group. However, when I run the application, I got the error 'Project {MyProject.exe} raised exception class EPackageError with message 'Cannot load package 'PumpMethod'. It contains unit 'FlEdit', which is also contained in package 'eXtractionUnitMethod'.
I already searched on SO, and I've found the cause. Especially Is "implicitly imported" always a bad thing in Delphi packages? was of big help. During compilation, both BPL's of my project, emit the following message:
[dcc32 Warning] PumpMethod.dpk(46): W1033 Unit 'FlEdit' implicitly imported into package 'PumpMethod'
Other one as well:
[dcc32 Warning] eXtractionUnitMethod.dpk(46): W1033 Unit 'FlEdit' implicitly imported into package 'eXtractionUnitMethod'
But the point is that FlEdit, a textbox control that allows only the input of floats, is already part of an installed package. This package, 'Spark190.bpl', contains the control, and thus also the FlEdit unit. I've registered it and the control appears on the Tool palette. This is the project with the control:
There is also a project DclSpark190.bpl, but that is a design time package (contains the registering of the controls). When I close this project group and create a new one, I can drag/drop 'My float edit' on a form, and this runs all fine.
When I now open the project group with the EXE, and build the BPL's I got this message:
This again seems okay for me. The Spark package (with the FlEdit) is now included in the 'requires' list:
But when I compile again, the 'the following changes...' is shown again. That looks abnormal to me; the Spark BPL is already included in the requires list? So:
Q1: Why is that happening? Is it a bug in Delphi XE5? Do I something wrong here?
Also, the 'FlEdit' implicitly imported into package 'PumpMethod' is still not away:
So:
Q2: I think I've put FlEdit in a separate package 'Spark'. Both BPL's contain 'Spark' in the required package list, but still the warning (W1033) is shown. What else can I do?

How to resolve "Main module of program is empty: nothing will happen when it is run"

I have two projects in an F# solution.
1. main project with [EntryPoint] and set as the StarUp project.
2. support, the second project, holds a group of support modules. I.e. they are only called and never initiate anything nor serve as the entry point nor are the StartUp project.
For the last module in the support project, compiling in Visual Studio gives
warning FS0988: Main module of program is empty; nothing will happen
when it is run
While using compiler option nowarn inline as #nowarn "988" in the module causing the warning does suppress the message I would rather add something like a dummy function with comments that resolves the issue.
How does one make such a dummy function to resolve the warning?
EDIT
Jack is correct in that my support project was setup as a Console Application instead of a Class Library. Changing to Class Library resolved the warning. It is also nice to know about do () for the other case.
EDIT
While it seemed odd that I would have set a support project as a Console Application, I recently found that for some reason when I made a change to the code in the project, something changed the Output type from Class Library to Console Application. I suspect it has to do with the F# PowerPack and it's build rules, but it's only a guess.
Are you building the support project as a Library or as a Console Application? (This is set via the project properties page.)
If you're building it as a library, then you may need to add a do() at the end of the last file in the project. This is necessary to make the F# compiler happy in a few specific scenarios, like when you create a module which contains only assembly-level attributes (because they're applied to the assembly, the module appears "empty" to the compiler).
You can see an example in my code here:
https://github.com/jack-pappas/FSharp.Compatibility/blob/master/FSharp.Compatibility.OCaml/AssemblyInfo.fs

Run-time component package requires itself further to a refactoring

I have a set of components in split runtime/designtime packages for Delphi XE2. I've had these for a long time and have had no problems like what I'm having now. I added a new basic control called TJDWebcam. All was fine until I decided to change the type name to TJDWebcamView. I did a find/replace in the main source unit where I have this class, and made some other changes, also in the design-time package's registration unit.
The problem is that now when I build the run-time package, I get a message saying that it requires its self (It requires a package JDComponents which is exactly the same package). I've uninstalled the package, and tried to re-build, but same error.
Here's the specific message I'm getting...
Add JDComponents.
JDComponents contains implicit unit(s) uPickFolder, JDCommon,
JD.VSample, JD.VFrames, NativeJpg.
...and every unit in the package which are OK to be there. The problem didn't start until I changed this control's type name and went to re-compile.
Now if I ignore that message and hit 'Cancel' everything seems to install fine, despite the warning that it "might cause errors".
For what reasons might it be doing this? And how to go about fixing it? I'd hate to have to post my entire component library to be debugged.
PS - My library makes use of the delphi version suffix (160 for XE2) and my own version suffix (2), so the package names actually read JDComponents.160.bpl.2 and DCLJDComponents.160.bpl.2.
UPDATE
I managed to get it installed, please see my answer below.
After doing these following steps, I managed to get it re-built successfully:
Uninstalled the package
Deleted all DCU's, package, and anything compiled
Restarted the PC
Re-build everything
So the source of the problem is still unknown, but most likely somewhere in a compiled file (DCU or the package), it was still referring to this old type name from before it got changed. When the compiler came across this, it got confused and told me I had to include this other package, which is actually the same package.

Delphi package problem : Packaged units must refer only to packaged units.. (E2411)

The error I get is like this:
[DCC Fatal Error] myunit3.pas(244): E2411 Unit XBAT in package B_Dsgn refers to unit QBEE which is not found in any package. Packaged units must refer only to packaged units
I need to know what this error I am encountering really means, and if possible how to troubleshoot and solve such problems, especially when the facts stated in the error message are not correct (the units are in fact referring to other units in other valid packages).
Such problems involve package dependencies. I am having an interesting problem with a series of three designtime and three runtime packages related like this:
What is most odd about it is that each time I clean and rebuild, I get a different unit name in the error. (Shown above as Unit XBAT refers to unit QBEE).
The other odd thing is that it's referring to units that are in a top level dependency, and are part of a package that was already built.
Steps;
Compile A, it works.
Compile A_Dsgn, it works.
Compile B, it Works.
Compile B_Dsgn, it works.
Compile C, and it fails with this E2411 error.
Since I doubt anybody can tell me how to fix this exactly, I am looking for the steps to troubleshoot a complex dependency problem in a package. The literal meaning of the above error suggests for example, that I should have a corresponding message about an implicit linked unit, which I do not have. I have added all implicitly used units to the base packages A, and B, so that no implicit unit warnings are made.
My next idea was to separate the DCU output folders for each package, to prevent the DCU outputs from one from confusing the compiler. Now I can not even build the packages.
Update I tried playing with the Explicit Rebuild and Rebuild as Needed options. I have found that this error is related to having 'Rebuild as Needed' turned on. When it is turned off, the packages fail with other errors which are more to the point. I find it odd that the compiler emits weird errors that can be disabled by turning off Rebuild as needed. Any ideas what is going on?
Update 2 The basic underlying problem is not solved by turning on or off explicit rebuild. Instead of getting this error, I get annoying runtime/designtime package problems, which result in a set of packages, that can not be loaded at the same time. (Can not load package foo because it contains unit bar which is also in package bat. Do you want to attempt to load this package the next time a project is loaded?).
I suspect it is an obscure compiler bug.
The project I experienced it in had at least 4 levels of dependent runtime packages:
PackageA <- PackageB <- PackageC <- PackageD
E2411 Unit '%s' in package PackageD refers to unit '%s' which is not
found in any package. Packaged units must refer only to packaged units.
The only solution I found that worked was to make packages A, B and C never-build (i.e. Explicit Build) packages and use Project Dependencies to enforce build order instead. I had to make all three never-build or I would get
E2220 Never-build package '%s' requires always-build package '%s'
I know its probably not the answer you were looking for but there it is.
Btw, this happened to me in Delphi 2009.
It is quite simple: If a unit in C refers to a unit not in any package referred to by package C, that unit should be included in C, or the package in which it can be found should be referenced by C. If necessary, put the unit in a package of its own.
Where you put which unit depends on the dependencies. It makes sense to draw it out, like you did, but with a unit level resolution.
Update
Your update 1 and update 2 still make me think there is a unit one of your units uses (directly or indirectly) that is not properly referenced. Perhaps even an RTL or VCL unit. Since you have design packages, I assume you have components in them.
IME, the minimum set of packages to include is
requires
rtl,
designide,
vcl,
vclactnband,
vclx,
xmlrtl;
In the project that gives the error must be added as required the. dcp error.
In your case:
[DCC Fatal Error] myunit3.pas (244): E2411 Unit in package B_Dsgn XBAT Refers to unit QBEE Which is not found in Any package. Must Refer Packaged units only to packaged units
In the package where it myunit3.pas drive, add in required: QBEE
At least I managed to do so.
You are using the QBEE unit in the unit XBAT, in this case you have foure options:
1- you didn't add the QBEE to the contains list in the Package B_Dsgn.
2- If QBEE is already containd in another Package lets call it Original_Package then you should add the Package to the requires list in B_Dsgn and not contain the unit.
3- the Original_Package has
{$IMPLICITBUILD ON}
in it's dpk file so first what you have to do is to turn IMPLICITBUILD off and build Original_Package after that you can build your B_Dsgn package.
4-you probably didn't have XBAT in B_Dsgn but you have it in another middle package lets call it B_Run and you have B_Run in the requires list of B_Dsgn, in this case try first to fix B_Run with one of the upper three options and then build it, after that you can build B_Dsgn.
Note:
the last two cases could be reproduced with a long list of units and not just two or three packages that are requiring each other, in this case all of the packages should have IMPLICITBUILD off.
Clean the code for every single package of the packages that effect the issue before building them.
good luck

Resources