C ++可执行分发策略

时间:2009-09-13 22:04:20

标签: c++ linux distribution

最近我问了一个关于我应该对create self-contained executables that would be deployed under a number of Linux distribution使用什么的问题。起初我非常害怕,但在阅读了一下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 .a文件):

$ 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 个答案:

答案 0 :(得分:4)

您可以尝试this technique

答案 1 :(得分:0)

有许多事实上的标准,但都没有标准化。 :(如果你想分发一个已编译的二进制文件,你可能想要为你想要定位的每个平台创建一个包。生成一个rpm和一个deb可能会让你90%的方式。如果你想自动化构建过程中,autoconf / automake仍然(可能)是最好的方式。

答案 2 :(得分:0)

如果您使用平台包管理器(.rpm或.deb),系统将为您检查正确版本的共享库,并在需要时下载它。

CPack可能是最简单的包生成器

答案 3 :(得分:0)

也许最好的解决方案是使用CMake

CMake是跨平台的开源构建系统。它是一系列用于构建,测试和打包软件的工具。对于包装,Mgb是正确的,CMake可以很容易地与CPack结合。

KDE正在使用此解决方案,它是automake / autoconf的一个非常好的替代方案。