1

So, I want to compile and run a string of C source code, where the string is a const char* and represents an entire program. It should be taken from either a constant or constructed string, such as

const char* prog = "#include <stdio.h> int main(void) {puts(\"foo\"); return 0;}"

I have already tried tcclib, but it currently doesn't build on Mac OS and due to lack of a consistent maintainer I don't think it's a viable way to do this.

I am mainly asking about this as a means to have a backend for a programming language that compiles to C. If there is some library function in gcc or clang, that would work too.

Note: This is specifically about compiling C code from C, not injecting it into a process.

6
  • 7
    Why not just write the string to a file and call a compiler? Commented Jan 7, 2019 at 17:29
  • 1
    why you do not write that string in a file then ask to compile it then run the exe ? Where s the problem if you have gcc installed ? Commented Jan 7, 2019 at 17:29
  • 1
    I'm almost sure I have seen this question (or very similar) asked before, but the one that is currently marked as duplicate does not seem to be it. This question is about compiling C code from C code, not about taking a string of code and injecting it into a process. Commented Jan 7, 2019 at 17:35
  • @bruno My idea was not having to deal with different windows and unix path names (windows utf-16 pathnames). But perhaps just calling gcc is a preferable solution. Commented Jan 7, 2019 at 17:35
  • 1
    So in principle there is an experimental programmatic interface to GCC, libgccjit, and LLVM was designed to be much more accessible in this sense, you may be able to find more information googling for "use clang/llvm as a library" (like this now unmaintained repository). Commented Jan 7, 2019 at 17:49

1 Answer 1

4

@bruno My idea was not having to deal with different windows and unix path names (windows utf-16 pathnames). But perhaps just calling gcc is a preferable solution.

I think calling GCC is easiest. However, just because you're calling GCC as an external process, doesn't mean you have to write your generated C to a file.

GCC is capable of taking its output from standard in. Here's an example, written in Bash.

echo "main(){}" | gcc -x c -

Here's the same thing in C:

#include <stdio.h>
#include <string.h>

const char *prog = "#include <stdio.h>\nint main(void) {puts(\"foo\"); return 0;}";

int main() {
    FILE *proc = popen("gcc -x c -", "w");
    fwrite(prog, sizeof(char), strlen(prog), proc);
    pclose(proc);
}

And here's the same thing, but with error handling:

#include <stdio.h>
#include <string.h>

const char *prog = "#include <stdio.h>\nint main(void) {puts(\"foo\"); return 0;}";

int main() {
    FILE *proc = popen("gcc -x c -", "w");
    if(!proc) {
        perror("popen gcc");
    }
    fwrite(prog, sizeof(char), strlen(prog), proc);
    if(ferror(proc)) {
        perror("writing prog");
    }
    if(pclose(proc) == -1) {
        perror("pclose gcc");
    }
}

I think that's the best way of accomplishing this.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.