[fpc-pascal] fpcmake packaging

Tony Whyman tony.whyman at mccallumwhyman.com
Tue Sep 1 16:04:51 CEST 2020


On 01/09/2020 14:29, Ryan Joseph via fpc-pascal wrote:
>
>> On Sep 1, 2020, at 7:46 PM, Tony Whyman via fpc-pascal <fpc-pascal at lists.freepascal.org> wrote:
>>
>> fpcmake is a pre-processor that generates makefiles for fpc projects. You can use it to do just about anything a standard makefile can do, including including resource files and running scripts. I use it all the time for building production versions of lazarus programs and prior to packaging the programs and resources in .deb and .rpm files.
>>
>> On 01/09/2020 13:37, Ryan Joseph via fpc-pascal wrote:
>>
> Apparently there is fpmake and fpcmake, which I didn't know.
>
> I guess what you're saying is that I start with fpcmake and get makefiles which I can then use to do packing and all the stuff I need? I've thought of using makefiles before but I ran into the problem of have all this logic that I need to duplicate for each project. What I'm really after is something more like lazbuild that takes a config file and does all the commands for you. I guess I could even use lazbuild but again, the packaging doesn't seem possible since lazbuild is so Lazarus focused (obviously).
>
> Regards,
> 	Ryan Joseph
>
>
My primary motivation for going with fpcmake is that it is a very good 
fit with the debian package management system (and rpmbuild). My normal 
build target is Ubuntu and hence I want to generate .deb files in order 
to distribute my application. The Debian Package Manager does not 
actually mandate use of makefiles - but it is built around the makefile 
concept and I have only ever seen examples of use based on makefiles.

I would position fpcmake as similar to autoconf/ automake in the C/C++ 
work. With automake, you need a Makefile.am in every directory of your 
project that contains something to compile or include in your package. 
With fpcmake you need a Makefile.fpc instead. This file contains the 
directives needed to generate the makefile and looks like an ini file.

An example follows taken from a simple application I have for 
Requirements Management.

The Makefile.fpc uses external environment variables, such as 
"INTERFACE". An external script (or a Debian rules file) that calls 
"make" itself to compile the project would define

export INTERFACE=gtk2

assuming you want gtk2 for your GUI.

Otherwise, the [compiler] section defines the fpc options, and 
directories to search. Most of these are part of my project. I have also 
used environment variables to define the build target and where to find 
the lazarus units. The [install] section is where I tell it  to install 
resource files. This includes an icon for the program and Firebird 
resource files. My project also requires that a .res file is built 
before the program is linked and there is a [prerules] section for this. 
"mkversioninfo" is my own utility, which generates the input to the 
windres utility for .res file generation.

Finally, there is an extra [rules] section to ensure that my resources 
are built when a "make all" is called.

[requires]
packages=fcl-res
libc=y

[compiler]
options= -MDelphi -Scghi -O3 -CX -Xs -vewnhi -l -dUseCThreads -dLCL 
-dLCL$(INTERFACE)
unittargetdir=units/$(CPU_TARGET)-$(OS_TARGET)
includedir=$(LZINCLUDE)
unitdir=$(LAZUNITDIR)/*  $(LAZUNITDIR)/*/$(INTERFACE) \
../frames \
../forms \
../dlg \
../reports \
../ole \
../ \
.


[target]
programs=RequirementsManagerPersonal

[install]
datadir=$(INSTALL_PREFIX)/share/RequirementsManager
files=RequirementsManagerPersonal.xpm firebird.conf firebird.msg

[prerules]
resources:
     rm -f RequirementsManagerPersonal.res
     mkversioninfo requirementsmanager-personal RequirementsManager.ico 
| $(WINDRES) -o RequirementsManagerPersonal.res

[rules]
all: resources fpc_all

A debian rules file for use with fpcmake is usually the same for every 
fpc project i.e.

Note this calls fpcmake automatically. A C/C++ build would call 
"configure" at the same point. I have defined the INTERFACE as an 
argument to the call to make.

#!/usr/bin/make -f
# -*- makefile -*-
# Sample debian/rules that uses debhelper.
#
# This file was originally written by Joey Hess and Craig Small.
# As a special exception, when this file is copied by dh-make into a
# dh-make output file, you may use that output file without restriction.
# This special exception was added by Craig Small in version 0.37 of 
dh-make.
#
# Modified to make a template file for a multi-binary package with separated
# build-arch and build-indep targets  by Bill Allombert 2001

# Uncomment this to turn on verbose mode.
export DH_VERBOSE=1

# This has to be exported to make some magic below work.
export DH_OPTIONS

DEB_HOST_GNU_TYPE   ?= $(shell dpkg-architecture -qDEB_HOST_GNU_TYPE)
DEB_BUILD_GNU_TYPE  ?= $(shell dpkg-architecture -qDEB_BUILD_GNU_TYPE)

export FPCDIR=/usr/lib/fpc/$(shell fpc -iV)

configure: configure-stamp
configure-stamp:
     dh_testdir
     # Add here commands to configure the package.
     fpcmake -r Makefile.fpc

     touch configure-stamp

#Architecture
build: build-arch build-indep

build-arch: build-arch-stamp
build-arch-stamp: configure-stamp

     # Add here commands to compile the arch part of the package.
     $(MAKE) INTERFACE=gtk2
     touch build-arch-stamp

build-indep: build-indep-stamp
build-indep-stamp: configure-stamp

     # Add here commands to compile the indep part of the package.
     #$(MAKE) doc
     touch build-indep-stamp

clean:
     dh_testdir
     dh_testroot
     rm -f build-arch-stamp build-indep-stamp configure-stamp

     # Add here commands to clean up after the build process.
     -$(MAKE)  clean

     dh_clean

install: install-indep install-arch
install-indep:
     dh_testdir
     dh_testroot
     dh_clean -k -i
     dh_installdirs -i

     # Add here commands to install the indep part of the package into
     # debian/<package>-doc.
     #INSTALLDOC#

     dh_install -i

install-arch:
     dh_testdir
     dh_testroot
     dh_clean -k -s
     dh_installdirs -s

     # Add here commands to install the arch part of the package into
     # debian/tmp.
     $(MAKE) INSTALL_PREFIX=$(CURDIR)/debian/tmp/usr/local install
     dh_install -s
# Must not depend on anything. This is to be called by
# binary-arch/binary-indep
# in another 'make' thread.
binary-common:
     dh_testdir
     dh_testroot
#    dh_installchangelogs ChangeLog
     dh_installdocs
     dh_installexamples
#    dh_installmenu
#    dh_installdebconf
#    dh_installlogrotate
#    dh_installemacsen
#    dh_installpam
#    dh_installmime
#    dh_python
#    dh_installinit
#    dh_installcron
#    dh_installinfo
     dh_installman
     dh_link
     dh_strip
     dh_compress
     dh_fixperms
#    dh_perl
     dh_makeshlibs
     dh_installdeb
#    dh_shlibdeps
     dh_gencontrol
     dh_md5sums
     dh_builddeb
# Build architecture independant packages using the common target.
binary-indep: build-indep install-indep
#    $(MAKE) -f debian/rules DH_OPTIONS=-i binary-common

# Build architecture dependant packages using the common target.
binary-arch: build-arch install-arch
     $(MAKE) -f debian/rules DH_OPTIONS=-s binary-common

binary: binary-arch binary-indep
.PHONY: build clean binary-indep binary-arch binary install 
install-indep install-arch



More information about the fpc-pascal mailing list