Delphi debug output folder attributes - delphi

I am trying to figure out how I can set the default attributes on the folders that delphi created when it builds a project. All my googling has provided no answer.
For example:
Say I have a delphi project at C:\MyProject\myProject.dpr. When I build this project, Delphi will create C:\MyProject\Win32\Debug\ folders.
The Win32\Debug\ folders comes from Tools - Options - Environment Options - Delphi Options - Debug DCU Path.
The Problem is the Debug folder delphi created has the Read-Only attribute checked. With that folder being Read-Only, I get frequent build errors, like:
[fatal error] could not create output file C:\MyProject\myProject.exe
If I manually uncheck the Read-Only attribute I can build my project fine.
So does anyone on SO know how to tell Delphi to create this folder without being Read-Only?
(I am using Delphi XE8 but I believe this applies to all versions and Windows 7 Professional)

The folders are created with a call to CreateDirectory that passes NULL as the lpSecurityAttributes parameter. As documented this means that:
If lpSecurityAttributes is NULL, the directory gets a default security descriptor. The ACLs in the default security descriptor for a directory are inherited from its parent directory.
In other words the security settings are inherited from the parent. You can make this directory writeable by making its parent writeable.

You have no control over how the folders are created. There is no option to specify the desired attributes. However, you can try using a Pre-Build event to execute a command-line script that manually changes the folder attributes before compiling begins.

Related

Error: F1026 File not found: 'System.Actions.dcu' by Command Line Compiler

The editor automatically adds the System.Actions unit when one of my forms is saved.
It compiles without a problem in the IDE, but unfortunately the Command Line Compiler can not find the file and gives me the error:
Error: F1026 File not found: 'System.Actions.dcu'
What am I missing?
In what follows, I am assuming that you are using msbuild to compile your program.
The System.Actions unit was added in XE3 to support actions in both FMX and VCL frameworks. Prior to that release FMX had no actions. Some classes were moved around, out of VCL units and into the new System.Actions unit which can be used by both FMX and VCL code.
So, the compiler error that you see suggests to me that you are unintentionally compiling with a version that pre-dates this change. My guess is that your IDE is XE3 or later, but that your command line build is configured to use an earlier version of Delphi. Most likely through the PATH environment variable, and whatever Embarcadero entry happens to be first in that variable.
If my hunch is correct then you need to ensure that you compile with the desired version.
The way I organise machines that have multiple Delphi installations is as follows:
Remove all Embarcadero entries from your PATH environment variable.
Whenever you need to build at the command line, configure the environment, for instance by running the appropriate rsvars.bat script (found in the bin directory of your Delphi installation) before you call msbuild.
This way you cannot accidentally find the wrong version because you have to explicitly configure an environment.
On the other hand, perhaps you are calling dcc32 directly. Don't do that. You will have to supply all the options and paths that are already defined in your project file. Repeating that is just a way to create a maintenence headache and make it likely that your command line build won't match the IDE build.
Instead, use msbuild to build your program. That way you can use the settings defined in your project file.
Thanks Hefferman for your advice but we shall stick with dcc32. It's easier to customize. For example we didn't figure out how to use more than one 'define' parameter with msbuild. It's possible to use dcc32 with the -NS switch for dependent 'uses' and that is our solution. We also create some .dpr files with code and in that case we do not have a corresponding .dproj file.

Where can I configure DCC_ExeOutput?

Is it possible to configure DCC_ExeOutput from Delphi? I could only change this by editing the dproj file.
I couldn't find where to edit this option even using Delphi IDE Insight.
Update 1:
This is my Project Options:
#TOndrej have suggested me change output directory, but I have already done this, and DCC_ExecOutput didn't change. The only way was editing dproj file.
Update 2:
My purpose is organize the folder structure of Delphi projects like suggested by Zarco Gajic in his article How to Layout Delphi Project Files - Best Practice.
Delphi creates folders for each platform to store .dcu, .exe and other files. .\$(Platform)\$(Config) is the default for Delphi. So in the same level of .dproj Delphi creates the folders Win32, Win64, Android, etc.
As you can see in the picture above, I've configured Delphi to put those files in a better organized form, in my opinion. Below an example:
My_Delphi_Project_folder
Bin
|___Debug
| |____Win32
| |____Win64
| |____Android
|___Release
|____Win32
|____Win64
|____Android
But after compile, the resulted structure was like below:
My_Delphi_Project_folder
Win32
Win64
Android
Bin
|___Debug
| |____Win32
| |____Win64
| |____Android
|___Release
|____Win32
|____Win64
|____Android
After investigating .dproj file I found the guilty. It was DCC_ExeOutput.
As I didn't find a way to configures it in Delphi, I asked for help here.
It has a long time that I don't work with Delphi, and I thought that could be a very simple thing that I have passed up. That's the cause of lack of information in my question.
See "Output Directory" in Project Options.
The important information here is the type of project. Your project is a package. As such the DCC_ExeOutput setting is not relevant. It has no impact on the build process. What matters for a package is the DCC_BplOutput setting. The IDE still appears to emit to the .dproj file a value for the DCC_ExeOutput setting, but this value is ignored, and can be removed from the .dproj file.
Package projects
Main source file begins with package.
The output location for the package is determined by the DCC_BplOutput node in the .dproj file.
In the IDE this setting corresponds to the Package output directory option in the project options dialog.
The IDE's new package dialog produces a .dproj file that contains a DCC_ExeOutput node. This node is ignored and can safely be removed from the .dproj file. There is no option in the IDE that corresponds to the DCC_ExeOutput node in a package .dproj file.
Executable and library projects
Main source file begins with program or library.
The output location for the project is determined by the DCC_ExeOutput node in the .dproj file.
In the IDE this setting corresponds to the Output directory option in the project options dialog.

Where do I find the bpl file after I compile a package?

I want to create *.bpl file but I am failing to do so.
Specifically, I am trying to make JEDI plugins, but I have tried an empty pure Delphi package, too.
If I create a new package in Delphi XE3, I get an empty unit - if I "make" this project called "Package1.bpl", I get a .dcu file in "debug/win32/", but no .bpl file.
No error is reported by the compiler.
An empty JEDI plugin (bpl-style) only gives a .dcu, too, while an empty dll-style JEDI plugin gives a .cdu and a .dll file in "debug/win32/".
This is the first time I am trying to make a new package, so I am completely lost.
What am I missing?
Go to the Tools menu and navigate to Environment Options -> Delphi Options -> Library.
There you find the Package Output Directory and the DCP Output Directory. These directories are the default output directories for BPLs and DCPs, so the bpl will be created if your packages is compiled, but in a different directory from what you expect.
The JEDI plugins probably have their output directory configured otherwise in Project -> Options.
For those that don't want to travel into Delphi IDE/options etc, lately in Delphi XE it's something like this:
"C:\Users\Public\Documents\Embarcadero\Studio\17.0\Bpl;"
Your exact folder might be different based on 17.0
These folders also end up in the path environment variable of your system, bit dangerous and can lead to some mighty magic loading confusion ?!
"How's that BPL still loading after it was deleted from my local project folder ?" :)
Another solution is to add "." to your project settings without the "". Prevents you from having to modify your delphi environment options/settings, something you probably never want to do since JEDI and other projects may rely on these default settings to function properly. Only change it if you know what you are doing and how to correctly make JEDI and others work if it was changed, this may get tricky/hairy, probably requires search paths to be added.

How to recreate "default" .res file from command line?

When the "default" .res file of your project is missing Delphi will offer to recreate it when you open the project in the IDE. Can this functionality be invoked from command line?
Background:
A project is under version control, its .res file is not checked in (some musings about why can be found here). The project is checked out automatically and build from command line. The problem now is the missing .res file which causes the build to fail. Can I somehow invoke the auto-creation feature the IDE uses from command line? Otherwise it seems like I am forced to check in the .res file.
No, there is no command-line tool in Delphi to re-create the default resource file.
That's just as well since you don't need the default resource file. It would contain a generic version number and a generic icon, which you obviously don't want in any project important enough for automated builds.
Binary resource files don't do well in source control, which is what prompted the other question. Write .rc files instead, and compile them as part of your build. Delphi won't auto-increment build numbers anymore, but it's easy enough to reproduce that in your build script as well by updating your .rc file (or generating an included file) prior to compilation.
If you really want a binary resource file, then you could store one in source control, but under a different name or location than what the compiler expects to find. After checkout but before the build, copy it into the proper location. Changes to the copy won't be recorded in source control.

Where to keep Delphi DCU files?

Currently I have not set any specific output directory for Delphi DCUs in my main project. This results in the DCU files ending up in the same directory as my .pas source files. To me, this feels ugly as I don't like the idea of mixing .pas and .dcu files in the same directory. What is the best practice for storing Delphi .dcu files - keep them all one directory for each project? Or maybe create one DCU directory for each source folder? Any ideas welcome.
The best way to do it is to create a DCU folder for each project, especially if you have more than one project that uses the same files. Otherwise, you can end up with different compiles with different compiler settings stomping each other's DCUs.
.dcu's are also dependant on defines, and e.g. debugging vs release configuration (*).
(*) While Delphi XE allows to put the "configuration" in the output path, IMHO that cure is worse than the problem
So I regularly recursively delete all .dcu's from the root of the dir where I do all my SVN checkouts.
The directory with components has a delphi version suffixed, and is outside the SVN checkout directory.
Agreed...mixing PAS and DCU files in the same directory is 'dirty'.
Whenever you start a new application, dll, or other Delphi project, one of the first things to do is to set the output directory. In later versions of Delphi this is done for you as the output directory is set as .\$(Config)\$(Platform) which correlates to the Debug or Release config option and Win32 platform. (Ending up with a default output directory of Debug\Win32)
If you build with custom compiler defines then it would be wise to have different project build options to include separate output directories for each set of custom compiler defines otherwise you have to do a full build to ensure that units are built correctly.

Resources