If the format directive is completely omitted then suitable defaults for all values are provided, largely based on the compiler being run. For example, assuming -c, running the console version (p.exe) creates a console executable whereas running pw.exe creates a gui executable. Likewise running a 32-bit version of phix by default creates a 32-bit executable whereas a 64-bit version creates a 64-bit executable. And of course running a Windows version of phix on a Windows machine by default creates a Windows PE format executable, whereas a Linux version on a Linux machine creates a Linux ELF format executable (but running a PE format phix under Wine will create a PE format output suitable for running under Wine). The format directive allows you to override that default behaviour and has the following formal syntax:
format "redirect.file"| (PE32|PE64) [GUI|console] [3.10|4.0|5.0] [DLL]) [icons] [version] [manifest]| (ELF32|ELF64) [SO]As a simple example, you could just use ("-c" and) "format PE32".
When DLL/SO is specified, the compiler collects export statements in the top-level file and uses that list (of symtab entry indexes) to construct the required export section. Note that constants (and enums) cannot be exported, and routines are subject to the same restrictions as call_back routines. You should also note that DLL/SO mandates the use of "-c -norun" on the command line, there is no interpret (or trace) mode, and further that "-c -nodiag -norun" (or the shorter/easier but equivalent "-dll") is recommended once things have been adequately tested.
At the time of writing, SO are in progress/not yet supported. [DEV]
Note that, as a relatively new addition, the format directive is subject to frequent change. One possible (but untried) use for the format directive might be for a library to assert that the target architecture is properly supported/tested, eg arwen.ew could begin with the line "format PE32|PE64" (literally including the "|") to assert that it does not run on ELF, or another component could have all four currently supported targets, as a safety measure against ARM or some other target being added in the future. (Note that arwen.ew is currently 32 bit only and I have no plans to attempt a 64 bit version of it.) Consequently this section is likely to be updated as/when things get implemented/fixed.
The format directive should be at the start of the main file, before any constant, variable, or routine definitions, or any executable code or include statements, but can be after namespace and with/without directives. To get technical for a moment, the real issue is that any #ilASM statements, as very commonly occuring in the builtins directory, are, before a format directive, rather likely to target the wrong architecture. Some special handling has been added to pmain.e (see Z_format) to allow trace() and profile() to precede a format statement, however it may not work in all cases. Likewise you may also get away with a few simple constants, etc. Otherwise once any "prohibited code" has been processed the compiler simply issues an "invalid" error against the word "format".
At most two redirects are permitted. For example, p.exw has the directive 'format "p.fmt"'; p.fmt is intended to contain one of 'format "pe32.fmt"',
As an example, the file pe32.fmt distributed with phix contains:
format PE32 4.0 icons {"ok.ico",{0,1}} version { "FileDescription","Phix Programming Language", "LegalCopyright","Pete Lomax", "FileVersion","0.6.3", "ProductName","Phix Programming Language", "ProductVersion","0.6.3", "OriginalFilename","pw.exe" } manifest ` <?xml version="1.0" encoding="UTF-8" standalone="yes"?> <assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0"> <assemblyIdentity name="x.x.x" processorArchitecture="x86" version="5.1.0.0" type="win32"/> <description>no</description> <dependency> <dependentAssembly> <assemblyIdentity type="win32" name="Microsoft.Windows.Common-Controls" version="6.0.0.0" processorArchitecture="x86" publicKeyToken="6595b64144ccf1df" language="*" /> </dependentAssembly> </dependency> </assembly>`Unusually, perhaps, p.exw does not specify either GUI or console since it always creates p.exe and pw.exe anyway. Subsystem version 4.0 is the default for 32-bit executables and 5.0 the default for 64-bit files (for PE format files, that is). Note that (the older) with/without console/gui affect exactly the same settings (variables OptConsole and subvers, which are defined in pglobals.e).
The values shown above for icons and manifest coincide with the defaults (see pglobals.e). If the version details (which must be an even number of strings) are omitted, then no version information is output in the resulting executable file. There is no way to dynamically set any values during compilation, though it should be trivial to (programmatically) create such a file beforehand.
I believe (but I’m not an expert) that a processorArchitecture of "*" would be best for PE32/PE64 compatibility. Since I encountered a problem trying to compile "x86" to PE64, I expect others will probably do so as well, and hence have implemented the following solution:
Any "x86" in the manifest are automatically replaced with "amd64" (including the quotes) when PE64 is in force, as it seems that doing so is necessary to properly initialise the common controls (without manually invoking InitCommonControlsEx). This was originally only intended to apply to the default rather than any explicit replacement, but since it is an easy fix to a possibly fairly common mistake that would otherwise completely hose an application, it has been deliberately left like that (applying across the board to everything). There is, however, no equivalent substitution of "amd64" with "x86" when PE32 is in force.
Lastly, when using a 32-bit compiler to create a 64-bit executable, be aware that the integer range is redefined as +/-#FFFF_FFFF rather than -#4000_0000_0000_0000 to #3FFF_FFFF_FFFF_FFFF. See ptok.e/