我想学习以下内容:
>我如何确定要传递给./configure的参数?
>共享库如何在OS X / Linux下工作 – 它们存在于文件系统中,如何./configure&& make找到它们,当它们被链接时实际发生了什么
>共享和静态链接库之间的实际差异是什么?为什么我不能静态地链接所有东西(RAM和磁盘空间这些天很便宜)因此避免了奇怪的库版本冲突?
>我怎么知道我安装了哪些库,以及哪些版本?
>如何在不破坏正常系统的情况下安装多个版本的库?
>如果我在使用软件包管理的系统上从源代码安装东西,那么最干净的方法是什么?
>假设我设法从源代码编译一些东西,我怎么能把它打包起来让其他人不必跳过同样的箍?特别是OS X ….
>为了擅长这些东西,我需要掌握哪些命令行工具?像otool,pkg-config等的东西
我愿意在这里投入相当多的时间和精力 – 我不一定要直接回答上述问题,我更愿意获得有关我能阅读的书籍/教程/常见问题解答的建议.知识我需要了解实际发生的事情,从而自己解决问题.
1.我如何确定要传递给./configure的参数?
真的练习. Autotools很容易,因为它是一致的.但是有大量的东西使用cmake或自定义构建脚本.通常,您不必通过任何配置,它应该弄清楚您的系统是否可以构建foo-tool.
配置和GNU工具都在/,/ usr和/usr/local中查找依赖项.如果你在其他地方安装任何东西(如果依赖项是由MacPorts或Fink安装的话会让事情变得很痛苦),你必须传递一个标志来配置或修改shell的环境,以帮助GNU工具找到这些依赖项.
2.共享库如何在OS X / Linux下工作 – 它们存在于文件系统中,当它们被链接时实际发生了什么
在Linux上,需要将它们安装到动态链接器可以找到的路径上,这由LD_LIBRARY_PATH环境变量和/etc/ld.conf的内容定义.在Mac上,对于大多数开源软件来说几乎总是如此(除非是Xcode项目).除了env变量是DYLD_LIBRARY_PATH之外.
链接器搜索库的默认路径.它是/ lib:/usr/lib:/usr/local / lib
您可以通过使用CPATH变量或CFLAGS或任何数量的其他环境变量(方便复杂)来补充这一点.我建议像这样CFLAGS:
export CFLAGS =“$CFLAGS -L / new / path”
现代的东西使用pkg-config工具.您安装的现代资料还会安装一个.pc文件,该文件描述了库及其位置以及如何链接到该库.这可以让生活更轻松.但它没有OS X 10.5,所以你也必须安装它.许多基本代表也不支持它.
链接的行为只是“在运行时解析此函数”,实际上它是一个很大的字符串表.
3.共享库和静态链接库之间的实际差异是什么?为什么我不能静态地链接所有东西(RAM和磁盘空间这些天很便宜)因此避免了奇怪的库版本冲突?
链接到静态库文件时,代码将成为应用程序的一部分.如果该库有一个巨大的.c文件并将其编译到您的应用程序中就好了.
动态库具有相同的代码,但是当运行应用程序时,代码将在运行时加载到应用程序中(简化说明).
您可以静态链接到所有内容,但遗憾的是,几乎没有任何构建系统可以轻松实现这一点.您必须手动编辑构建系统文件(例如Makefile.am或CMakeLists.txt).但是,如果您经常安装需要不同版本库的东西并且您发现难以并行安装依赖项,则可能值得学习.
诀窍是将链接行从-lfoo更改为-l / path /到/ static / foo.a
您可以找到并替换.然后检查工具是否使用ldd foo或otool -L foo链接到.so或dylib
另一个问题是并非所有库都编译为静态库.很多人.但随后MacPorts或Debian可能决定不发货.
4.如何判断我安装的库以及哪些版本?
如果你有这些库的pkg-config文件很容易:
pkg-config –list-all
否则你经常不能轻易. dylib可能有一个soname(即foo.0.1.dylib,soname是0.1),它与库的版本相同.但是,这不是必需的. soname是二进制可计算性功能,如果更改库中函数的格式,则必须碰撞soname的主要部分.所以你可以得到eg.版本14.0.5为2.0库的soname.虽然这并不常见.
我对这种事感到沮丧,并在Mac上为此开发了一个解决方案,接下来我正在谈论它.
5.如何在不破坏正常系统的情况下安装多个版本的库?
我的解决方案是:http://github.com/mxcl/homebrew/
我喜欢从源代码安装,并想要一个简单易用的工具,但需要一些软件包管理.所以我用Homebrew构建,例如.从源代码中获取自己,但请确保安装到特殊前缀:
/usr/local/Cellar/wget/1.1.4
然后我使用自制软件将所有这些符号链接到/usr/local,所以我仍然有/usr/local / bin / wget和/usr/local/lib/libwget.dylib
稍后如果我需要不同版本的wget,我可以并行安装它,只需更改链接到/usr/local树的版本即可.
6.如果我在使用软件包管理的系统上从源代码安装东西,那么最干净的方法是什么?
我相信Homebrew的方式是最干净的,所以使用它或做相同的.安装到/usr/local / pkgs / name / version和symlink或硬链接其余部分.
请使用/usr/local.存在的每个构建工具都在那里搜索依赖项和标头.你的生活会轻松得多.
7.假设我设法从源代码编译一些繁琐的东西,我怎么能把它打包起来让其他人不必跳过同样的箍?特别是OS X ….
如果它没有依赖关系,你可以打开构建目录并将其交给其他可以“make install”的人.但是,对于完全相同的OS X版本,您只能可靠地执行此操作.在Linux上,它可能适用于具有相同内核版本和libc次要版本的类似Linux(例如Ubuntu).
在Unix上分发二进制文件并不容易的原因是二进制兼容性. GNU人员和其他人经常更改他们的二进制接口.
基本上不要分发二进制文件.事情可能会以非常奇怪的方式打破.
在Mac上,最好的选择是制作一个macports包.每个人都使用macports.在Linux上有很多不同的构建系统和组合,我认为没有比写一篇关于如何在奇怪的配置中成功构建x工具的博客条目更好的建议.
如果你创建一个包描述(对于macports或homebrew),那么任何人都可以安装该包,它也解决了依赖性问题.然而,这通常并不容易,并且将macports配方包含在主macports树中也不容易.此外,macports不支持外来安装类型,它们为所有软件包提供了一个选择.
我使用Homebrew的未来目标之一是可以单击网站上的链接(例如,homebrew:// blah,它将下载该Ruby脚本,安装该软件包的deps然后构建应用程序.但是,是的,考虑到我选择的设计,还没有完成,但也不是太棘手.
8.为了擅长这些东西,pkg-config等的东西
otool之后才真正有用.它告诉你构建的二进制文件链接到什么.当你弄清楚你必须构建的工具的依赖关系时,它是无用的. pkg-config也是如此,因为您已经安装了依赖项,然后才能使用它.
我的工具链是,读取README和INSTALL文件,然后执行configure –help.观察构建输出以检查它是否合理.解析任何构建错误.也许在将来,请问服务器故障:)