Compiling SNL Programs ====================== *snc*, the SNL to C Compiler ---------------------------- The SNL to C compiler *snc* compiles the state notation language into C code. The resulting file can then be compiled with a C compiler. .. _CompilerOptions: Compiler Options ^^^^^^^^^^^^^^^^ SNC options start by a plus or minus sign, followed by a single character. A plus sign turns the option on, and a minus turns the option off. ====== =============================================================== Option Description ====== =============================================================== +a Asynchronous ``pvGet``: the program continues without waiting for completion of the ``pvGet`` operation. -a Synchronous ``pvGet``: the program waits for completion. This is the default if an option is not specified. +c Wait for process variables to connect before allowing the program to begin execution. This is the default. -c Allow the program to begin execution before connections are established to all channel. +d Turn on run-time debug messages. -d Turn off run-time debug messages. This is the default. +e Use the new event flag mode. This is the default. -e Use the old event flag mode (clear flags after executing a when statement). +l Add line markers to the generated code, so that C compiler messages refer to the SNL source file. This is the default. -l Do not produce line markers. +m Include main procedure (seqMain.c) for a stand-alone program. -m Do not include seqMain.c. This is the default. +s :ref:`Safe mode`: variables are local to state set and must be communicated explicitly. Implies +r. -s Traditional (non-safe) mode. This is the default for compatibility. +r Make the generated code reentrant, thus allowing more than one instance of the program to run on an IOC. -r Generated code is not reentrant. This is the default. +w Display SNC warning messages. This is the default. -w Suppress SNC warnings. ====== =============================================================== Note that :option:`+a` and :option:`-a` are ignored for calls to :c:func:`pvGet` that explicitly specify ``SYNC`` or ``ASYNC`` in the 2nd argument. Options may also be set from within the program (somewhere between the program name/parameter and the state set definitions), see :ref:`option definition` in the :doc:`Reference`. Output File ^^^^^^^^^^^ The output file name is that of the input file with the extension replaced with *.c*. The :option:`-o` option can be used to override the output file name. Actually the rules are a little more complex than stated above: *.st* and single-character extensions are replaced with *.c*; otherwise *.c* is appended to the full file name. In all cases, the :option:`-o` compiler option overrides. Errors ^^^^^^ If *snc* detects an error, it displays a message describing the error and the location in the source file and aborts further compilation. Note, however, that *snc* does *not* contain a type checker: all it knows (and cares) about C is the syntax. This means that many errors will only be found only during the C compilation phase. The C compiler will attributed these to the corresponding location in the SNL source file, since by default *snc* generates line markers in the output that point back to the original source. This can be turned off with the :option:`-l` ("ell") compiler switch. Warnings ^^^^^^^^ In certain cases *snc* cannot ultimately decide whether the code is erroneous. In such cases it will issue a warning message and continue. The most prominent example is the use of a variable or CPP macro that has not been declared in the SNL code, but could well be defined when compiling the generated C code (for example if the declaration has been in embedded C code, which *snc* does not interpret at all). Warnings can be suppressed with the :option:`-w` compiler option. Note that since version 2.1 you can avoid these warnings by declaring such variables in SNL, see the :ref:`foreign entities` declaration. C Pre-processor --------------- Depending on the application, it might be useful to pre-process the SNL source with a C pre-processor (*cpp*). Using the C pre-processor allows you to include other SNL files, define macros, and perform conditional compilation. *snc* supports this by interpreting *cpp*-generated line markers, so that error and warning messages refer to the line numbers in the un-pre-processed SNL source. Complete Build -------------- The C code generated by *snc* from an SNL program is not a complete program, but merely a collection of procedures, data types, and variables. The generated procedures are supposed to be called by the sequencer library, which must be linked to the program. Furthermore, the generated code includes a number of header files, both from the sequencer and from EPICS base. Thus the compiler needs to have the EPICS base and sequencer include directories in its include path, and when linking it needs to link with sequencer and some EPICS base libraries. Assume you have a SNL program file named *test.st* then the steps to build are, in principle:: snc test.st cc -c test.c -o test.o ...additional compiler options... cc test.o -o test ...additional linker options... or, if SNL sources are to be pre-processed:: cc -E -x c test.st > test.i snc test.i cc -c test.c -o test.o ...additional compiler options... cc test.o -o test ...additional linker options... .. image:: Figure3-1.png Assuming that ``EPICS_BASE`` contains the path to your EPICS base installation, and ``SEQ`` to your sequencer installation, then the extra include directories are: * $SEQ/include * $EPICS_BASE/include/os/ * $EPICS_BASE/include where ```` corresponds to your operating system, see Section 4.3.6 "Specifying osclass specific definitions" of the EPICS Application Developer's Guide. Here is an excerpt: | For vxWorks-* targets is vxWorks. | For RTEMS-* targets is RTEMS. | For solaris-* targets is solaris. | For win32-* targets is WIN32. | For linux-* targets is Linux. | For hpux-* targets is hpux. | For darwin-* targets is Darwin. | For aix-* targets is AIX. What libraries to link against and where to find them depends on whether you want to create a stand-alone program (e.g. a Unix executable), or create a library for an IOC. .. todo:: explain what libraries to link and where to find them .. _Building a Stand-alone Program: Building a Stand-alone Program ------------------------------ The :option:`+m` compiler option can be used to create a stand-alone program, otherwise an iocshell is needed to start sequencer programs. Since version 2.1 the main procedure is no longer hard-coded. Instead, the code generator adds a define and an include statement :: #define PROG_NAME name_of_your_snl_program #include "seqMain.c" at the end of the generated C file, where ``name_of_your_snl_program`` is the name (identifier) whose address is to be passed to the ``seq`` function. This means you can provide your own version of main simply by placing a file named ``seqMain.c`` in your source directory (the EPICS build system usually takes care that the source directory is at the front of the C compiler's include path). A simple default ``seqMain.c`` is provided and installed into the sequencer's ``include`` directory. Note that since version 2.1 the default main starts an ioc shell; this can be disabled by providing a ``-S`` (capital 's') argument. The old ``-s`` switch is accepted for backward compatibility but does nothing. Using makeBaseApp ----------------- The easiest way to build a sequencer program is to use ``makeBaseApp.pl``, a perl script that comes with your EPICS base. Assuming you have it in your ``PATH``, create an empty directory, go there, and issue the command:: ben@sarun[1]: .../tmp/test > makeBaseApp.pl -t example Name the application(s) to be created. Names given will have "App" appended to them. Application names? test ben@sarun[1]: .../tmp/test > ls -l total 12 -rw-rw-r-- 1 ben ben 467 May 14 22:25 Makefile drwxrwxr-x 2 ben ben 4096 May 14 22:25 configure drwxrwxr-x 4 ben ben 4096 May 14 22:25 testApp In ``testApp/src/`` you will find example ``.st`` and ``.stt`` files and a ``Makefile`` that shows how to define the make variables so that everything is compiled and linked correctly. All that's left to do is add:: SNCSEQ=/path/to/your/seq/installation to ``configure/RELEASE`` (that is, the one in the ``configure`` directory that ``makeBaseApp.pl`` just created).