Can Pascal units be compiled as executables?
I like my libraries to double as executables. The desired behavior is:
$ ./scriptedmain
Main: The meaning of life is: 42
$ ./test
Test: The meaning of life is: 42
How can I:
- Get
scriptedmain.p
to compile into ascriptedmain
binary? - Prevent
test.p
from running the code that's inscriptedmain.p
'sbegin
/end
section?
scriptedmain.p:
unit ScriptedMain;
interface
function MeaningOfLife () : integer;
implementation
function MeaningOfLife () : integer;
begin
MeaningOfLife := 42
end;
begin
write('Main: The meaning of life is: ');
writeln(MeaningOfLife())
end.
When I compile scriptedmain.p with fpc scriptedmain.p
, no executable is created, because Pascal detects that it's a unit. But I want it to be an executable in addition to a library.
$ ./scriptedmain
-bash: ./scriptedmain: No such file or directory
test.p:
program Test;
uses
ScriptedMain;
begin
write('Test: The meaning of life is: ');
writeln(MeaningOfLife())
end.
When I compile test.p with fpc test.p
, 开发者_高级运维the resulting executable combines the two begin
/end
declarations (NOT the desired behavior).
$ ./test
Main: The meaning of life is: 42
Test: The meaning of life is: 42
I don't know what flavour of Pascal you're using but some variants support conditional compilation with {$IFC condition} ... {$ENDC}
. You could perhaps use this in conjunction with a compile time define to include/exclude code that you need or don't need in a given version.
Thanks to Ager and Zhirov in the Free Pascal mailing list, I was able to construct a working scripted main example with minimal hacks. Also posted on RosettaCode.
Makefile:
all: scriptedmain
scriptedmain: scriptedmain.pas
fpc -dscriptedmain scriptedmain.pas
test: test.pas scriptedmain
fpc test.pas
clean:
-rm test
-rm scriptedmain
-rm *.o
-rm *.ppu
scriptedmain.pas:
{$IFDEF scriptedmain}
program ScriptedMain;
{$ELSE}
unit ScriptedMain;
interface
function MeaningOfLife () : integer;
implementation
{$ENDIF}
function MeaningOfLife () : integer;
begin
MeaningOfLife := 42
end;
{$IFDEF scriptedmain}
begin
write('Main: The meaning of life is: ');
writeln(MeaningOfLife())
{$ENDIF}
end.
test.pas:
program Test;
uses
ScriptedMain;
begin
write('Test: The meaning of life is: ');
writeln(MeaningOfLife())
end.
Example:
$ make
$ ./scriptedmain
Main: The meaning of life is: 42
$ make test
$ ./test
Test: The meaning of life is: 42
精彩评论