Linux程序设计笔记(第1章 入门)

1 UNIX、Linux和GNU

* UNIX

UNIX操作系统由贝尔实验室于20世纪70年代开发。

UNIX哲学是这样的,一个程序只做一件事,并做好。

KISS:Keep It Small and Simple

* Linux

Linux是一个可以自由发布的类UNIX内核实现,最初的Linux是由赫尔辛基大学的Linus Torvald开发。

* GNU

Richard Stallman倡导自由软件并发起GNU项目,该项目的宗旨是:试图创建一个与UNIX系统兼容,但并不受UNIX名字和源代码私有权限制的操作系统和开发环境。

GNU是GNU’s Not UNIX的递归缩写。主要的GNU项目软件有:

> GNU Emacs: 文本编辑器及环境

> GCC: GNU编译器集,包括GNU C编译器、G++(C++编译器)

> GDB: 源代码级的调试器

> GNU make: UNIX make 命令的免费版本

> Bison: 与UNIX yacc兼容的语法分析程序生成器

> bash: shell命令解释器

2 Linux程序设计

* Linux程序

Linux与UNIX虽然是用C语言编写,但C语言并不是Linux或UNIX变成的唯一选择,其他可用的部分编程语言有:

Ada CC++

java JavaScript Fortan

LispPascal Objectie C

PerlRuby Smalltalk

Python PHP Bourne Shell

Linux应用程序表现为两种特殊类型的文件:可执行文件与脚本文件。

Linux并不要求可执行文件或脚本文件具有特殊的文件名或扩展名。文件系统属性用来指明一个文件是否为可执行的程序。

* 开发系统引导

软件工具和开发资源在系统中存放的位置。

1> 应用程序

/usr/bin目录:系统为正常使用提供的程序(包括用于程序开发的工具),都可在该目录中找到。

/usr/local/bin目录:系统管理员为某个特定的主机或本地网络添加的程序,通常可在该目录中找到。

建议:

/usr/local目录,用于存放系统级的应用程序。

/home目录,用于存放开发用或个人的应用程序。

2> 头文件

头文件用来提供对常量的定义和对系统函数及库函数调用的声明。

C语言的头文件几乎总是位于/usr/include目录及其子目录中。

那些依赖于特定Linux版本的头文件通常可在目录/usr/include/sys和/usr/include/linux中找到。

3>库文件

标准系统库文件一般存储在/lib和/usr/ib目录中。

库是一组预先编译好的函数的集合,这些函数都是按照可重用的原则编写的。它们通常由一组相互关联的函数组成以执行某项常见的任务,比如屏幕处理函数库(curses和ncurses库)。

库文件的类型:

> .a 即archive(归档文件),代表静态函数库。

> .so 即shared object,用户层的共享函数库。

> .ko 即kernel object, 内核模块,可以手动加载(insmod)、卸载(rmmod)和查询(lsmod)。

* 静态库

函数库最简单的形式是一组处于“准备好使用”状态的目标文件。当程序需要使用函数库中的某个函数时,它包含一个声明该函数的头文件。编译器和链接器负责将程序代码和函数库结合在一起以组成一个单独的可执行文件。

静态库的一个缺点是,当你同时运行许多应用程序并且它们都使用来自同一个函数库的函数时,内存中就会有同一函数的多份副本,而且在程序文件自身中也有多份同样的副本。这将消耗大量内存和磁盘空间。

静态库,也称作归档文件(archive),按惯例它们的文件都以.a结尾。(使用ar程序和gcc -c命令对函数分别进行编译,就可以创建和维护自己的静态库)。例如,标准C语言函数库/usr/lib/libc.a

接下来,利用gcc与ar来创建一个小型函数库libfoo.a,它包含两个函数(fred和bill),并在一个示例中调用其中一个函数。

> 首先为库文件的两个函数创建各自的源文件fred.c和bill.c,并创建库文件的头文件lib.h。(该头文件最好也包含在源文件fred.c和bill.c中,这将帮助编译器发现所有错误)

/* * @file lib.h 函数库的头文件 */void bill(char *);void fred(int);

/* * @file fred.c源文件 * */#include <stdio.h>#include "lib.h"void fred(int arg){    printf("fred: we passed %d\n", arg);}

/* * @file   bill.c源文件 * */#include <stdio.h>#include "lib.h"void bill(char *arg){    printf("bill: we passed %s\n", arg);}

>分别编译这些函数以产生药包含在库文件中的目标文件。(gcc中-c选项的作用是阻止编译器创建一个完整的程序)

$ gcc -c bill.c fred.c

$ ls *.o

bill.o fred.o

> 调用程序(program.c 它包含库的头文件并且调用库中的一个函数)

/* <a target=_blank href="mailto:*@file">*@file</a>  program.c 调用库函数的源文件 * */#include <stdlib.h>#include "lib.h"int main(){    bill("Hello World");    exit(0);}

> 编译测试

$ gcc -c program.c

$ gcc -o program program.o bill.o

$ ./program

bill: we passed Hello Wolrd

$

> 创建库文件

$ av crv libfoo.a bill.o fred.o

a – bill.o

a – fred.o

> 使用库文件

创建库文件成功,两个目标文件也已添加进去。在某些系统,尤其是从Berkeley UNIX衍生的系统中,要想成功使用函数库,还需要为函数库生成一个内容表。(在Linux中,若使用GNU的软件开发工具时,这一步骤并不需要,但做了也无妨)

$ ranlib libfoo.a

之后函数库便可以使用了

$ gcc -o program program.o libfoo.a

$ ./program

bill: we passed Hello World

也可以使用-l选项来访问函数库,但因其未保存在标准位置,所以必须使用-L选项来告诉编译器在何处可以找到它,如下所示:

$ gcc -o program program.o -L. -lfoo

-L.选项攻速编译器在当前目录(.)中查找库函数。-lfoo选项告诉编译器使用名为libfoo.a的函数库(或者名为libfoo.so的共享库,如果它存在的话)

*共享库

许多支持共享库的UNIX系统和Linux系统可以克服静态库的缺点。

当一个程序使用共享库时,它的链接方式是这样的:程序本身不再包含函数代码,而是引用运行时可访问的共享代码。当编译好的程序被装载到内存中执行时,函数引用被解析并产生对共享库的调用,如果有必要,共享库才被加载到内存中。

通过这种方法,系统可以只保留共享库的一份副本供许多应用程序同时使用,并且在磁盘上也仅保存一份。

另一个好处是共享库的更新可以独立于依赖它的应用程序。例如,文件/lib/libm.so就是对实际库文件修订版本(/lib/libm.so.N,其中N代表主版本号)的符号链接。当Linux启动应用程序时,它会考虑应用程序需要的函数库版本,以防止函数库的新版本致使旧的应用程序不能使用。

Linux系统中,负责装载共享库并解析客户程序函数引用的程序(动态装载器)是ld.so。用于搜索共享库的额外位置可以在文件/etc/ld.so.conf中配置,如果修改了这个文件,需要执行命令ldconfig来处理它。(例如安装了X视窗系统后需要添加Xll共享库)

创建共享库:

> $ gcc -fPIC -shared -o libfoo.so bill.c fred.c

生成共享库libfoo.so

> $ gcc -oprogram program.c ./libfoo.so

$ ./program

bill: we passed Hello World

查看一个程序需要的共享库是ldd工具,如:

$ ldd program

libc.so.6 => /lib64/libc.so.6 (0x0000003258200000)/lib64/ld-linux-x86-64.so.2 (0x0000003257e00000)

本例中,标准C语言函数库(libc)是共享的(.so),程序需要的是主版本号是6

项目

UNIX

Windows

目标函数

func.o

FUNC.OBJ

静态函数库

lib.a

LIB.LIB

共享库

lib.so

LIB.DLL

程序

program

PROGRAM.EXE

* 内核模块

要构造内核模块,需先在自己的系统中配置并构造好内核树。

#include <linux/init.h>#include <linux/module.h>MODULE_LICENSE("Dual BSD/GPL");static int hello_init(void){    printk(KERN_ALERT "Hello, world\n");    return 0;}static void hello_exit(void){    printk(KERN_ALERT "Goodbye, cruel world\n");}module_init(hello_init);module_exit(hello_exit);

生成hello.ko内核模块后,超级用户有权加载和卸载该模块。

root# insmod ./hello.ko

Hello, world

root# rmmod hello

Goodbye, cruel world

root#

3获得帮助

*man

root# man gccGCC(1) GNU GCC(1)

NAME gcc – GNU project C and C++ compiler

SYNOPSIS gcc [-c│-S│-E] [-std=standard] [-g] [-pg] [-Olevel] [-Wwarn…] [-pedantic] [-Idir…] [-Ldir…] [-Dmacro[=defn]…] [-Umacro] [-foption…] [-mmachine-option…] [-o outfile] infile…

Only the most useful options are listed here; see below for the remainder. g++ accepts mostly the same options as gcc.

DESCRIPTION When you invoke GCC, it normally does preprocessing, compilation, assembly and linking. The "overall options" allow you to stop this process at an intermediate stage. For example, the -c option says not to run the linker. Then the output consists of object files output by the assembler.

:

* info

root# info gccFile: gcc.info, Node: Top, Next: G++ and GCC, Up: (DIR)

Introduction************

This manual documents how to use the GNU compilers, as well as theirfeatures and incompatibilities, and how to report bugs. It correspondsto GCC version 4.1.2. The internals of the GNU compilers, includinghow to port them to new targets and some information about how to writefront ends for new languages, are documented in a separate manual.*Note Introduction: (gccint)Top.

* Menu:

* G++ and GCC:: You can compile C or C++ programs.* Standards:: Language standards supported by GCC.* Invoking GCC:: Command options supported by `gcc’.* C Implementation:: How GCC implements the ISO C specification.* C Extensions:: GNU extensions to the C language family.* C++ Extensions:: GNU extensions to the C++ language.* Objective-C:: GNU Objective-C runtime features.* Compatibility:: Binary Compatibility–zz-Info:(gcc.info.gz)Top,39 行 –Top——————————————————————欢迎使用 Info 4.8 版。输入 ? 以获得帮助,m 将得到菜单。

思念是一种幸福的忧伤,是一种甜蜜的惆怅,是一种温馨的痛苦;

Linux程序设计笔记(第1章 入门)

相关文章:

你感兴趣的文章:

标签云: