mirror of
https://github.com/LCTT/TranslateProject.git
synced 2025-01-13 22:30:37 +08:00
Merge remote-tracking branch 'LCTT/master'
This commit is contained in:
commit
9605531693
235
published/20190826 How RPM packages are made- the source RPM.md
Normal file
235
published/20190826 How RPM packages are made- the source RPM.md
Normal file
@ -0,0 +1,235 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (wxy)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-11527-1.html)
|
||||
[#]: subject: (How RPM packages are made: the source RPM)
|
||||
[#]: via: (https://fedoramagazine.org/how-rpm-packages-are-made-the-source-rpm/)
|
||||
[#]: author: (Ankur Sinha "FranciscoD" https://fedoramagazine.org/author/ankursinha/)
|
||||
|
||||
RPM 包是如何从源 RPM 制作的
|
||||
======
|
||||
|
||||
![][1]
|
||||
|
||||
在[上一篇文章中,我们研究了什么是 RPM 软件包][2]。它们是包含文件和元数据的档案文件。当安装或卸载 RPM 时,此元数据告诉 RPM 在哪里创建或删除文件。正如你将在上一篇文章中记住的,元数据还包含有关“依赖项”的信息,它可以是“运行时”或“构建时”的依赖信息。
|
||||
|
||||
例如,让我们来看看 `fpaste`。你可以使用 `dnf` 下载该 RPM。这将下载 Fedora 存储库中可用的 `fpaste` 最新版本。在 Fedora 30 上,当前版本为 0.3.9.2:
|
||||
|
||||
```
|
||||
$ dnf download fpaste
|
||||
|
||||
...
|
||||
fpaste-0.3.9.2-2.fc30.noarch.rpm
|
||||
```
|
||||
|
||||
由于这是个构建 RPM,因此它仅包含使用 `fpaste` 所需的文件:
|
||||
|
||||
```
|
||||
$ rpm -qpl ./fpaste-0.3.9.2-2.fc30.noarch.rpm
|
||||
/usr/bin/fpaste
|
||||
/usr/share/doc/fpaste
|
||||
/usr/share/doc/fpaste/README.rst
|
||||
/usr/share/doc/fpaste/TODO
|
||||
/usr/share/licenses/fpaste
|
||||
/usr/share/licenses/fpaste/COPYING
|
||||
/usr/share/man/man1/fpaste.1.gz
|
||||
```
|
||||
|
||||
### 源 RPM
|
||||
|
||||
在此链条中的下一个环节是源 RPM。Fedora 中的所有软件都必须从其源代码构建。我们不包括预构建的二进制文件。因此,要制作一个 RPM 文件,RPM(工具)需要:
|
||||
|
||||
* 给出必须要安装的文件,
|
||||
* 例如,如果要编译出这些文件,则告诉它们如何生成这些文件,
|
||||
* 告知必须在何处安装这些文件,
|
||||
* 该特定软件需要其他哪些依赖才能正常工作。
|
||||
|
||||
源 RPM 拥有所有这些信息。源 RPM 与构建 RPM 相似,但顾名思义,它们不包含已构建的二进制文件,而是包含某个软件的源文件。让我们下载 `fpaste` 的源 RPM:
|
||||
|
||||
```
|
||||
$ dnf download fpaste --source
|
||||
|
||||
...
|
||||
fpaste-0.3.9.2-2.fc30.src.rpm
|
||||
```
|
||||
|
||||
注意文件的结尾是 `src.rpm`。所有的 RPM 都是从源 RPM 构建的。你也可以使用 `dnf` 轻松检查“二进制” RPM 的源 RPM:
|
||||
|
||||
```
|
||||
$ dnf repoquery --qf "%{SOURCERPM}" fpaste
|
||||
fpaste-0.3.9.2-2.fc30.src.rpm
|
||||
```
|
||||
|
||||
另外,由于这是源 RPM,因此它不包含构建的文件。相反,它包含有关如何从中构建 RPM 的源代码和指令:
|
||||
|
||||
```
|
||||
$ rpm -qpl ./fpaste-0.3.9.2-2.fc30.src.rpm
|
||||
fpaste-0.3.9.2.tar.gz
|
||||
fpaste.spec
|
||||
```
|
||||
|
||||
这里,第一个文件只是 `fpaste` 的源代码。第二个是 spec 文件。spec 文件是个配方,可告诉 RPM(工具)如何使用源 RPM 中包含的源代码创建 RPM(档案文件)— 它包含 RPM(工具)构建 RPM(档案文件)所需的所有信息。在 spec 文件中。当我们软件包维护人员添加软件到 Fedora 中时,我们大部分时间都花在编写和完善 spec 文件上。当软件包需要更新时,我们会回过头来调整 spec 文件。你可以在 <https://src.fedoraproject.org/browse/projects/> 的源代码存储库中查看 Fedora 中所有软件包的 spec 文件。
|
||||
|
||||
请注意,一个源 RPM 可能包含构建多个 RPM 的说明。`fpaste` 是一款非常简单的软件,一个源 RPM 生成一个“二进制” RPM。而 Python 则更复杂。虽然只有一个源 RPM,但它会生成多个二进制 RPM:
|
||||
|
||||
```
|
||||
$ sudo dnf repoquery --qf "%{SOURCERPM}" python3
|
||||
python3-3.7.3-1.fc30.src.rpm
|
||||
python3-3.7.4-1.fc30.src.rpm
|
||||
|
||||
$ sudo dnf repoquery --qf "%{SOURCERPM}" python3-devel
|
||||
python3-3.7.3-1.fc30.src.rpm
|
||||
python3-3.7.4-1.fc30.src.rpm
|
||||
|
||||
$ sudo dnf repoquery --qf "%{SOURCERPM}" python3-libs
|
||||
python3-3.7.3-1.fc30.src.rpm
|
||||
python3-3.7.4-1.fc30.src.rpm
|
||||
|
||||
$ sudo dnf repoquery --qf "%{SOURCERPM}" python3-idle
|
||||
python3-3.7.3-1.fc30.src.rpm
|
||||
python3-3.7.4-1.fc30.src.rpm
|
||||
|
||||
$ sudo dnf repoquery --qf "%{SOURCERPM}" python3-tkinter
|
||||
python3-3.7.3-1.fc30.src.rpm
|
||||
python3-3.7.4-1.fc30.src.rpm
|
||||
```
|
||||
|
||||
用 RPM 行话来讲,“python3” 是“主包”,因此该 spec 文件将称为 `python3.spec`。所有其他软件包均为“子软件包”。你可以下载 python3 的源 RPM,并查看其中的内容。(提示:补丁也是源代码的一部分):
|
||||
|
||||
```
|
||||
$ dnf download --source python3
|
||||
python3-3.7.4-1.fc30.src.rpm
|
||||
|
||||
$ rpm -qpl ./python3-3.7.4-1.fc30.src.rpm
|
||||
00001-rpath.patch
|
||||
00102-lib64.patch
|
||||
00111-no-static-lib.patch
|
||||
00155-avoid-ctypes-thunks.patch
|
||||
00170-gc-assertions.patch
|
||||
00178-dont-duplicate-flags-in-sysconfig.patch
|
||||
00189-use-rpm-wheels.patch
|
||||
00205-make-libpl-respect-lib64.patch
|
||||
00251-change-user-install-location.patch
|
||||
00274-fix-arch-names.patch
|
||||
00316-mark-bdist_wininst-unsupported.patch
|
||||
Python-3.7.4.tar.xz
|
||||
check-pyc-timestamps.py
|
||||
idle3.appdata.xml
|
||||
idle3.desktop
|
||||
python3.spec
|
||||
```
|
||||
|
||||
### 从源 RPM 构建 RPM
|
||||
|
||||
现在我们有了源 RPM,并且其中有什么内容,我们可以从中重建 RPM。但是,在执行此操作之前,我们应该设置系统以构建 RPM。首先,我们安装必需的工具:
|
||||
|
||||
```
|
||||
$ sudo dnf install fedora-packager
|
||||
```
|
||||
|
||||
这将安装 `rpmbuild` 工具。`rpmbuild` 需要一个默认布局,以便它知道源 RPM 中每个必需组件的位置。让我们看看它们是什么:
|
||||
|
||||
```
|
||||
# spec 文件将出现在哪里?
|
||||
$ rpm -E %{_specdir}
|
||||
/home/asinha/rpmbuild/SPECS
|
||||
|
||||
# 源代码将出现在哪里?
|
||||
$ rpm -E %{_sourcedir}
|
||||
/home/asinha/rpmbuild/SOURCES
|
||||
|
||||
# 临时构建目录是哪里?
|
||||
$ rpm -E %{_builddir}
|
||||
/home/asinha/rpmbuild/BUILD
|
||||
|
||||
# 构建根目录是哪里?
|
||||
$ rpm -E %{_buildrootdir}
|
||||
/home/asinha/rpmbuild/BUILDROOT
|
||||
|
||||
# 源 RPM 将放在哪里?
|
||||
$ rpm -E %{_srcrpmdir}
|
||||
/home/asinha/rpmbuild/SRPMS
|
||||
|
||||
# 构建的 RPM 将放在哪里?
|
||||
$ rpm -E %{_rpmdir}
|
||||
/home/asinha/rpmbuild/RPMS
|
||||
```
|
||||
|
||||
我已经在系统上设置了所有这些目录:
|
||||
|
||||
```
|
||||
$ cd
|
||||
$ tree -L 1 rpmbuild/
|
||||
rpmbuild/
|
||||
├── BUILD
|
||||
├── BUILDROOT
|
||||
├── RPMS
|
||||
├── SOURCES
|
||||
├── SPECS
|
||||
└── SRPMS
|
||||
|
||||
6 directories, 0 files
|
||||
```
|
||||
|
||||
RPM 还提供了一个为你全部设置好的工具:
|
||||
|
||||
```
|
||||
$ rpmdev-setuptree
|
||||
```
|
||||
|
||||
然后,确保已安装 `fpaste` 的所有构建依赖项:
|
||||
|
||||
```
|
||||
sudo dnf builddep fpaste-0.3.9.2-3.fc30.src.rpm
|
||||
```
|
||||
|
||||
对于 `fpaste`,你只需要 Python,并且它肯定已经安装在你的系统上(`dnf` 也使用 Python)。还可以给 `builddep` 命令一个 spec 文件,而不是源 RPM。在手册页中了解更多信息:
|
||||
|
||||
```
|
||||
$ man dnf.plugin.builddep
|
||||
```
|
||||
|
||||
现在我们有了所需的一切,从源 RPM 构建一个 RPM 就像这样简单:
|
||||
|
||||
```
|
||||
$ rpmbuild --rebuild fpaste-0.3.9.2-3.fc30.src.rpm
|
||||
..
|
||||
..
|
||||
|
||||
$ tree ~/rpmbuild/RPMS/noarch/
|
||||
/home/asinha/rpmbuild/RPMS/noarch/
|
||||
└── fpaste-0.3.9.2-3.fc30.noarch.rpm
|
||||
|
||||
0 directories, 1 file
|
||||
```
|
||||
|
||||
`rpmbuild` 将安装源 RPM 并从中构建你的 RPM。现在,你可以使用 `dnf` 安装 RPM 以使用它。当然,如前所述,如果你想在 RPM 中进行任何更改,则必须修改 spec 文件,我们将在下一篇文章中介绍 spec 文件。
|
||||
|
||||
### 总结
|
||||
|
||||
总结一下这篇文章有两点:
|
||||
|
||||
* 我们通常安装使用的 RPM 是包含软件的构建版本的 “二进制” RPM
|
||||
* 构建 RPM 来自于源 RPM,源 RPM 包括用于生成二进制 RPM 所需的源代码和规范文件。
|
||||
|
||||
如果你想开始构建 RPM,并帮助 Fedora 社区维护我们提供的大量软件,则可以从这里开始: <https://fedoraproject.org/wiki/Join_the_package_collection_maintainers>
|
||||
|
||||
如有任何疑问,请发邮件到 [Fedora 开发人员邮件列表][3],我们随时乐意为你提供帮助!
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://fedoramagazine.org/how-rpm-packages-are-made-the-source-rpm/
|
||||
|
||||
作者:[Ankur Sinha "FranciscoD"][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[wxy](https://github.com/wxy)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://fedoramagazine.org/author/ankursinha/
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://fedoramagazine.org/wp-content/uploads/2019/06/rpm.png-816x345.jpg
|
||||
[2]: https://linux.cn/article-11452-1.html
|
||||
[3]: https://lists.fedoraproject.org/archives/list/devel@lists.fedoraproject.org/
|
@ -1,238 +0,0 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: ( )
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
[#]: subject: (How RPM packages are made: the source RPM)
|
||||
[#]: via: (https://fedoramagazine.org/how-rpm-packages-are-made-the-source-rpm/)
|
||||
[#]: author: (Ankur Sinha "FranciscoD" https://fedoramagazine.org/author/ankursinha/)
|
||||
|
||||
How RPM packages are made: the source RPM
|
||||
======
|
||||
|
||||
![][1]
|
||||
|
||||
In a [previous post, we looked at what RPM packages are][2]. They are archives that contain files and metadata. This metadata tells RPM where to create or remove files from when an RPM is installed or uninstalled. The metadata also contains information on “dependencies”, which you will remember from the previous post, can either be “runtime” or “build time”.
|
||||
|
||||
As an example, we will look at _fpaste_. You can download the RPM using _dnf_. This will download the latest version of _fpaste_ that is available in the Fedora repositories. On Fedora 30, this is currently 0.3.9.2:
|
||||
|
||||
```
|
||||
$ dnf download fpaste
|
||||
|
||||
...
|
||||
fpaste-0.3.9.2-2.fc30.noarch.rpm
|
||||
```
|
||||
|
||||
Since this is the built RPM, it contains only files needed to use _fpaste_:
|
||||
|
||||
```
|
||||
$ rpm -qpl ./fpaste-0.3.9.2-2.fc30.noarch.rpm
|
||||
/usr/bin/fpaste
|
||||
/usr/share/doc/fpaste
|
||||
/usr/share/doc/fpaste/README.rst
|
||||
/usr/share/doc/fpaste/TODO
|
||||
/usr/share/licenses/fpaste
|
||||
/usr/share/licenses/fpaste/COPYING
|
||||
/usr/share/man/man1/fpaste.1.gz
|
||||
```
|
||||
|
||||
### Source RPMs
|
||||
|
||||
The next link in the chain is the source RPM. All software in Fedora must be built from its source code. We do not include pre-built binaries. So, for an RPM file to be made, RPM (the tool) needs to be:
|
||||
|
||||
* given the files that have to be installed,
|
||||
* told how to generate these files, if they are to be compiled, for example,
|
||||
* told where these files must be installed,
|
||||
* what other dependencies this particular software needs to work properly.
|
||||
|
||||
|
||||
|
||||
The source RPM holds all of this information. Source RPMs are similar archives to RPM, but as the name suggests, instead of holding the built binary files, they contain the source files for a piece of software. Let’s download the source RPM for _fpaste_:
|
||||
|
||||
```
|
||||
$ dnf download fpaste --source
|
||||
...
|
||||
fpaste-0.3.9.2-2.fc30.src.rpm
|
||||
```
|
||||
|
||||
Notice how the file ends with “src.rpm”. All RPMs are built from source RPMs. You can easily check what source RPM a “binary” RPM comes from using dnf too:
|
||||
|
||||
```
|
||||
$ dnf repoquery --qf "%{SOURCERPM}" fpaste
|
||||
fpaste-0.3.9.2-2.fc30.src.rpm
|
||||
```
|
||||
|
||||
Also, since this is the source RPM, it does not contain built files. Instead, it contains the sources and instructions on how to build the RPM from them:
|
||||
|
||||
```
|
||||
$ rpm -qpl ./fpaste-0.3.9.2-2.fc30.src.rpm
|
||||
fpaste-0.3.9.2.tar.gz
|
||||
fpaste.spec
|
||||
```
|
||||
|
||||
Here, the first file is simply the source code for _fpaste_. The second is the “spec” file. The spec file is the recipe that tells RPM (the tool) how to create the RPM (the archive) using the sources contained in the source RPM—all the information that RPM (the tool) needs to build RPMs (the archives) are contained in spec files. When we package maintainers add software to Fedora, most of our time is spent writing and perfecting the individual spec files. When a software package needs an update, we go back and tweak the spec file. You can see the spec files for ALL packages in Fedora at our source repository at <https://src.fedoraproject.org/browse/projects/>
|
||||
|
||||
Note that one source RPM may contain the instructions to build multiple RPMs. _fpaste_ is a very simple piece of software, where one source RPM generates one “binary” RPM. Python, on the other hand is more complex. While there is only one source RPM, it generates multiple binary RPMs:
|
||||
|
||||
```
|
||||
$ sudo dnf repoquery --qf "%{SOURCERPM}" python3
|
||||
python3-3.7.3-1.fc30.src.rpm
|
||||
python3-3.7.4-1.fc30.src.rpm
|
||||
|
||||
$ sudo dnf repoquery --qf "%{SOURCERPM}" python3-devel
|
||||
python3-3.7.3-1.fc30.src.rpm
|
||||
python3-3.7.4-1.fc30.src.rpm
|
||||
|
||||
$ sudo dnf repoquery --qf "%{SOURCERPM}" python3-libs
|
||||
python3-3.7.3-1.fc30.src.rpm
|
||||
python3-3.7.4-1.fc30.src.rpm
|
||||
|
||||
$ sudo dnf repoquery --qf "%{SOURCERPM}" python3-idle
|
||||
python3-3.7.3-1.fc30.src.rpm
|
||||
python3-3.7.4-1.fc30.src.rpm
|
||||
|
||||
$ sudo dnf repoquery --qf "%{SOURCERPM}" python3-tkinter
|
||||
python3-3.7.3-1.fc30.src.rpm
|
||||
python3-3.7.4-1.fc30.src.rpm
|
||||
```
|
||||
|
||||
In RPM jargon, “python3” is the “main package”, and so the spec file will be called “python3.spec”. All the other packages are “sub-packages”. You can download the source RPM for python3 and see what’s in it too. (Hint: patches are also part of the source code):
|
||||
|
||||
```
|
||||
$ dnf download --source python3
|
||||
python3-3.7.4-1.fc30.src.rpm
|
||||
|
||||
$ rpm -qpl ./python3-3.7.4-1.fc30.src.rpm
|
||||
00001-rpath.patch
|
||||
00102-lib64.patch
|
||||
00111-no-static-lib.patch
|
||||
00155-avoid-ctypes-thunks.patch
|
||||
00170-gc-assertions.patch
|
||||
00178-dont-duplicate-flags-in-sysconfig.patch
|
||||
00189-use-rpm-wheels.patch
|
||||
00205-make-libpl-respect-lib64.patch
|
||||
00251-change-user-install-location.patch
|
||||
00274-fix-arch-names.patch
|
||||
00316-mark-bdist_wininst-unsupported.patch
|
||||
Python-3.7.4.tar.xz
|
||||
check-pyc-timestamps.py
|
||||
idle3.appdata.xml
|
||||
idle3.desktop
|
||||
python3.spec
|
||||
```
|
||||
|
||||
### Building an RPM from a source RPM
|
||||
|
||||
Now that we have the source RPM, and know what’s in it, we can rebuild our RPM from it. Before we do so, though, we should set our system up to build RPMs. First, we install the required tools:
|
||||
|
||||
```
|
||||
$ sudo dnf install fedora-packager
|
||||
```
|
||||
|
||||
This will install the rpmbuild tool. rpmbuild requires a default layout so that it knows where each required component of the source rpm is. Let’s see what they are:
|
||||
|
||||
```
|
||||
# Where should the spec file go?
|
||||
$ rpm -E %{_specdir}
|
||||
/home/asinha/rpmbuild/SPECS
|
||||
|
||||
# Where should the sources go?
|
||||
$ rpm -E %{_sourcedir}
|
||||
/home/asinha/rpmbuild/SOURCES
|
||||
|
||||
# Where is temporary build directory?
|
||||
$ rpm -E %{_builddir}
|
||||
/home/asinha/rpmbuild/BUILD
|
||||
|
||||
# Where is the buildroot?
|
||||
$ rpm -E %{_buildrootdir}
|
||||
/home/asinha/rpmbuild/BUILDROOT
|
||||
|
||||
# Where will the source rpms be?
|
||||
$ rpm -E %{_srcrpmdir}
|
||||
/home/asinha/rpmbuild/SRPMS
|
||||
|
||||
# Where will the built rpms be?
|
||||
$ rpm -E %{_rpmdir}
|
||||
/home/asinha/rpmbuild/RPMS
|
||||
```
|
||||
|
||||
I have all of this set up on my system already:
|
||||
|
||||
```
|
||||
$ cd
|
||||
$ tree -L 1 rpmbuild/
|
||||
rpmbuild/
|
||||
├── BUILD
|
||||
├── BUILDROOT
|
||||
├── RPMS
|
||||
├── SOURCES
|
||||
├── SPECS
|
||||
└── SRPMS
|
||||
|
||||
6 directories, 0 files
|
||||
```
|
||||
|
||||
RPM provides a tool that sets it all up for you too:
|
||||
|
||||
```
|
||||
$ rpmdev-setuptree
|
||||
```
|
||||
|
||||
Then we ensure that we have all the build dependencies for _fpaste_ installed:
|
||||
|
||||
```
|
||||
sudo dnf builddep fpaste-0.3.9.2-3.fc30.src.rpm
|
||||
```
|
||||
|
||||
For _fpaste_ you only need Python and that must already be installed on your system (dnf uses Python too). The builddep command can also be given a spec file instead of an source RPM. Read more in the man page:
|
||||
|
||||
```
|
||||
$ man dnf.plugin.builddep
|
||||
```
|
||||
|
||||
Now that we have all that we need, building an RPM from a source RPM is as simple as:
|
||||
|
||||
```
|
||||
$ rpmbuild --rebuild fpaste-0.3.9.2-3.fc30.src.rpm
|
||||
..
|
||||
..
|
||||
|
||||
$ tree ~/rpmbuild/RPMS/noarch/
|
||||
/home/asinha/rpmbuild/RPMS/noarch/
|
||||
└── fpaste-0.3.9.2-3.fc30.noarch.rpm
|
||||
|
||||
0 directories, 1 file
|
||||
```
|
||||
|
||||
rpmbuild will install the source RPM and build your RPM from it. You can now install the RPM to use it as you do–using dnf. Of course, as said before, if you want to change anything in the RPM, you must modify the spec file—we’ll cover spec files in next post.
|
||||
|
||||
### Summary
|
||||
|
||||
To summarise this post in two short points:
|
||||
|
||||
* the RPMs we generally install to use software are “binary” RPMs that contain built versions of the software
|
||||
* these are built from source RPMs that include the source code and the spec file that are needed to generate the binary RPMs.
|
||||
|
||||
|
||||
|
||||
If you’d like to get started with building RPMs, and help the Fedora community maintain the massive amount of software we provide, you can start here: <https://fedoraproject.org/wiki/Join_the_package_collection_maintainers>
|
||||
|
||||
For any queries, post to the [Fedora developers mailing list][3]—we’re always happy to help!
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://fedoramagazine.org/how-rpm-packages-are-made-the-source-rpm/
|
||||
|
||||
作者:[Ankur Sinha "FranciscoD"][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[译者ID](https://github.com/译者ID)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://fedoramagazine.org/author/ankursinha/
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://fedoramagazine.org/wp-content/uploads/2019/06/rpm.png-816x345.jpg
|
||||
[2]: https://fedoramagazine.org/rpm-packages-explained/
|
||||
[3]: https://lists.fedoraproject.org/archives/list/devel@lists.fedoraproject.org/
|
@ -1,116 +0,0 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (geekpi)
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
[#]: subject: (SQLite is really easy to compile)
|
||||
[#]: via: (https://jvns.ca/blog/2019/10/28/sqlite-is-really-easy-to-compile/)
|
||||
[#]: author: (Julia Evans https://jvns.ca/)
|
||||
|
||||
SQLite is really easy to compile
|
||||
======
|
||||
|
||||
In the last week I’ve been working on another SQL website (<https://sql-steps.wizardzines.com/>, a list of SQL examples). I’m running all the queries on that site with sqlite, and I wanted to use window functions in one of the examples ([this one][1]).
|
||||
|
||||
But I’m using the version of sqlite from Ubuntu 18.04, and that version is too old and doesn’t support window functions. So I needed to upgrade sqlite!
|
||||
|
||||
This turned to out be surprisingly annoying (as usual), but in a pretty interesting way! I was reminded of some things about how executables and shared libraries work and it had a very satisfying conclusion. So I wanted to write it up here.
|
||||
|
||||
(spoiler: the summary is that <https://www.sqlite.org/howtocompile.html> explains how to compile SQLite and it takes like 5 seconds to do and it’s 20x easier than my usual experiences compiling software from source)
|
||||
|
||||
### attempt 1: download a SQLite binary from their website
|
||||
|
||||
The [SQLite download page][2] has a link to a Linux binary for the SQLite command line tool. I downloaded it, it worked on my laptop, and I thought I was done.
|
||||
|
||||
But then I tried to run it on a build server I was using (Netlify), and I got this extremely strange error message: “File not found”. I straced it, and sure enough `execve` was returning the error code ENOENT, which means “File not found”. This was kind of maddening because the file was DEFINITELY there and it had the correct permissions and everything.
|
||||
|
||||
I googled this problem (by searching “execve enoent”), found [this stack overflow answer][3], which pointed out that to run a binary, you don’t just need the binary to exist! You also need its **loader** to exist. (the path to the loader is inside the binary)
|
||||
|
||||
To see the path for the loader you can use `ldd`, like this:
|
||||
|
||||
```
|
||||
$ ldd sqlite3
|
||||
linux-gate.so.1 (0xf7f9d000)
|
||||
libdl.so.2 => /lib/i386-linux-gnu/libdl.so.2 (0xf7f70000)
|
||||
libm.so.6 => /lib/i386-linux-gnu/libm.so.6 (0xf7e6e000)
|
||||
libz.so.1 => /lib/i386-linux-gnu/libz.so.1 (0xf7e4f000)
|
||||
libc.so.6 => /lib/i386-linux-gnu/libc.so.6 (0xf7c73000)
|
||||
/lib/ld-linux.so.2
|
||||
```
|
||||
|
||||
So `/lib/ld-linux.so.2` is the loader,and that file doesn’t exist on the build server, probably because that Xenial installation didn’t have support for 32-bit binaries (?), and I needed to try something different.
|
||||
|
||||
### attempt 2: install the Debian sqlite3 package
|
||||
|
||||
Okay, I thought, maybe I can install the [sqlite package from debian testing][4]. Trying to install a package from a different Debian version that I’m not using is literally never a good idea, but for some reason I decided to try it anyway.
|
||||
|
||||
Doing this completely unsurprisingly broke the sqlite installation on my computer (which also broke git), but I managed to recover from that with a bunch of `sudo dpkg --purge --force-all libsqlite3-0` and make everything that depended on sqlite work again.
|
||||
|
||||
### attempt 3: extract the Debian sqlite3 package
|
||||
|
||||
I also briefly tried to just extract the sqlite3 binary from the Debian sqlite package and run it. Unsurprisingly, this also didn’t work, but in a more understandable way: I had an older version of libreadline (.so.7) and it wanted .so.8.
|
||||
|
||||
```
|
||||
$ ./usr/bin/sqlite3
|
||||
./usr/bin/sqlite3: error while loading shared libraries: libreadline.so.8: cannot open shared object file: No such file or directory
|
||||
```
|
||||
|
||||
### attempt 4: compile it from source
|
||||
|
||||
The whole reason I spent all this time trying to download sqlite binaries is that I assumed it would be annoying or time consuming to compile sqlite from source. But obviously downloading random sqlite binaries was not working for me at all, so I finally decided to try to compile it myself.
|
||||
|
||||
Here are the directions: [How to compile SQLite][5]. And they’re the EASIEST THING IN THE UNIVERSE. Often compiling things feels like this:
|
||||
|
||||
* run `./configure`
|
||||
* realize i’m missing a dependency
|
||||
* run `./configure` again
|
||||
* run `make`
|
||||
* the compiler fails because actually i have the wrong version of some dependency
|
||||
* go do something else and try to find a binary
|
||||
|
||||
|
||||
|
||||
Compiling SQLite works like this:
|
||||
|
||||
* download an [amalgamation tarball from the download page][2]
|
||||
* run `gcc shell.c sqlite3.c -lpthread -ldl`
|
||||
* that’s it!!!
|
||||
|
||||
|
||||
|
||||
All the code is in one file (`sqlite.c`), and there are no weird dependencies! It’s amazing.
|
||||
|
||||
For my specific use case I didn’t actually need threading support or readline support or anything, so I used the instructions on the compile page to create a very simple binary that only used libc and no other shared libraries.
|
||||
|
||||
```
|
||||
$ ldd sqlite3
|
||||
linux-vdso.so.1 (0x00007ffe8e7e9000)
|
||||
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fbea4988000)
|
||||
/lib64/ld-linux-x86-64.so.2 (0x00007fbea4d79000)
|
||||
```
|
||||
|
||||
### this is nice because it makes it easy to experiment with sqlite
|
||||
|
||||
I think it’s cool that SQLite’s build process is so simple because in the past I’ve had fun [editing sqlite’s source code][6] to understand how its btree implementation works.
|
||||
|
||||
This isn’t really super surprising given what I know about SQLite (it’s made to work really well in restricted / embedded contexts, so it makes sense that it would be possible to compile it in a really simple/minimal way). But it is super nice!
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://jvns.ca/blog/2019/10/28/sqlite-is-really-easy-to-compile/
|
||||
|
||||
作者:[Julia Evans][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[译者ID](https://github.com/译者ID)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://jvns.ca/
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://sql-steps.wizardzines.com/lag.html
|
||||
[2]: https://www.sqlite.org/download.html
|
||||
[3]: https://stackoverflow.com/questions/5234088/execve-file-not-found-when-stracing-the-very-same-file
|
||||
[4]: https://packages.debian.org/bullseye/amd64/sqlite3/download
|
||||
[5]: https://www.sqlite.org/howtocompile.html
|
||||
[6]: https://jvns.ca/blog/2014/10/02/how-does-sqlite-work-part-2-btrees/
|
@ -1,5 +1,5 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: ( )
|
||||
[#]: translator: (geekpi)
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
|
116
translated/tech/20191028 SQLite is really easy to compile.md
Normal file
116
translated/tech/20191028 SQLite is really easy to compile.md
Normal file
@ -0,0 +1,116 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (geekpi)
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
[#]: subject: (SQLite is really easy to compile)
|
||||
[#]: via: (https://jvns.ca/blog/2019/10/28/sqlite-is-really-easy-to-compile/)
|
||||
[#]: author: (Julia Evans https://jvns.ca/)
|
||||
|
||||
SQLite 真的很容易编译
|
||||
======
|
||||
|
||||
上周,我一直在做一个 SQL 网站(<https://sql-steps.wizardzines.com/>,一个 SQL 示例列表)。我使用 sqlite 运行网站上的所有查询,并且我想在其中一个例子([这个][1])中使用窗口函数。
|
||||
|
||||
但是我使用的是 Ubuntu 18.04 中的 sqlite 版本,它太旧了,不支持窗口函数。所以我需要升级 sqlite!
|
||||
|
||||
事实证明,这令人讨厌(通常),但是非常有趣!我想起了一些有关可执行文件和共享库如何工作的信息,结论令人满意。所以我想在这里写下来。
|
||||
|
||||
(剧透:<https://www.sqlite.org/howtocompile.html> 中解释了如何编译 SQLite,它只需花费 5 秒左右,这比我平时从源码编译的经验容易了许多。)
|
||||
|
||||
### 尝试 1:从它的网站下载 SQLite 二进制文件
|
||||
|
||||
[SQLite 的下载页面][2]有一个用于 Linux 的 SQLite 命令行工具的二进制文件的链接。我下载了它,它可以在笔记本电脑上运行,我以为这就完成了。
|
||||
|
||||
但是后来我尝试在构建服务器 (Netlify) 上运行它,得到了这个极其奇怪的错误消息:“File not found”。我进行了追踪,并确定 `execve` 返回错误代码 ENOENT,这意味着 “File not found”。这有点令人发狂,因为该文件确实存在,并且有正确的权限。
|
||||
|
||||
|
||||
我搜索了这个问题(通过搜索 “execve enoen”),找到了[这个 stackoverflow 中的答案][3],它指出要运行二进制文件,你不仅需要二进制文件存在!你还需要它的**加载程序**才能存在。 (加载程序的路径在二进制文件内部)
|
||||
|
||||
要查看加载程序的路径,可以使用 `ldd`,如下所示:
|
||||
|
||||
```
|
||||
$ ldd sqlite3
|
||||
linux-gate.so.1 (0xf7f9d000)
|
||||
libdl.so.2 => /lib/i386-linux-gnu/libdl.so.2 (0xf7f70000)
|
||||
libm.so.6 => /lib/i386-linux-gnu/libm.so.6 (0xf7e6e000)
|
||||
libz.so.1 => /lib/i386-linux-gnu/libz.so.1 (0xf7e4f000)
|
||||
libc.so.6 => /lib/i386-linux-gnu/libc.so.6 (0xf7c73000)
|
||||
/lib/ld-linux.so.2
|
||||
```
|
||||
|
||||
所以 `/lib/ld-linux.so.2` 是加载程序,而该文件在构建服务器上不存在,可能是因为 Xenial 安装程序不支持 32 位二进制文件(?),因此我需要尝试一些不同的东西。
|
||||
|
||||
### 尝试 2:安装 Debian sqlite3 软件包
|
||||
|
||||
好吧,我想我也许可以安装来自 [debian testing 的 sqlite 软件包][4]。尝试从另一个我不使用的 Debian 版本安装软件包并不是一个好主意,但是出于某种原因,我还是决定尝试一下。
|
||||
|
||||
这次毫不意外地破坏了我计算机上的 sqlite(这也破坏了 git),但我设法通过 `sudo dpkg --purge --force-all libsqlite3-0` 从中恢复,并使所有依赖于 sqlite 的软件再次工作。
|
||||
|
||||
### 尝试 3:提取 Debian sqlite3 软件包
|
||||
|
||||
我还尝试仅从 Debian sqlite 软件包中提取 sqlite3 二进制文件并运行它。毫不意外,这也行不通,但这个更容易理解:我有旧版本的 libreadline(.so.7),但它需要 .so.8。
|
||||
|
||||
```
|
||||
$ ./usr/bin/sqlite3
|
||||
./usr/bin/sqlite3: error while loading shared libraries: libreadline.so.8: cannot open shared object file: No such file or directory
|
||||
```
|
||||
|
||||
### 尝试 4:从源代码进行编译
|
||||
|
||||
我花费这么多时间尝试下载 sqlite 二进制的原因是我认为从源代码编译 sqlite 既烦人又耗时。但是显然,下载随机的 sqlite 二进制文件根本不适合我,因此我最终决定尝试自己编译它。
|
||||
|
||||
这有指导:[如何编译 SQLite][5]。它是宇宙中最简单的东西。通常,编译的感觉是类似这样的:
|
||||
|
||||
* 运行 `./configure`
|
||||
* 意识到我缺少依赖
|
||||
* 再次运行 `./configure`
|
||||
* 运行 `make`
|
||||
* 编译失败,因为我安装了错误版本的依赖
|
||||
* 去做其他事,之后找到二进制文件
|
||||
|
||||
|
||||
|
||||
编译 SQLite 的方式如下:
|
||||
|
||||
* [从下载页面下载整合的 tarball][[2]
|
||||
* 运行 `gcc shell.c sqlite3.c -lpthread -ldl`
|
||||
* 完成!!!
|
||||
|
||||
|
||||
所有代码都在一个文件(`sqlite.c`)中,并且没有奇怪的依赖项!太奇妙了。
|
||||
|
||||
对我而言,我实际上并不需要线程支持或 readline 支持,因此我用编译页面上的说明来创建了一个非常简单的二进制文件,它仅使用了 libc 而没有其他共享库。
|
||||
|
||||
```
|
||||
$ ldd sqlite3
|
||||
linux-vdso.so.1 (0x00007ffe8e7e9000)
|
||||
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fbea4988000)
|
||||
/lib64/ld-linux-x86-64.so.2 (0x00007fbea4d79000)
|
||||
```
|
||||
|
||||
### 这很好,因为它使体验 sqlite 变得容易
|
||||
|
||||
我认为 SQLite 的构建过程如此简单很酷,因为过去我很乐于[编辑 sqlite 的源码][6]来了解其 B 树的实现方式。
|
||||
|
||||
鉴于我对 SQLite 的了解,这并不令人感到意外(它在受限环境/嵌入式中确实可以很好地工作,因此可以以一种非常简单/最小的方式进行编译是有意义的)。 但这真是太好了!
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://jvns.ca/blog/2019/10/28/sqlite-is-really-easy-to-compile/
|
||||
|
||||
作者:[Julia Evans][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[geekpi](https://github.com/geekpi)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://jvns.ca/
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://sql-steps.wizardzines.com/lag.html
|
||||
[2]: https://www.sqlite.org/download.html
|
||||
[3]: https://stackoverflow.com/questions/5234088/execve-file-not-found-when-stracing-the-very-same-file
|
||||
[4]: https://packages.debian.org/bullseye/amd64/sqlite3/download
|
||||
[5]: https://www.sqlite.org/howtocompile.html
|
||||
[6]: https://jvns.ca/blog/2014/10/02/how-does-sqlite-work-part-2-btrees/
|
Loading…
Reference in New Issue
Block a user