C++可执行的分发策略

发布于 2024-08-04 20:04:49 字数 2578 浏览 4 评论 0原文

最近我问了一个问题,关于我应该使用什么来创建将部署在一些Linux发行版。一开始我非常害怕,但在阅读了一些关于 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 的类。

安装应该以自动化的方式进行,这一点非常重要。

所以我的问题实际上是双重的:

  • 如何分发这个编译的程序 。以最不复杂的方式针对所有这些发行版?

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

提前谢谢你,

费利佩。

Recently I have asked a question about what I should use to create self-contained executables that would be deployed under a number of Linux distribution. I got very scared at first, but after reading about C++ a little, I managed to get the first version of my executable going.

After a day full of joy, I just hit the wall again with another dilemma. The resulting executable must be installed in a number of Linux distributions (Slackware, Arch, Ubuntu, Debian, CentOS and a few more), and I am completely clueless on how to achieve it. All I know CentOS and Debian-based OSes has package managers, like apt or yum, but I am not sure those apply to my case.

The code I wrote depends on a couple of libraries (more specifically RudeSocket and yaml-cpp. I have been told that I would be able to compile the executable and link it dynamically, so I just needed to distribute the executable.

It happens that I could not find the .a file for the yaml-cpp library (just for RudeSocket). And here's my problem so far:

At first, I went with dynamic linking but (obviously) when I copied the executable to another box:

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

When trying to compile it statically, I get an error too (because I don't have the yaml-cpp .a file as I mentioned):

$ 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()'
(...)

It's pretty obvious to me that g++ cannot compile it statically without telling it where to find the classes for yaml-cpp.

It is very important that the installation should happen without human interaction, in an automated fashion.

So my question is really twofold:

  • how can I distribute this compiled program in the least complex way targeting all those distributions?

  • is there any de facto standard solution for this kind of problem?

Thank you in advance,

Felipe.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

挽袖吟 2024-08-11 20:04:49

You might give this technique a try.

べ繥欢鉨o。 2024-08-11 20:04:49

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

There are many de-facto standards, but none of them are standardized. :( If you want to distribute a compiled binary, you will probably want to make a package for each platform you want to target. Generating an rpm and a deb will probably get you 90% of the way. If you want to automate the build process, autoconf/automake is still (probably) the best way to go.

幻梦 2024-08-11 20:04:49

也许最适合您的解决方案是使用 CMake

CMake 是跨平台的开源构建系统。它是一系列旨在构建、测试和打包软件的工具。对于打包来说,Mmb 是正确的,CMake 可以轻松地与 CPack 结合使用。

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

Maybe The best solution for you is to use CMake.

CMake is cross-platform, open-source build system. It is a family of tools designed to build, test and package software. For Packaging, Mgb is right, CMake can easily be coupled with CPack.

KDE is using this solution and its a very good alternative to automake/autoconf.

貪欢 2024-08-11 20:04:49

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

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

If you use the platforms package manager (.rpm or .deb) the system will check for the correct version of the shared library for you and download it if it is needed.

CPack is probably the easiest package generator

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文