Let's say I have a C++ file called dummy.cpp, and I need to compile it with g++ in such a way that it's being from stdin and g++ spits the compiled binary out to stdout.

If only the stdin part is necessary the following command does the trick:

$ g++ -x c++ -o dummy - < dummy.cpp

Now adding the output part, as far as I know we need to use for example /dev/stdout (or /proc/self/fd/1) as the output parameter, however it won't work as it exits with a linker error.

$ g++ -x c++ -o /dev/stdout - < dummy.cpp
/usr/bin/ld: final link failed: Illegal seek
collect2: error: ld returned 1 exit status

If I redirect it from the terminal to a file via g++ -x c++ -o /dev/stdout - < dummy.cpp > dummy it will work correctly. I guess the problem is that stdout is not seekable and when it gets piped into a file it will "become". But why does ld the file to be seekable and can it be circumvented somehow?

New contributor
mraron is a new contributor to this site. Take care in asking for clarification, commenting, and answering. Check out our Code of Conduct.
  • The linker needs to fix up various back-references in the ELF format. Some of the storage type areas are put on page-sized boundaries for loading alignment purposes. There is no reason to constrain the linker to write the ELF serially. Oct 13 at 21:14
  • 1
    No, you can't do that. Use a temporary file (And if you're saying that you can't use temporary files -- then you can't use gcc either, because gcc is using temporary files itself.
    – zevzek
    Oct 13 at 21:54

As was mentioned in the comments, this is because the linker writes the file in stages and then fills in entries in the header area with the sizes and offsets. The ELF format has these values in the early part of the file to make finding the appropriate sections easy and efficient, and as a result, it's natural for the linker to work the way it does. Formats which are designed for streaming, like Zip files, tend to have much more complexity due to putting manifest data at the end.

While it is theoretically possible to implement streaming output support, doing so would likely require buffering large amounts of data, computing data twice, or various other inefficient practices, and because this scenario is so rare, it probably wasn't considered worth the code complexity and potential inefficiency in the linker. You could probably use a small shell script or even a shell one-liner to implement this using a temporary file with appropriate cleanup.

Your Answer

mraron is a new contributor. Be nice, and check out our Code of Conduct.

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.