代码之家  ›  专栏  ›  技术社区  ›  kolrie

C++可执行分发策略

  •  3
  • kolrie  · 技术社区  · 15 年前

    最近我问了一个问题,我应该用什么 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,但我不确定这些是否适用于我的案例。

    我编写的代码依赖于几个库(更具体地说 RudeSocket yaml-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 回复  |  直到 12 年前
        1
  •  4
  •   genpfault    15 年前

    你可以给 this technique 尝试一下。

        2
  •  0
  •   William Pursell    15 年前

    事实上有许多标准,但没有一个是标准化的。:(如果要分发已编译的二进制文件,则可能需要为要针对的每个平台制作一个包。生成一个RPM和一个DEB可能会给你带来90%的收益。如果您想自动化构建过程,autoconf/automake仍然(可能)是最好的方法。

        3
  •  0
  •   Nadir SOUALEM    15 年前

    也许你最好的解决办法是 CMake .

    克苏 是跨平台、开源的构建系统。它是一系列用于构建、测试和打包软件的工具。对于包装,MGB是正确的,CMAKE可以很容易地与 CPack .

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

        4
  •  0
  •   Stephane Rolland    12 年前

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

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