Shell
編譯到標準輸出時 g++ 的連結器錯誤
假設我有一個名為 的 C++ 文件
dummy.cpp
,我需要用 g++ 編譯它,使其來自標準輸入,而 g++ 將編譯後的二進製文件輸出到標準輸出。如果只需要 stdin 部分,則以下命令可以解決問題:
$ g++ -x c++ -o dummy - < dummy.cpp
現在添加輸出部分,據我所知,我們需要使案例如
/dev/stdout
(或/proc/self/fd/1
)作為輸出參數,但是它不會工作,因為它會因連結器錯誤而退出。$ g++ -x c++ -o /dev/stdout - < dummy.cpp /usr/bin/ld: final link failed: Illegal seek collect2: error: ld returned 1 exit status
如果我通過它將它從終端重定向到一個文件
g++ -x c++ -o /dev/stdout - < dummy.cpp > dummy
,它將正常工作。我想問題是標準輸出是不可搜尋的,當它通過管道傳輸到文件中時,它會“變成”。但是為什麼 ld 文件是可查找的,並且可以以某種方式規避它?
正如評論中提到的,這是因為連結器分階段寫入文件,然後用大小和偏移量填充標題區域中的條目。ELF 格式在文件的前半部分具有這些值,以便輕鬆高效地找到適當的部分,因此,連結器自然而然地以它的方式工作。為流媒體設計的格式,如 Zip 文件,由於將清單數據放在最後,往往會變得更加複雜。
雖然理論上可以實現流輸出支持,但這樣做可能需要緩衝大量數據、兩次計算數據或各種其他低效做法,並且由於這種情況非常罕見,因此可能不值得考慮程式碼複雜性以及連結器中潛在的低效率。您可能會使用一個小的 shell 腳本,甚至是一個 shell 單行程序,使用帶有適當清理的臨時文件來實現這一點。