Menu

Compiling a sample project

Shmuel Safonov

TMC Tutorial: Compiling a simple project

The example creates a static code that is called from a sample caller function.

The project source files

The original project has the following file structure:

  1. /App_caller/ dirctory contains the example caller function:
    Extiny_caller.c - sample caller function

  2. /MatSRC/ directory contains the source m-files
    myeq.m
    solvemyeq.m
    Optionally, the source files may be placed in multiple directories.

  3. /MexSRC/ directory contains the source C-files that implements MEX-functions.
    ExMex1.c : contains implementation of ExMex1 MEX function.

  4. /OutC/ output directory for C-files

  5. /OutL/ output directory for lsp-files (optional feature: files that represent lisp-presentation of the original code for debugging and code analysis)

  6. /OutO/ output directory for object files

  7. /Stubs/ source directory with root m-function and some additional definition files:
    external_fnc.sym.dat : symbol file for external functions (like MEX) called from m-code.
    External_func.h : C-prototypes for the external functions
    TestO.m : root function.

Symbol file for external functions

The file is needed for conveter to define the functions signature i.e. the function name and the number of its input and output arguments. If a referenced symbol is not found neither in any given source directories as a function definition nor in the symbol file, the symbol is considered as a variable. In our example the symbol file contains the following record:

  ExMex1,2,1,x;

This means that symbol ExMex1 is a function with 2 inputs and 1 output. (-1 means variable number of parameters). Simbol "x" is reserved for a MEX-file definition.

The in-build functions signature is defined in buildin_fnc.sym.dat file that is contained in runtime include directory. The set of in-build functions can be extended by writing user C-implementation and including the function signature definition to this file.

Compiler pass 1: building the actual source files list and common project symbol file

The pass 1 is needed to buid the symbol file that contains the signature definitions of all the functions that referenced in the project. The compiler parses the referenced files starting from the root file, using the project specific external_fnc.sym.dat file and the library buildin_fnc.sym.dat file and generates the output common project symbol file.

Before calling the compiler external_fnc.sym.dat file should be copied to /OutL/ output directory:

  type .\Stubs\external_fnc.sym.dat > .\OutL\external_fnc.sym.dat (Windows)

or

  cp ./Stubs/external_fnc.sym.dat  ./OutL/external_fnc.sym.dat (Linux)

The command line looks like:

tmcco  -L -w TestO  -r ./Stubs/TestO.m -h ..\..\include/ -l ./OutL/testO.lsp.txt -@ woo1_rsp.txt  -o ./OutL/ >>out.txt

The switch meanings are:
-L : means that pass 1 is perfomed to generate the symbol file

-w TestO : defines the workspace name that is attached for output files

 -r ./Stubs/TestO.m : defines the file with root function definition.

 -h  ..\..\include/ : define the directory for the library buildin_fnc.sym.dat file with build-in functions definitions

 -l ./OutL/testO.lsp.txt : define the file for the compilation listing information
 -o ./OutL/ : define the output directory definition.

  -@ woo1_rsp.txt : define the file with additional switch commands. This file may contain the list of directories that contains the source m-files: 
  -i ./MatSRC/  : search directory for source m-files. Multiple -i<path> switches may be given.

Compiler pass 2: generating the C-output

The pass 2 generates C-output files.

Before calling the compiler the project symbol file TestO.sym.dat file should be copied to /Stubs/ source directory:

   copy     .\OutL\TestO.sym.dat .\Stubs\ (Windows)

or

   cp   ./OutL/TestO.sym.dat ./Stubs/ (Linux)

The command line looks like:

tmcco -c -C   -d -q  -g2  -w TestO  -r .\Stubs\TestO.m -l .\OutC\testO2.err.log -@ woo2_rsp2.txt  -o .\OutC\ >outC2.txt

Some new switch are used here:

-g2 : means that pass 2 is perfomed to generate the C-code using the common project symbol file

-c: generate C-code.

-C: Include m-code as comments in generated C-code. Needs -s switches that define the source files search directories.

-d: Include special debugging information (optional feature)

-q: Quite mode, minimal display

-@ woo2_rsp2.txt define the file with additional switch commands. This file may contain the list of directories that contains the source m-files (as in pass 1):
-i ./MatSRC/ : search directory for source m-files. Multiple -i switches may be given.
and also list of directories that contains the source m-files for source comments inclusion:
-s ./MatSRC/
-s ./Stubs/

### Generated C-output ###
The generated C-code is contained in /OutC/ directory (as defined by switch -o /OutC/ ):
myeq.c - generated from myeq.m
solvemyeq.c- generated from solvemyeq.m
stdtmc.h - contains C-functions prototypes for all generated functions
TestO._init_hash_data.c - support for internal global data
TestO.c - generated from TestO.m
TestO.globals.c - support for global variables and some internals
TestO.globals.h - support for global variables and some internals (prototypes)
TestO.hash_init.dat - support data file (for structures field names and strings support)
TestO.inputfilelist.txt - actual input files list
TestO.srcfilelist.txt - source file list (for source comments)
testO2.err.log - compilation listing file

Files with internals support should be discussed in the following tutorials. They are important for understanding of structure fields and string implementation that is based on hash-tables. Such hash table is defined in TestO.hash_init.dat file.

Calling generated C-code and TMC runtime initialisation

The calling sequence should be the following:

  1. tmcInitLib(&Init_funcs_table); // TMC runtime initialisation

  2. create actual parameters to pass to TestO() function

  3. call TestO() function

  4. copy results from output parameters of TestO()

  5. free the created actual parameters

  6. tmcFreeLib(); // TMC runtime uninitialisation

This routine uses data prototypes from tmc_lib.h or tmc.h TMC library file. It calls TMC library functions tmcInitLib() and tmcFreeLib(). The initialisation function accepts the address of Init_funcs_table variable that is a constant variable defined in the project file TestO._init_hash_data.c. The function TestO() is the root function.

Final C-code compilation and linking

The final project building process from the generated source depends on the compiler and the operation system and should be described in details in the next section.

Compiling C-code

When the C-code is generated, it is the time to compile it and link
with run-time library. The list of C-files for the compilation (OutC_listC.txt) can be created
automatically.

At Linux:

find ./OutC -maxdepth 1 -type f -iname *.c > OutC_listC.txt

At Windows:

dir .\OutC*.c /B > OutC_listC2.txt

Then the compiler is launched. For GNU GCC compiler the following switches are set:

MYOPT =-Wformat=0 -ftree-vectorize -unroll-loops --param max-unroll-times=4 -fverbose-asm -Ofast -O3 -D TMCMEX_DLL -D SIMOLIB_EXPORTS -D TMC_SITARA -D TMC_EMBEDDED
MYOPT2 = -DTMC_NO_SEH=";" -DTRY=";" -DCATCH=";" -DENDCATCH=";" -DFINALLY=";" -DENDFINALLY=";" -DBLG_GCC -DEXTINY0_EXPORTS

At Linux the command in makefile looks like:

gcc $(MYOPT) $(MYOPT2) -D UNICODE -I$(TMCINC)/ -I./Stubs/ @OutC_listC.txt ./MexSRC/ExMex1.c ./App_caller/Extiny_caller.c $(TMCLIB)/tmcruntime.a -lm -o Ex1.out

At Windows the command in bat file looks like:

gcc %MYOPT% %MYOPT2% -D UNICODE -I../../../include/ -I./../Stubs/ @..\OutC_listC2.txt ../MexSRC/ExMex1.c ../App_caller/Extiny_caller.c ./../../../lib/%TMCLIBL% -lm -o ../%EXEDIR%/Ex1_%OUT_EX%_%TMCLIBLINK%.exe

where
TMCLIBL defines the name of runtime library, that may be shared DLL or static lib.

The Windows application may be compiled also using Microsoft Visual C(TM) environment.
In this compilation the symbols TMC_NO_SEH,TRY,CATCH, ENDCATCH, FINALLY, ENDFINALLY must be
undefined.

For Android OS platform symbol TMC_ANDROID must be defined.

Exception handling and try-catch-end blocks support.

The try-catch-end syntax in TMC compiler is implemented using Microsoft-specific
Structured Exception Handling (SEH) mechanism. SEH is implemented by MSVC, Borland compilers
but unfortunately is not implemented by GNU GCC. Thus for GNU GCC symbols TMC_NO_SEH,TRY,CATCH, ENDCATCH, FINALLY, ENDFINALLY
should be defined as described above. During the execution the catch-end block will be ignored
and if an error occured (raised by runtime) the execution will be terminated.


Related

Wiki: Home

Want the latest updates on software, tech news, and AI?
Get latest updates about software, tech news, and AI from SourceForge directly in your inbox once a month.