1

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?

1
  • 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, 2021 at 21:14

1 Answer 1

2

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.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .