解決 g++ 連結程式時的循環相依性的問題


在寫 C++ 的程式的時候,如果有拆分模組,有的時候會導致不同模組/函式庫之間的相依性變得很複雜、甚至可能會產生彼此互相相依的狀況(circular dependencies、維基百科有提供例子)。

在 Visual C++ 的環境下,linking 階段似乎是沒有順序、而且不會因為連結的順序、導致找不到參考的狀況。

但是在 g++ 的環境下,由於他的連結是有順序性的,所以如果加上 -lXXX 的順序不對,就可能會出現找不到參考的問題(錯誤訊息是「undefined reference」)。
比如說如果 libA 有用到 libB 的函式的話,那在連結的時候,libA 就必須要在 libB 的前面。

但是如果碰上 circular dependencies 的話,那基本上不管怎麼調整連結的順序,都是無法成功完成連結的。

碰上這種問題該怎麼辦呢?g++ 其實也是有考慮到這個問題,所以有提供 -WL,–start-group 的語法,來解決這樣的問題;它的使用方法如下

-Wl,--start-group -lLIBRARY1 -lLIBRARY2 -Wl, --end-group 

中間黃色的區塊,就是有循環相依的函式庫了。
-Wl 應該是把參數傳遞給 linker 的參數)

這個特殊語法內的函式庫,會在連結的時候被重複地去確認是否有找不到的參考,所以可以解決 circular dependencies 的問題。

下面就是官方的說明(連結):

-( archives -)

–start-group archives –end-group

The archives should be a list of archive files. They may be either explicit file names, or -l options.

The specified archives are searched repeatedly until no new undefined references are created. Normally, an archive is searched only once in the order that it is specified on the command line. If a symbol in that archive is needed to resolve an undefined symbol referred to by an object in an archive that appears later on the command line, the linker would not be able to resolve that reference. By grouping the archives, they all be searched repeatedly until all possible references are resolved.

Using this option has a significant performance cost. It is best to use it only when there are unavoidable circular references between two or more archives.

這邊他也有提醒,就是使用這樣的方法來連結,也會對效能造成不小的影響,所以非必要最好還是不要這樣用比較好。

參考:使用 –start-group 和 –end-group 解決 circular dependencies

發表迴響

在下方填入你的資料或按右方圖示以社群網站登入:

WordPress.com 標誌

您的留言將使用 WordPress.com 帳號。 登出 /  變更 )

Google photo

您的留言將使用 Google 帳號。 登出 /  變更 )

Twitter picture

您的留言將使用 Twitter 帳號。 登出 /  變更 )

Facebook照片

您的留言將使用 Facebook 帳號。 登出 /  變更 )

連結到 %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.