2
votes

I have a VCL component that runs on Delphi 7 to 10.3. I am now porting it to FMX.

To avoid maintaining two codebases, I will use conditional defines in my source to separate any custom FMX and VCL code. When I compile the component for distribution a script will output either the VCL or FMX source files.

My problem is how to make the VCL DCUs and FMX DCUs co-exist on the same system (for users who have both the VCL and FMX versions of my component) as both folders will need to be on the Delphi path.

In other words, my VCL units are named: myunit1.pas, myunit2.pas, etc.

And the FMX versions: fmx.myunit1.pas, fmx.myunit2.pas, etc

(Ideally I would name the VCL ones vcl.myunit1.pas, vcl.myunit2.pas, etc. That way the VCL version of the component would only see the vcl.-.pas files and the FireMonkey only the fmx.-.pas files. Unfortunately I cannot do this because then it won't work on older Delphi versions).

Now when I compile a FireMonkey app it tries to use the non-fmx prefixed source files, in preference to the fmx._.pas ones. I need to "hide" the vcl source folder to get it to compile (re-ordering the Delphi paths does not help).

If there another way to make FireMonkey avoid using the vcl files?

(I fear I will need to write a script to give all the files a new name, e.g. FMXmyunit1.pas and update all of the references in all of the files).

2
Use {$ifdef to ensure conditional compilation. You can use this whereever you see fit and using whatever {$define values suit your application design. - nolaspeaker
You don't need separate source files to support VCL and FMX. A single source will suffice, you just need different packages with different output folders, and you can register your component in such a way that the IDE will filter out the VCL version in FMX projects and vice versa. - Remy Lebeau
Am I right in assuming that you don't want to give the FMX source code to users who only buy VCL and vice versa? And that's the reason you create different source files from the originally combined sources? Are you sure that this is worth the effort? - dummzeuch
Thanks for all the feedback. I don't mind users having both the VCL and FMX source, but I thought it might be easier to have source in separate folders. There is no true FMX define in Delphi (just an "IF DECLARED", which means it cannot be used in an INC file and cannot conditionally specify units in the interface uses clause). So I have a different "platform" inc files in each folder. Come to think of it, they could be named fmx.plat.inc and vcl.plat.inc and the compiler would choose the correct one.... - Zax

2 Answers

3
votes

Because Delphi does not provide predefined compiler conditionals to distinguish between the Firemonkey and the VCL framework you can add the symbol $(FrameworkType) into the conditional defines list of the application project settings. This enables the differentiation of the framework within your library by using the conditional compiling symbols FMX and VCL.

Example of typical usage:

uses
  {$IFDEF FMX}
  FMX.Forms,
  {$ENDIF}
  {$IFDEF VCL}
  VCL.Forms,
  {$ENDIF}

This works in my own cross-platform library for pure VCL and FMX projects, where I let integrate the source files directly into the project. In this simple way, the DCU will be recompiled each time. In the case of mixed projects, the $(FrameworkType) contains the initial framework of the application.

When you deliver a package (bpl) things get more complex. You must provide two versions of your bpl for FMX and VCL. If you also provide the source code for debugging purposes, the only option is to completely differentiate the source code files for the FMX and VCL versions, as long as they have platform-dependent code.

0
votes

Well, I don't know if it's really a solution, but it works for me.

I wrote an application that copies all my VCL files to my FireMonkey folder and renames them with an FMX prefix, i.e myunit.pas becomes FMXmyunit.pas. It also updates all the references in the pas files and adds a {$DEFINE FMX} to the header. Now both my VCL and FMX versions coexist happily.

Also, I have set my merge tool (Beyond Compare) to ignore the FMX prefix, so I can merge either platform version directly to my local Git copy.