我正在尝试使用您的标准g ++编译器编译一些C ++代码。 但是,而不是从文件编译:
main.cpp中:
#include <iostream>
int main(){
std::cout << "Hello World!\n";
return 0;
}
我更喜欢做
之类的事情g++ ... "#include <iostream>\n int main(){ std::cout << \"Hello World!\n\"; return 0;}"
stackoverflow的前一个post显示
echo "int main(){}" | gcc -Wall -o testbinary -xc++ -
有效,但我想知道它是如何工作的,如果有办法做到这一点,而不需要管道内容。
编辑:
我正在进行运行时代码生成,我需要生成一个共享库并加载创建的函数。
我以为会有一个标志告诉编译器“嘿,我给你的是源代码而不是文件”。
再次感谢您的帮助!
答案 0 :(得分:4)
echo“int main(){}”| gcc -Wall -o testbinary -xc ++ -
有效,但我想知道它是如何工作的,如果有办法做到这一点,而不需要管道内容。
或者你可以说(例如在shell脚本中):
gcc -Wall -o testbinary -xc++ - << EOF
int main(){}
EOF
答案 1 :(得分:2)
编译器从输入源读取 - stdin
或提供的文件。你需要一个管道来从别处向编译器提供一些东西。没有其他选择(当然,有些编译器可能没有选择从stdin
读取)
答案 2 :(得分:2)
你提到动态生成C(或C ++)代码,然后编译它并dlopen
- 它。
我在MELT(扩展GCC的特定领域语言)中也这样做。
我没有看到任何有效的理由避免将代码放入某个(临时)文件中。编写甚至一百万行生成的C或C ++行非常快(在MELT中,不到几秒钟,大部分时间不是I / O!)。编译速度要慢得多(至少几十秒),并且生成C或C ++代码的兴趣尤其在于利用GCC(或其他一些编译器)提供的优化。避免生成文件只会赢得你几毫秒(你甚至无法显着衡量差异)。
所以只需在一些临时*.c
文件中生成你的文件(你可以使用哈希或时间戳技术生成一个唯一的文件名),然后让GCC将它编译成一些*.so
(可能是{{} 1}} - 一些fork
进程,就像我在MELT中那样),然后删除该临时文件(可能使用make
)。
BTW,这种技术实际上与当前PC上的人机交互兼容。 MELT有一个read-eval-print-loop,在每次交互上生成几百行的新C ++文件,编译和dlopen-s,它非常实用!
避免文件的生成是痛苦的,并且收益绝对可以忽略不计。您可以在Linux上的某些atexit
文件系统中生成它(例如在tmpfs
中)。大部分时间都是由GCC编译该文件所花费的(特别是如果你使用一些优化进行编译,例如/tmp/
)。将它写在磁盘上(由您的程序)并通过GCC读取它(甚至为C解析)的时间可以忽略不计。使用GCC的-ftime-report选项来了解GCC花费时间的地方,一旦您将gcc -O -fPIC -shared somefile.c -o someplugin.so
传递给GCC,就不会解析。
某些版本的GCC或其他C编译器可能拒绝 stdin 作为输入;某些C编译器可能希望-O
C源文件(例如,使用mmap
作为Glibc上"rm"
的模式)。通常,将不是fopen
文件的内容编译为 C 是非标准的等等......所以最好避免这样做,因为增益可以忽略不计。 < / p>
如果您根本不关心优化并希望将C(而不是C ++)快速编译成非常慢的机器代码,请考虑使用 tinycc (至少在32位机器上使用,64它可能是错误的,它有一个能够在字符串中编译一些C代码的库。 *.c
及其tcc
能够非常快速地编译(超过10倍GCC)一些C代码,但生成的机器代码的性能非常差(非常慢,未经优化的代码)。
一旦GCC编译了您生成的C代码,您当然可以libtcc.a
生成的源代码文件。 (您甚至可以在remove
编辑后删除.so
。
顺便说一下,您可以使用dlopen
来编译生成的C ++文件。您可以使用LLVM(并生成内部LLVM表示,而不使用任何文件)。
另见this answer。
答案 3 :(得分:1)
如何popen("gcc -o -xc++ -
“,”w“); ? Gives you a
FILE *`但输出直接进入GCC。
顺便说一下,使用-Wall
标志毫无意义。这是供人类消费的。事实上,-w -Wfatal-errors
是有道理的。无论是编译还是不编译。
答案 4 :(得分:0)
在Unix上,您可以使用shell自动化创建C / C ++程序的所有过程。
1.创建文件(例如run_c.sh)
2.将代码粘贴到此文件
#!/bin/bash
# Generate random filename
RANDOM_FILENAME=`cat /dev/urandom | tr -dc 'A-Za-z0-9' | fold -w 20 | head -n 1`
RANDOM_FILENAME=_$RANDOM_FILENAME
readonly RANDOM_FILENAME
# random filename for a C file
RANDOM_FILENAME_C=$RANDOM_FILENAME.c
readonly RANDOM_FILENAME
# catch stdin as code
CODE=$1
# names headers of the C standart language
declare -a C_STANDART_LIBRARY=('stdio' 'errno' 'assert' 'math' 'stdarg' 'stdbool' 'stdlib' 'string' 'time')
# create the C file
touch $RANDOM_FILENAME_C
# write a first line to the file
printf '// Compile C code from stdin\n\n' >> $RANDOM_FILENAME_C
# make include all headers to the file
for header in "${C_STANDART_LIBRARY[@]}"
do
printf '#include <%s.h>\n' $header >> $RANDOM_FILENAME_C
done
# make include all headers to the file
printf "\nint main(int argc, char *argv[]) {\n" >> $RANDOM_FILENAME_C
# split the code from stdin by ';' to an array lines
IFS=';' read -r -a LINES_CODE <<< "$CODE"
# write line by line the code
for line in "${LINES_CODE[@]}"
do
printf '%s;\n' "$line" | sed -e 's/^[[:space:]]//' | sed -e 's/^/\t/' >> $RANDOM_FILENAME_C
done
# write ending the function 'main'
printf "\treturn 0;\n}\n" >> $RANDOM_FILENAME_C
# uncomment for display the C code
# cat $RANDOM_FILENAME_C
# compile the file
gcc -Wall -std=c11 -o $RANDOM_FILENAME $RANDOM_FILENAME_C
# run programm if no errors
if [ -f "$RANDOM_FILENAME" ];
then
./$RANDOM_FILENAME
fi
# rm the file with source code
rm $RANDOM_FILENAME_C
# rm the compliled file
if [ -f "$RANDOM_FILENAME" ];
then
rm $RANDOM_FILENAME
fi
3.将此文件设为可执行文件
$ chmod +x run_c.sh
$ ls -l | grep run_c.sh
-rwxr-xr-x 1 setivolkylany setivolkylany 1589 Dec 26 11:19 run_c.sh
<强>用法:强>
$ ./run_c.sh 'int a = 4; int b = 6; int c = a + b; printf("%d + %d = %d\n", a, b, c)'
4 + 6 = 10
$ ./run_c.sh 'puts("Worked");'
Worked
测试环境
$ lsb_release -a
No LSB modules are available.
Distributor ID: Debian
Description: Debian GNU/Linux 8.6 (jessie)
Release: 8.6
Codename: jessie
$ uname -a
Linux localhost 3.16.0-4-amd64 #1 SMP Debian 3.16.36-1+deb8u2 (2016-10-19) x86_64 GNU/Linux
灵感来自http://django-notes.blogspot.com/2013/01/compiling-c-from-stdin.html和https://github.com/vgvassilev/cling
答案 5 :(得分:0)
-x
用于指定您将编译的语言。
这是一个例子:
gcc -x c - <<eof
#include <stdio.h>
void foo()
{
int a = 10;
static int sa = 10;
a += 5;
sa += 5;
printf("a = %d, sa = %d\n", a, sa);
}
int main()
{
int i;
for (i = 0; i < 10; ++i)
foo();
}
eof