【问题标题】:C++ Executable distribution strategyC++ 可执行文件分发策略
【发布时间】:2010-11-27 23:38:49
【问题描述】:

最近我向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 的类的情况下静态编译它。

安装应该在没有人工干预的情况下以自动化方式进行,这一点非常重要。

所以我的问题真的是双重的:

  • 如何以最简单的方式针对所有这些发行版分发这个已编译的程序?

  • 这类问题有没有事实上的标准解决方案?

提前谢谢你,

费利佩。

【问题讨论】:

    标签: c++ linux distribution


    【解决方案1】:

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

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

    【讨论】:

      【解决方案2】:

      也许对您来说最好的解决方案是使用CMake

      CMake 是跨平台的开源构建系统。它是一系列旨在构建、测试和打包软件的工具。对于 Packaging,Mgb 是对的,CMake 可以很容易地与CPack 耦合。

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

      【讨论】:

        【解决方案3】:

        你可以试试this technique

        【讨论】:

        • 这看起来是个不错的选择。基本上,您动态链接,但使用特殊的 -rpath 选项强制运行时链接器在与可执行文件相同的目录中查找库。然后,您将动态库与可执行文件一起分发。
        • 这是一个很好的技术,但我最终获得了Ermine 的副本。太值得了:-)
        【解决方案4】:

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

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2019-04-06
          • 2014-07-13
          • 2012-08-13
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多