Difference between revisions of "FPMake"

From Free Pascal wiki
m (Changing Working Directory)
m (More complex example fpmake.pp)
Line 94: Line 94:
 
   program fpmake;
 
   program fpmake;
  
   Type
+
   type TWidgetSet = (wsGDI,wsX,wCarbon);
    TWidgetSet = (wsGDI,wsX,wCarbon);
 
  
   Var
+
   var WidgetSet : TWidgetSet;
    WidgetSet : TWidgetSet;
+
      T : TTarget;
  
 
   procedure DetermineWidgetSet;
 
   procedure DetermineWidgetSet;

Revision as of 05:16, 27 January 2008

Introduction

This page summarizes all available knowledge on FPMake. FPMake is a pascal based build system developed for and distributed with FPC. It is possible to use FPMake with non FPC development related projects as a replacement for Make or other build systems (like cons, scons, etc).

See also fppkg.

Basics

The upcoming 2.2 will contain the basics for a package system. Look at all directories in the fpc source dirs. You'll find there a fpmake.pp or fpmake.inc.

The idea is that you do a

 fppkg <packagename>

this will look in a database for the package, extract it, and the compile fpmake.pp and run it. The fpmake contains all configuration to make and zip the package.

You could download a package manually, compile fpmake.pp and run

 ./fpmake build

or

 ./fpmake install

which would install the file.

The fpmake.pp file is very simple, just look at the examples, they are scattered all over the place.

The idea is that the release after 2.2 will use this system.

Commandline arguments

 C:\FPC\packages\fpmkunit>fpmake --help
 Usage: C:\FPC\packages\fpmkunit\fpmake.exe command [options]
 Where command is one of the following:
  compile      Compile all units in the package(s).
  build        Build all units in the package(s).
  install      Install all units in the package(s).
  clean        Clean (remove) all units in the package(s).
  archive      Create archive (zip) with all units in the package(s).
  manifest     Create a manifest suitable for import in repository.
 Where options is one or more of the following:
  -h --help             This message.
  -l --list-commands    list commands instead of actually executing them.
  -n --nodefaults       Do not use defaults when compiling.
  -v --verbose          Be verbose when working.
  -C --CPU=Value            Compile for indicated CPU.
  -O --OS=Value             Compile for indicated OS
  -t --target=Value         Compile for indicated target
  -P --prefix=Value         Use indicated prefix directory for all commands.
  -B --baseinstalldir=Value Use indicated directory as base install dir.
  -r --compiler=Value       Use indicated binary as compiler
  -f --config=Value         Use indicated config file when compiling.

Simple example fpmake.pp

<pascal>

 program fpmake;
 uses fpmkunit;
 Var
   T : TTarget;
 begin
   With Installer do
   begin
     StartPackage('MyNiceProgram'); // Actually optional.
     Targets.DefaultOS:=[win32,openbsd,netbsd,freebsd,darwin,linux];
     T:=Targets.AddUnit('myunit');
     T.ResourceStrings:=True; 
     T:=Targets.AddUnit('myprogram');
     T.Dependencies.Add('myunit');
     EndPackage; // Actually optional.
     Run;
   end;
 end.

</pascal>

Compile with

 fpc fpmake.pp

or

 fppkg build

which will build (if needed) fpmake and run fpmake in the current directory.

More complex example fpmake.pp

<pascal>

 program fpmake;
 type TWidgetSet = (wsGDI,wsX,wCarbon);
 var WidgetSet : TWidgetSet;
     T : TTarget;
 procedure DetermineWidgetSet;
 Var
   I : Integer;
 begin
   Case Installer.OS of
     Windows : WidgetSet:=wsGDI;
     Linux : Widgetset:=wsX;
     MacOS : WidgetSet:=wsCarbon
   end;
   // Check paramstr() to see if the widgetset was overriden on the commandline;
   For I:=1 to ParamCount do
     If ParamStr(i)='--widgetset=X' then
       WidgetSet:=wsX;
 end; 
 
 begin
   DetermineWidgetSet;
   With Installer do
   begin
     ... 
     Case WidgetSet of
       wsGDI : T.UnitPath.Add('corelib/gdi');
       wsX   : T.UnitPath.Add('corelib/x11');
       // etc.
     end;
     ...
     Run;
   end;
 end.

</pascal>

Changing Working Directory

If working with units in a subfolder relative to ./fpmake, then "Directory" can be changed. <pascal>

   With Installer do
   begin
     ...
     Directory:='some/subdir';
     T:= Targets.AddUnit('unitinfolder');
     ...
   end;

</pascal>

Adding directories

You can add directories with the unit path:

<pascal>

 Case OS of
   Windows : begin
               T.UnitPath.Add('corelib/gdi');
               T.Dependencies.Add('gfx_gdi');
             end;
   Linux   : begin
               T.UnitPath.Add('corelib/x11');
               T.Dependencies.Add('gfx_x11');
             end;
   // etc.
 end;

</pascal>

Appending Compiler Options

There is the ability append more custom compiler options (i.e. compiler command line parameters) by using TTarget.Options, TPackage.Options, or Defaults.Options.

<pascal>

 var T : TTarget;
 ...
 T.Options:= '-dSOMEDEFINE';
 T.Options:= T.Options + ' -xyzAnythingYouNeed';

</pascal>

Or <pascal>

 var P : TPackage;
 ...
 P.Options:='-dSOMEDEFINE';

</pascal>

Or <pascal>

 Defaults.Options:='-dSOMEDEFINE';

</pascal>

Commands

The fpmake executable takes several commands that determine the behavior.

Compile

The most basic usage of fpmake is:

 ./fpmake 

or

 ./fpmake compile

This will compile your project when required.

Build

To force a build of your project regardless whether it is nescesary or not a build command should be issued.

 ./fpmake build

When executing a build or compile command the units are placed in the directory:

 ./units/CPU-OS

The executable of library is placed under:

 ./bin/CPU-OS

If either of these directories does not exist, they are created.

The CPU and OS can be changed by using the following options:

 ./fpmake --CPU=PPC --OS=Darwin

where the CPU switch takes one from:

  • Arm
  • I386
  • PPC
  • SPARC
  • X86_64
  • M68K
  • PPC64

and OS takes one from:

  • Amiga
  • Atari
  • Darwin
  • FreeBSD
  • Go32v2
  • Linux
  • MacOS
  • MorphOS
  • NetBSD
  • Netware
  • NetwLibc
  • OpenBSD
  • OS2
  • PalmOS
  • Solaris
  • Win32
  • Win64
  • WinCE
  • Emx

Clean

 ./fpmake clean

Will clean units (i.e. ones that have been added with AddUnit).

Install

 ./fpmake install

Will install the project to the default location given in fpmake.pp. You can alter the install location with the following command:

 fpmake --baseinstalldir='c:\program files\my package';

There are two installer classes implemented:


TBasicInstaller

Does not set the base output directory, this needs to be set in either the code:

<pascal>

 with Installer(TBasicInstaller) do
 begin
   BaseInstallDir := 'c:\fpmake_test\';
   {$i fpmake.inc}
   Run;
 end;

</pascal>

Or with the commandline option -B or --baseinstalldir. Either way the use of TBasicInstaller needs to be initiated with the Installer(TBasicInstaller) function.


TFPCInstaller

Sets the output directory in code. This is done in several consecutive steps.

  1. Value of FPCDIR environment variable
  2. Hardcoded value

Just like TBasicInstaller its possible to use commandline options to control the base install directory.

Archive

 ./fpmake archive

will create a zip.

To filename of the archive by default is:

 packagename-version.zip

or

 packagename.zip 

when no version is defined.

It's possible to modify the archive filename by setting the FileName property:

<pascal>

 with Installer do
 begin
   ...;
   FileName := 'myfile.zip';
   ...;
 end;

</pascal>

Manifest

To create a manifest file suitable for import in a repository like FPC will use in the near future issue the manifest command.

An example manifest file is shown below.

<xml>

 <?xml version="1.0" ?> 
 <packages>
   <package name="my-package">
     <version release="0" major="7" minor="6" suffix="alpha" /> 
     <filename>my-package-0.7.6-alpha.zip</filename> 
     <author>my name</author> 
     <license>GPL</license> 
     <externalurl>www.freepascal.org</externalurl> 
     <email>myname@freepascal.org</email> 
     <description>this is the package description</description> 
   </package>
 </packages>

</xml>

This manifest file was created using the following code:

<pascal>

 with Installer do
 begin
   StartPackage('my-package');
   Author := 'my name';
   License := 'GPL';
   ExternalURL := 'www.freepascal.org';
   Email := 'myname@freepascal.org';
   Description := 'this is the package description';
   Version := '0.7.6-alpha';
   
   ...;
   EndPackage;
 end;

</pascal>

List sources

 ./fpmake listsources

Will create an xml file called sources.xml which lists all sources in the package. Each item has a type node that reveals the function of the file.

<xml>

readme.txt
project.pas
example.pas
test_unit.pas

</xml>

The sources.xml file can be read by fppkg which uses it to create a package by itself.

Innosetup

The plan is to also add

 ./fpmake innosetup

Which will generate a file that can be included in an inno setup file.