2009-09-13 87 views
3

最近我問了一個關於我應該使用什麼的問題create self-contained executables that would be deployed under a number of Linux distribution。起初我非常害怕,但在閱讀了一些關於C++的文章後,我設法得到了可執行文件的第一個版本。C++可執行分發策略

經過一天的歡樂,我再次遇到另一個困境。由此產生的可執行文件必須安裝在許多Linux發行版(Slackware,Arch,Ubuntu,Debian,CentOS等等)中,我完全無法知道如何實現它。我所知道的CentOS和基於Debian的操作系統都有軟件包管理器,比如apt或yum,但我不確定這些適用於我的案例。

我寫的代碼依賴於幾個庫(更具體RudeSocketyaml-cpp的。我被告知,我將能夠編譯可執行文件和動態鏈接,所以我只需要分發的可執行文件。

這是我找不到yaml-cpp庫的.a文件(僅適用於RudeSocket)。以下是我的問題到目前爲止:

起初,我使用動態鏈接,但顯然當我將可執行文件複製到另一個框中:

$ ./main 
./main: error while loading shared libraries: libyaml-cpp.so.0.2: cannot open shared object file: No such file or directory 

當嘗試靜態編譯它,我得到一個錯誤太多(因爲我沒有YAML-CPP某文件正如我所提到):

$ g++ main.cpp parse.cpp parse.h rudesocket-1.3.0/.libs/librudesocket.a -o main -static -L/usr/local/librudesocket-1.3.0/.libs/librudesocket.a(socket_connect_normal.o): In function `rude::sckt::Socket_Connect_Normal::simpleConnect(int&, char const*, int)': 
/root/webbyget/sockets/rudesocket-1.3.0/src/socket_connect_normal.cpp:250: warning: Using 'gethostbyname' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking 
/tmp/cc3cEVK1.o: In function `operator>>(YAML::Node const&, Job&)': 
parse.cpp:(.text+0x1a83): undefined reference to `YAML::Node::size() const' 
/tmp/cc3cEVK1.o: In function `handle_job(rude::Socket, char const*)': 
parse.cpp:(.text+0x1b79): undefined reference to `YAML::Parser::Parser(std::basic_istream<char, std::char_traits<char> >&)' 
parse.cpp:(.text+0x1bfd): undefined reference to `YAML::Node::Node()' 
parse.cpp:(.text+0x1c10): undefined reference to `YAML::Parser::GetNextDocument(YAML::Node&)' 
parse.cpp:(.text+0x1dc6): undefined reference to `YAML::Node::size() const' 
parse.cpp:(.text+0x1dee): undefined reference to `YAML::Node::~Node()' 
parse.cpp:(.text+0x1e18): undefined reference to `YAML::Node::~Node()' 
parse.cpp:(.text+0x1e37): undefined reference to `YAML::Parser::~Parser()' 
parse.cpp:(.text+0x1e61): undefined reference to `YAML::Parser::~Parser()' 
(...) 

這是很明顯,我認爲G ++不能編譯它靜態地不告訴它在哪裏找到yaml-cpp的類。

安裝應該在沒有人爲干預的情況下以自動方式進行,這一點非常重要。

所以我的問題的確是雙重性:

  • 我怎樣才能在最複雜的方式針對所有這些分佈分發該編譯的程序?

  • 這種問題是否有任何事實上的標準解決方案?

謝謝你在前進,

費利佩。

回答

4

您可能會給this technique一試。

+1

這看起來像一個非常好的選擇。基本上,您可以動態鏈接,但使用特殊的-rpath選項來強制運行時鏈接程序在可執行文件所在的同一目錄中查找庫。然後,您使用可執行文件分發動態庫。 – divegeek 2009-10-16 14:08:39

+1

這是一個很好的技術,但我最終獲得了[Ermine](http://www.magicermine.com/)的副本。所以值得:-) – kolrie 2010-09-06 03:17:15

0

有許多事實上的標準,但沒有一個是標準化的。 :(如果你想分發一個編譯好的二進制文件,你可能會想要爲每個你想要的平臺打包,生成一個rpm和一個deb文件可能會讓你獲得90%的優勢,如果你想自動構建過程的autoconf/automake的仍然是(可能),以最好的一段路要走。

0

如果您使用的平臺包管理器(或的.rpm .deb文件),系統將檢查共享庫的正確版本,並在需要時下載。

CPack可能是最簡單的軟件包生成器

0

也許最好的解決方案是使用CMake

CMake是跨平臺的開源構建系統。它是設計用於構建,測試和打包軟件的一系列工具。對於包裝,Mgb是正確的,CMake可以很容易地與CPack耦合。

KDE使用此解決方案,它是automake/autoconf的一個非常好的替代方案。