Linux,C ++,第三方库

15

好的,这是一个简单的问题。我在Windows上使用Visual C++编程,为了学习目的,我改用Ubuntu,并开始使用Code::Blocks、CodeLite和Eclipse。我使用SDL2GLEW编写了一些简单的程序,以基于SDL2窗口的OpenGL应用程序为基础。我使用以下命令下载了库:

  

sudo apt-get install...

我的主要问题是:由于此应用程序依赖于外部库(SDL2glewfluOIS),因此它在其他Linux计算机上无法正常工作。只有在使用终端命令安装所有这些库之后,程序才能正常运行。我的问题是,是否可能构建一个不需要安装这些库的程序。例如,在Windows上,您将程序链接到SDL2.lib并在.exe文件夹中包含SDL2.dll。在Linux上,我该如何做到这一点?我对Linux编程和其工作原理几乎没有经验,所以我希望这只是一个基本问题。


3
你同时打开了三个集成开发环境吗?我可以为你翻译。 - Lightness Races in Orbit
2
在Code::Blocks、CodeLite和Eclipse中同时启动,似乎有点过度了吧? - cbll
1
这个问题肯定值得回答,其中包括 LD_LIBRARY_PATHrpath - hyde
@hyde LD_LIBRARY_PATH并不是为了打包而设计的,只有在没有其他选项时才会使用它(例如具有只读根分区的嵌入式系统)。 - Dmitry Grigoryev
1
顺带一提,你考虑过将你的应用程序放入 Docker 容器中吗? - Dmitry Grigoryev
显示剩余2条评论
3个回答

18
在Linux中,相当于`dll`文件的是`.so`文件。所以您需要将它们与程序一起交付。
您还可以静态链接库。库文件的结尾通常是`.a`。使用这种方法,库文件会直接编译到程序中,您就不需要额外地交付这些文件了。
更高级的(像Linux一样的)方法如下:在Linux中(例如Debian/Ubuntu),通常会创建一个包(对于Debian来说是`.deb`文件——Debian包)。在包中,您可以添加元信息,例如依赖的其他软件包(这些软件包可以通过apt-get命令安装)。
然后,当您手动使用dpkg安装软件包时,它会告诉您缺少哪些依赖项,并且您可以使用`apt-get -f install` 命令解决依赖问题。您也可以创建自己的apt软件包仓库,只需使用`apt-get install ...`命令即可安装您的程序及其所有依赖项。
其他Linux发行版有其他的软件包管理系统。这只是Debian/Ubuntu的示例。

1
谢谢您的帮助 :) 我尝试了Windows风格并在usr/lib/...中找到了libSDL2.a、libSDL2main.a等其他SDL库。我已将它们添加到可执行文件夹中,但显然不起作用 :) 我确定这不是正确的方法,因为我是Linux编程的初学者 :) 我会进行更多的研究 :) 如果有什么需要尝试的,请告诉我 :) - Puso
1
你应该研究如何将库与编译器链接,并查看是否需要任何特定的内容来链接静态库。当你链接.a文件时,你不需要将它们复制到计算机上,而是它们应该被“包含”在你的二进制文件中。 - Hayt
1
请注意,在Windows上查找dll和Linux上的so的规则根本不同。在Windows上,只需将dll放在exe旁边即可,而在Linux上,则需要更多的操作。此外,请注意,在Linux上发布二进制文件远比在Windows上简单得多。仅因为您的二进制文件在一个发行版上运行正常,并不意味着它会在另一个发行版上运行正常。这就是为什么我们有像Holy Build Box这样的项目存在的很好的原因。 - ComicSansMS
3
将不同的 VC_redistributable 打包放入软件中是一个相对简单(尽管有点烦人)但很好支持的过程。然而,将不兼容的 GLIBC 版本打包到外部发行版中是不可行的。虽然我同意,在打包二进制文件时需要考虑两个平台的特点,但我仍然认为在这方面处理 Linux 显然更加困难。(这并不是针对 Linux 的抨击;它处理这些事情的哲学也有很多优势。) - ComicSansMS
不是很直接。就像我说的,回过头来看似乎更加直接了,但你必须一个一个地研究资源(这也不再是问题的主题)。但你可以在谷歌上找到它。当我想在旧系统上使用现代C++时,我遇到了这个问题。 - Hayt
显示剩余4条评论

5

除了Hayt的好回答之外,我认为值得一提的是,“经典”的UNIX方法是“开箱即用”的解决方案。也就是说:您实际上指定了程序编译所需的“外部”依赖项;并且您基本上使人们能够简单地下载某些源代码存档;然后在提取时...运行

./configure
make
make install

或者在他们的系统上进行类似操作。

在这种情况下,“配置”工具会检查所有所需依赖项。有关更多信息,请参见此处

现在,分发DEB、RPM等软件包更加常见;但是,能够从某个地方下载一些sources.tar.gz文件,运行这三个命令并拥有一个基于本地编译的工作安装的能力是非常美妙的。尤其是当您的用户可能想要对源代码进行更改时。但是,这当然需要您在思考上花费更多的时间 - 因为您希望尽可能限制自己的“依赖项”;换句话说:您希望“尽可能标准化”。


2
你必须检查第三方库的许可证。这取决于你如何链接它们。例如,如果你有商业利益,只能动态链接Qt等库。因此,你可能无法静态链接。如果你想在Linux和Windows上构建,我还可以推荐使用cmake - Hayt
好的,谢谢回复 :) 我会检查所使用库的许可证。关于cmake,我曾尝试在构建OGRE源代码时使用它,但发现很难理解其工作原理。您是否有任何教程/资源链接,可以学习如何使用cmake进行构建? - Puso
2
@Puso 两件事情:避免在评论中陷入“讨论”模式。另外,有关“推荐”的问题完全不适用于本站。请转向您最喜欢的搜索引擎;我相信一个想要做你在这里描述的事情的人...将能够找到适合他需要的cmake信息!只需下载并查看东西即可。 - GhostCat
这难道不会用缺少库的初始问题来替换为缺少开发包的新问题吗? - Dmitry Grigoryev
1
@DmitryGrigoryev:是的,真的。但首先您必须安装auto-apt。当./configure尝试访问不存在的文件时,auto-apt会将./configure进程暂停,安装适当的软件包,然后让./configure进程继续。 - Quora Feans
显示剩余4条评论

2

使你的应用程序易于安装的一种方法是对其进行打包(假设在Ubuntu上)。假设您已经构建了名为foobar的应用程序。创建以下目录结构:

foobar_1.0/
|-- usr/local/bin
|             `-- foobar
`-- DEBIAN/
    `--  control

并将以下文本放入DEBIAN/control文件中:

Package: foobar
Version: 1.0
Section: games
Priority: optional
Architecture: i386
Depends: libsdl2, libglew1.10, anotherLibrary, yetAnotherOne
Maintainer: Your Name <you@email.com>
Description: A neat package which does foo and bar

现在您可以使用以下命令构建您的软件包:
dpkg-deb --build foobar_1.0

你的用户需要使用 dpkg -i foobar_1.0.deb 命令来安装 foobar,这将把 foobar 安装在 /usr/local/bin 目录下。这个目录专门用于从源码构建或安装非官方软件包,避免与官方软件包中的二进制文件在 /usr/bin 目录中发生命名冲突。
如果你列在 DEBIAN/control 文件中的依赖项缺失,用户在安装时会被告知。只需运行 apt-get -f install 命令即可安装它们。卸载 foobar 还会标记这些依赖项为未使用,因此当用户卸载你的软件包时,他们将被提示删除这些依赖项。

1
这很不错,但是没有免费的午餐:如果您想支持几个发行版“家族”(.deb,.rpm等),并在几个发行版/版本之间保持包的兼容性(Ubuntu LTS12.04 ...最新的Debian不稳定版),那么这将变得很繁琐。如果您选择这条路线,可能值得为软件包创建PPA,以便用户可以自动获取更新,这是已建立的OSS应用程序的经过验证的方法。 - hyde
当然可以。我只是涵盖了一个开始,它只需要大约15分钟左右的时间就能完成。 - Dmitry Grigoryev

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接