Back to Contents


Compiling Programs

Summary:

See also: Tools, Form Files, Message Files, Localized Strings.


Compiling Source Code

Source code modules (4gl) must be compiled to p-code modules (42m) with the fglcomp tool. Compiled p-code modules are portable; you can compile a module on a Windows platform and install it on a Unix production machine.

The following lines show a compilation in a Unix shell session:

$ cat xx.4gl
main
  display "hello"
end main

$ fglcomp xx.4gl

$ ls -s xx.42m
   4 xx.42m

If an error occurs, the compiler writes an error file with the .err extension.

$ cat xx.4gl
main
  let x = "hello"
end main

$ fglcomp xx.4gl
Compilation was not successful.  Errors found: 1.
 The file xx.4gl has been written.

$ cat xx.err
main
  let x = "hello"
| The symbol 'x' does not represent a defined variable.
| See error number -4369. 
end main

With the -M option, you can force the compiler to display an error message instead of generating a .err error file:

$ fglcomp xx.4gl
xx.4gl:2:8 error:(-4369) The symbol 'x' does not represent a defined variable.

By default, the compiler does not raise any warnings. You can turn on warnings with the -W option:

$ cat xx.4gl
main
  database test1
  select count(*) from x, outer(y) where x.k = y.k
end main

$ fglcomp -W stdsql xx.4gl
xx.4gl:3: warning: SQL statement or language instruction with specific SQL syntax.

When a warning is raised, you can use the -W error option to force the compiler to stop as if an error was found.

For more details about warning options, see the fglcomp tool.


Creating Libraries

Compiled 42m modules can be grouped in a library file using the 42x extension.

Library linking is done with the fglrun tool by using the -l option. You can also use the fgllink tool.

The following lines show a link procedure to create a library in a Unix shell session:

$ fglcomp fileutils.4gl
$ fglcomp userutils.4gl
$ fgllink -o libutils.42x fileutils.42m userutils.42m

When you create a library, all functions of the 42m modules used in the link command are registered in the 42x file.

Warning: The 42x library file does not contain the 42m files. When deploying your application, you must provide all p-code modules as well as 42f, 42r and 42x files.

The 42x libraries are typically used to link the final 42r programs:

$ fglcomp mymain.4gl
$ fgllink -o myprog.42r mymain.42m libutils.42x

Note that 42r programs must be re-linked if the content of 42x libraries have changed. In the above example, if a function of the userutils.4gl source file was removed, you must recompile userutils.4gl, re-link the libutils42x library and re-link the myprog.42r program.

If you are using C Extensions, you may need to use the -e option to specify the list of extension modules if the IMPORT keyword is not used:

$ fgllink -e extlib,extlib2,extlib3 -o libutils.42x fileutils.42m userutils.42m


Linking Programs

Genero programs are created by linking several 42m modules and/or 42x libraries together, to produce a file with the 42r extension.

Program linking is done with the fglrun tool by using the -l option. You can also use the fgllink tool.

Warning: The 42r program file does not contain the 42m files. When deploying your application, you must provide all p-code modules as well as 42f, 42r and 42x files.

The following lines show a link procedure to create a library in a Unix shell session:

$ fglcomp main.4gl
$ fglcomp store.4gl
$ fgllink -o stores.42r main.42m store.42m

By default, if you do not specify an absolute path for a file, the linker searches for 42m modules and 42x libraries in the current directory.

Additionally, you can specify a search path with the FGLLDPATH environment variable:

$ FGLLDPATH=/usr/dev/lib/maths:/usr/dev/lib/utils
$ export FGLLDPATH
$ ls /usr/dev/lib/maths
mathlib1.42x
mathlib2.42x
mathmodule11.42m
mathmodule12.42m
mathmodule22.42m
$ ls /usr/dev/lib/utils
fileutils.42m
userutils.42m
dbutils.42m
$ fgllink -o myprog.42r mymodule.42m mathlib1.42x fileutils.42m

In this example the linker will find the specified files in the /usr/dev/lib/maths and /usr/dev/lib/utils directories defined in FGLLDPATH.

If you are using C Extensions, you may need to use the -e option to specify the list of extension modules if the IMPORT keyword is not used:

$ fgllink -e extlib,extlib2,extlib3 -o stores.42r main.42m store.42m

Warning: If none of the functions of a module are used by a program, the complete module is excluded when the program is linked. This may cause undefined function errors at runtime, such as when a function is only used in a dynamic call (an initialization function, for example.) 

The following case illustrates this behavior:

$ cat x1.4gl
function fx1A()
end function
function fx2A()
end function

$ cat x2.4gl
function fx2A()
end function
function fx2B()
end function

$ cat prog.4gl
main
  call fx1A()
end main

$ fglcomp x1.4gl
$ fglcomp x2.4gl
$ fglcomp prog.4gl

$ fgllink -o lib.42x x1.42m x2.42m

$ fgllink -o prog.42r prog.42m lib.42x

Here, module x1.42m will be included in the program, but module x2.42m will not. At runtime, any dynamic call to fx2A() or fx2B() will fail.

The link process searches recursively for the functions used by the program. For example, if the MAIN block calls function FA in module MA, and FA calls FB in module MB, all functions from module MA and MB will be included in the 42r program definition.


Using Makefiles

Most UNIX platforms provide the make utility program to compile projects. The make program is an interpreter of Makefiles. These files contain directives to compile and link programs and/or generate other kind of files.

When developing on Microsoft Windows platforms, you may use the NMAKE utility provided with Visual C++, however this tool does not have the same behavior as the Unix make program. To have a compatible make on Windows, you can install a GNU make or third party Unix tools such as Cygwin.

For more details about the make utility, see the platform-specific documentation.

The follow example shows a typical Makefile for Genero applications:

#------------------------------------------------------
# Generic makefile rules to be included in Makefiles

.SUFFIXES: .42s .42f .42m .42r .str .per .4gl .msg .hlp

FGLFORM=fglform -M
FGLCOMP=fglcomp -M
FGLLINK=fglrun -l
FGLMKMSG=fglmkmsg
FGLMKSTR=fglmkstr
FGLLIB=$$FGLDIR/lib/libfgl4js.42x

all::

.msg.hlp:
	$(FGLMKMSG) $*.msg $*.hlp

.str.42s:
	$(FGLMKSTR) $*.str $*.42s

.per.42f:
	$(FGLFORM) $*.per

.4gl.42m:
	$(FGLCOMP) $*.4gl

clean::
	rm -f *.hlp *.42? *.out


#-----------------------------
# Makefile example

include Makeincl

FORMS=\
 customers.42f\
 orderlist.42f\
 itemlist.42f

MODULES=\
 customerInput.42m\
 zoomOrders.42m\
 zoomItems.42m

customer.42x: $(MODULES)
	$(FGLLINK) -o customer.42x $(MODULES)
all:: customer.42x $(FORMS)

Getting Build Information

The compiler version used to build the 42m modules must be compatible to the runtime system used to execute the programs. The fglcomp compiler writes version information in the generated 42m files. This can be useful on site, if you need to check the version of the compiler that was used to build the 42m nodules.

To extract build information, run fglrun with the -b option:

$ fglrun -b mymodule.42m
2.11.01-1161.12 /home/devel/stores/mymodule.4gl 15

The output shows the following fields:

  1. The product version and build number (2.11.01-1161.12).
  2. The full path of the source file (/home/devel/stores/mymodule.4gl).
  3. The internal identifier of the pcode version. 

Tip: Since version 2.11, fglrun -b can read the header of pcode modules compiled with older versions of fglcomp and display version information for such old modules. If fglrun cannot recognize a pcode module, it returns with an execution status is different from zero.

When reading build information of a 42x or 42r file, fglrun scans all modules used to build the library or program. You will see different versions in the first column if the modules where compiled with different versions of fglcomp. Note however that it's not recommended to end up with mixed versions on a production site:

$ fglrun -b myprogram.42r
2.11.01-1161.12 /home/devel/stores/mymodule1.4gl 15
2.10.02-1148.36 /home/devel/stores/mymodule2.4gl 15
2.11.01-1161.12 /home/devel/stores/mymodule3.4gl 15

Warning: Before release 2.10, the 42m p-code files were also stamped with a compilation timestamp. This timestamp information is no longer written to p-code files, allowing 42m file comparison, checksum creation, or storage of 42m file in versioning tools; the same p-code data is now generated after successive compilations.

To check the version of the runtime system, run fglrun with the -V option.