学习从源代码编译东西(在Unix / Linux / OSX上)

虽然我尽可能从软件包(MacPorts / apt-get)安装软件,但我经常发现自己需要从源代码编译软件包. ./configure&&制造&& sudo make install通常就足够了,但有时它不起作用 – 当它没有时,我经常被卡住了.这几乎总是以某种方式与其他库依赖关系相关.

我想学习以下内容:

>我如何确定要传递给./configure的参数?
>共享库如何在OS X / Linux下工作 – 它们存在于文件系统中,如何./configure&& make找到它们,当它们被链接时实际发生了什么
>共享和静态链接库之间的实际差异是什么?为什么我不能静态地链接所有东西(RAM和磁盘空间这些天很便宜)因此避免了奇怪的库版本冲突?
>我怎么知道我安装了哪些库,以及哪些版本?
>如何在不破坏正常系统的情况下安装多个版本的库?
>如果我在使用软件包管理的系统上从源代码安装东西,那么最干净的方法是什么?
>假设我设法从源代码编译一些东西,我怎么能把它打包起来让其他人不必跳过同样的箍?特别是OS X ….
>为了擅长这些东西,我需要掌握哪些命令行工具?像otool,pkg-config等的东西

我愿意在这里投入相当多的时间和精力 – 我不一定要直接回答上述问题,我更愿意获得有关我能阅读的书籍/教程/常见问题解答的建议.知识我需要了解实际发生的事情,从而自己解决问题.

我为直接回答所有内容而道歉,但我不知道任何有用的教程,常见问题解答等.基本上下面是8年制作桌面应用程序(我帮助分发),沮丧和谷歌搜索:

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”

-L参数添加到链接路径.

现代的东西使用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.观察构建输出以检查它是否合理.解析任何构建错误.也许在将来,请问服务器故障:)

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


用的openwrt路由器,家里宽带申请了动态公网ip,为了方便把2280端口映射到公网,发现经常被暴力破解,自己写了个临时封禁ip功能的脚本,实现5分钟内同一个ip登录密码错误10次就封禁这个ip5分钟,并且进行邮件通知使用步骤openwrt为19.07.03版本,其他版本没有测试过安装bashmsmtpopkg
#!/bin/bashcommand1&command2&wait从Shell脚本并行运行多个程序–杨河老李(kviccn.github.io)
1.先查出MAMP下面集成的PHP版本cd/Applications/MAMP/bin/phpls-ls 2.编辑修改.bash_profile文件(没有.bash_profile文件的情况下回自动创建)sudovim~/.bash_profile在文件的最后输入以下信息,然后保存退出exportPATH="/Applications/MAMP/bin/php/php7.2.20/b
1、先输入locale-a,查看一下现在已安装的语言2、若不存在如zh_CN之类的语言包,进行中文语言包装:apt-getinstalllanguage-pack-zh-hans3、安装好后我们可以进行临时修改:然后添加中文支持: locale-genzh_CN.UTF-8临时修改> export LC_ALL='zh_CN.utf8'> locale永久
BashPerlTclsyntaxdiff1.进制数表示Languagebinaryoctalhexadecimalbash2#[0~1]0[0~7]0x[0~f]or0X[0~f]perl0b[0~1]0[0~7]0x[0~f]tcl0b[0~1]0o[0~7]0x[0~f]bashdifferentbaserepresntationreference2.StringlengthLanguageStr
正常安装了k8s后,使用kubect工具后接的命令不能直接tab补全命令补全方法:yum-yinstallbash-completionsource/usr/share/bash-completion/bash_completionsource<(kubectlcompletionbash)echo"source<(kubectlcompletionbash)">>~/.bashrc 
参考这里启动jar包shell脚本修改过来的#!/bin/bash#默认应用名称defaultAppName='./gadmin'appName=''if[[$1&&$1!=0]]thenappName=$1elseappName=$defaultAppNamefiecho">>>>>>本次重启的应用:$appName<
#一个数字的行#!/bin/bashwhilereadlinedon=`echo$line|sed's/[^0-9]//g'|wc-L`if[$n-eq1]thenecho$linefidone<1.txt#日志切割归档#!/bin/bashcd/data/logslog=1.logmv_log(){[-f$1]&&mv$1$2
#文件增加内容#!/bin/bashn=0cat1.txt|whilereadlinedon=[$n+1]if[$n-eq5]thenecho$lineecho-e"#Thisisatestfile.\n#Testinsertlineintothisfile."elseecho$linefidone#备份/etc目录#
# su - oraclesu: /usr/bin/ksh: No such file or directory根据报错信息:显示无法找到文件 /usr/bin/ksh果然没有该文件,但是发现存在文件/bin/ksh,于是创建了一个软连接,可以规避问题,可以成功切换到用户下,但无法执行系统自带命令。$. .bash_profile-ksh: .: .b
history显示历史指令记录内容,下达历史纪录中的指令主要的使用方法如果你想禁用history,可以将HISTSIZE设置为0:#exportHISTSIZE=0使用HISTIGNORE忽略历史中的特定命令下面的例子,将忽略pwd、ls、ls-ltr等命令:#exportHISTIGNORE=”pwd:ls:ls-ltr:”使用HIS
一.命令历史  1.history环境变量:    HISTSIZE:输出的命令历史条数,如history的记录数    HISTFILESIZE:~/.bash_history保存的命令历史记录数    HISTFILLE:历史记录的文件路径    HISTCONTROL:     ignorespace:忽略以空格开头的命令
之前在网上看到很多师傅们总结的linux反弹shell的一些方法,为了更熟练的去运用这些技术,于是自己花精力查了很多资料去理解这些命令的含义,将研究的成果记录在这里,所谓的反弹shell,指的是我们在自己的机器上开启监听,然后在被攻击者的机器上发送连接请求去连接我们的机器,将被攻击者的she
BashOne-LinersExplained,PartI:Workingwithfileshttps://catonmat.net/bash-one-liners-explained-part-oneBashOne-LinersExplained,PartII:Workingwithstringshttps://catonmat.net/bash-one-liners-explained-part-twoBashOne-LinersExplained,PartII
Shell中变量的作用域:在当前Shell会话中使用,全局变量。在函数内部使用,局部变量。可以在其他Shell会话中使用,环境变量。局部变量:默认情况下函数内的变量也是全局变量#!/bin/bashfunctionfunc(){a=99}funcecho$a输出>>99为了让全局变量变成局部变量
1、多命令顺序执行;  命令1;命令2  多个命令顺序执行,命令之间没有任何逻辑联系&&  命令1&&命令2  逻辑与,当命令1正确执行,才会执行命令2||  命令1||命令2  逻辑或,当命令1执行不正确,才会执行命令2例如:ls;date;cd/home/lsx;pwd;who ddif=输入文件of=输
原博文使用Linux或者unix系统的同学可能都对#!这个符号并不陌生,但是你真的了解它吗?首先,这个符号(#!)的名称,叫做"Shebang"或者"Sha-bang"。Linux执行文件时发现这个格式,会把!后的内容提取出来拼接在脚本文件或路径之前,当作实际执行的命令。 Shebang这个符号通常在Unix系统的脚本
1、历史命令history[选项][历史命令保存文件]选项:-c:  清空历史命令-w:  把缓存中的历史命令写入历史命令保存文件 ~/.bash_historyvim/etc/profile中的Histsize可改存储历史命令数量历史命令的调用使用上、下箭头调用以前的历史命令使用“!n”重复执行第n条历史
目录1.Shell脚本规范2.Shell脚本执行3.Shell脚本变量3.1环境变量3.1.1自定义环境变量3.1.2显示与取消环境变量3.1.3环境变量初始化与对应文件的生效顺序3.2普通变量3.2.1定义本地变量3.2.2shell调用变量3.2.3grep调用变量3.2.4awk调用变量3.3
   http://www.voidcn.com/blog/wszzdanm/article/p-6145895.html命令功能:显示登录用户的信息命令格式:常用选项:举例:w显示已经登录的用户及正在进行的操作[root@localhost~]#w 11:22:01up4days,21:22, 3users, loadaverage:0.00,0.00,0.00USER