Directives
Every directive starts with @. Build directives describe the build inside the source itself; conditional directives are PaskalCPP's own conditional compilation.
The reference lists every directive with the values it takes, read from the compiler's own tables.
Build directives
There are 25 build directives, written in exact case and each ended with ;:
@optimize @subsystem @target @addverinfo @unitTestMode @vimajor @viminor @vipatch @viproductname @videscription @vifilename @vicompanyname @vicopyright @exeicon @copydll @linklibrary @addlibrarypath @addmodulepath @addincludepath @addsourcefile @cppdefine @cppundef @breakpoint @message @outputpath
An unknown directive is PR0005; a value of the wrong shape (a string where a word belongs, a number where a string belongs) is PR0006.
Where they stand
- Build directives stand only in the directive prologue, right after
module ...;and before the import clause; elsewhere they are PR0008. @breakpointand@messageare also statements and may stand in bodies;@breakpointin the prologue has no effect and is the warning SM0109.- A single-valued directive given twice in one module is SM0102. The list directives (
@copydll@linklibrary@addlibrarypath@addmodulepath@addincludepath@addsourcefile@cppdefine@cppundef) accumulate. - In an imported unit the main-module-only directives (
@optimize@subsystem@target@addverinfo@unitTestMode@vi*@exeicon@addmodulepath@outputpath) are PR0023; the list directives add to the one build, and@breakpointand@messageare allowed.
Values
@optimizetakesdebug,safe,fastorsmall;@subsystemconsoleorgui;@addverinfoand@unitTestModeonoroff. Exact case; any other value is SM0100, naming the accepted ones. What each level does is on Optimize levels.- A retired
@optimizename (release_safe,release_fast,release_small) is SM0100 naming its new one:'release_fast' is no longer a value of @optimize: write 'fast'. @vimajor,@viminorand@vipatchtake 0..65535; outside is SM0101.- Version info is stamped only with
@addverinfo on; a@vi*without it is the warning SM0104. - A setting the module cannot take is the warning SM0103 and is not applied:
@exeiconon a non-exe or a non-Windows target,@addverinfo onon a lib or a non-Windows target,@subsystem guion a non-exe or a non-Windows target.
Paths and libraries
- A path directive's value is resolved once;
$P:is the folder pcpp.exe is in. A path that cannot be resolved is PR0022. - A path directive must name something that exists:
@exeiconand@copydlla file (else SM0105),@addlibrarypath,@addincludepathand@addmodulepatha directory (else SM0106). @linklibrary "m";names a library (m,user32), found by the system linker; a file name or a path is PR0055. A library the linker cannot find is reported at the@linklibrarythat names it.@copydllputs a DLL beside the built binary before the build.@addsourcefileadds a C, C++, assembly or LLVM IR file to the build, chosen by its exact-case extension:.c;.C .cc .cp .cpp .CPP .cxx .CXX .c++ .C++;.S .s;.ll. Another name (a header) is SM0114, a missing file SM0105.@outputpath "<path>";sets the build's output folder (main module only, at most once);pcpp -owins over it. With neither, it isoutputunder the working folder.
C preprocessor macros
@cppdefine "NAME";, @cppdefine "NAME" "VALUE"; and @cppundef "NAME"; define and undefine a C macro for every translation unit of the build: the generated C++, the runtime and every @addsourcefile file.
- NAME must be a C macro name (else SM0115);
PCPP_names are reserved (SM0116). One name defined with two values, or defined and undefined, anywhere in the program is SM0118 at the later one. - PaskalCPP's
@definesymbols and C macros never see each other:#ifdefdoes not see a@define, and@ifdefdoes not see a@cppdefine.
Target
@target takes an LLVM triple as a string. The official targets are x86_64-windows-gnu (the default) and x86_64-linux-gnu; the four-part spellings x86_64-pc-windows-gnu and x86_64-unknown-linux-gnu are accepted.
@targetstands in the prologue, outside and before any conditional directive, at most once: CD0005 out of the prologue, CD0006 inside a branch, CD0007 after a conditional, CD0008 twice; not a plain string CD0009, malformed CD0010, another triple CD0011.- Only the main module's target applies: an imported unit with a different
@targetis CD0012.pcpp -twins over every@target; with--defaults(the editor passes it) it only stands in for a missing one.
Messages
@message hint|warn|error|fatal "text"; reports the text at compile time as SM0108 with that severity, from the prologue or a body; an error or fatal message fails the build. A misspelt severity is PR0007, a missing text PR0006.
Conditional directives
@define X, @undef X, @ifdef X, @ifndef X, @elseif X, @else and @endif are PaskalCPP's own. They take no ;, may stand anywhere (the prologue, module level, inside a statement) and nest; @elseif X means "else, if X is defined".
module exe directives_target;
@define VERBOSE
begin
@ifdef TARGET_WINDOWS
println("built for Windows");
@elseif TARGET_LINUX
println("built for Linux");
@else
println("built for something else");
@endif
@ifdef VERBOSE
@ifdef TARGET_64BIT
println("64-bit pointers");
@endif
@endif
end.
built for Windows
64-bit pointers
[Heap] Allocs: 0, Frees: 0, Leaked: 0
built for Linux
64-bit pointers
[Heap] Allocs: 0, Frees: 0, Leaked: 0
- A missing symbol is CD0001,
@endifwith nothing open CD0002, a second@elseCD0003, an@ifdefnever closed CD0004. - Each file has these symbols defined:
PASKALCPP;BUILD_EXE,BUILD_DLL,BUILD_LIBorBUILD_UNITfrom the file's own kind;TARGET_<ARCH>(TARGET_X86_64),TARGET_<OS>(TARGET_WINDOWS,TARGET_LINUX),TARGET_<ABI>(TARGET_GNU), the whole triple (TARGET_X86_64_WINDOWS_GNU,TARGET_X86_64_LINUX_GNU), andTARGET_64BIT.
C preprocessor lines (#...) are not evaluated by PaskalCPP; they go to clang as written.