Sessho Sessho - 1 month ago 16
C Question

GCC doesn't compile when called by system() in Ruby

GCC compiles my C script when it's called on the command line by using

gcc main.c -o bfcout
. I wrote a script in Ruby where line 36 says
system("gcc main.c -o bfcout")
. I also tried
bash -c #{Shellwords.escape("gcc -Wall #{filename}.c -o bfcompoutput")}
.

But I get an error:
/usr/lib/gcc/x86_64-pc-linux-gnu/6.2.1/../../../../lib/crt1.o: In function '_start':
(.text+0x20): undefined reference to 'main'


There IS a main() function, and as I said, compiling on the command line works! What is wrong here?

EDIT:
C file looks like this. It is generated by the script. And yes, it's a reference to Brainf***. Sorry for the many lines(and the bad formatting).

#include <stdio.h>
unsigned char _c[30000]={};
int ptr=0;
int main(){
++_c[ptr];
++_c[ptr];
++_c[ptr];
++_c[ptr];
++_c[ptr];
++_c[ptr];
++_c[ptr];
++_c[ptr];
++_c[ptr];
++_c[ptr];
while (_c[ptr]) {
++ptr;
++_c[ptr];
++_c[ptr];
++_c[ptr];
++_c[ptr];
++_c[ptr];
++_c[ptr];
++_c[ptr];
++ptr;
++_c[ptr];
++_c[ptr];
++_c[ptr];
++_c[ptr];
++_c[ptr];
++_c[ptr];
++_c[ptr];
++_c[ptr];
++_c[ptr];
++_c[ptr];
++ptr;
++_c[ptr];
++_c[ptr];
++_c[ptr];
++ptr;
++_c[ptr];
--ptr;
--ptr;
--ptr;
--ptr;
--_c[ptr];
}
++ptr;
++_c[ptr];
++_c[ptr];
putchar(_c[ptr]);
++ptr;
++_c[ptr];
putchar(_c[ptr]);
++_c[ptr];
++_c[ptr];
++_c[ptr];
++_c[ptr];
++_c[ptr];
++_c[ptr];
++_c[ptr];
putchar(_c[ptr]);
putchar(_c[ptr]);
++_c[ptr];
++_c[ptr];
++_c[ptr];
putchar(_c[ptr]);
++ptr;
++_c[ptr];
++_c[ptr];
putchar(_c[ptr]);
--ptr;
--ptr;
++_c[ptr];
++_c[ptr];
++_c[ptr];
++_c[ptr];
++_c[ptr];
++_c[ptr];
++_c[ptr];
++_c[ptr];
++_c[ptr];
++_c[ptr];
++_c[ptr];
++_c[ptr];
++_c[ptr];
++_c[ptr];
++_c[ptr];
putchar(_c[ptr]);
++ptr;
putchar(_c[ptr]);
++_c[ptr];
++_c[ptr];
++_c[ptr];
putchar(_c[ptr]);
--_c[ptr];
--_c[ptr];
--_c[ptr];
--_c[ptr];
--_c[ptr];
--_c[ptr];
putchar(_c[ptr]);
--_c[ptr];
--_c[ptr];
--_c[ptr];
--_c[ptr];
--_c[ptr];
--_c[ptr];
--_c[ptr];
--_c[ptr];
putchar(_c[ptr]);
++ptr;
++_c[ptr];
putchar(_c[ptr]);
++ptr;
putchar(_c[ptr]);
++_c[ptr];
++_c[ptr];
++_c[ptr];
putchar(_c[ptr]);
return 0;
}


Script in Ruby:

require 'shellwords'

code = ""

loop do
x = gets.chomp
break if x=="__END__"
code << x
end

code_arr = []

code.split("").each {|ch|
case ch
when ">";code_arr << "++ptr;"
when "<";code_arr << "--ptr;"
when "+";code_arr << "++_c[ptr];"
when "-";code_arr << "--_c[ptr];"
when ".";code_arr << "putchar(_c[ptr]);"
when ",";code_arr << "_c[ptr] = getchar();"
when "[";code_arr << "while (_c[ptr]) {"
when "]";code_arr << "}"
end
}

filename = "main"

sp = ""

ostr = "#include <stdio.h>\nunsigned char _c[30000]={};#{sp}int ptr=0;#{sp}int main(){#{code_arr.join(sp)+sp}return 0;#{sp}}"
File.open("#{filename}.c","w").write(ostr)
puts ostr
result = system("gcc -Wall #{filename}.c -o ./#{filename}")
puts "Process exited with code #{result}"

Max Max
Answer

Writing to a file stream is buffered, you need to flush the buffer before compiling the C file. Change this

File.open("#{filename}.c","w").write(ostr)

to this

File.open("#{filename}.c","w") { |f| f.write(ostr) }

The block form automatically closes the file stream, flushing the write.