Crosscompiling with Lazarus 1.8 on Linux Mint 18.3

0

Suppose you installed Lazarus 1.8 on Linux Mint 18.3 as described before and want to build Windows binaries (well we don’t like Windows, but the users do 🙂 ). I’ve found the useful piece of information about crosscompiling here and started to adopt it to my 32-bit Linux system.

The first step is to build and install the crosscompiler. For the demonstration purposes I decided to build Win32 crosscompiler (the Win64 case should not be much different).

Lazarus 1.8 uses FPC version 3.0.4, so to perform the first step open up Terminal and execute following commands:

# Navigate to the fpc source folder.
cd /usr/share/fpcsrc/3.0.4

# Compile the cross-compiler.
sudo make clean all OS_TARGET=win32 CPU_TARGET=i386

# Install the cross-compiler.
sudo make crossinstall OS_TARGET=win32 CPU_TARGET=i386 INSTALL_PREFIX=/usr

# Link the cross-compiler and place the link where Lazarus can see it.
sudo ln -sf /usr/lib/fpc/3.0.4/ppcross386 /usr/bin/ppcross386

Now let us open Lazarus and create a simple GUI project. I dropped a button on the form and written OnClick handler:

procedure TForm1.Button1Click(Sender: TObject);
begin
  ShowMessage('Hello World!');
end;

I created subfolder /Projects/Lazarus/HelloWorldGUI in my home folder and saved the project under the name HelloW. You can build and run the project and see it works.

Now time to configure the project for Win32 crosscompiling. Open Project Options dialog (Ctrl-Shift-F11). You should see this:

Options0

Check Build Modes checkbox:

Options1

and click the ellipsis button; a new dialog appears:

BuildMode0

Click plus button to create a new build mode, and name it Win32:

BuildMode1

Now we should tell Lazarus to compile Win32 code for this build mode. Select Config and Target on the left panel and select Win32 as target OS:

ConfigWin32

Now you can build the project. I simply clicked green Run button and obtained the warning window:

DebugErr

Well I guess one can’t expect to debug Win32 binary on Linux. Still the work was done, and I’ve found HelloW.exe file in the project folder. To be sure I’ve copied the file on 64-bit Windows 10 system, and It Works!

CrossWin32

Installing Lazarus 1.8 on Linux Mint 18.3

4

Yesterday I come across my old 32-bit Celeron laptop with 2Gb memory and broken battery and decided to install Linux on it. First I tried Centos 7.5, then Ubuntu 16.04, and finally settled down on Mint 18.3 Cinnamon which I liked most. After playing a little with the OS I decided to install the brand new Lazarus 1.8. I spent a couple of hours searching for a clear installation guide in Internet; I scanned tons of outdated nonsense before I finally found what I was looking for.

My Linux Mint installation was fresh, and I need not purge it from previous fpc/lazarus installations. So I started from downloading three 32-bit .deb packages from sourceforge.

After downloading my Downloads folder looked so:

Downloads

The next recommended step is to check hashes of the files. I launched Terminal and changed to Downloads directory:

hashes2

Now time to install the packages. As recommended in the linked guide, I typed in Terminal

sudo apt install ./fpc_3.0.4-1_i386.deb
sudo apt install ./fpc-src_3.0.4-1_i386.deb
sudo apt install ./lazarus-project_1.8.0.0_i386.deb
sudo apt-mark hold fpc fpc-src lazarus lazarus-project

And that is all! After opening the Cinnamon menu I’ve found this:

menu

Nice feature of Lazarus IDE

4

Lazarus treats include files (*.inc) as a part of a project. That means you should not bother where you store include files in a project – just

{$I Smth.inc}

is enough.

Not so in Delphi (Delphi XE to be exact). You can add *.inc file to a Delphi project, but it does not matter for Delphi, you still need to write paths to include files like that

{$I ..\..\Source\Common\Smth.inc}

and sure the paths are different for units in different project folders.

Introduction to unit testing with Lazarus

5

1. Lazarus 1.0 comes with built-in unit testing framework called FPCUnit. FPCUnit is another Pascal clone of Java JUnit framework, like DUnit framework supplied with Delphi, but different from DUnit in some details.
If you are absolutely new to unit testing (or to Lazarus, like me) create your first unit test project by running the wizard. Select File->New… from IDE menu, choose FPCUnit Test Application and click ‘OK’:

Check two checkboxes and click ‘OK’ in the next dialog:

The wizard is very primitive, but you need not anything more. You can save the generated unit test project as a template and never run the wizard again.

2. Now time add a unit under test to the project. Most usual unit under test is a class, but it also can be a record with methods, or a pascal unit with flat procedures in interface section. For demonstration purposes I have written TCalc class implementing a simple calculator to be a unit under test:

unit Calcs;

{$mode objfpc}{$H+}

interface

uses
  Classes, SysUtils;

type
  TCalc = class
  private
    FAccumulator: Integer;
  public
    procedure Clear;
    procedure Add(Value: Integer);
    procedure Sub(Value: Integer);
    property Accumulator: Integer read FAccumulator;
  end;

implementation

{ TCalc }

procedure TCalc.Clear;
begin
  FAccumulator:= 0;
end;

procedure TCalc.Add(Value: Integer);
begin
  FAccumulator:= FAccumulator + Value;
end;

procedure TCalc.Sub(Value: Integer);
begin
  FAccumulator:= FAccumulator - Value;
end;

end.

3. To implement a testing of a unit we create a test case. Our generated unit test project already contains one test case – that is TTestCase1 class. Our unit under test has 3 functions to be tested: the methods TCalc.Clear, TCalc.Add and TCalc.Sub. Edit testcase1.pas unit as follows:

unit TestCase1;

{$mode objfpc}{$H+}

interface

uses
  Classes, SysUtils, fpcunit, testutils, testregistry, Calcs;

type
  TTestCase1= class(TTestCase)
  private
    FCalc: TCalc;
  protected
    procedure SetUp; override;
    procedure TearDown; override;
  published
    procedure Clear;
    procedure Add;
    procedure Sub;
  end;

implementation

procedure TTestCase1.SetUp;
begin
  FCalc:= TCalc.Create;
end;

procedure TTestCase1.TearDown;
begin
  FCalc.Free;
end;

procedure TTestCase1.Clear;
begin
  FCalc.Clear;
  AssertEquals(FCalc.Accumulator, 0);
end;

procedure TTestCase1.Add;
begin
  FCalc.Add(42);
  AssertEquals(FCalc.Accumulator, 42);
end;

procedure TTestCase1.Sub;
begin
  FCalc.Sub(42);
  AssertEquals(FCalc.Accumulator, -42);
end;

initialization
  RegisterTest(TTestCase1);
end.

4. Our first unit test project is ready now. Run it and see the result:

5. We created a published method of a test case for every tested function of a unit under test. Unit testing framework includes published methods of test case class into a test runner application. Notice that Setup and TearDown methods of a test case are called every time a published method of a test case is called. When I started to use unit testing I thought that Setup (TearDown) is called when test case class is created (destroyed) – that is not true, they are called ‘per function’.

6. You can add more units under test to a unit test project. If you have several units under test (and correspondent test cases) in a project you can have a separate test register unit. Remove the initialization section from the test case unit, add a second unit testcase2.pas with TTestCase2 test case class (you can make a replica of the first) to the project, and create a new RegTests.pas unit in to register test cases:

unit RegTests;

{$mode objfpc}{$H+}

interface

uses
  Classes, SysUtils, testregistry, testcase1, testcase2;

implementation

initialization
  RegisterTest(TTestCase1);
  RegisterTest(TTestCase2);
end.

Now we have a unit test project with 2 test cases:

7. If your unit test project grows one day you will want to have a hierarchical structure of test cases instead of a flat one. You can create a test hierarchy using a different RegisterTest overload. Create an additional hierarchy levels by updating RegTests.pas unit as follows:

unit RegTests;

{$mode objfpc}{$H+}

interface

uses
  Classes, SysUtils, testregistry, testcase1, testcase2;

implementation

initialization
  RegisterTest('Level1.Level2', TTestCase1);
  RegisterTest('Level1.Level2', TTestCase2);
end.

8. Our oversimplified test case class contains all testing code inside the published methods. More realistic published methods are wrappers for other functions which perform actual testing. You may be tempted to add private methods and fields to test case classes; it is OK if your test case class is simple, otherwise you will soon find your test case class cluttered with a mess of methods corresponding to different tests (published methods). My own experience lead me to creating (if needed) a separate helper class for every test. These helper classes inherit from a common base class which provides access to TTestCase functions:

type
  TTestHelper = class
  private
    FTestCase: TTestCase;
  public
    constructor Create(ATestCase: TTestCase);
    property TestCase: TTestCase read FTestCase;
  end;

implementation

constructor TTestHelper.Create(ATestCase: TTestCase);
begin
  FTestCase:= ATestCase;
end;

Happy unit testing with FPCUnit and Lazarus!

Best 1st April joke. Ever.

6

My regards to lazarus.su (in Russian). It’s 1st April post was:

Lazarus developers announced that the IDE source code is closed and sold to Embarcadero. Under the unconfirmed information the last Lazarus version 0.9.30 will become the base for the next Delphi release – FPC Edition.
Lazarus team was forced to make this step due to lack of sponsorship. They can’t continue to work on the project. On the other hand, by acquiring Lazarus code the Embarcadero is hoping to release the long-awaited Delphi versions for Linux and 64-bit platforms.