Engee documentation
Notebook

Compiling C code in Engee using GCC

Among the built-in tools of the Engee platform there are also tools for working with generated code. In this example we will learn how to compile code and call it from an Engee script.

You can learn more about executing external programs in the Engee environment from documentation.

Compilation tools in Engee

Engee executes models and programs on a Unix-compatible kernel, using libraries and tools unique to Engee. The operating system kernel is supplied with enough third-party tools to allow the creation of specific custom software and model development and testing paths.

In Engee, engineers can use many tools from the standard Unix kernel, such as:

  • gcc - C code compiler
  • g++ - C++ code compiler

Besides these, there are usually a lot of additional utilities and interpreters for different programming languages (python, perl...).

Let's perform the following checkbox to find out the version of the gcc compiler (and at the same time check its operability):

In [ ]:
;gcc -v
Using built-in specs.
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-linux-gnu/12/lto-wrapper
OFFLOAD_TARGET_NAMES=nvptx-none:amdgcn-amdhsa
OFFLOAD_TARGET_DEFAULT=1
Target: x86_64-linux-gnu
Configured with: ../src/configure -v --with-pkgversion='Debian 12.2.0-14' --with-bugurl=file:///usr/share/doc/gcc-12/README.Bugs --enable-languages=c,ada,c++,go,d,fortran,objc,obj-c++,m2 --prefix=/usr --with-gcc-major-version-only --program-suffix=-12 --program-prefix=x86_64-linux-gnu- --enable-shared --enable-linker-build-id --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --libdir=/usr/lib --enable-nls --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --with-default-libstdcxx-abi=new --enable-gnu-unique-object --disable-vtable-verify --enable-plugin --enable-default-pie --with-system-zlib --enable-libphobos-checking=release --with-target-system-zlib=auto --enable-objc-gc=auto --enable-multiarch --disable-werror --enable-cet --with-arch-32=i686 --with-abi=m64 --with-multilib-list=m32,m64,mx32 --enable-multilib --with-tune=generic --enable-offload-targets=nvptx-none=/build/gcc-12-bTRWOB/gcc-12-12.2.0/debian/tmp-nvptx/usr,amdgcn-amdhsa=/build/gcc-12-bTRWOB/gcc-12-12.2.0/debian/tmp-gcn/usr --enable-offload-defaulted --without-cuda-driver --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu
Thread model: posix
Supported LTO compression algorithms: zlib zstd
gcc version 12.2.0 (Debian 12.2.0-14) 

At the time this example was created, the Engee system allowed the gcc compilation chain to use the 12.2.0 version of , although we need this command more for debugging purposes - to make sure the compiler is installed and working.

Compiling code in Engee

Just in case, let's go to the same folder where this example is located:

In [ ]:
cd( @__DIR__ )

In this demonstration, we will run a simple programme that merely prints an informational message.

Here is the code for the programme we will compile and run:

#include <stdio.h>

int main (void)
{
  printf ("Hello, world!\n");
  return 0;
}

To get the executable from the source code, which is in the file hello.c, just run the following command:

In [ ]:
;gcc -Wall hello.c -o hello

As a result, an executable file hello is created in the working folder of this example, which can be run with arguments from the command line or from a script.

Executing compiled code

How do I get the output of this code in a script or on the command line? The first option is to execute the command in shell. This way you can get the output, but not put it in a variable.

In [ ]:
;./hello
Hello, world!

The run command works similarly, but the difference is that it creates a process whose execution can be controlled.

In [ ]:
run( `./hello` )
Hello, world!
Out[0]:
Process(`./hello`, ProcessExited(0))

If you want to put the result of a compiled file into a variable, you can use the read or readchomp commands (this variant of the command eliminates line breaks):

In [ ]:
c = readchomp( `./hello` )
Out[0]:
"Hello, world!"

Your code can accept parameters via an argument string passed as part of the command being called. This way only serialised (text) data can be passed into the code.

Another option is to compile the code with the key -shared, make a library of functions from it and pass any binary parameters into it using @ccall.

.

Finally, not the most technologically advanced but very reliable option is to exchange data via files in file storage.

Conclusion

In Engee, engineers can use both high-level tools such as data inspector, interactive scripts, and modelling canvas as well as the lowest-level operating system kernel commands.