Tuesday, March 17, 2015

How to set paths (library, debug, BPL, DCP, search) in Delphi XE7 (for multiplatform use)

So, Delphi's help doesn't tell us much about how to set up paths for DPK packages. It is ok. We got all used with Delphi's sloppy manual.

So, I will tell you how I do it so they work both on 32 and 64 Win platforms:



My packages


I have these major packages/folders:
  • Graphics32
  • Drag and Drop (Melander)
  • 3rd  Party (many small packages put together in a big package)
  • CommonPackages (these are my own packages)
I always build 'Graphics32', 'Drag and Drop' and '3rd  Party' packages only in Release mode. So, there is no DCUs and BPLs complied in Debug mode, therefore we don't set a path for $(Config).



Package setup 

Double click the DPK file to load it in Delphi. Go to project's settings and set xxxxxxxxxxxx.
This will ensure that the IDE and app that use this package don't have access to the package's PAS files. If the IDE has access to the PAS file it will recompile the files every time you complile the app.Even worst, if the IDE recompiles package's files, it will put the DCUs in app's folder!

Also unckeck 'Build as needed'. xxxxxxxxxxx




IDE setup 


IDE setup - Package output directory
  • For Win32 platform set it to: $(BDSCOMMONDIR)\Bpl
  • For Win64 platform set it to: $(BDSCOMMONDIR)\Bpl\$(Platform)
Do the same for 'DCP output directory'.


IDE setup - Library path settings

In Delphi options -> Library -> Library path, I set these paths for Win32 platform:
  • c:\MyProjects\Packages\DragDrop\$(Platform)
  • c:\MyProjects\Packages\Graphics32\$(Platform)
  • c:\MyProjects\Packages\Third party packages\$(Platform)
  • c:\MyProjects\Packages\CubicCommonControls\$(Platform)_$(Config)
Please note that Graphics32, Drag and Drop and 3rd  Partyonly have the $(Platform) set.

CommonPackages are multi-platform (Win32/64) and multi-config (debug, prerelease, release). Therefore, we use $(Config) in the path.
If the control uses *.res files you need to manually copy them in the $(Platform) folder (the folder where the DCU are written)

This is Delphi's help page for Browsing path: Specifies search paths where the compiler can find the required files for the package, such as .dcp and .bpi files.
This is the Delphi global library path. The compiler can find only those files that exist on the Library path. If you try to build your package with a file that is not on the Library path, you receive a compiler error.
Some resource files (such as controls.res) are only available in the Release folder (not the Debug folder), so you should ensure that your project Release directory either is specified in the Library path or will be resolved by at least one variable in the Library path.


Browse path

In Delphi options -> Library ->:
Enter the path to package's source code so the IDE will able to reach the code (for example to be able to open a file when you control+click a method in IDE):
  • c:\MyProjects\Packages\DragDrop\
  • c:\MyProjects\Packages\Graphics32\
  • c:\MyProjects\Packages\Third party packages\
  • c:\MyProjects\Packages\CubicCommonControls\
This is Delphi's help page for Browsing path: Specifies the directories where the Code Browsing feature of the Code Editor looks for unit files when it cannot find an identifier on the project search path or source path. The Code Editor searches for unit files used for code browsing in the following order:

  1. The project Search path for Delphi ( Project > Options > Delphi Compiler ) or the Include path for C++ ( Project > Options > Directories and Conditionals).
  2. The global browsing path (this option) for Win32 Delphi language projects; the directories specified with this option are appended to the debug source path for the project. Therefore, the debugger search order for unit files is determined by the following path settings:
    • The Browsing path (this option).
    • The project Source path (the directory in which the project was saved).


Search path

I am not sure you really need the thing below (I think you don't):

The project's 'Search Path' is set like this (for all platforms):
  • c:\MyProjects\Packages\DragDrop\$(Platform)
  • c:\MyProjects\Packages\Graphics32\$(Platform)
  • c:\MyProjects\Packages\Third party packages\$(Platform)
  • c:\MyProjects\Packages\CubicCommonControls\$(Platform)_$(Config)

You have to do the same for 32 and 64 bit platforms (in the 'Selected Platform' dropdown menu).


The applications

For applications (DPR) that are using the packages specified above I set the 'Unit output directory' like this (for 'All configurations/All platforms'):
  • .\$(Platform)_$(Config)


__________


Update: I had problems making a project to work when when I used a combination of $(Platform)_$(Config) and $(Platform) in the paths. It worked after I replaced $(Platform)_$(Config) with $(Platform).

Tuesday, March 3, 2015

Trying to do some multi-platform programming

So, I purchased Delphi XE7 for a pile of money (around 1000euros) hoping to do all the wonderful things they advertised.
After struggling with their grandiose (read as 'scarce' or 'almost nonexistent') user manual I managed compiling my 32 bit application for Windows 64.

Since Delphi is 32 bit and my Windows machine is also 32 bit you need to somehow deploy your app on Windows 64 and run/debug it there. This is what PAServer (debugger platform assistant) is supposed to do.
However, PAServer keeps crashing as soon you press the Run button in Delphi. Sometimes this error is shown:


Error setting debug exception hook.

[223ADB5B]{win32debugide210.bpl} Win32Debug.TNativeProcess.SetDelphiTracingLevel (Line 2324, "Win32Debug.pas" + 5) + $11
[223AD5ED]{win32debugide210.bpl} Win32Debug.TNativeProcess.InitExceptRanges (Line 2195, "Win32Debug.pas" + 3) + $4
[223ADFB8]{win32debugide210.bpl} Win32Debug.TNativeProcess.DoSetExceptOption (Line 2436, "Win32Debug.pas" + 2) + $6
[203620D0]{dbkdebugide210.bpl} Debug.TDebugger.SetProcess (Line 11394, "Debug.pas" + 31) + $10
[20363397]{dbkdebugide210.bpl} Debug.TProcess.SetExceptOption (Line 11709, "Debug.pas" + 1) + $4
[203574BF]{dbkdebugide210.bpl} Debug.TThread.ntfyThread (Line 6355, "Debug.pas" + 58) + $6
[1B76C593]{bordbk210.dll} Unknown function at @isDbkLoggingOn$qv + $626BB
[1B79C22A]{bordbk210.dll} Unknown function at @isDbkLoggingOn$qv + $92352
[1B79680A]{bordbk210.dll} Unknown function at @isDbkLoggingOn$qv + $8C932
[1B76B927]{bordbk210.dll} Unknown function at @isDbkLoggingOn$qv + $61A4F
[1B76C593]{bordbk210.dll} Unknown function at @isDbkLoggingOn$qv + $626BB
[1B793703]{bordbk210.dll} Unknown function at @isDbkLoggingOn$qv + $8982B
[1B79C4D7]{bordbk210.dll} Unknown function at @isDbkLoggingOn$qv + $925FF
[1B709D72]{bordbk210.dll} Unknown function at DllUnregisterServer + $17EF6
[1B76B8CC]{bordbk210.dll} Unknown function at @isDbkLoggingOn$qv + $619F4
[505C2850]{vcl210.bpl  } Vcl.Controls.TControl.Perform (Line 7010, "Vcl.Controls.pas" + 10) + $8
[1B76C7FC]{bordbk210.dll} Unknown function at @isDbkLoggingOn$qv + $62924
[1B714263]{bordbk210.dll} Unknown function at @isDbkLoggingOn$qv + $A38B
[505C76E2]{vcl210.bpl  } Vcl.Controls.TWinControl.WndProc (Line 10038, "Vcl.Controls.pas" + 153) + $6
[505C2850]{vcl210.bpl  } Vcl.Controls.TControl.Perform (Line 7010, "Vcl.Controls.pas" + 10) + $8
[505C5E7E]{vcl210.bpl  } Vcl.Controls.TWinControl.GetControl (Line 9130, "Vcl.Controls.pas" + 4) + $A
[505CA48F]{vcl210.bpl  } Vcl.Controls.TWinControl.CMInvalidate (Line 12012, "Vcl.Controls.pas" + 10) + $4
[505C2C15]{vcl210.bpl  } Vcl.Controls.TControl.WndProc (Line 7232, "Vcl.Controls.pas" + 91) + $6
(0003C651){CnWizards_DXE7.dll} [0DCCD651]
(0003C6B8){CnWizards_DXE7.dll} [0DCCD6B8]
(0003C769){CnWizards_DXE7.dll} [0DCCD769]
(00039EF6){CnWizards_DXE7.dll} [0DCCAEF6]
[500636D0]{rtl210.bpl  } System.@FinalizeArray (Line 31435, "System.pas" + 139) + $0
[500636C0]{rtl210.bpl  } System.@FinalizeArray (Line 31423, "System.pas" + 127) + $0
[50716363]{vcl210.bpl  } Vcl.Forms.TApplication.ProcessMessage (Line 10354, "Vcl.Forms.pas" + 25) + $1
[5071639E]{vcl210.bpl  } Vcl.Forms.TApplication.HandleMessage (Line 10382, "Vcl.Forms.pas" + 1) + $4
[507166D1]{vcl210.bpl  } Vcl.Forms.TApplication.Run (Line 10520, "Vcl.Forms.pas" + 26) + $3



Some people suggested that if you set your connection (the network connection between the 32 bit debugging machine and 64 bit debugged machine) without a password it may not work! I have tried that but with no success.


UPDATE

I tried to fix this and I spend too much time. In the end I gave up and installed Delphi in a second computer (yes, and did all the madness about installing all tools, libraries, etc) that has Win64 bits.


I also contacted Embarcadero support about this issue. They said that somebody will call me but I never heard from them. They know they can't fix the problem.

The conclusion is that Delphi is not even by far ready for multi-platform development. It has some multi-platform capabilities but I would say it doesn't go beyond the 'experimental' or 'beta' stage. Multi-platform (FMX included) is not ripe yet. Maybe in a couple of years. But then if it is too wait that long (and pay lots of money for upgrades) we should also consider Lazarus.