Ubuntu 下 C/C++ 编程与 Mono 开发全解析
1. C 与 C++ 基础
Linux 内核大多用 C 语言编写,这使得 Linux 能适配众多不同的 CPU。C++ 是 C 语言的面向对象扩展,C++ 编译器能正确编译 C 程序,且可以在 C++ 中编写非面向对象代码,但 C 编译器无法编译 C++ 代码。C++ 通过提供面向对象设计和代码所需的特性扩展了 C 的功能,还具备一些如将函数与数据结构关联等不依赖基于类的面向对象技术的特性,这使得现有的 UNIX 程序能逐步向面向对象迁移。gcc 支持 C++ 编程,编译 C++ 代码时使用 g++ 命令。
2. Ubuntu 中的 C/C++ 项目管理工具
Ubuntu 提供了丰富的工具,让 C/C++ 程序员的工作更轻松,具体如下表所示:
|工具类型|工具名称|功能|
| ---- | ---- | ---- |
|程序创建|编辑器|创建程序代码|
|程序编译|gcc|编译程序|
|库创建|ar|创建库|
|源码控制|Git、Mercurial、Subversion|控制源码|
|自动构建|make|自动构建程序|
|程序调试|gdb 和 ddd|调试程序|
|性能分析|gprof|分析程序性能瓶颈|
3. 使用 make 构建程序
-
使用 Makefiles
:make 命令通过 Makefile 自动构建和更新应用程序。Makefile 是一个文本文件,包含传递给编译器预处理器、编译器、汇编器和链接器的选项,还指定了要编译的源文件以及构建程序所需的代码模块,这一机制称为依赖检查。make 命令非常灵活,可以使用简单的 Makefile,也可以编写包含大量宏、规则或命令的复杂 Makefile,它几乎可以与任何程序配合使用,包括 TeX 等文本处理系统。
-
编译、构建和安装软件包的简单命令:
sudo make install -
使用指定的 Makefile:
sudo make -f MyMakeFile -
查看 make 的内置规则:
make -p
-
编译、构建和安装软件包的简单命令:
- 使用宏和 Makefile 目标 :使用宏可以使程序具有可移植性,用户可以通过指定本地值(如所需软件工具的名称、位置或路径名)轻松配置程序构建。以下是一个示例 Makefile:
# a sample makefile for a skeleton program
CC= gcc
INS= install
INSDIR = /usr/local/bin
LIBDIR= -L/usr/X11R6/lib
LIBS= -lXm -lSM -lICE -lXt -lX11
SRC= skel.c
OBJS= skel.o
PROG= skel
skel: ${OBJS}
${CC} -o ${PROG} ${SRC} ${LIBDIR} ${LIBS}
install: ${PROG}
${INS} -g root -o root ${PROG} ${INSDIR}
注意:上述示例中的缩进行使用的是制表符,而非空格,这一点非常重要。使用该 Makefile 构建程序的命令如下:
- 构建程序:
sudo make
- 构建指定目标:
sudo make skel
- 一步完成构建和安装:
sudo make install
大型软件项目的 Makefile 可能包含以下传统目标:
- test:对最终软件运行特定测试。
- man:使用 man 宏处理包含文件或 troff 文档。
- clean:删除任何剩余的目标文件。
- archive:清理、归档和压缩整个源代码树。
- bugreport:自动收集并邮寄构建或错误日志的副本。
4. 使用 autoconf 工具配置代码
许多以源码形式分发的 Linux 软件包需要使用 GNU 的 autoconf 工具。该工具会生成一个名为 configure 的可执行 shell 脚本,执行该脚本时,它会根据目标主机(Linux 系统)上安装的软件资源(如编程工具、库和相关实用程序)自动检查并定制客户端的源码构建。配置源码包、构建软件并安装新程序的步骤如下:
1. 解压源码:将源码包解压到指定目录。
2. 进入构建目录:使用
cd
命令进入解压后的目录。
3. 执行配置脚本:
./configure
,该脚本会检查系统环境,生成 Makefile。
4. 构建软件:
make
,根据 Makefile 编译源码。
5. 安装软件:
sudo make install
,将编译好的程序安装到系统中。
autoconf 使用一个名为 configure.in 的文件,该文件包含基本规则集或宏集,可使用 autoscan 命令创建。构建正确执行的 configure 脚本还需要一个名为 Makefile.in 的 Makefile 模板。虽然可以手动创建依赖检查的 configure 脚本,但使用 KDE 的 KDevelop 或 GNOME 的 Glade 等图形化项目开发工具可以轻松克服任何复杂的依赖关系。
5. 调试工具
调试既是一门科学,也是一门艺术。有时,最简单的工具——代码清单就是最好的调试工具,但有时需要使用其他调试工具,如 splint、gprof 和 gdb。
-
使用 splint 检查源代码
:splint 命令类似于传统的 UNIX lint 命令,它静态检查源代码中可能存在的问题,并具有许多额外的功能。即使 C 代码符合 C 标准且能干净地编译,也可能包含错误。splint 可以执行多种类型的检查并提供详细的错误信息。例如:
matthew@seymour:~$ gcc -o tux tux.c
matthew@seymour:~$ ./tux
matthew@seymour:~$ splint tux.c
使用 -strict 选项可以获得更详细的报告:
splint -strict tux.c
。gcc 也通过 -Wall 和 -pedantic 选项提供广泛的警告信息:
gcc -Wall tux.c
。
-
使用 gprof 跟踪函数时间
:gprof 命令用于研究程序的时间开销。如果程序在编译和链接时使用 -p 标志,执行时会创建一个 mon.out 文件,其中包含每个函数的调用频率和执行时间数据。gprof 会解析并显示这些数据,通过分析其输出可以确定性能瓶颈所在。使用优化编译器可以加快程序速度,但花时间使用 gprof 分析并修改瓶颈函数可以显著提高程序性能。
-
使用 gdb 进行符号调试
:gdb 是一个符号调试器。当程序使用 -g 标志编译时,会保留符号表,此时可以使用符号调试器来跟踪程序中的错误。基本技术是在核心转储(包含崩溃程序内存快照的文件)后调用 gdb 并获取堆栈跟踪信息,堆栈跟踪信息会指示核心转储发生的源代码行以及调用到该行的函数,通常这足以识别问题。gdb 还提供了一个交互式调试程序的环境,调用 gdb 并指定程序后,可以设置断点、检查变量值和监视变量。如果怀疑某行代码附近存在问题,可以在该行设置断点并运行 gdb,当程序执行到该行时会中断,此时可以检查变量值、查看堆栈跟踪信息并观察程序环境,还可以单步执行程序以检查值,并在任何时候恢复执行。通过使用断点,可以发现代码中的许多错误。gdb 的图形化 X 窗口界面称为 Data Display Debugger(ddd)。
6. 使用 GNU C 编译器
如果在安装 Ubuntu 时选择安装开发工具包(或者稍后使用 synaptic 安装),就会拥有 GNU C 编译器(gcc)。GNU C 编译器有许多不同的选项,其中很多与其他 UNIX 系统上的 C 和 C++ 编译器的选项类似。可以查看 gcc 的手册页或信息文件以获取完整的选项列表和说明。GNU C 编译器是 GNU Compiler Collection 的一部分,该集合还包括其他几种语言的编译器。使用 gcc 构建 C 程序时,编译过程分为以下几个步骤:
graph LR
A[C 预处理器解析文件] --> B[编译器解析修改后的代码]
B --> C[链接不同的文件和库]
- C 预处理器解析文件:按顺序读取文件行,包含头文件并进行宏替换。
- 编译器解析修改后的代码:检查语法是否正确,构建符号表并创建中间目标格式,大多数符号会被分配特定的内存地址,但其他模块中定义的符号(如外部变量)除外。
- 链接阶段:将不同的文件和库链接在一起,解析之前未解析的符号。
遵循严格的 ANSI 规则,大多数 C 程序可以使用 C++ 编译器编译,例如可以使用 GNU C++ 编译器编译标准的 hello.c 程序,通常可以将文件命名为 hello.cc、hello.C、hello.c++ 或 hello.cxx,GNU C++ 编译器会接受这些名称。
7. 图形化开发工具
Ubuntu 包含许多用于 X 会话的图形化原型设计和开发环境。如果要为 KDE 或 GNOME 构建客户端软件,KDevelop、Qt Designer 和 Glade 等程序会非常有用,可以使用它们构建交互式窗口客户端的图形框架,并自动生成支持自定义界面所需的基本代码框架。
-
使用 KDevelop 客户端
:可以从应用程序菜单或终端窗口的命令行启动 KDevelop 客户端:
kdevelop &
。按下 Enter 键后,KDevelop 设置向导会运行,通过几个简短的向导对话框设置并确保稳定的构建环境,之后需要再次运行 kdevelop(可以从命令行或在桌面面板的编程菜单中点击其菜单项),然后会看到 KDevelop 主窗口,通过选择 KDevelop 的项目菜单并点击新建菜单项可以开始项目。通过逐步完成向导对话框开始构建项目,点击创建按钮后,KDevelop 会自动生成 KDE 客户端源目录中通常包含的所有文件(包括检查依赖关系并构建客户端 Makefile 的 configure 脚本)。测试客户端时,可以点击构建菜单的 Make 菜单项(或按 F8),也可以直接点击执行菜单项(或按 F9),客户端会自动构建。可以使用 KDevelop 创建 KDE 客户端、Konqueror 浏览器插件、KDE 任务栏小程序、KDE 桌面主题、基于 Qt 库的客户端,甚至是 GNOME 程序。
-
使用 Glade 客户端进行 GNOME 开发
:如果更喜欢使用 GNOME 及其开发工具,Glade GTK+ GUI 构建器可以在构建程序的基本框架时节省时间和精力。从桌面面板的编程菜单启动 Glade,启动后会在主目录中创建一个名为 Projects 的目录,并显示一个主窗口以及两个浮动的调色板和属性窗口。可以使用 Glade 的文件菜单保存空白项目,然后通过点击调色板窗口中的用户界面元素来开始构建客户端。例如,先点击调色板窗口的 Gnome 按钮,然后点击创建新客户端的主窗口,会出现一个带有菜单和工具栏的窗口,这就是新 GNOME 客户端的基本框架。
8. 使用 Mono
Microsoft 的 .NET 平台原本是为 Windows 设计的,但由于 Mono 项目的出现,它已经扩展到了许多其他操作系统。Mono 是 .NET 的免费重新实现,遵循 GPL 许可证。由于存在专利问题,大多数发行版花了很长时间才将 Mono 纳入其中,但现在它已经可以正常使用了。Mono 支持 C# 和 Visual Basic .NET,以及完整的 .NET 1.0 和 1.1 框架(以及大部分 2.0 框架),易于学习且使用效率高。
曾经有人担心 Mono 会停止开发。2011 年 5 月初,Attachmate 收购了 Novell 及其 SUSE Linux 发行版,而 Novell 是 Mono 项目的主导者。收购后,Attachmate 做的第一件事就是取消 Mono 项目,并解雇了约 30 名 Mono 开发人员。不过,2011 年 5 月 16 日,Mono 的首席开发人员 Miguel de Icaza 在他的博客上宣布成立了一家名为 Xamarin(http://xamarin.com)的新公司,该公司致力于继续开发 Mono 并构建 Mono 应用程序。许多(如果不是大多数)原来在 Novell 从事 Mono 开发的人员现在都受雇于 Xamarin,并且在 Ubuntu 11.10 中默认安装了 Mono 2.10 以及几个用 Mono 编写的默认应用程序。2011 年 7 月 18 日,SUSE 宣布与 Xamarin 达成知识产权协议并授予永久许可证,允许其继续将 Mono 作为平台进行开发和使用。
Ubuntu 下 C/C++ 编程与 Mono 开发全解析
9. Mono 开发的优势
Mono 为开发者带来了诸多优势,具体体现在以下几个方面:
|优势|说明|
| ---- | ---- |
|跨平台性|打破了 .NET 只能在 Windows 运行的限制,可在多种操作系统上使用,扩大了应用的适用范围。|
|语言支持丰富|支持 C# 和 Visual Basic .NET 等多种语言,开发者可以根据自身熟悉的语言进行开发。|
|框架兼容性|兼容完整的 .NET 1.0 和 1.1 框架以及大部分 2.0 框架,方便开发者复用已有的 .NET 代码和知识。|
|易于学习|对于熟悉 .NET 开发的人员来说,能够快速上手 Mono 开发,降低了学习成本。|
|高效开发|借助 Mono 提供的工具和库,能够提高开发效率,快速构建出高质量的应用程序。|
10. MonoDevelop 开发环境
MonoDevelop 是一个专门为 Mono 开发设计的集成开发环境(IDE),它提供了丰富的功能,帮助开发者更高效地进行 Mono 项目开发,其使用步骤如下:
1.
安装 MonoDevelop
:可以通过 Ubuntu 的软件包管理工具进行安装。
2.
启动 MonoDevelop
:安装完成后,在应用程序菜单中找到 MonoDevelop 并启动。
3.
创建新项目
:启动后,选择“文件” -> “新建” -> “解决方案”,选择合适的项目模板,如 C# 控制台应用程序、C# 桌面应用程序等。
4.
编写代码
:在项目中创建或打开代码文件,开始编写代码。MonoDevelop 提供了代码高亮、智能提示等功能,帮助提高编码效率。
5.
编译和运行
:编写完代码后,点击工具栏上的“编译”按钮进行代码编译。编译成功后,点击“运行”按钮即可运行项目。
11. 基于 Mono 库的开发
Mono 提供了丰富的库,开发者可以基于这些库构建各种类型的应用程序,以下是一个简单的基于 Mono 的 C# 控制台应用程序示例:
using System;
namespace MonoExample
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Hello, Mono!");
Console.ReadLine();
}
}
}
上述代码实现了一个简单的控制台应用程序,在控制台输出“Hello, Mono!”,并等待用户输入。开发基于 Mono 库的应用程序的一般步骤如下:
graph LR
A[确定应用需求] --> B[选择合适的 Mono 库]
B --> C[创建项目]
C --> D[引用 Mono 库]
D --> E[编写代码实现功能]
E --> F[编译和测试]
- 确定应用需求 :明确要开发的应用程序的功能和目标。
- 选择合适的 Mono 库 :根据应用需求,从 Mono 提供的库中选择合适的库来使用。
- 创建项目 :使用 MonoDevelop 或其他开发工具创建一个新的项目。
- 引用 Mono 库 :在项目中引用所需的 Mono 库。
- 编写代码实现功能 :根据应用需求和所选的 Mono 库,编写代码实现具体的功能。
- 编译和测试 :编译代码并进行测试,确保应用程序能够正常运行。
12. 总结
在 Ubuntu 系统下,无论是 C/C++ 编程还是 Mono 开发,都有丰富的工具和资源可供使用。C/C++ 编程方面,Ubuntu 提供了一系列完善的项目管理工具,如 make、autoconf 等,以及强大的编译和调试工具,如 gcc、gdb 等,同时还有方便的图形化开发工具,如 KDevelop 和 Glade,能够帮助开发者高效地进行程序开发和调试。而 Mono 开发则为开发者提供了在 Linux 系统上使用 .NET 技术的可能,通过 MonoDevelop 和丰富的 Mono 库,开发者可以轻松构建出跨平台的应用程序。
总之,Ubuntu 为开发者提供了一个强大而灵活的开发环境,无论是初学者还是有经验的开发者,都能在其中找到适合自己的开发方式和工具,从而实现各种创意和功能。希望本文介绍的内容能够对大家在 Ubuntu 下的 C/C++ 编程和 Mono 开发有所帮助。
超级会员免费看
7

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



