Linux 软件开发与应用全解析
1. pkg - config 相关知识
在 Ubuntu 系统中,位于
/usr/lib/i386 - linux - gnu/pkgconfig
的 OpenSSL 配置文件如下:
prefix=/usr
exec_prefix=${prefix}
libdir=${exec_prefix}/lib/i386-linux-gnu
includedir=${prefix}/include
Name: OpenSSL
Description: Secure Sockets Layer and cryptography libraries and tools
Version: 1.0.1
Requires:
Libs: -L${libdir} -lssl -lcrypto
Libs.private: -ldl -lz
Cflags: -I${includedir} exec_prefix=${prefix}
这个文件可以进行修改,例如在库标志中添加
-Wl,-rpath=${libdir}
来定义运行时的动态链接器路径。
pkg - config 默认会在其安装前缀的
lib/pkgconfig
目录中查找
.pc
文件。例如,安装前缀为
/usr/local
的 pkg - config 会在
/usr/local/lib/pkgconfig
中查找。
若要安装非标准位置的 pkg - config 文件,有两种基本方法:
- 创建
.pc
文件的符号链接(或副本)到中央
pkgconfig
目录。
- 设置环境变量
PKG_CONFIG_PATH
以包含额外的
pkgconfig
目录,但这种策略并非对整个系统都适用。
2. 软件安装相关
了解如何生成和安装软件固然重要,但知道何时以及在何处安装自己的软件包更为关键。自己安装软件包有以下优点和缺点:
| 优点 | 缺点 |
| — | — |
| 可以自定义软件包的默认设置。 | 需要花费时间。 |
| 安装软件包时,通常能更清楚地了解如何使用它。 | 自定义软件包不会自动更新,对于与网络交互的软件包,需要手动保证安全更新。 |
| 可以控制要运行的版本。 | 如果不实际使用该软件包,就是在浪费时间。 |
| 更易于备份自定义软件包。 | 存在错误配置软件包的风险。 |
| 在网络中更易于分发自己安装的软件包(前提是架构一致且安装位置相对独立)。 | |
一般来说,默认在 GNU autoconf 和其他一些软件包中的安装前缀是
/usr/local
,这是本地安装软件的传统目录。系统升级会忽略
/usr/local
,所以在系统升级时不会丢失安装在该目录下的软件。但如果安装了大量自定义软件,可能会导致
/usr/local
目录变得混乱。若情况失控,可以创建自己的软件包。
3. 应用补丁
软件源代码的大部分更改通常以开发者在线源代码版本的分支形式提供(例如在 git 仓库中)。但有时会获得一个补丁(修正),需要将其应用到源代码中以修复漏洞或添加功能。
补丁的开头通常如下所示:
--- src/file.c.orig 2015-07-17 14:29:12.000000000 +0100
+++ src/file.c 2015-09-18 10:22:17.000000000 +0100
@@ -2,16 +2,12 @@
通常,补丁会包含对多个文件的更改。在补丁中查找连续的三个连字符(
---
)可以查看有更改的文件,并始终观察补丁的开头以确定所需的工作目录。例如,上述示例引用了
src/file.c
,因此在应用补丁之前,应进入包含
src
的目录,而不是
src
目录本身。
应用补丁的命令如下:
$ patch -p0 < arquivo_de_patch
如果一切顺利,
patch
命令将顺利完成,留下一组更新后的文件。但
patch
可能会询问:
File to patch:
这通常意味着当前不在正确的目录中,也可能表示源代码与补丁中的源代码不匹配。在这种情况下,可能就不太幸运了,即使能识别出一些要应用补丁的文件,其他文件也可能无法正确更新,导致源代码无法编译。
如果补丁引用了软件包的版本,例如:
--- package-3.42/src/file.c.orig 2015-07-17 14:29:12.000000000 +0100
+++ package-3.42/src/file.c 2015-09-18 10:22:17.000000000 +0100
而自己的版本号略有不同(或只是重命名了目录),可以让
patch
忽略路径中的部分内容。例如,假设当前位于包含
src
的目录中,要让
patch
忽略路径中
package - 3.42/
部分(即移除路径的一个初始组件),可以使用
-p1
:
$ patch -p1 < arquivo_de_patch
4. 编译和安装问题解决
理解编译器错误、编译器警告、链接器错误和共享库问题之间的区别,有助于解决软件开发过程中出现的各种问题。在讨论具体问题之前,需要能够读懂
make
的某些输出类型,了解真正的错误和可忽略的错误之间的区别。
- 真正的错误需要调查,例如:
make: *** [alvo] Error 1
-
一些
Makefile预计可能会出现错误情况,但知道这些错误是无害的,通常以下类型的消息可以忽略:
make: *** [alvo] Error 1 (ignored)
在大型软件包中,GNU make 通常会多次调用自身,错误消息中的每个
make
实例都会用
[N]
标记,其中
N
是一个数字。通常,在编译器错误消息之后紧接着的
make
错误往往就是问题所在。例如:
[mensagem de erro do compilador envolvendo file.c]
make[3]: *** [file.o] Error 1
make[3]: Leaving directory '/home/src/package-5.0/src'
make[2]: *** [all] Error 2
make[2]: Leaving directory '/home/src/package-5.0/src'
make[1]: *** [all-recursive] Error 1
make[1]: Leaving directory '/home/src/package-5.0/'
make: *** [all] Error 2
从上述输出的前三行可以看出,问题集中在
/home/src/package - 5.0/src
目录下的
file.c
文件。
常见的编译错误及解决方法如下:
-
问题
:编译器错误消息为
src.c:22: conflicting types for 'item'
和
/usr/include/file.h:47: previous declaration of 'item'
。
解释和解决方法
:程序员在
src.c
的第 22 行错误地重新声明了
item
。通常可以通过删除违规行(使用注释、
#ifdef
或其他有效方法)来解决。
-
问题
:编译器错误消息为
src.c:37: 'time_t' undeclared (first use this function)
等。
解释和解决方法
:程序员忘记包含一个关键的头文件。可以通过查看手册页来找到缺失的头文件。首先查看违规行(这里是
src.c
的第 37 行),可能是类似
time_t v1;
的变量声明。在程序中查找
v1
在函数调用附近的使用情况,例如
v1 = time(NULL);
。然后执行
man 2 time
或
man 3 time
查找名为
time()
的系统调用和库调用。在这种情况下,第 2 节的手册页包含所需信息:
SYNOPSIS
#include <time.h>
time_t time(time_t *t);
这意味着
time()
需要
time.h
头文件,将
#include <time.h>
添加到
src.c
的开头,然后再次尝试编译。
-
问题
:编译器(预处理器)错误消息为
src.c:4: pkg.h: No such file or directory
。
解释和解决方法
:编译器在
src.c
上执行 C 预处理器时,找不到
pkg.h
包含文件。源代码可能依赖于一个需要安装的库,或者可能只需要向编译器提供非标准的包含路径。通常,只需要在 C 预处理器标志(
CPPFLAGS
)中添加
-I
包含路径选项(同时可能还需要
-L
链接器标志来配合包含文件)。如果看起来不是缺少库,可能是尝试为不支持该源代码的操作系统进行编译,需要查看
Makefile
和
README
文件以获取平台相关的详细信息。如果使用的是基于 Debian 的发行版,可以尝试执行以下命令:
$ apt-file search pkg.h
对于提供
yum
的发行版,可以尝试:
$ yum provides */pkg.h
-
问题
:
make错误消息为make: prog: Command not found。
解释和解决方法 :要生成软件包,系统中必须有prog。如果prog是cc、gcc或ld之类的工具,说明系统中没有安装开发工具。如果认为prog已经安装在系统中,可以尝试修改Makefile以指定prog的完整路径名。在极少数情况下,make生成prog后立即使用它,假设当前目录(.)在命令路径中。如果$PATH不包含当前目录,可以编辑Makefile将prog改为./prog,或者临时将.添加到路径中。
5. 后续探索方向
软件开发的基础知识只是一个开始,掌握自己的构建过程后,可以探索以下额外主题:
- 了解如何使用除
autoconf
之外的构建系统,如 CMake 和 SCons。
- 为自己的软件配置构建过程。如果正在创建自己的软件,需要选择一个构建系统并学习如何使用它。
- 编译 Linux 内核。内核的构建系统与其他工具的系统完全不同,它有自己的配置系统来定制内核和模块。但操作过程相对简单,只要理解引导加载程序的工作原理,就不会有太大问题。不过要注意,在操作时要始终保留旧内核,以防新内核无法引导。
- 特定发行版的源代码包。Linux 发行版以特殊的源代码包形式维护自己版本的软件源代码。有时可以找到有用的补丁,用于扩展功能或修复无人维护的软件包中的问题。源代码包管理系统包括自动构建工具,如 Debian 的
debuild
和基于 RPM 的
mock
。
6. Linux 在服务器和 Web 应用中的应用
Linux 是一种流行的 Web 服务器操作系统,其中 Apache HTTP Server(通常简称为“Apache”)是 Linux 服务器中的佼佼者。另一个常见的 Web 服务器是 Tomcat(也是一个 Apache 项目),它为基于 Java 的应用程序提供支持。
Web 服务器本身的功能有限,只能提供文件服务。大多数 Web 服务器(如 Apache)的最终目标是提供一个底层平台来运行 Web 应用程序。例如,Wikipedia 是基于 MediaWiki 软件包开发的,用户可以使用它创建自己的维基。WordPress 和 Drupal 等内容管理系统允许用户创建自己的博客和媒体网站。这些应用程序都是用在 Linux 上运行效果特别好的编程语言开发的,如 MediaWiki、WordPress 和 Drupal 都是用 PHP 编写的。
Web 应用程序的构建块具有高度模块化的特点,因此可以轻松添加自己的扩展,并使用 Django、Flask 和 Rails 等框架创建应用程序,这些框架提供了常见的 Web 基础设施和功能,如模板、多用户支持和数据库支持。
一个运行良好的 Web 服务器依赖于操作系统的坚实基础。特别是网络配置不能有任何故障,更重要的是要理解资源管理。合理配置内存和磁盘非常关键,尤其是在应用程序中计划使用数据库时。
7. Linux 中的数据库应用
数据库是专门用于存储和访问数据的服务,许多不同的数据库服务器和系统都可以在 Linux 上运行。数据库具有两个主要特点,使其具有吸引力:它们提供了简单统一的方式来管理单个和分组数据,并且在数据访问方面具有卓越的性能。
与解析和修改文本文件相比,数据库使应用程序更易于分析和更改数据。例如,Linux 系统中的
/etc/passwd
和
/etc/shadow
文件在计算机网络中可能难以维护。可以配置一个数据库,通过 LDAP(轻量级目录访问协议)提供用户信息,为 Linux 认证系统提供这些信息。Linux 客户端的配置很简单,只需要编辑
/etc/nsswitch.conf
文件并添加一些额外的配置即可。
数据库通常在数据访问方面表现出色的主要原因是它们使用索引来跟踪数据的位置。例如,假设有一组数据表示一个包含名字、姓氏和电话号码的列表,数据库可以为其中任何一个属性(如姓氏)创建索引。当根据姓氏查找某人时,数据库只需查询与姓氏相关的索引,而不是搜索整个列表。
数据库主要有两种基本格式:关系型和非关系型。关系型数据库也称为 RDBMS(关系数据库管理系统),非关系型数据库则有不同的特点和适用场景。
Linux 软件开发与应用全解析
8. 关系型与非关系型数据库对比
| 类型 | 特点 | 优势 | 劣势 | 适用场景 |
|---|---|---|---|---|
| 关系型数据库(RDBMS) | 数据以表格形式存储,具有行和列,通过 SQL 进行操作,数据之间存在关联关系。 | 数据一致性强,支持复杂查询,适合处理结构化数据。 | 扩展性较差,处理海量数据时性能可能下降。 | 金融系统、电商系统等对数据一致性要求高的场景。 |
| 非关系型数据库 | 数据存储形式多样,如键值对、文档、图形等,不依赖于传统的表结构。 | 扩展性好,能处理海量数据和高并发,灵活性高。 | 数据一致性较弱,不支持复杂的 SQL 查询。 | 日志分析、实时数据处理、社交网络等场景。 |
常见的关系型数据库有 MySQL、PostgreSQL 等,非关系型数据库有 MongoDB、Redis 等。
9. 数据库操作示例
以下是在 Linux 系统中使用 MySQL 数据库的基本操作步骤:
1.
安装 MySQL
:在基于 Debian 的系统中,可以使用以下命令安装:
sudo apt-get update
sudo apt-get install mysql-server
- 启动 MySQL 服务 :
sudo systemctl start mysql
- 进入 MySQL 命令行 :
sudo mysql -u root -p
输入密码后即可进入 MySQL 命令行界面。
4.
创建数据库
:
CREATE DATABASE testdb;
- 使用数据库 :
USE testdb;
- 创建表 :
CREATE TABLE users (
id INT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(255),
age INT
);
- 插入数据 :
INSERT INTO users (name, age) VALUES ('John', 25);
- 查询数据 :
SELECT * FROM users;
10. 数据库备份与恢复
数据库备份和恢复是保障数据安全的重要操作。以下是使用 mysqldump 工具备份 MySQL 数据库的示例:
1.
备份数据库
:
mysqldump -u root -p testdb > testdb_backup.sql
输入密码后,会将
testdb
数据库备份到
testdb_backup.sql
文件中。
2.
恢复数据库
:
mysql -u root -p testdb < testdb_backup.sql
输入密码后,会将备份文件中的数据恢复到
testdb
数据库中。
11. 总结
通过以上内容,我们对 Linux 系统中的软件开发、安装、补丁应用、编译问题解决以及数据库应用等方面有了较为全面的了解。在软件开发过程中,我们需要掌握 pkg - config 的使用、合理选择软件安装位置、正确应用补丁以及解决常见的编译错误。在数据库应用方面,要了解关系型和非关系型数据库的特点和适用场景,掌握基本的数据库操作和备份恢复方法。
在实际应用中,我们可以根据具体需求选择合适的技术和工具,构建高效、稳定的系统。例如,在开发 Web 应用时,可以选择 Linux 作为服务器操作系统,使用 Apache 或 Tomcat 作为 Web 服务器,结合 MySQL 等数据库存储数据,并使用 Django、Flask 等框架进行开发。
总之,Linux 系统为软件开发和应用提供了丰富的资源和强大的支持,不断学习和实践这些技术,将有助于我们在软件开发领域取得更好的成果。
12. 流程图示例
graph TD;
A[开始] --> B[安装 MySQL];
B --> C[启动 MySQL 服务];
C --> D[进入 MySQL 命令行];
D --> E[创建数据库];
E --> F[使用数据库];
F --> G[创建表];
G --> H[插入数据];
H --> I[查询数据];
I --> J[备份数据库];
J --> K[恢复数据库];
K --> L[结束];
这个流程图展示了在 Linux 系统中使用 MySQL 数据库的基本操作流程,从安装到备份恢复,涵盖了主要的步骤。通过这个流程图,可以更直观地了解数据库操作的顺序和逻辑。
超级会员免费看

被折叠的 条评论
为什么被折叠?



