Sign in Join
Wiki copytemporary

InstantFPC: what changed

Revision 1 to 2. Removed lines have a minus sign; added lines have a plus sign.

OldNewLine
11# Overview
22
33This tool allows to run pascal programs as scripts under Linux, BSD, macOS and Windows. For example:
44
55``` pascal
66#!/usr/bin/env instantfpc
77begin
88 writeln('Hello fpc user');
99end.
1010```
1111
1212Save the file as hello.pas, set the permission to execute and run it:
1313
1414``` bash
1515chmod a+x hello.pas
1616./hello.pas
1717Hello fpc user
1818```
1919
2020**Notes:**
2121
2222- The first line is called *shebang* and is stripped from the source before passing it to the compiler.
2323- The line 'program hello;' is optional in FPC. Because **instantfpc** passes the **-o** option to the compiler the line is ignored, so you can omit it.
2424
2525Of course you can pass parameters to your script:
2626
2727``` pascal
2828#!/usr/bin/env instantfpc
2929var
3030 i: Integer;
3131begin
3232 for i:=0 to ParamCount do writeln(ParamStr(i));
3333end.
3434```
3535
3636Save the file as params.pas, set the permission to execute and run it:
3737
3838``` bash
3939chmod a+x params.pas
4040./params.pas A B
4141```
4242
4343It gives output like:
4444
4545 /home/username/.cache/instantfpc/params.pas
4646 A
4747 B
4848
4949# Download
5050
5151No need to download: instantfpc is part of the FPC 2.6+ sources under *utils/instantfpc* and installed by default.
5252
5353## Old versions
5454
5555For fpc 2.5.1 and above: It is in the fpc sources:
5656
5757``` bash
5858svn co http://svn.freepascal.org/svn/fpc/trunk/utils/instantfpc instantfpc
5959```
6060
6161For fpc 2.4.4 and 2.4.5:
6262
6363``` bash
6464svn co https://lazarus-ccr.svn.sourceforge.net/svnroot/lazarus-ccr/applications/instantfpc instantfpc
6565```
6666
6767# Installation
6868
6969Note: It is already installed when using fpc 2.5.1 and above. Windows users have to put the instantfpc.exe into a directory of their PATH.
7070
71711. Compile the instantfpc.lpi with Lazarus or lazbuild. Or compile directly with *fpc instantfpc.pas*.
72722. Put the executable into PATH, for example /usr/bin:
7373
7474``` bash
7575sudo cp instantfpc /usr/bin/
7676```
7777
7878# How it works
7979
8080It uses a cache directory to compile. Default is \$HOME/.cache/instantfpc. If HOME is not set it gives an error. You can override the directory by setting the environment variable INSTANTFPCCACHE. It compares the source with the stored file in cache and if it differs compiles the source, given the parameters in the shebang line (the first line of the script after \#!). After successful compile it executes the program. If compilation fails it writes the fpc output to stdout.
8181
8282# Parameters for instantfpc
8383
8484- **-h**: Print help and exit
8585- **-v**: Print current version and exit
8686- **--get-cache**: Print current cache directory and exit
8787- **--set-cache=\<directory\>**: Set cache directory
8888- **-B**: always compile even if cache is valid.
8989- **--compiler=\<path to compiler\>** use this compiler. By default fpc is searched in PATH.
9090- **--skip-run**: Do not execute the program. Useful to test if script compiles. Best combined with -B.
9191- **--**: Read the program source from standard input. Note that the compiled program has no input then.
9292- Environment variable **INSTANTFPCCACHE**: Set cache directory. The --get-cache can override this.
9393- Environment variable **INSTANTFPCOPTIONS**: Options to pass to the compiler. Passed before the command line parameters.
9494
9595# Passing parameters to the compiler
9696
9797Compiler parameters can be passed in the shebang line. Note: You can not use the 'env' command.
9898
9999``` pascal
100100#!/usr/bin/instantfpc -O1 -Ci
101101begin
102102end.
103103```
104104
105105And/Or you can put compiler options in the environment variable **INSTANTFPCOPTIONS**:
106106
107107``` bash
108108export INSTANTFPCOPTIONS="-Fu~/lazarus/components/codetools/units/x86_64-linux/"
109109```
110110
111111``` pascal
112112#!/usr/bin/instantfpc
113113uses FileProcs; // unit FileProcs is in codetools
114114begin
115115end.
116116```
117117
118118# Example
119119
120120The following example script delivers the (unintelligible!) numeronym of a string (e.g. i18n for internationalization) that may be provided either as a parameter or, if missing, be entered by the user:
121121
122122``` pascal
123123#!/usr/bin/env instantfpc
124124uses
125125 SysUtils;
126126var
127127 theWord: String;
128128begin
129129 if ParamStr(1) = '' then
130130 begin
131131 write('Please enter the word to be numeronymized: ');
132132 readln(theWord);
133133 end
134134 else
135135 theWord := ParamStr(1);
136136 if length(theWord) > 2 then
137137 writeln(theWord[1] + IntToStr(length(theWord)-2) + theWord[length(theWord)])
138138 else
139139 writeln('N/A');
140140end.
141141```
142142
143143The following shows how you don't even need to have a source file to use instantfpc:
144144
145145``` pascal
146146echo "begin writeln('hello, world!') end." | ./instantfpc --
147147```
148148
149149# Using with Lazarus
150150
151151Since Lazarus 0.9.31 the IDE ignores the shebang line. You get all the normal code features.
152152
153153Install the IDE package **instantfpclaz**, which comes with Lazarus. This will add a new project item to create instantfpc programs, for example under File / New / Project / InstantFPC program.
154154
155155## Compile in Lazarus
156156
157157How to convert a Lazarus project to compile it with **instantfpc**:
158158
159159Requires:
160160
161161- Lazarus project main source file is the instantfpc program
162162
163163Setup:
164164
165165- Go to Project Options / Compiler Options / Compilation
166166- Disable all **Call on** checks for **Compiler**
167167- Set in **Execute before** the **Command** to:
168168
169169``` bash
170170instantfpc --skip-run -B -gl "-Fu$(ProjUnitPath)" $Name($(ProjFile))
171171```
172172
173173- Enable checkboxes to scan *make* and *fpc*
174174
175175Notes:
176176
177177- The *-gl* will tell FPC to compile with debugging information
178178- The *--skip-run -B* compiles without executing
179179- See [[IDE Macros in paths and filenames|IDE Macros]]
180180
181181## Debug with Lazarus
182182
183183How to convert a Lazarus project to debug an instantfpc program:
184184
185185Requires:
186186
187187- The above **Compile in Lazarus**
188188
189189Setup:
190190
191191- Go to Run / Run parameters
192192- Set **Local / Host application** to
193193
194-`$(InstantFPCCache)/$NameOnly($(ProjFile))`
194+```text
195+$(InstantFPCCache)/$NameOnly($(ProjFile))
196+```
195197
196198- Set **Working Directory** to
197199
198-`$(ProjPath)`
200+```text
201+$(ProjPath)
202+```
199203
200204## Use as Pascal script without an .lpi file
201205
202206Open the script in the source editor. Then click in menu **Run / Configure Build and Run**.
203207
204208- Page **Options**:
205209 - **On build project execute the Build File command instead**: Enable this if you like to compile the script on Ctrl+F9.
206210 - **On run project execute the Run File command instead**: Enable this if you like to execute the script on F9. Note: **instantfpc** automatically compiles if the file has changed.
207211- Page **Build**:
208212 - *'Build Command*: /path/to/instantfpc --skip-run -B -gl \$(EdFile)
209213 - **Scan for FPC messages**: enable
210214- Page **Run**:
211215 - *'Build Command*: /path/to/instantfpc -gl \$(EdFile)
212216
213217Click Ok. You should see something like this:
214218
215219``` pascal
216220#!/usr/bin/instantfpc
217221{%BuildCommand /path/to/instantfpc --skip-run -B -gl $(EdFile)}
218222{%RunCommand /path/to/instantfpc -gl $(EdFile)}
219223begin
220224end.
221225```
222226
223227# Using in Apache
224228
225229This is how to use instantfpc in Apache Webserver. Instantfpc needs the cache directory, which must be writable by the account of Apache. Let's say Apache is running under user www-data, group www-data (Redhat, Fedora: apache.apache, see apache config for User and Group).
226230
227231``` bash
228232mkdir /var/apacheinstantfpc
229233chown www-data.www-data /var/apacheinstantfpc
230234```
231235
232236Pass an environment variable to cgi scripts by adding the following line to the Apache configs:
233237
234-`SetEnv INSTANTFPCCACHE /var/apacheinstantfpc`
238+``` pascal
239+SetEnv INSTANTFPCCACHE /var/apacheinstantfpc
240+```
235241
236242**Security advice:** Although the apache user must have full access to the cache directory, make sure the directory is not available from outside (e.g. do not put it under /var/www). It may contain old scripts. And like any other type of scripts: Check all input for attacks.
237243
238244**Optimization note:** The instantfpc cache uses one file per script name. **Do not use the same script name twice**, otherwise it will be compiled many times. You can create multiple cache directories. Each \<directory\> and \<virtualhost\> section can define their own environment variables, and therefore you can setup one cache directory for each.
239245
240246## Apache example showing env
241247
242248Configure a directory to execute cgi scripts. For example:
243249
244-` ScriptAlias /cgi-bin/ /usr/lib/cgi-bin/`\
245-` <Directory "/usr/lib/cgi-bin">`\
246-`   AllowOverride None`\
247-`   Options +ExecCGI -MultiViews +SymLinksIfOwnerMatch`\
248-`   Order allow,deny`\
249-`   Allow from all`\
250-`   SetEnv INSTANTFPCCACHE /var/apacheinstantfpc`\
251-`   # You can put fpc options into /etc/fpc.cfg or here:`\
252-`   #SetEnv INSTANTFPCOPTIONS -Fu/path/to/somevar/ppufiles`\
253-`   # If this is root directory, you might have to set:`\
254-`   #Require all granted`\
255-` </Directory>`
250+``` pascal
251+ ScriptAlias /cgi-bin/ /usr/lib/cgi-bin/
252+ <Directory "/usr/lib/cgi-bin">
253+ AllowOverride None
254+ Options +ExecCGI -MultiViews +SymLinksIfOwnerMatch
255+ Order allow,deny
256+ Allow from all
257+ SetEnv INSTANTFPCCACHE /var/apacheinstantfpc
258+ # You can put fpc options into /etc/fpc.cfg or here:
259+ #SetEnv INSTANTFPCOPTIONS -Fu/path/to/somevar/ppufiles
260+ # If this is root directory, you might have to set:
261+ #Require all granted
262+ </Directory>
263+```
256264
257265If your apache has not yet enabled the **cgi** module:
258266
259-`a2enmod cgi`
267+```text
268+a2enmod cgi
269+```
260270
261271Put the following script into /usr/lib/cgi-bin/showenv.pas:
262272
263273``` pascal
264274#!/usr/bin/instantfpc
265275{$mode objfpc}{$H+}
266276uses  SysUtils;
267277var  i: Integer;
268278begin
269279  writeln('Content-type: text/html');
270280  writeln;
271281  writeln('<HTML><BODY>');
272282  for i:=0 to Paramcount do
273283    writeln('Param ',i,' ',ParamStr(i),'<br>');
274284  for i:=1 to GetEnvironmentVariableCount do
275285    writeln('Env ',GetEnvironmentString(i),'<br>');
276286  writeln('</BODY></HTML>');
277287end.
278288```
279289
280290# Bugs / ToDos / Limitations
281291
282292- Changes to the compiler or installed units are not checked. If you install a new compiler you should clean the cache (e.g. delete the directory ~/.cache/instantfpc).
283293- Under Windows only the first parameter is passed to the script.
284294- With instantfpc versions less than 1.3 you can not compile in parallel. The compiler creates hidden files like 'link.res' while compiling. Since 1.3 instantfpc uses temporary directories for compiling.
285295- The cache uses the file name without the path. So you cannot execute two scripts in parallel of the same name. Every run time the script will be compiled.
286296
287297# Alternatives
288298
289299The following trick works using the *bash* shell. Put the program into a file *fpc_script.sh*:
290300
291301``` pascal
292302// 2>/dev/null; fpc fpc_script.pp &> build.log && exec ./fpc_script "$@" || cat build.log; exit
293303begin
294304 writeln(' no one knows how this is a trick or offers any advantage at all ');
295305end.
296306```
297307
298308---
299309*From the Free Pascal wiki, page "InstantFPC", as it stood on 2022-03-18 after a change by Kai Burghardt, out of the wiki's dump of 2024-05-26. Copyright stays with the author who wrote it, according to the old wiki's [[Licensing]] page. If you have concerns about this material, [message the admin](/wiki-contact).*

Back to history