编译开源软件时,prefix, sysroot, DESTDIR怎么整

简介: 开发环境ubuntu12.04,x86_64,gcc4.6 arm板子环境armeabi,32bit,gcc5.3 以shell里面经常用到的file程序为例子 从ftp://ftp.astron.com/pub/file/上面下载源代码,因为我的ubuntu使用的是file5.09,不支持编译最新版本的file.5.25,所以我就下载file5.09了。

开发环境ubuntu12.04,x86_64,gcc4.6

arm板子环境armeabi,32bit,gcc5.3


以shell里面经常用到的file程序为例子

从ftp://ftp.astron.com/pub/file/上面下载源代码,因为我的ubuntu使用的是file5.09,不支持编译最新版本的file.5.25,所以我就下载file5.09了。


如果是从源代码编译安装file程序,应该这样做:

./configure
make
sudo make install

没啥好说的


如果我没有root权限,不是sudo组的,或者想把file安装到其他目录,怎么办呢?有两种情况:

第一种,错误的方法

./configure
make
make install DESTDIR=/home/tree/tools

编译完了,使用DESTDIR参数指定了一个安装路径,也没什么难理解的。运行/home/tree/tools/bin/file /home/tree/tools/bin/file:

/home/tree/tools/bin/file: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.32, BuildID[sha1]=0x1be35519b339d86fd2d4f73686b27c3573bdd988, not stripped

这不可以运行嘛,怎么能说是错误的方法呢?确实可以运行,但是如果你

sudo mv /usr/share/misc/magic.mgc{,.bak}
然后就发现你的/home/tree/tools/bin/file用不了了,即使你重新编译安装也用不了了,所以说这是一种错误的方法。

仔细看/home/tree/tools/bin/file的错误提示(可以使用/home/tree/tools/bin/file -v查看file需要的magic file的路径),说找不到/usr/share/misc/magic.mgc,肯定找不到,因为你编译安装的被magic.mgc安装在/home/tree/tools/share/misc/magic.mgc。

file程序使用绝对路径去找它需要的magic file,谁知道你把magic file安装到哪里了(测试前需要删除/usr/share/misc/magic.mgc,这是系统自带的,/home/tree/tools/bin/file会使用一个默认值去找这个文件,编译安装前删除它,防止干扰),所以用不了,如果file程序使用相对路径去找magic file的话,是可以正确运行的。

第二种方法,当然是正确的方法了

./configure --prefix=/home/tree/tools
make
make install
挺像的吧,即使你删除了/usr/share/misc/magic.mgc,编译出来的file也是可以正确运行的,毫无压力。vi config.log查看一下:
prefix='/home/tree/rootfs'
datarootdir='${prefix}/share'
datadir='${datarootdir}'
pkgdatadir='$(datadir)/misc'

vi src/Makefile.am可以看到:

MAGIC = $(pkgdatadir)/magic
AM_CPPFLAGS = -DMAGIC='"$(MAGIC)"'
--prefix参数被用来拼接目录,然后定义MAGIC宏传递给file程序,file从这个目录里面找magic file(当然,file也会从一些默认的位置查找magic file,自己看源码)

可以这样理解,--prefix为程序运行所需的目录的前缀,默认为/usr,经过和/bin, /etc, /lib等拼接后,指定程序运行时需要dlopen的.so存放的位置,配置文件/数据文件存放的位置等

DESTDIR指定安装程序的前缀,默认为空,程序最终将安装到DESTDIR/prefix的位置,里面有bin/file, share/misc/magic.mgc等。

ps:如果将tools文件夹重命名了,file程序就用不了了,原理很简单,file程序找不到/home/tree/tools/share/misc/magic.mgc了,所以程序中使用这种绝对路径的方式是有一些不便之处的,不能将程序安装到任意位置了,使用相对路径就可以解决这个问题。


那么--build, --host, --target又是什么鬼呢?

--build指定编译机器的架构,configure程序基本上可以自己猜出来这个值,不用设置

--host指编译出来的程序,运行在哪里,默认值为--build

--target指编译出来的程序,处理什么平台的文件,默认为--host

比如编译x86_64程序,在x86_64上编译,编译出来的程序运行在x86_64上面,处理x86_64的文件,不用指定这三个参数,默认都为x86_64-unknown-linux-gnu这样的

编译交叉编译工具链,在x86_64上编译,编译出来的程序运行在x86_64上面,处理arm的文件,需要修改--target=arm-unknown-linux-gnueabi这样的

使用交叉编译工具链编译arm程序,在x86_64上编译,编译出来的程序运行在arm上面,处理arm的文件,需要修改--host=arm-unknown-linux-gnueabi,--target默认和--host相同,可以不指定(注意configure时需要指定CC=arm-unknown-linux-gnueabi)


好了,我们来编译一个arm版本的file程序玩玩吧:

CC=arm-unknown-linux-gnueabi ./configure --prefix=/home/tree/rootfs
make
make install

能用不,不能用。把file,libmagic.so,magic.mgc拷贝到arm板子上,提示找不到magic file /home/tree/rootfs/share/misc/magic.mgc,能找到才怪了呢,那是编译机器上面的路径,那么怎么玩呢?

CC=arm-unknown-linux-gnueabi ./configure --prefix=/usr
make
make install DESTDIR=/home/tree/rootfs/usr
这个才能用,arm版本的file觉得我应该去/usr/share/misc/magic.mgc里面找文件,刚好能找到。如果make install时不指定DESTDIR,就会把arm程序安装到编译机器的/usr目录了,顺便还没有安装权限。
再把file, libmagic.so, magic.mgc文件拷贝到板子上去,发现可以正常使用了。


还有一个参数,--with-sysroot,整啥的?

一般是交叉编译才能用得到的,包括编译交叉编译工具链和使用交叉编译编译arm程序,用于指定从编译器从哪里找所要的.so, .h什么的,不指定--with-sysroot的话,就会找编译机器的/usr/include, /usr/lib下面的东西。编译arm程序去找x86_64的头文件,那肯定是有问题的,如果有一些硬件平台相关的文件,才会暴露出问题,否则也看不出来有什么问题,比如之前编译的arm版本的file程序,就没有--with-sysroot参数。


总结一下,交叉编译arm的程序,--prefix必需设置为/usr这样的,不能够带编译机器的绝对路径,必需指定--with-sysroot=${arm_rootfs},必需使用DESTDIR=${arm_rootfs}去make install,${arm_rootfs}是你的arm的rootfs的路径,需要设置一下。

编译x86_64程序,程序很可能使用了--prefix去拼接一些目录,使用绝对路径去查找一些文件,这种情况下,不能够使用DESTDIR参数,也不能随便将编译出来的程序放到别的文件夹下面去运行;如果没使用绝对路径查找文件,而是使用相对路径,那么可以指定DESTDIR ,也可以将程序拷贝到其他位置,或者其他机器上运行。





目录
相关文章
|
1月前
|
SQL 安全 PHP
PHP 自发布以来一直在 Web 开发领域占据重要地位,PHP 8 更是带来了属性、刚性类型等新特性。
【10月更文挑战第1天】PHP 自问世以来,凭借其易用性和灵活性,在 Web 开发领域迅速崛起。从简单的网页脚本语言逐步演进为支持面向对象编程的现代语言,尤其自 PHP 5.3 引入命名空间后,代码组织和维护变得更加高效。PHP 7 的性能优化和 PHP 8 的新特性(如属性和刚性类型)进一步巩固了其地位。框架如 Laravel、Symfony、Yii2 和 CodeIgniter 等简化了开发流程,提高了效率和安全性。
40 2
|
23天前
|
JavaScript 前端开发 Docker
拿下奇怪的前端报错(二):nvm不可用报错`GLIBC_2.27‘‘GLIBCXX_3.4.20‘not Found?+ 使用docker构建多个前端项目实践
本文介绍了在多版本Node.js环境中使用nvm进行版本管理和遇到的问题,以及通过Docker化构建流程来解决兼容性问题的方法。文中详细描述了构建Docker镜像、启动临时容器复制构建产物的具体步骤,有效解决了不同项目对Node.js版本的不同需求。
|
6月前
|
算法 程序员 编译器
【cmake 踩坑记录】CMake文件安装深入解析:EXCLUDE的奥秘与替代方案
【cmake 踩坑记录】CMake文件安装深入解析:EXCLUDE的奥秘与替代方案
230 0
|
安全 编译器 Linux
别忘了给gcc编译器工具链加上-fno-common选项
别忘了给gcc编译器工具链加上-fno-common选项
|
PHP
PHP8.0尝鲜系列(二):命名参数的使用
PHP8.0尝鲜系列(二):命名参数的使用
138 0
PHP8.0尝鲜系列(二):命名参数的使用
|
Linux API 开发工具
|
JavaScript 前端开发 API
前端工程化必备,语义化版本号扫盲,支持任意版本号位数的比较方法
因为最近在做 Node 相关的项目,涉及到版本号的处理,根据版本号大小做升级 js 处理的,而因为多加了一位数,导致线上的 js 不能升级。 所以只能重写一个支持任意位数的版本号对比方法。 顺便先来一个语义化版本号的扫盲吧。
320 0
|
IDE 关系型数据库 MySQL
Tars C++版本的编译及相关教程
Tars C++版本的编译及相关教程
527 0
Tars C++版本的编译及相关教程
|
存储 数据可视化 Linux
PHP 依赖镜像出问题后,阿里工程师的一顿“神操作“令人叫绝!
上个月,PHP开发者在网上纷纷反映出现 Composer 镜像无法访问的问题。阿里云内部一位 90 后工程师顾咏连夜开工排查,快速解决问题后,他在问题群里收到了一大波来自用户的红包。顾咏最后谢绝了红包,接受了阿里技术的邀请,来聊一聊这次事件问题背后的技术。
14756 0
PHP 依赖镜像出问题后,阿里工程师的一顿“神操作“令人叫绝!
|
Windows
同样是编译jogl,不同平台的编译速度相差几十倍?
同样是编译jogl,不同平台的编译速度相差几十倍?
103 0