User avatar
HermannSW
Posts: 4658
Joined: Fri Jul 22, 2016 9:09 pm
Location: Eberbach, Germany
Contact: Website Twitter YouTube

Adding (tcc) "-run" option to gcc and g++

Mon Sep 20, 2021 12:03 am

I always wanted to have tcc compiler's "-run" option for gcc and g++. With my new "memrun" repo execution of ELF binary from RAM became possible, and gcc/g++ can send ELF binary there. I added "-run" option with tcc's syntax to gcc and g++:

Code: Select all

pi@raspberrypi400:~/memrun/C $ tcc | grep \-run
Usage: grep [OPTION]... PATTERNS [FILE]...
Try 'grep --help' for more information.
pi@raspberrypi400:~/memrun/C $ 

Find the details (and code) in new section "Adding (tcc) "-run" option to gcc and g++" of memrun repo:
https://github.com/Hermann-SW/memrun/tr ... -gcc-and-g

Normal g++ errors out if "-run" option is present:

Code: Select all

pi@raspberrypi400:~/memrun/C $ g++ -run demo.cpp
g++: error: unrecognized command line option \u2018-run\u2019
pi@raspberrypi400:~/memrun/C $ 

Prepend memrun's bin directory to $PATH, now gcc and g++ know how to deal with "-run" option:

Code: Select all

pi@raspberrypi400:~/memrun/C $ export PATH=~/memrun/C/bin:$PATH
pi@raspberrypi400:~/memrun/C $

Here you can see that it works -- as said g++ ELF binary gets store in RAM and executed from there, not stored in filesystem:

Code: Select all

pi@raspberrypi400:~/memrun/C $ uname -a | g++ -O3 -Wall -run demo.cpp 42
bar 42
Linux raspberrypi400 5.10.60-v7l+ #1449 SMP Wed Aug 25 15:00:44 BST 2021 armv7l GNU/Linux
pi@raspberrypi400:~/memrun/C $ 

This is demo.cpp:

Code: Select all

/**
*/
#include <iostream>

int main(int argc, char *argv[])
{
  printf("bar %s\n", argc>1 ? argv[1] : "(undef)");

  for(char c; std::cin.read(&c, 1); )  { std::cout << c; }

  return 0;
}
https://github.com/Hermann-SW/memrun
https://stamm-wilbrandt.de/2wheel_balancing_robot
https://stamm-wilbrandt.de/en#raspcatbot
https://github.com/Hermann-SW/Raspberry_v1_camera_global_external_shutter
https://stamm-wilbrandt.de/en/Raspberry_camera.html

User avatar
jahboater
Posts: 7399
Joined: Wed Feb 04, 2015 6:38 pm
Location: Wonderful West Dorset

Re: Adding (tcc) "-run" option to gcc and g++

Mon Sep 20, 2021 12:26 am

I have always done this sort of thing with a simple shell function in ~/.bashrc

Code: Select all

run() { gcc $1 && ./a.out; }

Code: Select all

$ run hello.c
Hello world
Of course it doesn't try and run the program if the compilation fails.

User avatar
HermannSW
Posts: 4658
Joined: Fri Jul 22, 2016 9:09 pm
Location: Eberbach, Germany
Contact: Website Twitter YouTube

Re: Adding (tcc) "-run" option to gcc and g++

Mon Sep 20, 2021 12:46 am

You did store a.out in filesystem, and execute from there.
tcc's "-run" option compiles into RAM and executes from there.
ELF binary gets NOT stored anywhere in filesystem.
I just implemented tcc's "-run" option for gcc and g++, different to what you do.
https://github.com/Hermann-SW/memrun
https://stamm-wilbrandt.de/2wheel_balancing_robot
https://stamm-wilbrandt.de/en#raspcatbot
https://github.com/Hermann-SW/Raspberry_v1_camera_global_external_shutter
https://stamm-wilbrandt.de/en/Raspberry_camera.html

User avatar
HermannSW
Posts: 4658
Joined: Fri Jul 22, 2016 9:09 pm
Location: Eberbach, Germany
Contact: Website Twitter YouTube

Re: Adding (tcc) "-run" option to gcc and g++

Mon Sep 20, 2021 7:31 am

With latest commit shebang processing got added for "-run" enabled gcc and g++ (see "Scripting" section in tcc man page):
https://github.com/Hermann-SW/memrun/tr ... processing

gcc example:

Code: Select all

pi@raspberrypi400:~/memrun/C $ ./HelloWorld.c
Hello, World!
pi@raspberrypi400:~/memrun/C $ cat HelloWorld.c
#!/home/pi/memrun/C/bin/gcc -run
#include <stdio.h>

int main(void)
{
  printf("Hello, World!\n");
  return 0;
}
pi@raspberrypi400:~/memrun/C $ 
https://github.com/Hermann-SW/memrun
https://stamm-wilbrandt.de/2wheel_balancing_robot
https://stamm-wilbrandt.de/en#raspcatbot
https://github.com/Hermann-SW/Raspberry_v1_camera_global_external_shutter
https://stamm-wilbrandt.de/en/Raspberry_camera.html

User avatar
HermannSW
Posts: 4658
Joined: Fri Jul 22, 2016 9:09 pm
Location: Eberbach, Germany
Contact: Website Twitter YouTube

Re: Adding (tcc) "-run" option to gcc and g++

Thu Sep 23, 2021 7:30 pm

Just posted "memfd_create system call for bash" thread:
viewtopic.php?f=31&t=320170

New memfd_create.c exposes memfd_create system call to bash. In the thread a bash script demonstrates how to use. Basically it allows to create a file in RAM, that can be used by bash script as long as it likes, and then closed (see thread for details and/or "man memfd_create").

I modified "bin/grun" (which is used by "-run" enabled gcc and g++) to make use of memfd_create.c instead of memrun.c. From "git diff", these are the differences (compile memfd_create.c if needed, create memory file, compile ELF binary into the memory file, execute that and finally close memory file):
grun.html.crop.png
grun.html.crop.png
grun.html.crop.png (27.43 KiB) Viewed 1288 times

No change in behavior of grun or "-run" enabled gcc or g++, just more clean in using the exposed memfd_create system call only. Here with dynamic input for demonstration, after I installed "fortune":

Code: Select all

pi@raspberrypi400:~/memrun/C $ fortune -s | g++ -run demo.cpp foo 123
bar foo
A consultant is a person who borrows your watch, tells you what time it
is, pockets the watch, and sends you a bill for it.
pi@raspberrypi400:~/memrun/C $

demo.cpp:

Code: Select all

/**
*/
#include <iostream>

int main(int argc, char *argv[])
{
  printf("bar %s\n", argc>1 ? argv[1] : "(undef)");

  for(char c; std::cin.read(&c, 1); )  { std::cout << c; }

  return 0;
}
https://github.com/Hermann-SW/memrun
https://stamm-wilbrandt.de/2wheel_balancing_robot
https://stamm-wilbrandt.de/en#raspcatbot
https://github.com/Hermann-SW/Raspberry_v1_camera_global_external_shutter
https://stamm-wilbrandt.de/en/Raspberry_camera.html

User avatar
HermannSW
Posts: 4658
Joined: Fri Jul 22, 2016 9:09 pm
Location: Eberbach, Germany
Contact: Website Twitter YouTube

Re: Adding (tcc) "-run" option to gcc and g++

Sun Sep 26, 2021 4:50 pm

I learned form @Trejan that gcc/g++ do create temporary files while compiling C/C++.
In this posting I investigated, and in case you prevent any of the possible directories for temporary files, gcc/g++ abort:
viewtopic.php?f=31&t=320170&p=1917561#p1917142

So a directory is needed for temporary files.
With this commit
https://github.com/Hermann-SW/memrun/co ... c5089dddf1
/bin/grun does
  • create memory file
  • create filesyystem in memory file
  • mount that filesystem
  • create executable "doit" in that filesystem, inclusive all temporary files
  • execute "doit"
  • release memory file&filesystem
So now "-run" enabled gcc/g++ runs completely in RAM!

Code: Select all

pi@raspberrypi400:~/memrun/C $ fortune -s | bin/g++ -run demo.cpp foo 123
bar foo
Sorry.  I forget what I was going to say.
pi@raspberrypi400:~/memrun/C $ 
https://github.com/Hermann-SW/memrun
https://stamm-wilbrandt.de/2wheel_balancing_robot
https://stamm-wilbrandt.de/en#raspcatbot
https://github.com/Hermann-SW/Raspberry_v1_camera_global_external_shutter
https://stamm-wilbrandt.de/en/Raspberry_camera.html

User avatar
HermannSW
Posts: 4658
Joined: Fri Jul 22, 2016 9:09 pm
Location: Eberbach, Germany
Contact: Website Twitter YouTube

Re: Adding (tcc) "-run" option to gcc and g++

Sun Sep 26, 2021 7:30 pm

Temporary inserting "strace" call into "bin/grun", and redirecting error output into file "err" ...

Code: Select all

...
 # compile $src, store executable in memory file ...
-TMPDIR="$mnt" "/usr/bin/$cmp" $opts -o $mnt/doit -x $lng <(shebang < "$src")
+TMPDIR="$mnt" strace "/usr/bin/$cmp" $opts -o $mnt/doit -x $lng <(shebang < "$src") 2>err
...

... allows to see that temporary files really end in filesystem created in memory file, and that really everything is done in RAM while executing demo.cpp with g++ "-run" option:

Code: Select all

pi@raspberrypi400:~/memrun/C $ fortune -s | bin/g++ -run demo.cpp foo 123
bar foo
In any formula, constants (especially those obtained from handbooks)
are to be treated as variables.
pi@raspberrypi400:~/memrun/C $

The temporary files appear in filesystem mounted under "/proc/31851/fd", because 31851 was the process id of that g++ call:

Code: Select all

pi@raspberrypi400:~/memrun/C $ tail -12 err
access("/usr/lib/gcc/arm-linux-gnueabihf/8/collect2", X_OK) = 0
vfork()                                 = 31872
wait4(31872, [{WIFEXITED(s) && WEXITSTATUS(s) == 0}], 0, NULL) = 31872
--- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_EXITED, si_pid=31872, si_uid=1000, si_status=0, si_utime=0, si_stime=0} ---
stat64("/proc/31851/fd/cc6iH5mu.res", {st_mode=S_IFREG|0600, st_size=0, ...}) = 0
unlink("/proc/31851/fd/cc6iH5mu.res")   = 0
stat64("/proc/31851/fd/ccXJyZjS.o", {st_mode=S_IFREG|0600, st_size=2452, ...}) = 0
unlink("/proc/31851/fd/ccXJyZjS.o")     = 0
stat64("/proc/31851/fd/cckju3hf.s", {st_mode=S_IFREG|0600, st_size=3022, ...}) = 0
unlink("/proc/31851/fd/cckju3hf.s")     = 0
exit_group(0)                           = ?
+++ exited with 0 +++
pi@raspberrypi400:~/memrun/C $ 
https://github.com/Hermann-SW/memrun
https://stamm-wilbrandt.de/2wheel_balancing_robot
https://stamm-wilbrandt.de/en#raspcatbot
https://github.com/Hermann-SW/Raspberry_v1_camera_global_external_shutter
https://stamm-wilbrandt.de/en/Raspberry_camera.html

User avatar
HermannSW
Posts: 4658
Joined: Fri Jul 22, 2016 9:09 pm
Location: Eberbach, Germany
Contact: Website Twitter YouTube

Re: Adding (tcc) "-run" option to gcc and g++

Sat Oct 09, 2021 5:21 pm

I learned fron Uncle Bill on unix.stackexchange.com about "mount -t tmpfs ...". That allows to do what I need without memfd_create system call. New "-run" enabled gcc/g++ make use of that technique now. All worked fine under Raspberry Pi OS as well as Intel Ubuntu. But on Red Hat Enterprise Linux (RHEL) mounting under "/proc/$$/fd" is not allowed (selinux, $$ is current process id). I learned how to create a policy for allowing that, but made grun tool use "/tmp/$$" instead with a warning in case it is not allowed. All temporary files gcc/g++ create are stored in that directory, as well as the created executable "doit". I documented all in new section "mount_tmpfs technique works without memfd_create system call":
https://github.com/Hermann-SW/memrun/tr ... ystem-call

One C++ script got enhanced, demonstrating interaction of bash script and C++ code execution. Here bash reads C++ output, and prints it "C: " prefixed. Bash passes "42" as first arg to C++ code, which prints it:

Code: Select all

pi@raspberrypi400:~/memrun/C/mount_tmpfs $ uname -o | ./run_from_memory_cin.cpp 
foo
C: bar 42
C: GNU/Linux
bar
pi@raspberrypi400:~/memrun/C/mount_tmpfs $ 

This is the C++ bash script run_from_memory_cin.cpp.
Just calling "g++" is fine, new tools get installed under /usr/local/bin by "_install.sh" script, can be easily removed by "_uninstall.sh" script:
run_from_memory_cin.cpp.png
run_from_memory_cin.cpp.png
run_from_memory_cin.cpp.png (31.12 KiB) Viewed 427 times
Last edited by HermannSW on Sat Oct 09, 2021 5:48 pm, edited 1 time in total.
https://github.com/Hermann-SW/memrun
https://stamm-wilbrandt.de/2wheel_balancing_robot
https://stamm-wilbrandt.de/en#raspcatbot
https://github.com/Hermann-SW/Raspberry_v1_camera_global_external_shutter
https://stamm-wilbrandt.de/en/Raspberry_camera.html

ejolson
Posts: 8300
Joined: Tue Mar 18, 2014 11:47 am

Re: Adding (tcc) "-run" option to gcc and g++

Sat Oct 09, 2021 5:36 pm

HermannSW wrote:
Sat Oct 09, 2021 5:21 pm
I learned fron Uncle Bill on unix.stackexchange.com about "mount -t tmpfs ...". That allows to do what I need without memfd_create system call. New "-run" enabled gcc/g++ make use of that technique now. All worked fine under Raspberry Pi OS as well as Intel Ubuntu. But on Red Hat Enterprise Linux (RHEL) mounting under "/proc/$$/fd" is not allowed (selinux, $$ is current process id). I learned how to create a policy for allowing that, but made grun tool use "/tmp/$$" instead with a warning in case it is not allowed. All temporary files gcc/g++ create are stored in that directory, as well as the created executable "doit". I documented all in new section "mount_tmpfs technique works without memfd_create system call":
https://github.com/Hermann-SW/memrun/tr ... ystem-call

One C++ script got enhanced, demonstrating interaction of bash script and C++ code execution. Here bash reads C++ output, and prints it "C: " prefixed. Bash passes "42" as first arg to C++ code, which prints it:

Code: Select all

pi@raspberrypi400:~/memrun/C/mount_tmpfs $ uname -o | ./run_from_memory_cin.cpp 
foo
C: bar 42
C: GNU/Linux
bar
pi@raspberrypi400:~/memrun/C/mount_tmpfs $ 

This is the C++ bash script run_from_memory_cin.cpp.
Just calling "g++" is fine, new tools get installed under /usr/local/bin by _install script, can be easily removed by _uninstall script:
run_from_memory_cin.cpp.png
Does all this work without root or sudo?

dsyleixa123
Posts: 1556
Joined: Mon Jun 11, 2018 11:22 am

Re: Adding (tcc) "-run" option to gcc and g++

Sat Oct 09, 2021 7:53 pm

I always wanted to have tcc compiler's "-run" option for gcc and g++. With my new "memrun" repo execution of ELF binary from RAM became possible, and gcc/g++ can send ELF binary there. I added "-run" option with tcc's syntax to gcc and g++:
to run my C/C++ source I just press F9,F5 with Geany or ctrl+R with qt5 :mrgreen:

User avatar
HermannSW
Posts: 4658
Joined: Fri Jul 22, 2016 9:09 pm
Location: Eberbach, Germany
Contact: Website Twitter YouTube

Re: Adding (tcc) "-run" option to gcc and g++

Sat Oct 09, 2021 7:57 pm

ejolson wrote:
Sat Oct 09, 2021 5:36 pm
Does all this work without root or sudo?
No, execution of "mount -t tmpfs ..." requires sudo, grun linked by gcc/g++:
https://github.com/Hermann-SW/memrun/bl ... s/grun#L24
dsyleixa123 wrote:
Sat Oct 09, 2021 7:53 pm
I always wanted to have tcc compiler's "-run" option for gcc and g++. With my new "memrun" repo execution of ELF binary from RAM became possible, and gcc/g++ can send ELF binary there. I added "-run" option with tcc's syntax to gcc and g++:
to run my C/C++ source I just press F9,F5 with Geany or ctrl+R with qt5 :mrgreen:
But that stores compiler temporary files under "/tmp" which is not a memory filesystem under Raspberry Pi OS, and the executable is stored in fileseystem as well. "-run" option of tcc is compiling executable into RAM and execute from there, after execution it is gone.
https://github.com/Hermann-SW/memrun
https://stamm-wilbrandt.de/2wheel_balancing_robot
https://stamm-wilbrandt.de/en#raspcatbot
https://github.com/Hermann-SW/Raspberry_v1_camera_global_external_shutter
https://stamm-wilbrandt.de/en/Raspberry_camera.html

Return to “C/C++”